1、程序的翻译环境:源代码被转换成可执行的机器指令
2、程序的执行环境:用于实际自行代码
3、C语言程序的编译和链接:
(1)预处理:头文件展开、去注释、宏替换、条件编译
(2)编译:将C变成汇编代码
(3)汇编:将汇编代码变成二进制目标文件——不可执行
(4)链接:将目标文件和C库文件进行链接,形成可执行程序
其中(1)~(3)步在编译器完成,(4)在链接器完成
编辑器——vim:写代码;
编译连接器——gcc:将代码变成二进制;
调试器——gdb:找bug;
4、预处理符号介绍
举例:
5、#define
(1)#define定义标识符和宏
1>在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号
2>替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值替换
3>最后,再次对结果文件进行扫描,看看是否包含任何由#define定义的符号
注意事项:
1>宏参数和#define定义中可以出现其他#define定义的变量,但是对于宏,不能出现递归
2>当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索
(2)#和##
1>#的作用是把一个宏参数编程对应的字符串
2>##的作用是可以把位于它两边的符号合成一个符号
6、宏和函数
(1)宏的优点:
1>宏比函数在程序的规模和速度方面更胜一筹
2>宏是与类型无关的
(2)宏的劣势:
1>每次使用宏的时候,一份宏定义的代码将插入到程序中,除非宏比较短,否则可能大幅度增加程序的长度
2>宏是不能调试的
3>宏与类型无关,不够严谨
4>宏可能会带来运算符优先级的问题,呆滞程序容易出现错误
(3)命名约定
宏名全部大写;函数名不要全部大写
(4)#undef:用于移除一个宏定义
7、条件编译
常见的条件编译指令:
(1)#if 常量表达式
//.....
#endif
//常量表达式由预处理器求值
如:
#define __DEBUG__ 1
#if __DEBUG__
//.....
#endif
(2)多个分支的条件编译
#if 常量表达式
//.....
#elif 常量表达式
//......
#else
//.....
#endif
(3)判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
(4)嵌套指令
#if defined(OS_UNIX)
#ifdef OPTION1
unix_version_option1();
#endif
#ifdef OPTION2
unix_version_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#endif
#endif
8、文件包含
(1)头文件被包含的方式
1>本地文件包含:#include"filename"
2>库文件包含:#include<filename.h>