C语言重点难点精讲C语言预处理

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言重点难点精讲C语言预处理相关的知识,希望对你有一定的参考价值。

一:C/C++程序程序编译过程

(1)预处理

  • 预处理主要包括宏定义,文件包含,条件编译,去注释
  • 输入gcc -E hello.c -o hello.i,其中选项E作用是让gcc在预处理后停止编译

(2)编译

  • 此阶段,gcc检查代码的规范性,是否具有语法错误
  • 输入gcc -S hello.i -o hello.s,即可将预处理里的结果继续继续编译

(3)汇编

  • 编译阶段无误后,进入汇编,将“.s”文件转化为“.o”二进制文件
  • 输入gcc -c hello.s -o hello.o,即可将编译停止在此阶段


(打开二进制文件使用od命令)

(4)链接

  • 此阶段,将目标文件与系统库进行链接生成可执行文件。
  • 输入gcc hello.o -o hello,则完成编译

选项描述
-E进行预处理,不进行编译,汇编和链接
-S进行编译,不进行汇编和链接
-c进行汇编,不进行链接
-o链接
static采用静态链接
-g生成调试信息
-shared使用动态库
-O0无优化
-O1默认优化级别
-O3优化最高
-w不生成警告信息
-Wall生成所有警告信息

二:宏定义

(1)数值宏常量

(2)字符串宏常量

(3)使用宏充当注释

先去掉注释,再进行宏替换

(4)使用宏充当表达式

#define SUM(X) (X)+(X)

int main()
{
	printf("%d\\n", SUM(10));
	return 0;
}

需要注意使用宏充当多条语句时有可能出现一些潜在的问题,比如下面这个宏有两条语句,但是在if后面如果直接跟上宏而没有带花括号就会出现问题

#define INT_VAL(a,b) a=0;b=0

如果需要宏替换大块语句,可以使用do-while(0)结构

#define GIVE_VALUE(a,b) do{a=0;b=0;}while(0)

int main()
{
	int x = 10;
	int y = 20;
	int flag = 0;
	scanf("%d", &flag);
	printf("before:%d,%d\\n", x,y);
	if (flag)
		GIVE_VALUE(x, y);
	else
		x = 10, y = 20;
	printf("after:%d,%d\\n", x, y);

}

三:宏其他

第一: 宏定义在文件的任何位置都可以,只要是在你使用这个宏之前定义就可以

void show()
{
#define M 10
	printf("show:%d\\n", M);
}
int main()
{
	show();
	printf("main:%d\\n", M);
	return 0;

}

第二 可以使用#undef来结束宏的作用

int main()
{
#define M 10//从这里开始
	printf("main:%d\\n", M);
	printf("main:%d\\n", M);
	printf("main:%d\\n", M);
#undef M//到这里结束
	printf("main:%d\\n", M);//错误

	return 0;

}

四:条件编译

(1)#ifdef和#ifndef

  • ifdef:判定宏是否被定义,宏为真假没有关系,倾向于要定义
  • ifndef:判定宏是否没有定义,宏为真假没有关系,倾向于不要定义

下面的例子中没有定义PRINT所以代码只会保留#else这一部分,代码在预处理时直接被裁掉

int main()
{
#ifdef PRINT//实际未定义
	printf("hello\\n");
#else
	printf("no print\\n");
#endif
	return 0;
}


如果PRINT被定义了,然后换成ifndef,效果也是一样的

#define PRINT//宏被定义
int main()
{
#ifndef PRINT//如果没有定义
	printf("hello\\n");
#else
	printf("no print\\n");
#endif
	printf("continue\\n");
	return 0;
}

(2)#if

  • #if:判定是否存在,以及是否为真,倾向于存在且为真

如下宏PRINT,被定义了但是为0,因此会输出#else里面内容

# define PRINT 0//定义了但是为假

int main()
{
#if PRINT
	printf("hello\\n");
#else PRINT
	printf("other");
#endif
	return 0;
}

#if可以进行多分支控制

#define HELLO 2

//注意这里使用的是==,像!=,<,>等可以使用
int main()
{
#if HELLO==1
	printf("hello1\\n");
#elif HELLO==2
	printf("hello2\\n");
#elif HELLO==3
	printf("hello3\\n");
#else
	printf("other\\n");
#endif
	return 0;
}


如果要判断多个宏,可以这样进行

#define Condition1 1
#define Condition2 0

int main()
{
#if Condition1 && Condition2
	printf("all\\n");
#else
	printf("other\\n");
#endif
	return 0;
}

以上是关于C语言重点难点精讲C语言预处理的主要内容,如果未能解决你的问题,请参考以下文章

C语言重点难点精讲C语言指针

C语言重点难点精讲C语言文件

C语言重点难点精讲C语言内存管理

C语言重点难点精讲C语言中的重要符号

C语言重点难点精讲第一部分关键字:第一节-关键字分类细讲

漫谈C语言重点难点