1 运算符的优先级
2 类型转换
2.1 有符号与无符号数
结果输出为
-2 -2
-1 2147483647
-1 2147483647
2.2 浮点数与整数
3 控制流
这一部分主要需要注意if else之间的嵌套时的配对情况,及循环语句的终止条件与状态。
4 转义字符
除了/n /t这一类的转义字符,还有一类/ddd(三位八进制数) /xhh(两位二进制数)的转义字符,这些字符都代表单个char类型,而且其十进制制数可以由相应的数制转换过来。
5 变量的作用域与生命期
全局变量:所有文件都能看到,程序退出时生命期结束
局部变量:只在定义的范围内可见,离开定义的范围后生命期结束
全局静态变量:只在所定义的文件中可见,程序退出时生命期结束
局部静态变量:只在定义的范围内可见,程序退出时生命期结束
6 指针与数组
数组名不是指针,因为我们取一个数组名的sizeof,结果为数组长度×元素大小,而我们取指针取sizeof,总得到4。在一定程度上可以说数组名是一个常量标识。但数组名在使用时经常表现的类型与指针。数组名在作为实参传递时,将变为普通的指针。
一维数组int a[]
数组名a,指代了数组的起始地址,我们有int* p=a=&a[0],二者的类型均为int*。而对于&a,它的值等于&a[0],但它的类型是(int (*)[])即指向一维数组的指针。我们使用[]时a[i]被编译器翻译为*(a+i)。
如果我们使用指针int *p=a;则p在所有a出现的地方都可以替换之,即数组名与一个指向数组首地址的整形指针的使用是神似的。
二维数组int a[2][4]
数组名a表示数组的起始地址,有int *p=&a[0][0]=(int*)a,但此时a的类型不再是int*,而成为类似于指向一维数组的指针即int(*)[4]。而对于&a,成为int (*)[2][4],即类似指向二维数组的指针。此时a[i]=a+i=*(a+i)取得的各行的首地址,要得到行内的元素即a[i][j]应该使用*(*(a+i)+j)
7 字符串常量
字符串常量,分配在常量区,在编译时就已经分配完成,在程序运行中可以取其值,但不可以修改其内容。程序员不需要担心使用字符串常量会泄露内存,因为它不并在堆上分配,而是由系统管理,使用过多常量的后果是程序所占空间有所增大。对于许多函数而言,字符串常量都可以作为一个指针使用。
8 乘、除2与移位
在C中,乘2操作可以转换为左移操作,不论有符号数还是无符号数,这一结论都是成立的。
除法操作遵照向0取整,如5/2=2,-5/2=-2。因此除2的近似操作与右移存在误差。对于被除数为非负情况下,不存在误差,而被除数为负时,存在误差。x/2^k = (x+(2^k - 1))>>k;
9 相异符号两数模运算
结果与被除数保持相同
10 switch(i)
switch中的i只能是整数类型,或可以和整数类型直接等价表示的,如char类型。
11 数组成员的地址与内容
对于数组,注意取元素要用[],或者等的对地址取*,对于数组名加偏移,只是元素的地址而已。