一、Makefile
例如项目有很多源文件,彼此关联。例如下面main.c用到了myutil.c。
1. myuti.h
|
|
2. myutil.c
|
|
3. main.c
|
|
4.Makefile
Makefile可以完成多文件的编译。
注意Makefile文件名的大小写,下面的缩进行必须是tab,否则在make的时候会报错。
|
|
main.out需要myutil.o和main.c,生成的方法就是下面的gcc myutil.o main.c -o main.out,注意下行是tab
myutil.o需要myutil.c,生成方法gcc -c myutil.c
二、重定向
main.c
|
|
1. 正常运行
|
|
2.使用文件作为标准输入
|
|
标准的输入是键盘,这里用文件替换了标准输入。
3.标准输出
改为0,触发错误输出
1是标准输出,2是错误输出。
|
|
三、main函数参数
argv是参数个数,argc是参数字符串数组,第一个参数就是命令本身。
|
|
运行结果
四、main返回值
在linux中每执行一条命令都会有返回结果,如果返回0代表成功,其他代表有异常。例如
|
|
例如我们执行两条命令可以用&&连接,如果第一条成功了,才可以执行下一条
|
|
所以在main函数中正确的返回是0
五、宏
1.函数宏
|
|
注意没有{},也没有return
2.系统宏
|
|
输出结果:
|
|
有些开发需要判断当前的操作系统,例如redis中的overcommit,系统要判断当前操作系统。
|
|
如果是linux,可以用这个。
|
|
六、ifdef、ifndef、endif
|
|
输出
|
|
如果换为ifndef,则输出
|
|
如果定义了HELLO, 且为ifdef
|
|
则输出
|
|
七、malloc free
|
|
输出:
|
|
八、结构体
结构体有很多种使用方法:
|
|
typedef给struct Point定义了一个别名point,这样理解就容易多了。
|
|
有几点需要注意:
point p相当于已经生成对象(Java: new Point())。
point p只是定义了空指针(Java: Point p)。
因为使用了typedef,所以struct Point p 等价于 point p; (point可以看做是struct Point的别名)
point p如果赋值,需要使用malloc开辟空间。
point p,则(p).x等价于p->x,同时等价于point p中的p.x。
|
|
九、函数指针和指针函数
简而言之:
函数指针:实际是一个指针,只不过指向了函数地址:
|
|
指针函数:实际是一个函数,只不过返回结果是指针
|
|
下面是测试:
|
|
输出结果:
|
|