目录
前言
一、翻译环境和执行环境
源文件到可执行程序要经过翻译环境,翻译环境包括编译和链接,编译包括预编译、编译、汇编。源文件经过编译器处理回生成目标文件(.obj),目标文件和链接库通过链接器生成可执行程序。
二、编译+链接
1.预编译
本质是文本操作:
1.头文件展开
2.宏替换
3.条件编译(#if)
4.去掉注释
生成text.i
2.编译
把C语言转换成汇编代码
1.语法分析
2.词法分析
3.语义分析
4.符号汇总
生成text.s
3.汇编
把汇编代码转化成二进制指令:
生成text.o
4.链接
链接到一起生成可执行程序
生成a.out
5.运行环境
1.程序必须载入到内存中
2.开始执行,调用main函数
3.程序使用运行堆栈,存储函数局部变量返回地址
4。终止程序
三、预处理
1.定义符号
__FILE__
__LINE__
__DATE__
__TIME__
__STDC__//进行编译的源文件
//文件当前的行号
//文件被编译的日期
//文件被编译的时间
//如果编译器遵循ANSI C,其值为1,否则未定义
2.#define
#define name( parament-list ) stuff
//其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中
#define SQUARE( x ) x * x
//这个宏接收一个参数 x .
//如果在上述声明之后,你把
SQUARE( 5 );
//置于程序中,预处理器就会用下面这个表达式替换上面的表达式
5 * 5
提示:
所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中。的操作符或邻近操作符之间不可预料的相互作用。
3.#和##
int i = 10;
#define PRINT(FORMAT, VALUE)
printf("the value of " #VALUE "is "FORMAT "\n", VALUE);
//输出结果
the value of i+3 is 13
//##可以把位于它两边的符号合成一个符号。
//它允许宏定义从分离的文本片段创建标识符。
#define ADD_TO_SUM(num, value)
sum##num += value;
ADD_TO_SUM(5, 10);//作用是:给sum5增加10.
4.宏和函数的对比
命名约定:
把宏名全部大写
函数名不要全部大写
5.#undef
#undef NAME
//如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除
6.条件编译
#ifndef __TEST_H__
#define __TEST_H__
//头文件的内容
#endif //__TEST_H__
或者
#pragma once
这样做是为了避免头文件的重复定义。当第一次包含盖头文件时_TEST_H因为没有定义,所以满足ifndef_TEST_H,向下执行让后定义_TEST_H。下一次在包含该头文件时因为已经定义过_TEST_H,所以就不满足ifndef_TEST_H。就不会执行#ifndef_TEST_H到#endif之间的部分。
总结
查看《高质量C/C++编程指南》中附录的考试试卷。