源文件.c经过处理变成.exe文件,中间经过了编译链接,形成了可执行程序,编译链接经过翻译环境,变成.exe在经过运行环境运行
exe后缀放的是二进制信息,.c放的是文本文件里面都是字符。
每一个源文件都会单独经过编译处理生成目标文件 每个目标文件经过连接器链接在一起生成目标文件
链接器中同时也可以链接库函数任何该程序所用到的函数,而且它们可以搜索程序员个人的程序库,将其需要的函数链接到程序中
编译又分为预编译,编译,汇编三个环节,
Linux系统中输入gcc-E test.c就是生成预编译文件,test.i最后生成
预处理会把头文件包含,并且删除注释,把宏定义替换,都是文本文件
gcc-S test.i生成test.s编译把c代码翻译为汇编代码,
gcc-c test.s生成test.o就是目标文件obj汇编会形成符号表,
链接中有1,合并段表2,符号表的合并和重定位
每个obj目标文件都有固定的eff格式,
运行环境,1.程序运行中必须载入内存中,一般由操作系统中,还可以手动植入
2.程序执行从main函数开始
3.开始执行程序,数据堆栈,存储局部变量返回地址,还可以设置静态内存
4.中止程序包括正常中止和意外中止
预编译详解
__FILE__表示代码所对应文件名称 __LINE__表示当前代码行数
__DATA__表示日期 __TIME__表示时间
预处理指令#define #includee #pragma pack #endif
#define可以定义标识符,也可以定义宏
#define机制允许把参数替换到文本中,这种实现称为宏 、
#define SQUARE(x) x*x #define不能递归,不能调试,字符串里面的内容并不会被替换
使用#可以把一个宏参数变为字符窜,
##可以把位于它两端的符号合成一个符号,它允许宏定义从分离的文本创建标识符
宏可以做到函数也做不到的事情,宏不受类型限制,里面参数可以是数据类型,例如int
宏和函数有缺点也有优点
预处理指令在预处理阶段解决
1.#if 常量表达式(条件编译指令)
#endif 两个一对结束#if 常量表达式为真参与编译,为假不参与编译
2.#if常量表达式 #elif常量表达式#else//#endif 多分枝编译
3.判断是否被定义 #if defined(symbol)等价#ifdef symbol结尾还得用#endif(如果symbol定义参与编译)
如果没被定义编译写成#if !defined #ifndef 都是不定义编译的意思
4.嵌套指令 #if defined(os) #elif defined()#endif 参考多分支理解
避免头文件被多次使用可以用#pragma once
或者用#ifndef __TEST.H__ #define __TEST.H__ #endif
表示如果没给定义就定义一次,以后在扫到就是定义过不在定义
offsetof(struct s,c1)可以算结构体中变量相对于起始位置的偏移量