您的位置:首页 - 教程 - C语言 - 正文
C语言的一些杂货

好久不写C,发现以前自己踩过的坑,又会踩一遍。朦胧的感觉一直有,就下决心总结一下,以免再次犯傻了。

 

首先是编译问题。什么放在.c文件中,什么放在.h文件中?为什么要分开两个文件?编译的时候是怎么处理的?

从功能性的角度来看,把所有代码都放到一个大的.c文件中并没有什么不好,甚至还帮助编译器做了很多工作。为什么要非看不同的.c和.h文件是因为代码是给人看的,只有编译过后的那个可执行文件才是给机器用来执行的。看代码和看书是一样的道理,总希望有个相应的目录,把相同模块的内容集中在一起,这样做一来是可以方便人理解,二来是很多相同名字的概念不用再做区分了。一个合理的目录绝对是一本好书必备的,甚至写书的人就应该先想到目录的结构。

 

弄明白这个以后只要说明.c和.h里面内容的差别,就能够轻松的分辨什么内容要放到什么里面了。.h文件叫做头文件,顾名思义它是对应的.c文件的开头部分,也就是总的描述这个.c文件是干什么的。.h里面放的是.c文件中的函数的声明,一些变量的声明,一些宏定义,大量的注释。这样做的好处有比如说自己以前写的几个函数,放到了.c文件中,现在想知道这几个函数干什么用的,又不想再读一遍自己的代码,其实看看自己写的.h文件就差不多能回忆起个大概了。另一个好处是如果其他好几个.c文件都要用到这里面的函数,那么只要每个.c文件中都include这个.h文件就可以了。当然光光include是不够的,需要编译器来做一些其他工作,这个后面说。

 

现在说一下编译的过程,来理解.h和.c文件。如果我们只要编译一个.c和对应的.h文件,那么问题很简单,首先#include这句话就可以看做是把.h里的内容直接复制到.c中,然后编译器的工作就只针对这一个文件了。没什么好说的。关键是多个文件进行编译的时候,文件之间可能有依赖关系,举个例子,b.c里面用到了a.c里面的函数,main.c里面用到了a.c和b.c里面的函数。如下:

a.c b.c main.c
#include"a.h"

#include"a.h"

#include"b.h"

#include"main.h"

#include"a.h"

#include"b.h"

首先是include这句话的功能就是复制粘贴是不变的,也就是说a.h这个文件里的内容会出现在a.c,b.c,main.c中。但是没关系啊,因为里面都是函数的声明,重复声明同一个函数是不会出问题的,这和变量是一个道理,比如你连写10行int a; 最后也只是有一个a变量。编译的时候首先让编译器把a.c和a.h合起来进行编译,用gcc编译器的话命令是gcc a.c -c a.o 其中a.o是生成的中间文件并不是最终结果,同样的道理编译b.c和c.c,并生成相应的b.o和c.o文件。然后用编译器中的连接器把这些中间文件.o们连接起来生成最后的可执行文件。gcc的编译命令是gcc a.o b.o c.o -o test。这个test文件就可以运行了。

 

然后是指针问题

平时的工作中经常要用到多维数组,这里主要说明多维数组的函数间的参数传递问题。这里主要说的是C中的情况,C++中的指针问题可能会有更好的解决方法,比如说引用,在形式上会更好看。

 

首先要明白数组和指针是不同的变量类型,举个例子:int a[10]; 其中a的地址和&a的内存地址是相同的,但C中并不把它们当做相同的类型,a和&a[0]是对等的,可以直接赋值给一个int * 的指针。但如果把&a赋值给一个int *类型的指针的话,就会给一个警告warning: assignment from incompatible pointer type [enabled by default]。虽然由于它们的值相同这样做不会出现什么问题,但是能够看到它们是不同的。那么哪里会遇到问题呢?我遇到的问题是在用sizeof运算符的时候。sizeof(a)返回的应该是sizeof(int)*10,而sizeof(&a)返回的就是sizeof(void*)一个普通指针的大小。我的情形是想要在传递数组的时候,检测出数组的长度,这样就不用再传递一个数组长度的参数了。但事实上这在C里面是不可能的,因为sizeof的功能就是返回对象占用空间的大小,如果不是采用值复制的方式传递数组,必定只是传递了指针,那么指针所占用的空间一定是一个void*的大小。所以遇到类似的问题还是老老实实的再传一个参数吧。

 

另外想补充的一点是数组指针和指针数组的差别,比较懒,看到别人写的比较好,引用一下吧。

http://see.xidian.edu.cn/cpp/html/476.html

http://www.cnblogs.com/hongcha717/archive/2010/10/24/1859780.html


评论: