编译
编译过程
文件.c->(预处理)->文件.i->(编译)->文件.S->(汇编)->文件.o->(链接)->elf程序
预处理
内容:加载头文件(#include),清除注释(//,./*),替换条件编译(#if #elif #endif #ifdef),替换宏定义(#define)
结果:生成.i文件(gcc -E xx.c -o xx.i)
作用:用于debug调试
注意:typedef定义由编译器处理
链接库
静态链接库
gcc x.c -o x.o -c
只编译不连接,生成.o文件
ar打包成 .a文件
ar crs lib${func1}.a ${func1}.o
c创建库(不管是否存在)
r库中插入模块
s创建文件索引,创建较大库时候能加快时间
编译:gcc x.c -o x -lx -L.
nm查看.a文件中有哪些符号
注意:gcc默认是动态库链接,-static强制静态链接指定链接(-lxxx),指定动态库地址(-L)
动态链接库
gcc x.c -o x.o -c -fPIC
gcc -o libx.so aston.o -shared
-fPIC位置无关码
-shared共享库方式链接
指定环境变量LD_LIBRARY_PATH(动态链接库运行时需要被加载)
编译:gcc test.c -o test -laston -L.
关键字
static修饰局部变量,形成静态局部变量,静态局部变量分配在数据段/bss段
register修饰变量会分配在寄存器,用于提升程序运行效率
extern声明外部全局变量(变量初始化在其他文件)
volatile变量不被被编译器改变
void:p = NULL; <=> p = (void *)0;即0地址处
'\0','0',0,NULL
'\0'是转义字符,ASCII编码值是0
'0'是字符,ASCII编码值是48
0是数字
NULL是(void *)0
变量
局部变量分配在栈上,作用域为代码块作用域,生命周期是临时的,连接属性为无连接,定义时未初始化则值随机,变量地址运行时在栈上随机分配地址
静态局部变量,分配在数据段/bss段(初始化非0在数据段,初始化0或未初始化在bss段),作用域为代码块作用域,生命周期为永久,链接属性为无连接,静态局部变量<==>全局变量
static使全局变量和函数链接属性由外部转为内部是为解决重名问题,宏和inline函数的链接属性为无连接
宏
宏定义
最值:#define MAX(a,b) (((a)>(b))?(a):(b))
一年有多少秒:#define SEC_PER_YEAR (3652460*60UL)
注意:类型默认int,超int类型范围(UL == unsigned int)
带参宏,带参函数,inline
宏定义在预处理期间处理,函数编译处理
宏定义在调用处展开,函数在调用处跳转执行,执行完跳回
宏定义原地展开,没有调用开销,函数是跳转执行再返回,有较大调用开销
带参宏定义不检查参数类型,返回值不附带类型,函数有明确参数类型和返回值类型,调用函数编译会做参数类型检查
函数体小适合用带参宏,函数体大用函数调用
inline修饰的函数为内联函数,内联函数编译器做参数静态类型检查也不用调用开销而是原地展开
debug宏
#define DEBUG
#ifdef DEBUG
#define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", FILE, FUNCTION, LINE); fprintf(stderr, VA_ARGS)
#else
#define DBG(...)
#endif
__FILE__是预定义宏,在编译的c文件名
__FUNCTION__是在编译的函数
__LINE__是在编译的行号
__VA_ARGS__表示一个或多个参数,类似可变参数中的省略号
...表示参数个数和类型是可变的,…为参数占位符
内核DEBUG宏
#ifdef DEBUG_S3C_MEM
#define DEBUG(fmt, args...) printk(fmt, ##args)
#else
#define DEBUG(fmt, args...) do {} while (0)
#endif
demo:
debug宏
#include <stdio.h>
#define DEBUG
#ifdef DEBUG
#define DBG(...) fprintf(stderr, " DBG(%s, %s(), %d): ", __FILE__, __FUNCTION__, __LINE__); fprintf(stderr, __VA_ARGS__)
#else
#define DBG(...)
#endif
int main()
{
DBG("test bug\n");
return 27;
}
结果示例: