-
不要使用函数库中没有对输入数据进行长度检查的函数。 在2.3.3节中展示了gets()在程序中可能导致的缓存越界问题,在现在的编程中应当使用fgets()来确保不会出现对输入长度无限制而导致缓存越界的问题。 因此在所有进行输入或内存拷贝等操作时,都应当使用对输入/拷贝长度进行限制的方法,避免出现越界bug。
-
声明 char* const*(*next)(); 的含义。
A. next是一个指针;
B. next是一个指向[函数]的指针;
C. next是一个指向[返回一个[指针]的函数]的指针;
D. next是一个指向[返回一个[指向类型为char的常量指针的指针]的函数]的指针;
-
使用typedef来帮助使声明更易懂。 在ANSI C标准中signal()的声明是:
void (*signal(int sig, void(*func)(int)))(int);
signal是一个函数函数;其返回类型为F,参数类型为int和void(\*func)(int);类型F为void\*(\*func)(int)。
可以有:
typedef void(*ptr_to_func)(int);
ptr_to_func signal(int , ptr_to_func);
这和signal的原始定义完全一致但显然更容易理解。
- typedef在对类型进行声明之后不能对声明后的类型进行扩展,这是与使用#define宏之间的显著区别。 例如:
#define dint32 int
unsigned dint32 udi;
typedef int tint32;
unsigned tint32 uti; /* 非法! */
另一个区别可以在下面的例子中清晰的呈现出来:
#define dint_ptr int*
dint_ptr pA, pB; /* 实际上可还原为 int* pA, pB; 导致pB类型为int而非int* */
typedef int* tint_ptr;
tint_ptr pC, pD; /* pC和pD的类型均为int* */
- 进一步思考typedef。typedef实际上是创建了一个类型的别名,而这个别名的创建方式与变量声明的方式是相似的。
typedef int (*array_ptr)[100];
typedef int array[100];
array_ptr pArr = NULL;
printf("%d %d\n", sizeof(array_ptr), sizeof(*pArr)); /* 输出:4 400 */
printf("%d \n", sizeof(array)); /* 输出:400 */
-
大神警示:不要为了方便起见对结构使用typedef。对结构使用typedef唯一的好处是能够省略书写“struct”关键字,但是这个关键字可以可以提示一些信息,不应该被省略。
typedef应该用在: - 数组、结构、指针以及函数的组合类型; - 可移植类型。例如若你需要一个20比特的类型,可以使用typedef来定义类型,当移植至不同平台时,修改typdef所定义的类型就可以了。