使用带参数宏定义时,除了前面提到的使用宏定义预处理的注意事项外,还要注意下面几点:①带参宏定义中,宏名和形参表之间不能有空格出现。②带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而带参数的宏对实参表达式不作计算直接照原样代换,只是进行简单的替换。③带参数宏的形式参数与函数中的形式参数不同,它没有确定的数据类型。带参数宏调用替换问题的理解示例。......
2023-11-20
不带参数的宏定义一般形式是:
#define宏名 字符串
例如:#define PI 3.1415926
其中,宏名用标识符表示,也就是前面讨论过的符号常量,上面示例中的PI就是宏名。预处理过程中,将C源程序中的宏名用对应的字符串进行替换,如将PI替换为3.1415926,这个过程称为宏调用或宏展开。宏调用的格式为:
标识符宏定义预处理的工作只是纯粹的替换或展开,没有任何计算功能。正确使用“宏定义”的关键是宏调用时的“原样替换”。
【例9.1】 宏定义使用的简单示例。
上面程序在预处理时,语句sum=20+N;中出现的宏名(标识符N)代换为100。即将上面的程序处理成如下所示程序后再进行程序代码的编译工作。
在C程序中使用宏定义预处理时,还应注意以下几方面问题:
①宏名一般用大写,以区别程序中使用的变量名。
②宏定义不分配内存,变量定义分配内存。
③预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
④宏定义不存在类型问题,它的参数也是无类型的。
⑤宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。(www.chuimin.cn)
⑥字符串常量("")中永远不包含宏,即宏名出现在字符串常量中时,不进行替换工作。
⑦宏定义允许嵌套。如:
#define N 100
#define M 2*N
#define K 5+M
⑧可以用#undef或不带替换字符串的宏定义终止宏定义的作用域。如下面两条预处理命令都可以终止#define N 100的作用域。
#undef N
#define N⑨宏定义末尾不需要用分号结尾,如果末尾有分号,则分号将作为字符串的组成部分。如上例中,假设定义为:#define N 100;,则替换后变为sum=100;+20;,显然本程序是有语法错误的。假如本语句改为sum=20+100;;,此时程序并没有语法错误,语句后多余的分号可以看成一个空语句。预处理后也可以得到正确结果。
⑩使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。在阅读含有宏定义的源程序时,一定要掌握“先替换,后计算”的原则,切忌“边替换,边计算”。
【例9.2】 编写程序实现功能:输入100个实型数据到数组中,然后求出数组中所有元素之和。
上面程序中,如果设计时直接使用长度为100的数组,那么每次调试程序就需要输入100个数据,这样势必给程序的调试工作带来极大的工作量。程序中通过宏定义#define N 3的使用,使得在程序调试的时候仅需输入3个数据。当程序调试成功后,只需要将程序中宏定义语句修改为:#define N 100,然后重新编译即可实现对100个数据进行处理的程序设计要求。
有关C语言程序设计基础(第3版)的文章
使用带参数宏定义时,除了前面提到的使用宏定义预处理的注意事项外,还要注意下面几点:①带参宏定义中,宏名和形参表之间不能有空格出现。②带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而带参数的宏对实参表达式不作计算直接照原样代换,只是进行简单的替换。③带参数宏的形式参数与函数中的形式参数不同,它没有确定的数据类型。带参数宏调用替换问题的理解示例。......
2023-11-20
宏也可以带参数,其定义的一般形式为:#define标识符 字符串其中标识符是宏名,字符串中包含括号内指定的参数,称为宏扩展。这时由于带参数的宏从形式上看很像函数,为了统一,多数人在定义带参数的宏时喜欢使用小写字母。......
2023-11-18
不带参数的宏用指定标识符来代替一个字符串。其一般格式为:#define标识符 字符串例如:#define PI 3.1415926用标识符PI来表示3.1415926,这叫做宏定义。但多数人习惯把所有的宏定义都写在文件的前面虽然这不是必须的。一个宏定义后,就可以在程序中使用了,例如:这个函数返回圆的面积。这里的1、0与一般意义下的1、0形式上没有任何不同,不容易让人理解,有了宏,我们就可以很方便地解决这个问题了。......
2023-11-18
我们通过下面的示例来说明按值传递方式中参数在函数之间的传递。图5.1实参与形参传递示意图当数组名作为函数参数时,函数传递数据方式采用的是“按地址传递”的方式,但要求形参和相对应的实参都必须是类型相同的数组。图5.3数组v的存储形式这样一来,形参数组中元素值的改变就会反过来影响到实参数组。......
2023-11-18
书写在特定函数内部时,用于向该函数声明被调用函数的特征,此时仅有书写了函数声明语句的函数知道被声明函数的存在。当被调函数与主调函数位于同一源文件,且被调函数的定义出现在主调函数之前时,不必对被调函数进行声明,其原因是编译系统此时已经知道了被调函数的所有特征。对被调函数不必进行声明的示例。......
2023-11-20
用户自己定义的结构体类型,与系统定义的标准类型一样,是可以用来定义结构体类型的变量。这种方法定义的结构体类型在程序后面不可使用,因为缺少完整的结构体类型名。......
2023-10-21
项目2:输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。图3.15兔子问题输出结果根据以上的分析可以知道,循环次数可以为0,因此该程序是一个条件型循环,可以利用while语句编写程序。熟悉了循环结构在程序设计中的运用,循环结构语句包含了while语句、do…......
2023-11-18
还可以在枚举类型定义中对枚举元素起始值作多次改变,每次改变后枚举值从该处开始递增直到遇到下一次起始值的指定为止。枚举数据类型定义完成后,仍然需要定义枚举变量才能使用,常见的方法有:①先定义枚举类型,然后定义枚举变量。枚举变量的输入输出示例。......
2023-11-20
相关推荐