使用C语言函数案例6-参数化宏和函数

合集下载

比较C语言中带参数的宏

比较C语言中带参数的宏
不是函数调用,其在系统编译前就被处理成: y=((-2)>0?(-2):-(-2)); 在宏定义中,形参通常需要用括号括起来避免出错,而且应该在 整个字符串外加上括号。 在进行宏定义时,在宏名与带参数的括号之间不应该加空格;否 则将空格以后的内容作为替代字符串的一部分,即系统将其看作 不带参数的宏定义。
谢谢观看!
窗棂趣分享
例:#define ABS(x) ((x)>0?(x):-(x))
#define ABS (x) ((x)>0?(x):-(x))
与C++中的内联函数、函数模板比较
C++内联函数在程序运行的时候在调用点“就地展开”,而C 语言中的带参数的宏是在编译前“就地展开”。由于两者都 没有像函数调用那样需要入栈和出栈,所以程序运行速度加 快,但是在多次使用后,代码都会占用大量的空间。
比较C语言中带参数的宏与C++中内联函数 和函数模板及一些注意事项
以奇渠
C语言中带参数的宏
1.带参数的宏定义指令
#define 宏名(参数表) 字符串 例:#define ABS(x) ((x)>0?(x):-(x))
这里x是参数,三目运算符表达式为计算参数的绝对值。这里的 ABS(x)既不是函数定义,也不是语句(此处无分号)。y=ABS(-2);
宏不存在类型问题,宏名无类型,它的参数也无类型,只是 一个符号代表,展开时代入指定的字符串即可。宏定义时, 字符串可以是任意类型的数据。而内联函数需要的实参和形 参都要定义类型,而且两者的类型应相同。

函数模板格式: Template <typename 形式数据类型表> 返回类型 函数模板名
例:template <typename T> T Max(T a,T b)

C语言:代码宏详解

C语言:代码宏详解

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语言中创建自定义函数。

二、带参数的宏定义基础在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语言中如何使用宏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语言chap6(函数与宏定义)

C语言chap6(函数与宏定义)

6.5 函数的嵌套调用
C 语言函数的定义都是相互平行、独立的,不能 嵌套定义。但可以嵌套调用函数。所谓函数的嵌套调 用就是在被调用的函数中又调用另外的函数。
6.6 函数的递归调用
在调用一个函数的过程中又出现直接或间接地调 用该函数本身,称为函数的递归调用。
2012-6-12
13
例6.4 有5人排成一队,从最后一人开始,其年龄均比 前面的人大2岁,而最前面的人年龄是10岁,问最后 一人的年龄是多少岁?
age(1)=12
2012-6-12
14
函数的递归调用利用了堆栈技术。在本例中: Age(4–1)+2 Age(3–1)+2 Age(2–1)+2 Age(5–1)+2 Age(5)
Age(2–1)+2
Age(3–1)+2
Age(2–1)+2
Age(3–1)+2
10+2=12
12+2=14
Age(4–1)+2
int max(int x, int y);
float fun(int a[10], int n);
2012-6-12 5
2.函数的返回值 函数的返回值是通过return语句获得的。当不需返回 函数值时,可省去return语句。
return语句的后面可以有括号,也可以没有。如:
return z ; return(z); return(x >y ? x : y); return语句返回值的类型应与该函数的类型一致。否 则以函数类型为准。
2012-6-12 11
例6.3 编程求11~999之间的数m,而m、m2和m3均是回文数(数 位左右对称)。 如:m=11、m2=121、m3=1331,…… 。 #include “stdio.h” main( ) {long int m; for (m=11; m<1000; m++) if (fun(m)&&fun(mm)&&fun(mmm)) printf("m=%ld,\t mm=%ld,\t mmm=%ld\n", m, mm, mmm); } int fun(long n) {long i, k; i= n; k=0; while (i) { k=i%10+k10; i = i /10; } if (k==n) return 1; else return 0; } 2012-6-12 12

C语言中宏的使用

C语言中宏的使用

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 语言中宏的使用】。

第5章 函数与带参数宏 《C语言程序设计及应用教程》课件-PPT课件

第5章 函数与带参数宏  《C语言程序设计及应用教程》课件-PPT课件

5.2 函数的嵌套与递归调用
函数的嵌套调用
不允许嵌套定义,函数间平行的、独立。 C中的函数:
允许嵌套调用。
main( ) 调用函数a 结束
a函数
调用函数b
b函数
【例5-7】 输入两个整数,求平方和
#include <stdio.h>
int fun1(int x,int y)
int fun1(int x,int y);
斐波那契数列");
for(i=0;i<N;i++)
{
printf("%d\t",iF[i]);
if((i+1)%10==0)
printf("\n");
}
printf("\n");
}
int Sum(int iF[],int n); void main() { int i,Fibonacci[N],m,n; //生成斐波那契数列 CreateFibonacci(Fibonacci); //输出斐波那契数列 PrintFibonacci(Fibonacci); //求数列前n项的和 printf(" 请输入要求和的项数 n(n<%d): ",N); scanf("%d",&n); m=Sum(Fibonacci,n); printf("\n 斐波那契数列前 %d项的和:%4d\n",n,m);}
第5章 函数与带参数宏 ?C语言 程序设计及应用教程?课件
5.1 函数的声明、定义与调用
5.1.1 函数的声明与定义 5.1.2 函数调用 5.1.3 函数参数传递 5.1.4 主函数中的参数

C语言深入分析函数与宏的使用

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 ⽂件,部分结果如下:这样就能解释了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《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行,两端对齐。

相关文档
最新文档