脚本宝典收集整理的这篇文章主要介绍了C缺陷与陷阱(C Traps and Pitfalls)学习笔记,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
前言
近来学习操作系统这门课,课程的实验基于linux 0.11,于是从图书馆借来了 C Traps and PITalls 和 Expert C PRogramming,打算提高一下c语言水平。
先从前一本开始。这本书很薄,即使是英文版也只有140多页,讲的都是c语言中容易犯错的地方。
注意:这篇笔记并没有包括整本书的内容,而只是摘抄了本人需要的知识(加上了一些自己的理解)。如需完整了解,还请自行看书。
第一章:词法陷阱
符号之间的空白(extra space)是被忽略的。
extra space包括空格、制表符和换行
比如你觉得这个函数声明太长
int* foo(int arg1, const char *arg2, double arg3, struct bar *arg4)
{
/*...*/
}
可以写成
int* foo( int arg1,
const char *arg2,
double arg3,
struct bar *arg4)
{
/*...*/
}
符号分析策略
编译器从左到右分析符号,使获取的符号尽可能地长。
a---b;
等价于 a-- -b;
所以 a = b/*p;
这种写法很可能不是你想要表达的意思。 /*
会被认为是注释符的左边,于是它后面的内容都成了注释,实现除法的写法应该是 a = b / *p;
。
但是,形如a-----b
就不能理解成 (a--)-- (-b)
,而应该是 (a--)-(--b)
,因为 (a--)--
这样是不符合语法的。
关于整型常量
int a = 90;
和 int b = 090;
是不一样的呀。
后者在9的前面多了一个0,编译器就会以为090是八进制,于是b的值就是9*8^1 + 0*8^0 = 72d
关于char
char就相当于整型,只是它的大小是1字节。相应地,字符'a'就是对应ASCII码里的数字。
char*是指针,32位下大小为4字节。与其它指针无异。
一个用双引号括起来的字符串(如"hello"
),就是一个指向字符串(加上结尾的' '
)首地址的指针缩写。
所以
printf("hello");
类似于
char* str = "hello";
printf(str);
第二章:语法陷阱
关于调用函数
假如有函数
void bar(int arg);
那么:
bar();
执行函数
int (*p)(int a) = bar;
bar是函数地址,可以赋值给函数指针(当然类型要相同)
第三章:语义陷阱
关于指针和数组
Only two things can be done to an array: determine its size and oBTain a pointer to element 0 of the array. All other array operations are actually done with pointers, even if they are written with what look like subscripts.
如果定义指针来当数组用,需要手动用Malloc在运行时堆获得空间;而定义数组,编译器就自动在栈帧里分配空间。指针和数组的操作相似,关于数组的操作大部分都是基于指针的。
指针不是数组 Orz...
这里要指出的是关于char类型数组和指针的两个不同。
假定现在需要一个hello的字符串,可以这么写: