首页 > 其他分享 >C语言编译预处理详细易懂版

C语言编译预处理详细易懂版

时间:2024-08-21 15:51:59浏览次数:9  
标签:宏名 定义 C语言 编译 参数 endif 易懂 程序段 预处理

C语言允许在源程序中包含编译预处理命令,他们以"#"开头,包括宏定义、文件包含和条件编译。本博客主要详细介绍宏定义、文件包含和条件编译。


一、宏定义

1、无参数的宏定义

是指用一个指定的标识符来代表一个字符串,一般格式如下:

#define  宏名  字符串

说明:①#表示预处理命令,在C语言中以“#”开头的均为预处理命令。
②define表示宏定义命令。
③宏名常用大写字母表示,这样易于区别程序中的宏名和普通变量名。
④字符串表示宏的内容文本,也称为宏体,是一个ASCII 码的字符序列,可以是常
数、表达式、格式串等。 

注意:(1)宏定义是用宏名替换一个字符串,即原样替换,不做语法检查。如有错误,
只能在展开后编译源程序时才被发现。
(2)宏定义不是C语句,在行末不必加分号,如果加上分号则连分号也一起替换。

#define PI 3.14;
//则语句“area=PI*R*R;"宏扩展为"area=3.14;*R*R;",编译时将出现语法错误


(3)宏名在源程序中若用引号括起来,则预处理时不对其进行宏替换。例如:

//语句"printf("PI");的输出结果为字符串PI而不是前面所定义的值


(4)宏定义必须写在函数之外,其作用域为从宏定义开始到源程序末尾结束。若要终止其作用域可以用#undef命令。

(5)宏定义允许嵌套,即可以引用已定义的宏名,层层置换。
(6)宏定又是预处理命令,它与变量的含义不同,不分配内存空间,只做字符替换。


2.带参数的宏定义

是指宏名后面带有参数。在编译预处理时,不仅要对宏名进行字符串替换,还要对参数进行替换。宏定义中的参数称为形式参数(简称形参),宏调用中的参数称为
实际参数(简称实参),这点与函数有此相似。带參数的宏定义的一般格式为:

#define 宏名(形参列表)  字符串


说明:
①宏名和括号之间不能有空格,否则将空格以后的字符串均作为替换的字符串。
例如,有如下宏定义:

#define MAX (a,b) (a>b)? (a): (b)
//则MAX被当作无参数宏的宏名,“(a,b) (a>b)? (a): (b)"为要替换的字符串。


②形参列表由个或多个参数构成,参数只有参数名,没有数据类型说明符,参数
之间用逗号隔开,参数名必须是合法的标识符。


在处理带参数的宏时,预处理程序首先将宏的内容文本中的形参替换成实参,这样就形成
宏的实际内容文本,然后再用宏的实际内容文本替换源程序中的宏名。带参数的宏调用的一
最格式如下:


宏名(实参列表)


说明:
①实参列表由一个或多个参数构成,与宏的形参列表一一对应 ,实参可以是常量、
变量或表达式,参数之间用逗号隔开。
②带参数的宏在使用时,若参数为表达式,应将宏参数用“( )”括起来。例如,有
如下宏定义:
 

#define SQRT(a) a*a

3.函数与宏定义的区别

(1)宏定义中形参不分配存储空间,因此不必进行数据类型说明;而函数在调用时要为
参分配临时的存储空间,因此形参需要进行数据类型说明。
(2) 函数调用时,先计算实参表达式的值,然后再将其传递给对应的形参;而带参数的工
定义则对实参表达式不做计算而是将字符串进行原样替换。
(3)丽数通过函数名只能返回一个计算结果; 而宏定义可以得到多个计算结果。

二、文件包含

文件包含是指一个源文件可以将另个源 文件的内容包含进来。一般格式如下


linclude <文件名>

include“文件名"


文件包含#include命令的预处理就是将被包含的文件的内容插人源程序中,如图:


说明:
①文件包含命令可以使用尖括号“< >”和双引号" "
这两种形式的区别在于:
使用双引号则表示首先在源文件当前目录中查找,若未找到才到存放C库函数头文件
所在的目录中查找。使用尖括号表示在存放C库函数头文件所在的目录中查找(由用
户在设置编译环境时进行设置)。
②一个include 命令只能指定一个被包含文件,若有多个文件包含,则用多个include命令。
③文件包含允许嵌套。 

三、条件编译

1. #ifdef...#else...#endif

语法格式如下: 


#ifdef  宏名
程序段1
#else
程序段2
#endif


功能:如果”宏名”已经用#define命令定义过,则编译“程序段1”;否则编译”程序段2”。
说明:①如果没有“程序段2”,则本格式中的#else部分可以没有,但#endif必须存在,即
可以写成:

#ifdef  宏名
程序段1
#endif


②"#ifdef   宏名”的含义是判断是否定义了宏。

