如何写出高质量c代码(一)C的陷阱

1.函数声明
首先让我们来看一个函数的声明

(* ( void  (*)() )0));

面对这样的一个函数声明也许有人会很迷惑,那么我们来一步步剖析
第一我们要分清指向函数的指针和返回指针的函数
我前面的一篇博客已经写过关于指向函数的指针了,他的一般声明方式是

void (*h)(); //h是指向返回值为void类型的指针
void *h();//这是一个返回void *类型的函数h

那么我们把一个指针强制类型转换成一个指向函数的指针就可以用

void  (*)() )xxx   //这里的xxx指针,或者地址

还有一点要知道的是,其实我们的函数名就是一个地址

例如:
void f();

但是我们调用的时候要用

f()去掉用,而不能直接用f  -----哈哈哈这个错误你肯定不会犯

所以我们一开始的时候那个声明的意思就很明显了

(* ( void  (*)() )0));//这是一个函数,执行0地址处的函数

2.分隔符要小心

例一:
if(a > 1);
a++;
例二:
ifa > 1a++;

这两个例子的结果是截然不同的,不要为自己的代码留下隐患

3.二维数组
二维数组和二重指针,指针数组,数组指针的关系我将会在以后写到,这里仅仅写比较易错的地方

int a[3][5];
siezeof(a);   //这是二维数组的总大小  即:3 * 5 * 4
sizeof(a[3]);  //这是二维数组的列大小 即:5 * 4
sizeof(a[3][5]);  //这就是二维数组的第三行第五列的元素的大小  int类型  4

这里还有一点大家常问我的问题,为什么sizeof(a)不是 4
我们在学校的时候很多老师都给我们说数”组名就是指针”,其实这是错误的,数组和指针区别我也会写在在接下来的博客

4.指针的初始化
前些天一个同学让我帮他找一个bug,其中有这样几行

int *p = NULL;
*p = 0

当我让他给我讲指针初始化的时候,他还理直气壮的和我说,初始化了啊,你看

int *p = NULL;

哈哈,那我来仔细和他讲讲这个错在哪里

int *p  =  NULL//这是声明一个指针p,并且让他指向NULL,也就是0地址处

然后直接赋值,也就是直接修改了0地址处的值,导致出错。这是一个很典型的错误。
5.外部引用
我们知道如果使用在其他文件中定义的变量或者函数,那么使用 extern关键字就可以使用了,这方面了多个文件共享变量,但是会有一些易犯的错误,例如

file1.c
int array[10]; //file1.c中定义了array这个数组
file2.c
extern int *array    //file2.c中声明一个外部变量,且认为*array和array[]是等价的

这样会导致错,并且编译器根本检测不到

猜你喜欢

转载自blog.csdn.net/bin_zhang1/article/details/80964033