C语言对源程序处理的四个步骤:预处理、编译、汇编、链接——预处理篇
C/C++学习总结积累(超详细)——C提高:预处理(include、define、可变宏参)、编译、汇编、链接
预处理
1)预处理的基本概念
C语言对源程序处理的四个步骤:预处理、编译、汇编、链接。
预处理是在程序源代码被编译之前,由预处理器(Preprocessor)对程序源代码进行的处理。这个过程并不对程序的源代码语法进行解析,但它会把源代码分割或处理成为特定的符号为下一步的编译做准备工作。
2)预编译命令
C编译器提供的预处理功能主要有以下四种:
1)文件包含 #include
2)宏定义 #define
3)条件编译 #if #endif ..
4)一些特殊作用的预定义宏
a、文件包含处理
1)文件包含处理
文件包含处理”是指一个源文件可以将另外一个文件的全部内容包含进来。C语言提供了#include命令用来实现“文件包含”的操作。
2)#include< > 与 #include ""的区别
" "表示系统先在file1.c所在的当前目录找file1.h,如果找不到,再按系统指定的目录检索。
< >表示系统直接按系统指定的目录检索。
注意:
1. #include <>常用于包含库函数的头文件
2. #include " "常用于包含自定义的头文件 (自定义的头文件常用“ ”,因为使用< >时需要在系统目录检索中加入自定义头文件的绝对地址/相对地址否则无法检索到该自定义的头文件,编译时会报错)
3. 理论上#include可以包含任意格式的文件(.c .h等) ,但我们一般用于头文件的包含。
b、宏定义
1)基本概念
在源程序中,允许一个标识符(宏名)来表示一个语言符号字符串用指定的符号代替指定的信息。
在C语言中,“宏”分为:无参数的宏和有参数的宏。
2)无参数的宏定义
#define 宏名 字符串
例: #define PI 3.141926
在编译预处理时,将程序中在该语句以后出现的所有的PI都用3.1415926代替。
这种方法使用户能以一个简单的名字代替一个长的字符串,在预编译时将宏名替换成字符串的过程称为“宏展开”。宏定义,只在宏定义的文件中起作用。
1 #include <stdio.h>
2
3 #define PI 3.1415f
4
5 int main(void)
6 {
7 float L,S,R,V;
8 printf("Input Radius:");
9 scanf("%f",&R);
10
11 L=2.0f*PI*R;
12 S=PI*R*R;
13 V=4.0f/3*PI*R*R*R;
14
15 printf("L=%.4f,S=%.4f,V=%.4f\n",L,S,V);
16
17 return 0;
18 }
说明:
- 1) 宏名一般用大写,以便于与变量区别
- 2) 字符串可以是常数、表达式等
- 3) 宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错
- 4) 宏定义不是C语言,不在行末加分号
- 5) 宏名有效范围为从定义到本源文件结束
- 6) 可以用#undef命令终止宏定义的作用域
- 7) 在宏定义中,可以引用已定义的宏名
3)带参数的宏定义
1) 格式:#define 宏名(形参表) 字符串
2) 调用:宏名(形参表)
3) 宏展开:进行宏替换
#define S(a,b) a*b
……
Area = S(3,2);
1 #include <stdio.h>
2
3 #define SQ_1(y) (y)*(y)
4 #define SQ_2(y) y*y
5
6 int main(void)
7 {
8 int a = 0,num_1 = 0,num_2 = 0;
9 scanf("%d",&a);
10 num_1 = SQ_1(a+1); //num_1 = (a+1)*(a+1);
11 num_2 = SQ_2(a+1); //num_2 = a+1*a+1;
12
13 printf("num_1 = %d\n",num_1);
14 printf("num_2 = %d\n",num_2);
15
16 return 0;
17 }
c、条件编译
1)基本概念
一般情况下,源程序中所有的行都参加编译。但有时希望对部分源程序行只在满足一定条件时才编译,即对这部分源程序行指定编译条件。
2)条件编译的作用
1)防止头文件被重复包含引用
1 #ifndef _SOMEFILE_H
2 #define _SOMEFILE_H
3
4 //需要声明的变量、函数
5 //宏定义
6 //结构体
7
8 #endif
2) 软件裁剪
同样的C源代码,条件选项不同可以编译出不同的可执行程序。
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define BIG 1
5 int main(void)
6 {
7 char str[20] = "C Language";
8 char C;
9 int i = 0;
10 while ((C = str[i++]) != '\0')
11 {
12 #if BIG
13 if (C >= 'a' && C <= 'z')
14 C = C - 32;
15 #else
16 if (C >= 'A'&& C <= 'Z')
17 C = C + 32;
18 #endif
19 printf("%c", C);
20 }
21
22 system("pause");
23
24 return 0;
25 }
d、一些特殊的预定宏
C编译器,提供了几个特殊形式的预定义宏,在实际编程中可以直接使用,很方便。
1 // __FILE__ 宏所在文件的源文件名
2 // __LINE__ 宏所在行的行号
3 // __DATE__ 代码编译的日期
4 // __TIME__ 代码编译的时间
5
6 #include <stdio.h>
7 #include <stdlib.h>
8
9 int main(void)
10 {
11
12 printf("%s\n", __FILE__);
13 printf("%d\n", __LINE__);
14 printf("%s\n", __DATE__);
15 printf("%s\n", __TIME__);
16
17 system("pause");
18
19 return 0;
20 }