2.#ifndef...#else...#endif

#ifndef  宏名

         程序段1

#else

         程序段2

#endif

功能:如果宏名没有用define命令定义过则编译“程序段1”,否则编译“程序段2,刚好与第一种格式的功能相反。
例如:

#ifndef A
      a=32;
#else
      a=16;
#endef
//上述条件编译命令表示,如果宏名A没有用#define定义过,则编译“a=32",否则编译“a=16”。

3.#if...#else...#endif


#if 常量表达式

             程序段1

#else

            程序段2

#endif

功能:如果常量表达式的值为真(非0)则编译“程序段1”否则编译程序段2。
说明:1.常量表达式中不能包含变量名,通常会用到宏名,可以不加括号()

2.如果没有程序段2则本格式中的#else部分可以省略,但#endif必须存在。

4.#if...#elif...#endif

#if  常量表达式1

          程序段1

#elif   常量表达式2

          程序段2

#else

          程序段3

#endif

功能:如果常量表达式1的值为真(非0)则编译程序段1,否则判断常量表达式2,如果值为真(非0)则编译程序段2,否则编译程序段3。 


本期博客到这里结束啦~如果对你有用的话点个赞收藏吧! 

标签:宏名,定义,C语言,编译,参数,endif,易懂,程序段,预处理
From: https://blog.csdn.net/Jasmine5606/article/details/141393349

相关文章

  • C语言文件操作详细易懂版
     本期博客将介绍在C语言中进行文件操作的常见函数和基本方法,包括文件的基本概念、文件的打开和关闭、文件的读写操作、文件定位、文件检测等内容。目录一、文件的概念二、文件的分类1.文本文件:2.二进制文件:三、文件类型指针四、文件的打开操作五、文件的关闭操作六......
  • [C语言]-基础知识点梳理-动态内存管理
    前言各位师傅大家好,我是qmx_07,今天给大家讲解动态内存管理的相关知识,下一章节更新文件管理部分的知识点为什么要进行动态内存分配intval=20;//在栈空间上开辟四个字节chararr[10]={0};//在栈空间上开辟10个字节的连续空间上述的开辟空间的⽅式有两个特点:空......
  • C语言典型例题46
    《C程序设计教程(第四版)——谭浩强》题目:习题3.6企业发放的奖金根据利润提成。利润I低于或等于100000元的,奖金可提成10%;                   利润高于100000元,低于200000元(100000<I≤200000)时,低于100000元的部分按10%提成,高于1000......
  • C语言函数递归
    前言与概述本文章将通过多个代码并赋予图示,详细讲解C语言函数递归的定义和函数递归的运算过程。函数递归定义程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它通常把一个大型......
  • C语言:递归
    递归简单来说就是函数自己调用自己。特点:一般代码比较简洁,没有出口。例子1:用一个函数计算阶乘#include<stdio.h>//不用递归intfac(intn){ intval=1; for(inti=1;i<=n;i++) { val*=i; } returnval;}//用递归intfac1(intn){ if(n==1) {......
  • c语言基础------数组指针
    在C语言中,数组指针是一种特殊的指针类型,它指向一个数组。具体来说,数组指针是指向数组首元素的指针,但它与普通指针有所不同,因为它包含了数组的大小信息。下面是关于数组指针的一些基本概念和用法:定义数组指针数组指针可以通过以下方式定义:int(*arrayPtr)[10];//arra......
  • c语言基础--------字符串指针
    在C语言中,字符串指针是一个指向字符类型的指针,通常用于指向字符串的第一个字符。字符串在C语言中通常表示为字符数组,而字符串指针则是用来存储这种字符数组首地址的变量。定义字符串指针字符串指针的定义方式如下:char*stringPtr;这里的char*表示stringPtr是......
  • 数据结构-队列 c语言使用链表和数组分别实现
    队列定义队列(queue)是一种遵循先入后到规则的线性数据结构,将队列头部称为“队首”,尾部称为“队尾”,把元素加入队尾称为“入队”,删除队首元素称为“出队”。队列实现基于链表的实现将链表的头节点和尾结点分别视为“队首”和“队尾”,规定队尾仅可添加节点,队首仅可删除节点。......
  • 打印空心正方形(c语言)
    1.//KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的“空心”正方形图案。//输入描述://多组输入,一个整数(3~20),表示输出的行数,也表示组成正方形边的“*”的数量。//输出描述://针对每行输入,输出用“*”组成的“空心”正方形,每个“*......
  • 【C语言】基础知识详解(二) 字符串
    一、什么是字符串?在C语言中,字符串是一种特殊的字符数组,用于存储一系列字符。字符串的表示:在C语言中,字符串是由字符组成的数组,并以空字符'\0'结束。空字符用于标识字符串的结束。例如,字符串"hello"在内存中实际上是{'h','e','l','l','o','\0'}。字符串声明:可以使......