使用C语言函数案例6-参数化宏和函数
- 格式:doc
- 大小:52.00 KB
- 文档页数:3
C语⾔:代码宏详解⽬录1、定义宏2、宏函数3、多⾏宏4、宏变长参数5、原样输出变量名6、例⼦7、宏与函数的差异总结1、定义宏#define ARRAY_SIZE 100double data[ARRAY_SIZE];如下图,上⽅代码在编译器进⾏宏替换时会将代码中的ARRAY_SIZE替换成1002、宏函数宏函数的参数是没有任何类型的概念的,因此宏函数使⽤如下,代码中的MAX(3,4)会替换成宏定义的表达式#define MAX(a,b) a > b ? a : bint n1 = MAX(3,4);注意上⽅替换出错,是因为给宏函数的参数传递的是⼀个表达式,可以使⽤下图⽅法宏函数的参数不要传表达式,如下图,表达式进⾏了2次运算3、多⾏宏使⽤斜杠连接下⼀⾏代码,适⽤于代码很长的宏#define IS_HEX_CHARACTOR(ch) \( (ch) >= '0' && (ch) <= '9') || \( (ch) >= 'A' && (ch) <= 'F') || \( (ch) >= 'a' && (ch) <= 'f')int main(){printf("is hex charactor:%d", IS_HEX_CHARACTOR('a'));}4、宏变长参数#define PRINTLNF(format, ...) printf(format, __VA_ARGS__)5、原样输出变量名6、例⼦#include <stdio.h>#define PRINTF(format, ...) printf("("__FILE__":%d) %s: "format,__LINE__,__FUNCTION__, ##__VA_ARGS__) #define PRINT_INT(value) PRINTF(#value":%d \n", value)int main(){int no = 1;PRINT_INT(no);return 0;}7、宏与函数的差异总结本篇⽂章就到这⾥了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!。
c语言带参数的宏定义例题一、引言在C语言中,宏定义是一种常用的预处理指令,它允许程序员创建可重用的代码片段。
通过宏定义,我们可以简化代码,提高可读性和维护性。
在本文中,我们将讨论如何使用带参数的宏定义在C语言中创建自定义函数。
二、带参数的宏定义基础在C语言中,宏定义类似于函数定义,但它允许我们在编译时直接替换代码中的宏名称。
带参数的宏允许我们在调用宏时提供具体的数据,这样宏可以在不改变代码结构的情况下执行更复杂的操作。
以下是一个简单的带参数的宏定义的例子:```c#defineSQUARE(x)((x)*(x))```这个宏定义将把任何传入的参数`x`的平方作为结果。
例如:```cinta=5;intresult=SQUARE(a);//result的值现在是25```三、带参数的宏定义的应用带参数的宏定义在很多情况下都非常有用,例如:*简化复杂的表达式:使用带参数的宏可以避免编写冗长的表达式,同时保持代码的可读性和简洁性。
*条件编译:通过传递不同的参数,我们可以根据条件选择性地使用不同的代码片段。
*生成代码:宏可以用于生成特定的代码片段,例如循环或条件语句。
下面是一个使用带参数的宏定义的例子,用于生成一个简单的for循环:```c#defineLOOP_STARTdo{\intx=0;\while(1){\if(x<MAX){\x++;\}else{\break;\}\}\}while(0)```这个宏定义将生成一个无限循环,直到`x`的值达到`MAX`为止。
你可以通过传递不同的参数来生成不同条件的循环。
四、总结通过使用带参数的宏定义,我们可以创建自定义函数,简化代码,提高可读性和维护性。
在许多情况下,使用带参数的宏定义可以更有效地处理复杂的逻辑和生成特定的代码片段。
在C语言编程中,灵活使用宏定义可以提高效率和代码质量。
C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念)。
下面对常遇到的宏的使用问题做了简单总结。
宏使用中的常见的基础问题#符号和##符号的使用...符号的使用宏的解释方法我们能碰到的宏的使用宏使用中的陷阱常见的基础性问题关于#和##在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。
比如下面代码中的宏:#define WARN_IF(EXP) \do{ if (EXP) \fprintf(stderr, "Warning: " #EXP "\n"); } \while(0)那么实际使用中会出现下面所示的替换过程:WARN_IF (divider == 0);被替换为do {if (divider == 0)fprintf(stderr, "Warning" "divider == 0" "\n");} while(0);这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。
而##被称为连接符(concatenator),用来将两个Token连接为一个Token。
注意这里连接的对象是Token就行,而不一定是宏的变量。
比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。
那么下面的代码就非常实用:struct command{char * name;void (*function) (void);};#define COMMAND(NAME) { NAME, NAME ## _command }// 然后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:struct command commands[] = {COMMAND(quit),COMMAND(help),...}COMMAND宏在这里充当一个代码生成器的作用,这样可以在一定程度上减少代码密度,间接地也可以减少不留心所造成的错误。
C语言中宏的使用C 语言中宏的使用宏的主要作用是在编译预处理时,对程序中所有出现的“宏名”都用宏定义中的字符串去代换。
宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的。
在C 语言中,“宏”分为有参数和无参数两种,即分别简称为有参宏和无参宏。
无参宏无参宏的宏名后不带参数,其定义的一般形式为:#define 标识符字符串其中的. “#” 表示这是一条预处理命令,凡是以“#” 开头的均为预处理命令。
“define” 为宏定义命令,“标识符” 为所定义的宏名称,“字符串” 可以是常数、表达式、格式串等。
#include#define NUM 4int main(int argc, const char * argv[]) { int a = 4;a *= NUM; printf("%d ", a); return 0;}运行结果:16 。
这里可以看出我们定义了一个宏名称为 NUM 的宏,当 main 中代码出现 NUM 的地方,就会自动用数字 4 进行替换,这样做的好处是当代码中多处存在同一变量时,只需要修改宏NUM 的值即可,而无需在代码中一处处的进行修改。
有参宏C 语言允许宏带有参数,在宏定义中的参数称为形式参数,宏调用中的参数称为实际参数。
对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。
带参宏定义的一般形式为:#define 宏名(形参表) 字符串示例代码:#include#define SUM(a) a+aint main(int argc, const char * argv[]) { int a = SUM(4); printf("%d ", a); return 0;}运行结果:8 。
这里可以发现 SUM 将 4 传入,通过 a + a ,即 4 + 4 = 8 。
【C 语言中宏的使用】。
C语⾔深⼊分析函数与宏的使⽤⽬录⼀、函数与宏⼆、宏的妙⽤三、⼩结⼀、函数与宏宏是由预处理器直接替换展开的,编译器不知道宏的存在函数是由编译器直接编译的实体,调⽤⾏为由编译器决定多次使⽤宏会导致最终可执⾏程序的体积增⼤函数是跳转执⾏的,内存中只有⼀份函数体存在宏的效率⽐函数要⾼,因为是直接展开,⽆调⽤开销函数调⽤时会创建活动记录,效率不如宏下⾯看⼀个函数与宏的⽰例,先看这个程序:#include <stdio.h>#define RESET(p, len) \while( len > 0 ) \((char*)p)[--len] = 0void reset(void* p, int len){while( len > 0 )((char*)p)[--len] = 0;}int main(){int array[] = {1, 2, 3, 4, 5};int len = sizeof(array);int i = 0;RESET(array, len);for(i=0; i<5; i++){printf("array[%d] = %d\n", i, array[i]);}return 0;}输出结果如下:但是如果我们这么写,RESET(6, len); 程序直接出现段错误,都没有给出警告:⽽我们使⽤函数 reset(6, len); 时,则会出现警告:所以说能⽤函数实现的功能就尽可能的不使⽤宏。
宏的效率⽐函数稍⾼,但是其副作⽤巨⼤宏是⽂本替换,参数⽆法进⾏类型检查可以⽤函数完成的功能绝对不⽤宏宏的定义中不能出现递归定义下⾯看⼀个宏的副作⽤的代码:#include <stdio.h>#define _ADD_(a, b) a + b#define _MUL_(a, b) a * b#define _MIN_(a, b) ((a) < (b) ? (a) : (b))int main(){int i = 1;int j = 10;printf("%d\n", _MUL_(_ADD_(1, 2), _ADD_(3, 4)));printf("%d\n", _MIN_(i++, j));return 0;}输出结果如下:按理说输出结果应该是 21 和 1 ,为什么是 11 和 2 呢?下⾯进⾏单步调试,输⼊ gcc -E test.c -o test.i ,得到 test.i ⽂件,部分结果如下:这样就能解释了。
c语⾔之带参数的宏定义1.带参数的宏定义中,宏名和新参表之间不能有空格,2.在带参数的宏定义中,形参参数不分配内存单元,因此不必作类型定义。
⽽宏调⽤中的实参有具体值,要⽤它去代换形参,因此必须作类型说明。
#include<stdio.h>#include<iostream>#define MAX(a,b) (a>b)?a:bint main() {int x, y, max;x = 2;y = 3;max = MAX(x,y);printf("%d\n", max);system("pause");return0;}3.在宏定义中的形参是标识符,⽽宏调⽤中实参可以是表达式。
4.在宏定义中,字符串内的形参通常要⽤括号括起来以避免出错。
5.带参的宏和代餐函数类似,但本质不同,除此之外,把同⼀表达式⽤函数处理和⽤宏处理两者的结果有可能不同。
普通函数:#include<stdio.h>#include<iostream>int SQ(int y) {return ((y) * (y));}int main() {int i = 1;int SQ(int y);while (i <= 5) {printf("%d ", SQ(i++));}printf("\n");system("pause");return0;}输出:宏定义:#include<stdio.h>#include<iostream>#define SQ(y) (y)*(y)int main() {int i = 1;while (i <= 5) {printf("%d ", SQ(i++));}printf("\n");system("pause");return0;}输出:为什么结果不同呢?这是因为普通函数调⽤时,实参传给形参的是值,⽽在宏定义时,要⽤表达式进⾏替换,即(i++)*(i++),所以I++会被执⾏两次。
c语言带参数的宏定义用法
C 语言带参数的宏定义用法如下:
```c
#define macro_name(parameter) macro_body
```
在宏定义中,`macro_name` 是宏的名称,`parameter` 是宏的参数,在宏的主体部分
`macro_body` 中可以使用参数进行替换和操作。
例如,下面是一个带参数的宏定义示例:
```c
#include <stdio.h>
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
int main() {
int x = 10;
int y = 20;
int max_num = MAX(x, y);
printf("The maximum number is %d\n", max_num);
return 0;
}
```
在上面的示例中,宏定义 `MAX(a, b)` 带有两个参数 `a` 和 `b`,并返回其中较大的数。
在
`main` 函数中,通过调用宏 `MAX` 传入不同的参数 `x` 和 `y`,得到最大的数并进行输出。
注意,在带有参数的宏定义中,参数的使用需要用括号括起来,以防止出现意外的优先级问题。
在宏的主体部分,可以对参数进行计算、替换等操作,使用括号可以确保操作正确执行。
《C概念C语言能力教程》实
验报告
使用C语言函数案例
参数化宏和函数
一、实验目的
对参数化宏和函数进行理解和区别
二、实验环境
VC++
实验内容与实验过程及分析(写出详细的实验步骤,并分析实验结果)实验步骤:
#include <stdio.h>
#define A(x) ((x)>0?(x):(-x))
double my(double x)
{
return x>0?x:-x;
}
void main ()
{
printf("A(-3)=%d\n",A((-3)));
printf("my(-3)=%lf\n",my(-3));
printf("A(-3-1)=%d\n",A((-3-1)));
printf("my(-3-1)=%lf\n",my(-3-1));
printf("A(-3.5)=%.1f\n",A((-3.5)));
printf("my(-3.5)=%lf\n",my(-3.5));
}
实验结果图为:
三、实验总结(每项不少于20字)
存在问题:对文件包含不熟悉,在同一个文件中的分布程序连接时不能分开的完整或者连接时左差右差。
解决方法:既然不能将程序很好的分开,就不能完成以后的合作任务,我对程序的每一步都进行尝试分离,最终得到了很好的效果。
收获:学会了参数化宏与函数可以达到相同的效果,却也有些区别。
还巩固了对文件包含的理解和应用以及条件编译。
四、教师批语
宋体,小四,行间距20磅,首行缩进2字符,段前段后0行,两端对齐。