Linux C语言:预处理

1 . 什么是预处理

编译分为4个步骤:
① .c文件生成.i文件,预处理;
② .i文件生成.s文件,编译;
③ .s文件生成.o文件,汇编;
④ .o文件生成可执行文件,链接;

文件中:$可以直接到文件底部;

gcc -o main.i main.c -E

生成预处理文件,-E表示只进行预处理;、
查看预处理文件只需 vi main.i

预处理做的第一件事:展开头文件,在.i文件中可以显示,不再以include的形式出现;然后再进行宏替换。

2 . 预处理之宏定义

#define R  10 

预处理的第二步宏替换就是把比如 int a = R;这样的语句替换成int a = 10;

不要认为这个10是int,而认为这个10是个字符串,替换过程中单纯的将字符串替换而已;

宏的本质:发生在预处理阶段的字符串替换;

例:

#include<stdio.h>
#define R 10
#define M int main()

M
{
	int a=R;
	printf("a=%d\n",a);
	printf("hello world!\n");
	return 0;
}

程序也可以运行出来。

在预处理阶段,宏不考虑编译器的语法;

3 . 预处理之宏函数

#include<stdio.h>
#define R 20
#define M int main()
#define N(n) n*10
M
{
	int a=R;
	printf("a=%d\n",a);
	int b=N(a);
	printf("b=%d\n",b);
	return 0;
}

运行结果:

linux@ubuntu:~/workspace2/les1$ ./a.out
a=20
b=200

.i文件中int b=N(a);被替换成了int b=a*10;

#define ADD(a,b) a+b
int main()
{
	int a=20;
	int b=200;
	int d=ADD(a,b);
	int e=ADD(a,b) * ADD(a,b);
}

d的结果可以实现ADD函数的功能;
e的理想结果是48400,但实际结果是4220;
原因:.i文件中宏替换的结果是 int e= a+b*a+b;·运算是编译之后执行的时候才会进行,在预处理阶段不会进行运算操作。
需要把.c文件改成 int e= (ADD(a,b))*(ADD(a,b));
(yy是复制,p是粘贴,u是撤销,ctrl+r取消撤销);

宏函数跟正常的函数有什么区别?
宏函数没有返回类型和参数类型,可以不考虑类型;

在预处理阶段,除了宏之外,还提供了条件编译的功能,可以按照不同的条件去编译不同的程序部分,从而产生不同的代码文件,对程序的移植和调试很有用。

4 . typedef

typedef是一个关键字,可以给变量类型起个别名;

typedef int tni;
typedef int* p;
p q=NULL;// 写法等同于int *q = NULL;

给int*类型起个别名叫p;

typedef与宏的区别:
1.typedef的结果以分号结尾;
2.typedef在预处理是不进行替换,.i文件中不被替换;
3.宏定义了之后下面都可以使用,而typedef有作用域,一般在本函数体内?
typedef通常给自己自定义的数据类型起个别名:

typedef unsigned long size_t;

结构体未使用typedef:

struct stu{
};
struct stu a;

结构体使用typedef:

typedef struct stu{
}stu_t;
stu_t a;
发布了30 篇原创文章 · 获赞 36 · 访问量 685

猜你喜欢

转载自blog.csdn.net/qq_42745340/article/details/103946198