顺序结构、选择结构(分支结构)、循环结构*
2.位 字节bit是位 是指为0或者1,byte是指字节,一个字节 = 八个位
3.基础认识- c语言编写的程序称为源程序,又称为编译单位
- 只有一个main函数,是程序运行的起点
- 关键词不能作为表示符号
- 预定义标识符:define scanf printf include
- 可以做为用户标识符
-
十进制转换成二、八、十六进制
-
二、八、十六进制转换成十进制
-
C语言只有八、是、十六进制,没有二进制。
- !!!但运行的时候,所有的进制都要转换成为二进制来进行处理
-
C语言中八进制规定要义 0 开头,八进制没有8,逢8进1
-
C语言中十六进制规定要义 0x 开头
-
整型一般是 4个字节, 字符型是 1个字节,双精度一般是 8个字节
- long int x;表示x是长整型
- unsigned int x;表示x是无符号整型
- / 两边是整型,结果为整型
- / 一边是小数,结果为小数
- % 余数,求整
- 定义时不可用连续赋值 eg: int x=y=10 ❌
- 定义完变量后,可以连续赋值 eg: int x,y; x=y=10;✔️
++在前 先加后用, ++在后 先用后加
7.注释- 注释不是C语言
- 不占运行时间
- 没有分号
- 不可以嵌套
- int a = 1.6;
- (int) a;
- 1/2; 3/2;
- ‘1’ 是字符占一个字节, "1"是字符串占两个字节(含有一个结束符号)
- ‘0’ 的ASCII码表的数值为48,'a’为87,‘A’为65
- 字符可以进行算术运算 ‘0’ - 0 = 48
- 大写字母和小写字母的转换的方法 ‘A’ + 32 = ‘a’ 相互之间一般相差32
- 转义字符
- ,n ,’ ‘’,
- 八进制转义字符
- ‘141’ 合法的,前导的0不能写
- 十六进制转义字符
- ‘x6d’ 合法的,前导0不能写,并且x是小写
- printf可以只有一个参数,也可以有两个参数
- printf(“xxx”, xxx);把第二部分的变量、表达式、常量以第一部分的形式展现出来
-
printf(“%2d”,123 ); 第二部分有三位,大于指定的两位,原样输出123
printf(“%5d”,123 ); 第二部分有三位,小于指定的五位,左边补两个空格 123
printf(“%10f”,1.25 ); 小数要求补足6位的,没有六位的补0,。结果为 1.250000
printf(“%5.3f”,125 ); 小数三位,整个五位,结果为1.250(小数点算一位)
printf(“%3.1f”,1.25 );小数一位,整个三位,结果为1.3(要进行四舍五入)
- scanf(“a=%d, b=%d”, &a, &b);
- 以第一部分的格式在终端输入数据
- 只有输入 a=12,b=32 才能正确赋值
- scanf("%d, %d", x,y);❌
- scanf("%d, %d", &x, &y); ✔️
- scanf的第二部分一定是要地址
eg:
scanf(“%d”,x) 错误 ; scanf(“%d”,p)正确
scanf(“%d”,&p) 错误 ; scanf(“%d”,*p)错误
10.2.1指定输入的长度- scanf("%2d%4d%d", &x, &y, &z); x为12,y为3456,z为7;
- scanf**(“%2d%4d%d”,&x,&y,&z);x为1,y为2345,z为67**
- scanf("%d", &x);输入1,表示整数1
- scanf("%d", &x);输入1,表示是字符‘1’对应ASCII码表的数值为整数48
- y=(int)(x*100+0.5)/100.0 这个保留两位,对第三位四舍五入
- y=(int)(x1000+0.5)/1000.0 这个保留三位,对第四位四舍五入
- y=(int)(x*10000+0.5)/10000.0 这个保留四位,对第五位四舍五入
- -_- => x = (int)x 这样是把小数部分去掉
C语言是用非0表示逻辑真的,用0表示逻辑假的 C语言有构造类型,没有逻辑类型11.1关系表达式
- 表达式的数值只能为1(表示真),或0(表示假)
- eg: int x= 1,y=0,z=2;则:x
0<2 返回1
- && || ! 三种逻辑运算符号
- 优先级别: ! > && > ||
if语句没有大括号 只包括if后的第一条语句
11.4三元表达式eg: int x=5,y=1; x > y ? ‘结果为真的返回值’ : ‘结果为假的返回值’
11.5 swtich- switch只可以和break一起用,不可用和continue用
- case中break;表示退出switch循环
-
函数:是具有一定功能的一个程序块,是C语言的基本组成单位
-
不能嵌套调用,但可嵌套使用
-
函数名缺省返回值类型,默认为int
-
判断质数
void isPrime(int n){ for(int i = 2;i< n;i++){ if(n % i == 0){ printf("不是质数"); break; }else { printf("是质数"); break; } } } int main(){ int x; printf("输入一个正整数: "); scanf("%d",&x); isPrime(x);s }
-
求阶层
-
int jiecen(int n){ int result = 1; for(int i = 1;i<=n;i++){ result *= i; } return result; } int main(){ int x; scanf("%d", x); printf("%d", jiecen(x)); }
-
-
参数传递
- 传 数值,形参的变化不会改变实参的变化
- 传 地址,形参的变化有可能改变实参的变化
指针变量的本质是用来存放地址,而一般的变量是存放数值的
不同类型的指针变量不能赋值,不同类型的指针变量不能赋值
13.1 *p 和 p差别- *p是数值,p是地址
- *p可以作为变量使用,*的作用是取后面地址p里的数值
- p是当作地址来使用。可以用在scanf函数中:scanf("%d", p);
-
*p++是地址会变化。 取当前值,然后在移动地址
-
(*p)++ 是数值会变化。取当前值,然后在是数值增加1
-
例题:int *p,a[]={1,3,5,7,9};p=a; 请问*p++和(*p)++的数值分别为多少? *p++: 这个本身的数值为1。由于是地址会增加一,所以指针指向数值3了。 (*p)++ 这个本身的数值为1。由于有个++表示数值会增加,指针不移动,但数值1由于自加了一次变成了2。
-
*p:一级指针:存放变量地址
-
**q:二级指针:存放一级指针的地址
-
int x=7; int*p=&x,**q=p; 问你:*p为多少?*q为多少?**q为多少? 7 p 7 再问你:**q=&x的写法可以吗? 不可以,因为二级指针只能存放一级指针的地址。
-
char *s="meikanshu"; while(*s){ printf("%c",*s); s++; } //这个s首先会指向第一个字母m然后通过循环会一次打印出一个字符,s++是地址移动,打印了一个字母后,就会移动到下一个字母
- int a = 2; *p = &a;(定义的同时初始化)
- int a = 2,*p; p = &a;(定义之后初始化)
//传数值 传地址 void fun(int a,int b) void fun(int *a,int *b) { int t ; { int t ; t=a;a=b;b=t; t=*a;*a=*b;*b=t; } } main() main() { int x=1,y=3, { int x=1,y=3, fun(x,y); fun(&x,&y) printf(“%d,%d”,x,y); printf(“%d,%d”,x,y); } } 这个题目答案是1和3。 这个题目的答案就是3和1。 传数值,fun是用变量接受,所以fun中 传地址,fun用指针接受!这个时候fun 的交换不会影响到main中的x和y 。 中的交换,就会影响到main中的x和y。 传数值,形参的变化不会影响实参。 传地址形参的变化绝大多数会影响到实参!13.7函数返回值是地址
int *fun(int *a,int *b) 可以发现函数前面有个*,这个就说明函数运算结果是地址 { if(*a>*b)return a; return a 可以知道返回的是a地址。 else return b; } main() { int x=7,y=8,*max; max = fun(&x,&y); 由于fun(&x,&y)的运算结果是地址,所以用max来接收。 print("%d", max); }TIP:
指针变量是存放地址的。并且指向哪个就等价于哪个,所有出现*p 的地方都可以用它等价的代替
-
eg:
-
int a = 2, *p = &a; *p = *p + 2; //由于*p指向变量a,所以指向哪个就等价哪个,这里的*p等价于a,相当于是 a = a + 2
-
数组:存放的类型是一致的。多个数组元素的地址是连续的;
14.1初始化int a[5]={1,2,3,4,5}; 合法 int a[5]={1,2,3, }; 合法 int a[]={1,2,3,4,5}; 合法,常考,后面决定前面的大小! int a[5]={1,2,3,4,5,6}; 不合法,赋值的个数多余数组的个数了14.2定义
int a[5];注意这个地方有一个重要考点,定义时数组的个数不是变量一定是常量。 int a[5] 合法,最正常的数组 int a[1+1] 合法,个数是常量2,是个算术表达式 int a[1/2+4] 合法,同样是算术表达式 int x=5,int a[x]; 不合法,因为个数是x,是个变量,非法的, define P 5 int a[P] 合法,define 后的的P是符号常量,只是长得像变量14.3二维数组初始化
int a[2][3]={1,2,3,4,5,6}; 合法,很标准的二维的赋值。 int a[2][3]={1,2,3,4,5, }; 合法,后面一个默认为0。 int a[2][3]={{1,2,3,} {4,5,6}}; 合法,每行三个。 int a[2][3]={{1,2,}{3,4,5}}; 合法,第一行最后一个默认为0。 int a[2][3]={1,2,3,4,5,6,7}; 不合法,赋值的个数多余数组的个数了。 int a[][3]={1,2,3,4,5,6}; 不合法,不可以缺省行的个数。 int a[2][]={1,2,3,4,5,6}; 合法,可以缺省列的个数。14.4补充
-
一维数组的重要概念
- 对a[10]这个数组的讨论
- a表示数组名,是第一个元素的地址,也就是元素a[0]的地址(等价于&a)
- a是地址常量,所以只要出现a++,或者是a=a+2赋值都是❌的
- a是一维数组名,它是列指针,也就是a+1是跳一列
- 对a[3] [3]的讨论
- a是数组名,第一个元素的地址,也就是a[0] [0]的地址
- a是地址常量,所以只要出现a++,或者是a=a+2赋值都是❌的
- a是二维数组行,它是行指针,也就是a+1是跳一行
- a[0]、a[1]也都是地址常量,不可以对它进行赋值 *** 作,同时它们都是列指针,+1后 都是跳一列
- 注意a和a[1]、a[0]是不同的,它们的 基类型是不同的。前者是一行元素,后者是一列元素
- 对a[10]这个数组的讨论
-
二维数组做题技巧
-
如果有a[3][3]={1,2,3,4,5,6,7,8,9}这样的题目。 步骤一:把他们写成: 第一列 第二列 第三列 a[0]-> 1 2 3 ->第一行 a[1]-> 4 5 6 —>第二行 a[2]-> 7 8 9 ->第三行 步骤二:这样作题目间很简单: *(a[0]+1)我们就知道是第一行的第一个元素往后面跳一列,那么这里就是a[0][1]元素,所以是1。 *(a[1]+2)我们就知道是第二行的第一个元素往后面跳二列。那么这里就是a[1][2]元素,所以是6。 一定记住:只要是二维数组的题目,一定是写成如上的格式,再去做题目,这样会比较简单。
-
-
数组初始化
-
int a[]={1,2} 合法。 int a[][4]={2,3,4}合法。 但int a[4][]={2,3,4}非法。
-
-
二维数组中的行指针
-
int a[1][2]; //其中a现在就是一个行指针,a+1跳一行数组元素搭配(*)p[2]指针 //a[0],a[1]现在就是一个列指针。a[0]+1 跳一个数组元素。搭配*p[2]指针数组使用
-
-
脱衣服法则
- a[2] 变成 *(a+2) a[2][3]变成 *(a+2)[3]再可以变成 *(*(a+2)+3)
- 语言简洁,紧凑使用方便 灵活(37个关键词,9中控制语句)
- 运算符丰富(34中运算符)
- 数据类型丰富
- 具有结构化的控制语句
- 语法限制不太严格,程序设计自由度大
- 允许直接访问物理地址、能进行位 *** 作,可以直接对硬件进行 *** 作
- 可移植性好
- 生成目标代码质量高,程序执行效率高
- 一个程序由一个或多个源程序文件组成
- 函数是C程序的主要组成部分
- 一个函数包括两个部分(函数首部,函数体(声明、执行部分))
- 程序总是从main 函数开始执行
- C程序对计算机的 *** 作由 C 语句完成
- 数据声明和语句最后必须要有分号 ;
- C语言本身不提供输入输出语句(由C标准函数库中的函数来实现的)
- 程序应当包含注释,增强可读性
- 对数据的描述
- 再程序中要指定用到哪些数据以及这些数据的类型和数据的组织形式,这就是 数据结构
- 对 *** 作的描述
- 要求计算机进行 *** 作的步骤,也就是 算法
数据是 *** 作的对象, *** 作的目的是对数据进行加工处理,得到期望的结果
算法 + 数据结构 = 程序17.2.算法是什么
- 数值运算算法 (目的是求数值解)
- 非数值运算算法 (包括面十分广泛,常用于事务管理领域)
- 有穷性。有限的 *** 作步骤
- 确定性。每一个步骤都是确定的
- 有零个或多个输入。执行算法时需要从外界取得必要的信息
- 有一个或多个输出。算法的目的是为了求解,没有输出算法没有意义
- 有效性。算法中的每一个步骤都能有效地执行
- 顺序结构
- 选择结构
- 循环结构
- 当型循环结构
- 直到型循环结构
- 自顶向下
- 逐步细化
- 模块化设计
- 结构化编码
- 顺序结构
- 分支结构
- 循环结构
- 关系、算术、赋值运算符的优先级:算数运算符 > 关系运算符 > 赋值运算符
- 逻辑运算符的优先次序: ! → && → || (! 为三者中最高)
- 与其他运算符的优先次序:赋值运算符 < &&和|| < 关系运算符 < 算数运算符 < !
- 先无条件地执行循环体,然后判断循环条件是否成立
- continue 只是结束本次循环,而不是终止整个循环的执行
- break 结束整个循环过程,不再判断执行循环的条件是否成立
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LJcR0ua-1636447704374)(images1635301661977.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8YV6aKlr-1636447704376)(images1635301676467.png)]
24.函数调用形式 1.函数调用时的数据传递- 形式参数(形参),定义函数时函数名后面的变量名
- 实际参数(实参),主函数调用函数时,函数名后面的参数
一个函数中调用另一个函数需要具备:
- 被调用函数必须时已经定义的函数(是库函数或用户自己定义的函数)
- 如果使用库函数,应该再本文箭头加对应的 #include 指令
- 如果使用自己定义的函数,而该函数的位置再调用它的函数后面,应该声明
两中形式:
- float add(float x, float y);
- float add(float, float);
- 原型说明可以放在文件的开头,这时所有函数都可以使用此函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QgFvxecB-1636447704378)(images1635302523867.png)]
28.格式转换说明符p = (int *)malloc(4); p = (int *)malloc(sizeof(int)); //两个式子等价 //malloc的返回类型是void2.函数指针的用法
int add(int x, int y) {....} main() { int (*f)(); f=add; } 赋值之后:合法的调用形式为1、add(2,3); 2、f(2,3); 3、(*f)(2,3)3.scanf 和 gets
//传入字符串 good good study! scanf("%s", a); //只会接收 good;不可用接受空格 gets(a); //接收good good study!;可以接收空格4.指针
#include5.字符串的赋值int main(){ char ch[] = "iamhandsome"; char *p = ch; printf("%d n", *p); printf("%d n", p); printf("%d n", p + 2); printf("%d n", *(p + 2)); printf("%d n", *p + 2); } //对应ASCII码表 105 i 6422028 6422030 109 m 107 k
C语言中没有字符串变量,所以用数组和指针存放字符串: 1、char ch[10]={“abcdefgh”}; 对 2、char ch[10]=“abcdefgh”; 对 3、char ch[10]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’}; 对 4、char *p=“abcdefgh”; 对 5、char *p; 对 p=“abcdefgh”; 6、char ch[10]; 错了!数组名不可以赋值! ch=“abcdefgh”; 7、char *p={“abcdefgh”}; 错了!不能够出现大括号!6.字符串赋值的函数
//把s指针中的字符串复制到t指针中的方法 1.while( (*t=*s)!=null ){s++;t++;} 完整版本 2、while( *t=*s ){s++;t++;} 简单版本 3、while( *t++=*s++); 高级版本7.typedef
- 取别名,不会产生新的类型,也是关键词
- typedef int qq 那么 int x 就可以写成 qq x
- typedef int *qq 那么 int *x就可以写成 qq x
- 若用数组名作为函数调用的实参,传递给形参的是:数组的首地址
- 递归算法必须包括:终止条件 和 递归部分
- 一个链表最常用的 *** 作是再末尾插入结点和删除尾节点,选用: 带头结点的双循环链表 最节省时间
- 二叉树的 叶子结点 个数: n = n2 + 1;
- n为叶子结点个数, n2:度为2的结点数
- 判别有向图中是否存在回路,可使用: 拓扑排序算法
- 无向图的邻接矩阵是一个: 对称矩阵
- 循环队列存储在数组A[m]中,则入队时的 *** 作为: rear = (rear + 1) % (m + 1);
- Kruskal 算法 适合 构造一个稠密图G的最小生成树
- 快速排序在 被排序数据完全无序的情况下最易发挥其长处
- 10000个数组元素中取几个元素,采用 简单选择排序算法 最节省时间
- 线性表的链式存储结构,要求内存中可用存储单元的地址:连续或不连续都可以
- 树的存储形式:
- 双亲表示法
- 孩子链表表示法
- 孩子兄弟表示法
- 连通图:若从无向图的任意一个顶点出发进行一次深度优先搜索可以访问图中所有的
顶点 - 浮点型变量分别为:单精度,双精度
- 符号 ‘&’ 是 取地址运算符,&a是指:a在内存中的地址
- 在C程序中,指针变量能够赋 地址值 或 NULL(或ˊˊ,或 0,或空值)值
- C语言中一个字母占一个字节。但 字符串后必须跟一个结束字符’’,因此总共占了2个字节
- eg: “abc” 占4个字节
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)