1、scanf函数:双引号内:“只保留输入控制符”。多余的字符都需要按原样输入,增加麻烦。
2、int* a,b; 【特别注意】这种情况,a是指针,b不是指针。
3、NULL的值:0x00000000 ,一个不能被用户使用的地址。
4、free()函数:
malloc两次只free一次会内存泄漏;malloc一次free两次肯定会出错。也就是说,在程序中malloc的使用次数一定要和free相等,否则必有错误。这种错误主要发生在循环使用malloc函数时,往往把malloc和free次数弄错了。
既然使用free函数之后指针变量p本身保存的地址并没有改变,那我们就需要重新把p的值变为NULL。避免使用野指针。
5、函数不能返回在此函数内定义的局部数组,因为局部数组分配在栈上,返回的地址内存退出函数后释放。
6、长度为0的字符串和字符串指针为NULL是不一样的。char *a=NULL,*b="";
7、char *a=NULL,*b=0,c='\0'; 数值上变量a,b,c都等于0。
8、switch()语句 判断表达式只能是整型(包括字符型)
9、char a[]="zh"; sizeof(a)等于3.
char a[2]="zh"; sizeof(a)等于2.这种情况是危险的,因为字符串没有存储结束符。
10、
char a[]="zh";
char b[]="abc";
char **string;
string = (char**)malloc(sizeof(char*)*2);
string[0] = &a;//数组名此处不是常量指针
string[1] = b;
11、数组名出现在表达式中才认为其是指针常量;两种情况数组名不是指针常量:1)作为sizeof的参数,2)对数组名取地址
对数组名取地址:(都是指针,指向的地址也相同,但是指针的类型不同)
char a[]="zhou";
printf("a=%p\n",a);
printf("&a=%p\n",&a);
printf("a+1=%p\n",a+1);
printf("&a+1=%p\n",&a+1);
return 0;
12、局部数组每次进入代码块都要分配空间,降低运行效率。
13、结构体的内存分配和边界对齐。(将边界要求严格的数据类型放在前面可以节省空间)
1.编译器按照结构体成员列表顺序给每个成员分配内存
2.当成员需要满足正确的边界对齐时,成员之间用额外字节填充
3.结构体的首地址必须满足结构体中边界对齐要求最为严格的数据类型所要求的首地址
4.结构体的大小为其最宽数据类型的整数倍
14、三目运算符:
#define MAX(a,b) ((a)>(b)?(a):(b))
int x=5;
int y=8;
int Z=MAX(x++,y++);
printf("x=%d,y=%d,z=%d",x,y,z);
//结果: x=6,y=10,z=9
15、转移表:使用回调函数(把函数名(指针)作为参数传递给另一个函数调用)
一个指针数组,数组的元素都指向一个函数,通过下标的改变使用不同的函数,可以代替switch语句。
16、二级指针做形式参数的时候,不要用二维数组做实参。
区分:指向指针的指针 和 二维数组