预处理

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 }

C语言对源程序处理的四个步骤:预处理、编译、汇编、链接——预处理篇的更多相关文章

  1. C语言预处理 编译 汇编 链接四个阶段

    c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接. 编译过程 编译过程又可以分成两个阶段:编译和会汇编. 编译 编译是读取源程序(字符流),对之进行词法和语法的分析,将高 ...

  2. GCC编译源代码的四个步骤【转】

    GCC编译C源代码有四个步骤:预处理---->编译---->汇编---->链接. 可以利用GCC的参数来控制执行的过程,这样就可以更深入的了解编译C程序的过程. 下面将通过对一个程序 ...

  3. C语言编程入门之--第四章C语言基本数据类型

      导读:C语言程序中经常涉及一些数学计算,所以要熟悉其基本的数据类型.数据类型学习起来比较枯燥,不过结合之前的内存概念,以及本节的字节概念,相信数据类型也就不难理解了.本章从二进制的基本概念开始,然 ...

  4. Gcc的编译流程分为了四个步骤:

    http://blog.csdn.net/xiaohouye/article/details/52084770(转) Gcc的编译流程分为了四个步骤: 1.预处理,生成预编译文件(.文件): Gcc ...

  5. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台: ...

  6. C语言的本质(21)——预处理之三:其它预处理特性及总结

    C标准规定了几个特殊的宏,在不同的地方使用可以自动展开成不同的值,预编译程序对于在源程序中出现的这些串将用合适的值进行替换.这些宏有下面这些: __FILE__ 展开为当前源文件的文件名,是一个字符串 ...

  7. C语言编译和链接

    编译链接是使用高级语言编程所必须的操作,一个源程序只有经过编译.链接操作以后才可以变成计算机可以理解并执行的二进制可执行文件. 编译是指根据用户写的源程序代码,经过词法和语法分析,将高级语言编写的代码 ...

  8. 区块链学习(四)truffle部署编译智能合约以太坊私有链

    前面我们介绍了以太坊私有链的搭建以及多节点私有链网络,这次我们介绍如何使用truffle框架来部署编译智能合约到我们之前搭建的私有链网络中. 搭建环境及需使用的工具:ubuntu18.04  Truf ...

  9. 学习linux/unix编程方法的建议,学习Linux的四个步骤(转)

    解答:学习Linux的四个步骤假设你是计算机科班出身,计算机系的基本课程如数据结构.操作系统.体系结构.编译原理.计算机网络你全修过我想大概可以分为4个阶段,水平从低到高从安装使用=>linux ...

随机推荐

  1. kNN(k近邻)算法代码实现

    目标:预测未知数据(或测试数据)X的分类y 批量kNN算法 1.输入一个待预测的X(一维或多维)给训练数据集,计算出训练集X_train中的每一个样本与其的距离 2.找到前k个距离该数据最近的样本-- ...

  2. 使用windows自带linux子系统开发esp32

    步骤: 1.打开windows商店,搜索ubuntu,安装18.04版本. 2.控制面板 /程序和功能 /打开或关闭windows功能 3.关机重启 4.打开刚安装得ubuntu,设置用户名和密码. ...

  3. 同步a表的数据到 b表

    //同步a表的数据到 b表UPDATE a t1 JOIN b t2 ON t1.finance_id = t2.idSET t1.a_id = t2.a_id,t1.b_name = t2.b_na ...

  4. PhpStorm 编辑器上更改文件后自动上传服务器

    在编辑器内设置自动上传后很方便,,,就不用编辑完了之后还要去服务器里面上传,很麻烦!!!设置了自动上传Ctrl +S  就可以上传了 方便至极~~~~~~~希望可以帮到大家 1.菜单栏找到[工具/To ...

  5. pycharm实用常用快捷键

    我们在实用pycharm时候,可以使用一些快捷键来帮助我们写代码. 1 alt + enter 快速导包,在需要导入包时候可以使用这个快捷键: 2 alt + 1 可以快速打开或者关闭左侧projec ...

  6. IEAD关于git配置以及拉代码和提交代码

    1.提前安装git客户端,注册码云帐号 注册地址:https://gitee.com/signup 2.新建仓库 3.修改仓库信息 4.从IDEA拉git项目,下面两个地方都可以配置 首次创建需要输入 ...

  7. 构造器注入的方式给Cart属性赋值 关系1:1;1:n

    1.通过Spring创建对象,现有Users和Cart实体类,关系为1:1 属性注入的方式给Users属性赋值 2.Cart和Product实体类,关系1:n 构造器注入的方式给Cart属性赋值 Ca ...

  8. 记录一次SQL函数和优化的问题

    一.前言 上次在年前快要放假的时候记录的一篇安装SSL证书的内容,因为当时公司开始居家办公了,我也打算回个家 毕竟自己在苏州这半年一个人也是很想家的,所以就打算年过完来重新写博客.不巧的是,当时我2月 ...

  9. Java基础——StringBuilder

    /* StringBuilder作用: String 在new一个新的对象以及进行字符串拼接时,会在常量池创建拼接之前的两个字符串对象,拼接完成后会造成内存浪费,时间浪费 StringBuilder ...

  10. web服务器-nginx负载均衡

    web服务器-nginx负载均衡 一 负载均衡的作用 负载均衡: 分摊到多个操作单元上进行执行,和它的英文名称很匹配.就是我们需要一个调度者,保证所有后端服务器都将性能充分发挥,从而保持服务器集群的整 ...