在以上知识点总结7里面,有很多同学对宏定义的理解还不是很透彻,今天以一个例题深入分析一下。没复习到的同学可以查看上面链接先熟悉一下。 首先,什么是宏定义?...l 宏定义可以嵌套使用,例如:#define R 3.0#define PI 3.14159#define L 2*PI*R 3.知识点:带参数的宏定义l 一般形式:#define 宏名(参数表)...l 要注意有括号和没括号的区别 不带参数的宏定义比较简单,我们今天讲的是带参数的。最后红色字体提到有括号、没括号的区别。那提一个问题:怎么用宏定义表示数学上的函数 f(x)=x*x ?...有同学会说,这不简单,顺手就来: #define f(X) X*X 但是,忽略了一点,宏代换是直接进行代换的。...+1); 我们在宏定义的时候尽量就避免这个问题,使用带参数的宏时,要注意参数要带上括号,最好整个宏也要带上括号: #define f(X) ((X)*(X)) 否则,容易误导别人的同时,自己也容易出错
对象宏 #define M_PI 3.1415926535 double r = 1.0; double circlePerimeter = 2 * M_PI * r; // => double circlePerimeter...= 2 * 3.1415926535 * r ## 函数宏 #define FUNC(x) x NSLog(@"Hello %@", FUNC("world"); // => NSLog(@"Hello
1.无参数的宏定义 #define _CRT_SECURE_NO_WARNINGS #include #include #include /...int a = MAX; printf("%d", a); return 0; } 说明: 2.带参数的宏定义(宏函数) #define _CRT_SECURE_NO_WARNINGS...#include #include #include //宏 函数 //1.将短小,频繁使用的函数写成宏函数 //2.加括号保证运算完整性 //...3.优点:空间换时间 #define SUM(x,y) x+y void test() { int ret = SUM(10, 20); printf("%d", ret); } int main(...函数 //1.将短小,频繁使用的函数写成宏函数 //2.加括号保证运算完整性 //3.优点:空间换时间 #define SUM(x,y) ((x)+(y)) void test() { int ret
C++宏定义 学过C语言的读者,对宏定义应该不陌生,同样在C++中,也可以用宏定义命令将一个指定的标识符来代表一个字符串,宏定义的作用一般是用一个短的名字代表一个长的字符串。...一般形式为: #define 标识符 字符串 定义PI的符号常量: #define PI 3.14 在C++中还可以用#define命令定义带参数的宏定义,一般形式为: #define 宏名(参数表)...中基本上已不再用#define 命令定义宏了,宏定义主要用于条件编译中。...经典案例:C++宏定义求面积,要求可以手动输入长和宽。...C++宏定义求面积 更多案例可以go公众号:C语言入门到精通
前面题目主要是自定义函数的题,相信经过这些题目的训练,大家对自定义函数的理解想必更近了一步。...接下来呢,我们主要来练习跟自定义函数异曲同工的宏定义,先看看下面这题 题目描述 三角形面积=SQRT(S*(S-a)*(S-b)*(S-c)) 其中S=(a+b+c)/2,a、b、c为三角形的三边。...定义两个带参的宏,一个用来求area, 另一个宏用来求S。 写程序,在程序中用带实参的宏名来求面积area。 输入 a b c三角形的三条边,可以是小数。...输出 三角形面积,保留3位小数 样例输入 3 4 5 样例输出 6.000 PS:有句话很经典哦“宏定义只是简单的字符替换哦” 详细题解见C语言网题库1038题 明天就是咱们C语言网有奖月赛的日子了,希望大家积极参加哦
1 概述 在工程规模较小,不是很复杂,与硬件结合紧密,要求移植性的时候,可采用宏定义简化编程,增强程序可读性。 当宏作为常量使用时,C程序员习惯在名字中只使用大写字母。...不要使用宏来定义新类型名,应该使用typedef,否则容易造成错误。 给宏添加注释时请使用块注释(/* */),而不要使用行注释。因为有些编译器可能会把宏后面的行注释理解为宏体的一部分。...尽量使用const取代宏来定义符号常量。...对于较长的使用频率较高的重复代码片段,建议使用函数或模板而不要使用带参数的宏定义;而对于较短的重复代码片段,可以使用带参数的宏定义,这不仅是出于类型安全的考虑,而且也是优化与折衷的体现。...尽量避免在局部范围内(如函数内、类型定义内等)定义宏,除非它只在该局部范围内使用,否则会损害程序的清晰性。
本文链接:https://blog.csdn.net/solaraceboy/article/details/102729793 C语言中宏的定义与使用 三种类型的预处理指令 宏定义 宏是比较常用的一种预处理指令...,这里我们主要讨论带参数的宏。...带参数的宏(函数式宏)定义如下: #define EXAMPLE(x,y,z) 替换列表 注意:在宏的名字和左括号之间没有空格。 宏的优点: 程序可能会更快一些; 宏更同意。...宏的缺点: 编译后代码通常会变大。 宏的参数没有类型检查。 无法用指针来指向一个宏。 宏可能会不止一次地计算它的参数。
container_of 宏用来在给定一个变量的结构体类型,和这个变量的某个成员的地址的条件下,计算出这个变量的地址。...ptr->brightness); printf("ptr->flags = 0x%x\n", ptr->flags); return 0; } 运行结果 led address : 0x55745d380020...ptr->flags = 0xff 我们定义了一个 led 变量,不过这里我们假设 led 变量是在别处定义的,我们拿不到。...从运行结果也可以看到,我们已知 led.link 的地址为 0x55745d380030,求得 led 的地址为 0x55745d380020,和代码一开始打印的 led 的地址相同,故结果正确。...(type *)( (char *)__mptr - offsetof(type,member) ); 1、2、3、 同 offsetof 4、typeof 获取变量类型 5、使用获取到的类型定义一个临时指针变量
使用#define定义的常量也称为符号常量,可以提高程序的运行效率。...Microsoft Word中对宏定义为:“宏就是能组织到一起作为一独立的命令使用的一系列word命令,它能使日常工作变得更容易”。...a + 1) ); 这里还有一个宏定义: #define DOUBLE(x) (x) + (x) 定义中我们使用了括号,想避免之前的问题,但是这个宏可能会出现新的错误。...#define DOUBLE( x) ( ( x ) + ( x ) ) 提示: 所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用...0; } 五、带有副作用的宏参数 当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。
无参数的宏没什么好说的,但还是有些地方使用时要注意。 几点注意: 1. 在宏定义的#之前可以有若干个空格、制表符,但不允许有其它字符。...宏定义的有效范围称为宏定义名的辖域(也可以叫做生命周期,类似于变量的生命周期),辖域从宏定义的定义结束处开始到其所在的源程序文件末尾。宏定义名的辖域不受分程序结构的影响。...在新的宏定义中,可以使用前面已定义的宏名,示例: # define R 2.5 # define PI 3.1415926 # define Circle 2*PI*R # define Area PI...宏进行定义时不会考虑参数的类型。 3. 参数宏的使用会使具有同一作用的代码块在目标文件中存在多个副本,即会增长目标文件的大小。 4....宏中”#”和”##”的用法 一般用法: 1.使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起,看下面的示例: #include #include<climits
这时在脚本中就可以采用自定义的宏来实现: 例如: #if VNSpine using Spine.Unity; #endif Unity中有专门开启和关闭自定义宏的位置:PlayerSettings-OtherSettings-Configuration-Scripting
如下形式↓ #define M(x) ((x)+(x)) 其实这也无非就是操作符的优先级大小,切记(✿◕‿◕✿) 说明 宏参数和#define的定义中可以出现其他的#define...在使用函数的时候我们需要注意它的数据类型,但是在宏当中我们是不需要注意的,想是整形就是整形想是浮点型就是浮点型。说明用宏在这里是更加灵活的只是处理简单问题上切记。...命名事项 相信有些小伙伴已经发现了这个函数的宏的使用语法和函数是非常类似滴。所以语言本身就会没办法帮我们区分二者的一些使用。...,但是由于我们使用了#undef取消宏定义了。...此时编译器就相当于未定义标识符NUM了说的简单点相当于不存在了,注:是在取消宏定义之后的语句当中的。 拓展知识点⇥宏可以在任意地方使用。
在C语言中,有这样一个特殊的宏,叫offsetof,它的功能是啥呢?
Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。...实现方式: container_of(ptr, type, member) ; 其实它的语法很简单,只是一些指针的灵活应用,它分两步: 第一步,首先定义一个临时的数据类型(通过typeof...第二步,用(char *)__mptr减去member在结构体中的偏移量,得到的值就是整个结构体变量的首地址(整个宏的返回值就是这个首地址)。
二、关于“宏定义” 宏使用#define来进行定义,宏定义分为两种,一种是对象式宏,一种是函数式宏。...例如,我们可以将π的值定义成一个对象式宏,在使用的时候,用有意义的宏名要比直接使用π的字面值方便很多,例如: #import #define PI 3.1415926...,首先__COUNTER__在每次宏替换时都会进行自增,##是一种宏中专用的特殊符号,用来将参数拼接到一起,但是需要注意,使用##符号拼接的如果是另外一个宏,则其会阻止宏的展开,因此我们定义了一个转换宏...多语句功能性宏,要使用do-while包裹 这条原则看上去有些莫名其妙,但是其非常重要,例如,我们需要编写一个自定义的LOG宏,在进行打印时添加一些自定义的信息,你或许会这样写: #define...对于不定参数的宏,借助##符号来拼接参数 在定义函数时,我们可以定义函数的参数为不定个数参数,定义函数式宏时也类似,使用符号"..."
C语言提供的预处理功能有三种,分别为宏定义、文件包含和条件编译,下面将对它们进行简单介绍: 宏定义:在 C语言源程序中允许用一个标识符来表示一个字符串,称为“宏” ,被定义为“宏”的标识符称为“宏名”。...在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。 宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的。...无参宏的宏名后不带参数,其定义的一般形式为: #define 标识符 字符串; 其中“#”表示这是一条预处理命令(在 C 语言中凡是以“#”开头的均为预处理命令)“define”为宏定义命令,“标识符...”为所定义的宏名, “字符串”可以是常数、表达式、格式串等。...符号常量的定义就是一种无参宏定义。 此外,常常对程序中反复使用的表达式进行宏定义。例如: #define M (y*y+3*y); 它的作用是指定标识符 M 来代替表达式(y*y+3*y)。
#define offsetof ( TYPE, MEMBER) \
前面,我们既一起研究了自定义函数的题,有看了宏定义的题,下面这题刚好就是要用自定义函数和宏定义解题的,帮大家巩固知识点 题目描述 分别用函数和带参的宏,从三个数中找出最大的数。...输入 3个实数 输出 最大的数,输出两遍,先用函数,再用宏。 保留3位小数。...样例输入 1 2 3 样例输出 3.000 3.000 大家会发现宏定义比自定义函数简单,方便,但自定义函数的功能更加强大 PS:宏定义只是简单的宏替换 详细题解见C语言网题库1041题 比赛也打完了,
有同学写过或者想写这样的宏定义吗? 求两个或几个数的乘积: #define SQU(x) x*x 我们正常使用没有问题: 但如果这样写呢?...原因在于,宏定义的本质是文本替换!所以在预处理期间SQU(5+5)这段代码被宏替换为5+5*5+5,结果因为乘法优先级高于加法,变成5+25+5,可想而知!...我们继续验证: 正常写,不会触发陷阱,关键没错并不代表没有问题(虽然每个x都加了小括号!) 大家试试这样写: 艾玛! 为嘛不是20*20的400呢?...还是遵循宏的本质,我们展开来看:10+10*10+10=120 又是一个优先级问题,又一个陷阱,防不胜防呀! 那怎么解决呢?答:干脆一了百了,整体全加括号吧!...这么写:#define ADD(x) ((x)+(x)) 怎么样,这样写就没问题了!你的宏,从此百毒不侵! 有什么学习中遇到的问题,请联系我们! C语言研究中心(www.dotcpp.com)
习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件 •C语言提供的预处理指令主要有:宏定义、文件包含、条件编译 宏定义分类 •宏定义可以分为2种: –不带参数的宏定义...–带参数的宏定义 一、不带参数的宏定义 •1.一般形式 •#define 宏名 字符串 •比如 #define ABC 10 •右边的字符串也可以省略,比如#define ABC 2.作用 •它的作用是在编译预处理时...5> 定义一个宏时可以引用已经定义的宏名 #define R 3.0 #define PI 3.14 #define L 2*PI*R #define S PI*R*R 带参数的宏定义 •#define...3.使用注意 •1> 宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串....,带参数的宏定义,在源程序中出现的形式与函数很像。
领取专属 10元无门槛券
手把手带您无忧上云