- C编译器判断符号的方式是“贪心法”,即一直读入下一字符,看能否组成一个符号,直到不可能组成一个符号为止。
- 单引号括起的一个字符表示一个整数,双引号括起的一个字符代表一个指针。
- float *g();
g是一个函数,该函数的返回值类型为指向浮点数的指针。 - float (*h)();
h是一个函数指针,指向返回值是浮点数的函数。 - 分析(*(void(*)())0)(); :
void(*)() → 一个指向返回值为void的函数指针
(void(*)()) → 一个指向返回值为void的函数指针 的 类型强制转换符
(void(*)())0 → 指向内存首地址 的 函数指针
(*(void(*)())0)(); → 调用内存首地址处的函数 - 实现上述功能,更清晰的代码:
typedef void (*funcptr)(); (*(funcptr)0)();
- 运算符优先级表:
运算符 结合性 () [] -> . 自左向右 ! ~ ++ -- (type) * &(取地址) sizeof 自右向左 * / % 自左向右 + - 自左向右 << >> 自左向右 < <= > >= 自左向右 == != 自左向右 &(与) 自左向右 ^ 自左向右 | 自左向右 && 自左向右 || 自左向右 ?: 自右向左 assignments 自右向左 , 自左向右
- 根本上,C语言只有一维数组。但C种数组的元素可以是任何类型,所以可以通过一维数组去“仿真”出多维数组。
- 如果两个指针指向的是同一数组内的元素,它们相减等于数组中这两个位置的下标相减。如果两个指针不在同一数组,无法保证相减结果。
- 对于一个数组指针,由于*(a+i)和*(i+a)是一样的,所以 a[i] 和 i[a] 是一样的,只是不推荐这么写。
- 一个良好的编程习惯:需要被用到的外部对象只在一个地方声明,就是头文件。
test.h 文件 extern int a;
test.c 文件 int a=1;
- 即使以"r+"方式fopen一个文件,也不能在fread之后紧跟着fwrtie,反之亦然,必须在他们中间插入一个fseek
- 类型定义最好还是用typedef,而不是用宏。避免定义类型是指针时,出现错误。