C语言学习总结
看了李明杰老师的C语言课程,感觉老师讲得很细、很透。收获了很多新的知识,对C语言的理解更深了。本文将一些自己觉得容易遗忘和搞错的知识点整理出来,作为对李老师C语言课程的学习总结。
一、基础语法
1. 运行C语言程序的步骤
1> 编写.c源文件
2> 编译.c源文件为.o目标文件
3> 链接.o目标文件为可执行文件
4> 运行可执行文件
2. 常用格式符:
1> %d%i 整数(int)
2> %f 小数(float、double)默认是6位小数
3> %c 字符(char)
2. 变量作用范围:从定义变量的那行代码开始,一直到函数结束
3. 代码块的作用:及时回收不再使用的变量,可以提升性能
4. 变量内存地址分配原则:内存寻址由大到小,优先分配内存地址比较大的字节给变量
5. scanf参数中用什么分隔符,输入的时候也要加上,如果scanf参数中以空格隔开,可以输入可以以空格、tab、回车作为分隔符
6. include 的作用:拷贝文件的所有内容到#include所在的位置。自定义的文件用"",系统自带的文件用<>
7. printf函数返回的字符串常量的字符数,并不是字数
8. scanf函数返回成功接收得到的变量数
9. cc -o可更改可执行文件的名字
二、基本运算
1. 取余运算:取余结果的正负性只跟%左边的数值有关
2. a += 5 + 6 + 4; 运算顺序为a = a + (5 + 6 + 4);
3.“sizeof 变量名”是正确的用法,“sizeof 类型名”是错误的用法
4. 常量不能进行++运算
三、流程控制
1. 选择结构
1) if结构
if(条件1)
{
语句1;
语句2;
......
}
else if(条件2)
{
}
else
{
}
2) switch结构
switch (数值)
{
case 数值1:
语句1;
break;
case 数值2:
语句2;
break;
default :
语句3;
break;
}
2. 循环结构
while (条件)
{
循环体
}
do {
} while(条件);
for (语句1; 条件; 语句2)
{
循环体
}
1. 一个好习惯:在比较大小时,常量值放左边,变量放右边,防止出错
2. 如果要在if后面的语句中定义新的变量,必须用大括号{}(不用括号的话变量的作用域不明确,编译器会报错)
3. 如果在case中定义了新的变量,必须用大括号{}包住
4. 如果需要用到死循环,最简单的死循环是:while(1);或者for(;;);
5. while和do while的区别:
while:如果一开始的条件不成立,永远不会执行循环体
do while:不管一开始的条件是否成立,至少会执行一次循环体
6.如果要在循环体中定义新的变量,必须用大括号{}包住
四、函数
格式:
返回值类型 函数名(形式参数列表)
{
函数体
}
1. 起一个有意义的函数名
2. 如果没有明确说明返回值类型,默认是返回int类型,如果明确声明了返回值类型,也可以不返回任何值
3. 函数不能重复定义,但是可以重复声明
4. 如果有函数的声明,没有函数的定义
1> 编译可以通过,因为编译器只会检测语法合不合理,并不会检测函数有没有定义
2> 链接报错,因为链接的时候会检测函数是否定义
5.循环的使用原则:一般优先使用for循环然后再考虑while最后再考虑do while
五、内存剖析
1.输出格式
%d%i 十进制形式输出整数
%c 输出字符
%p 输出地址
%f 输出小数
%o 八进制形式输出整数
%x 十六进制形式输出整数
2.signed和unsigned的区别:
signed 最高位要当做符号位
unsigned 最高位不要当做符号位
3.异或的规律:
交换 956 == 965
任何数值跟0进行异或,结果还是原来的数值,9^0 == 9
aba == aab == 0^b == b
六、复杂数据类型
1、如果想再定义数组的同时进行初始化,数组元素个数必须是常量,或者不写
2、只能在定义数组的同时进行初始化
3、数组作为函数参数,传递是整个数组的地址,修改函数形参数组元素的值,会影响到外面的实参数组
4、把字符数组的数组名传入printf,仅仅是个警告,可以打印出数组里的内容。
5、字符串必须以’\0’(ASCII码值为0)结尾,char name5[] = {'i', 't'};只能说是字符数组(没有以’\0’结尾)
6、Strlen函数:计算的是字符数,并不是字数。一个汉字算作3个字符计算的字符不包括\0
7、结构体所占用的存储空间 必须是 最大成员字节数的倍数
七、常见错误整理
1. 忘记引入头文件
2. 单引号和双引号使用不当:单引号只能括住单字节的字符,不能括住中文字符和字符串
3. 空格问题
touch和cc指令后面加入了空格,系统会当成两个文件使用,解决办法:使用“\ ”代替空格
在程序中不该敲空格的地方多敲了空格
4. 链接错误undefined symbols for architecture x86_64 “_main”,原因:没有main函数
5. redefinition of “函数名”,原因:函数同名
6. 标示符错误
| 合法标识符 | 非法标识符 | 注释 |
|---|---|---|
| fromNo12 | from#12 | 标识符中不能使用#符号 |
| my_Boolean | my-Boolean | 标识符中不能使用“-”符号,应使用下划线“_”代替 |
| Obj2 | 2ndObj | 标识符不能使用数字开头 |
| myInt | int | “int”是内建关键字 |
| jack_rose | jack&rose | 符号“&”不能出现在标识符中 |
| GUI | G.U.I | 标识符内部需要出现“.”分隔符 |
7. 变量没有初始化就使用,解决办法:变量声明以后就初始化
8. implicit conversion from ...to ...类型不匹配
9. 在case后定义新变量,解决办法:用大括号保住
10. while (...); 死循环
11. 在for循环后写分号,后面语句只执行一次
12. scanf直接传入变量
八、交换两个变量的值的三种方法
1) 使用第三个变量
int temp = a;
A = b;
B = temp;
2) 利用两个变量的差值
a = b - a;
b = b - a;
a = b + a;
3) 利用位运算
a = a ^ b;
b = a ^ b;
a = a ^ b;
