1、gcc编译器的工作流程和基本原理
1)首先对文件进行预处理,例如文件名为 test.c ,则在shell中输入命令‘gcc -E test.c -o test.i,命令运行后会产生一个名为test.i的文件 2)然后进行编译(词法分析、语法分析、语义分析),然后在shell中输入命令’gcc -S test.i -o test.s‘。这一部只进行编译,不做其他处理。此时会产生一个名为test.s的文件 3)之后进行汇编,即把汇编程序翻译成CPU可以识别的二进制文件。 在shell中输入命令’gcc -c test.s -o test.o ,运行完会产生一个名为test.o的目标文件 4)在shell中输入命令‘gcc test.o -o test’,运行完毕后就可得到一个名为test的文件 ,输入命令‘./test’执行该文件就可以得到运行结果。
2、GDB的使用方法
1)查看源文件,普通文本环境中无法直接获得gcc给出产生警告或错误的代码行数,GDB通过命令1查看所有代码行数 2)设置断点、 通过断点可以知道程序每一步的执行状况,在GDB中通过命令b进行设置 3)查看断点情况 4)通过命令r运行程序 5)通过命令‘p变量名’查看当前变量值 6)继续运行程序 7)单步运行 通过‘s’和‘n’一步步运行
3、为何仅通过gcc命令进行编译非常低效
1)源文件个数越多,gcc命令越长,各种编译规则加大gcc命令行的复杂度2)使用gcc编译时,gcc会把没有被修改的 源文件一起编译,影响编译总体效率
4、makefile文件的基本组成
1)需要生成的目标文件 2)生成目标文件所需要的 依赖文件 3)生成目标文件的编译规则命令行
5、编码时需要考虑的问题
编码的长度 正负号的编码 小数点的编码
6、常量的值在其作用域内会不会发生改变?
不会,他不能再被赋值,再它出现时就被当做一个立即数来使用。也就是说,它只能被访问、被读,而不能被写,被赋值。
7什么是声明?第一重含义,告诉编译器,这个名字已经匹配到一块内存上了。 第二重含义,告诉编译器,这个名字我预定了,别的地方不能用它作为变量名或对象名
8、const的作用和使用技巧
一个变量前面用const来修辞,就意味这该变量里的数据可以被访问,不能被修改。
辨别:将类型去掉,const修饰谁,谁的值就不能修改
9、使用寄存器变量时要注意的
寄存器变量是单个变量,变量长度应小于等于寄存器长度 不能对寄存器变量使用取地址符‘&’,因为该变量没有内存地址 尽量在大量频繁操作时使用寄存器变量,且声明的变量个数应该尽量少
10.typedef char *p_str; #define p_str char*; 两种定义类型哪种更好?
typedef比#define要好特别是在有指针的时候
例 typedef char * p_strl;
#define p_str2 char *;
p_strl s1,s2;
p_str2 s3,s4; 在上面变量定义中,S1,S2,S3,都被定义成char*,而S4定义为char,不是我们预期的指针变量,根本原因在于#define 只是简单的字符串替换而typedef则是为一饿类型起新名字。