首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

#define宏的边际效应

在C语言和C++中,#define宏进行的字符替换,要注意边际效应: 举例: #define N 2+3 我们预想的N值是5,我们这样使用N,int a = N/2; 我们预想的a的值是2.5,可实际上...a的值是3.5(这样说不太恰当,因为是取整,但为了说明先这样理解) 原因在于在预处理阶段,编译器将 a = N/2处理成了 a = 2+3/2;这就是宏定义的字符串替换的“边缘效应”,因此要如下定义:#...define N (2+3) 边际效应要用括号去完善 在C++中,不如直接用const,const常量有数据类型,而宏常量没有数据类型。...而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误(边际效应) 再来考察一题: #include #define N 3 #define Y(n) ((...如果喜欢我的文章,欢迎关注、点赞和转发,下面可以留言~~~

72120

C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)

四、#define定义宏 #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。​...下面是宏的申明方式: #define name( parament-list ) stuff 其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。​...所以输出的结果是:x=6 y=10 z=9 六、宏替换的规则​ 在程序中扩展#define定义符号和宏时,需要涉及几个步骤。​ 1....在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。 2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。 3....用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹。 2. 更为重要的是函数的参数必须声明为特定的类型。

97410
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++工程中常用的宏定义(#define)

    参考链接: C++ vsnprintf() 尽管说define有很多不足之处,很多时候我们需要使用const来替代define, 也可以使用typedef来替代define。 ...但是,在一些实际工程中,我们还是不可避免的使用到了define,这给我们带来了极大的方便。 ...1 定义头文件,防止重复包含  其实不是真正的防止重复包含头文件,而是忽略除了第一次之外的其他包含:  http://blog.csdn.net/wangshubo1989/article/details...kDate = "2016-11-25";  3 分平台实现  对于一些快平台开发,完全可以使用define来包含不同的文件,或是实现不同的功能:  #if (MY_PLATFORM == MY_PLATFORM_WIN32...MY_PLATFORM_WIN32) #include #include #include #endif  4 定义级别  比如打日志,我们可能有很多种日志的级别

    1.9K20

    C++工程中常用的宏定义(#define)

    尽管说define有很多不足之处,很多时候我们需要使用const来替代define, 也可以使用typedef来替代define。...但是,在一些实际工程中,我们还是不可避免的使用到了define,这给我们带来了极大的方便。...1 定义头文件,防止重复包含 其实不是真正的防止重复包含头文件,而是忽略除了第一次之外的其他包含: http://blog.csdn.net/wangshubo1989/article/details...= "2016-11-25"; 3 分平台实现 对于一些快平台开发,完全可以使用define来包含不同的文件,或是实现不同的功能: #if (MY_PLATFORM == MY_PLATFORM_WIN32...MY_PLATFORM_WIN32) #include #include #include #endif 4 定义级别 比如打日志,我们可能有很多种日志的级别

    2.6K60

    C语言中的宏陷阱 #define SQU(x) x*x

    有同学写过或者想写这样的宏定义吗? 求两个或几个数的乘积: #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)

    1.3K50

    C语言带参数的宏定义:#define f(X) ((X)*(X))

    2.知识点:不带参数的宏定义l 一般形式:#define 宏名 字符串(或数值)即用字符串或数值取代宏名。l 宏名一般采用大写字母表示,以与变量名区别,也可用小写字母。...l 宏定义可以嵌套使用,例如:#define R 3.0#define PI 3.14159#define L 2*PI*R 3.知识点:带参数的宏定义l 一般形式:#define 宏名(参数表)...有同学会说,这不简单,顺手就来: #define f(X) X*X 但是,忽略了一点,宏代换是直接进行代换的。...,使用带参数的宏时,要注意参数要带上括号,最好整个宏也要带上括号: #define f(X) ((X)*(X)) 否则,容易误导别人的同时,自己也容易出错。...实际编程中,这种问题遇到的很少,一般都使用函数代替,不会有这种问题,考试时候遇到的话,只能直接带进去看了。----本公众号资源在QQ群文件群共享也可下载。

    5.2K00

    iOS学习——iOS 宏(define)与常量(const)的正确使用

    概述   在iOS开发中,经常用到宏定义,或用const修饰一些数据类型,经常有开发者不知怎么正确使用,导致项目中乱用宏与const修饰。你能区分下面的吗?知道什么时候用吗?...变量、常量 //宏 #define HSCoder @"汉斯哈哈哈" //变量 NSString *HSCoder = @"汉斯哈哈哈"; //常量,四种写法 static const NSString...N块内存空间,可以根据const修饰的位置设定能否修改,在编译阶段会执行类型检查   我们来看一段代码 #define avatar @"60" if (false) { #define...当然这个时候编译器是会有一个警告的,但是不知道有多少同学会忽略这个警告。...更加重要的是用这种方法定义的常量是带有类型信息的,而这点则是define不具备的。

    1.8K31

    C++避坑之#define常量和形似函数的宏

    尽量避免#define定义常量 在C++中,定义常量应该尽量避免使用#define来定义一个常量,主要原因宏定义只做替换,不做类型检查和计算,不仅没有作用域限制,而且容易产生错误。...,#define确实是按照顺序来全局进行替换,初始定义A的值为10,因此main函数中的A和func2中的A均被替换为10,而最后在处理到func1的函数体的时候,A重新被定义为20,所以func1中的...因此,在C++中我们尽量避免使用#define来定义一个常量,应使用const和enum来定义常量。 尽量避免形似函数的宏 #define的另外一个需要注意的地方就是,尽量减少形似函数宏的使用。...同时,因为我们使用了函数,因此也遵守了作用域和访问的规则,使得我们的代码更具标准性和规则性。 总结 在C++中,尽量避免#define常量和形似函数宏的使用。...引用《Effective C++》中的话来做总结就是: 对于单纯常量,最好以const对象和enum替换#define。 对于形似函数的宏,最好改用inline函数替换#define。

    30710

    【编程经验】C语言中的宏陷阱 #define SQU(x) x*x

    咳咳咳,今天讲讲C中宏定义(片面),希望对小伙伴们有帮助,开始了: 有同学写过或者想写这样的宏定义吗?...求两个或几个数的乘积: #define SQU(x) x*x 我们正常使用没有问题: 但如果这样写呢? 哎呀,竟然不是100了,难道SQU(10)和SQU(5+5)不等价吗?5+5不是10吗?...原因在于,宏定义的本质是文本替换!所以在预处理期间SQU(5+5)这段代码被宏替换为5+5*5+5,结果因为乘法优先级高于加法,变成5+25+5,可想而知!...为嘛不是20*20的400呢? 还是遵循宏的本质,我们展开来看:10+10*10+10=120 又是一个优先级问题,又一个陷阱,防不胜防呀! 那怎么解决呢?答:干脆一了百了,整体全加括号吧!...这么写:#define ADD(x) ((x)+(x)) 怎么样,这样写就没问题了!你的宏,从此百毒不侵!

    1.1K80

    Java中的宏变量,宏替换详解。

    群友在微信群讨论的一个话题,有点意思,特拿出来分享一下。 输出true false 来看下面这段程序,和群友分享的大致一样。...首先来理解下宏变量: Java中,一个用final定义的变量,不管它是类型的变量,只要用final定义了并同时指定了初始值,并且这个初始值是在编译时就被确定下来的,那么这个final变量就是一个宏变量。...编译器会把程序所有用到该变量的地方直接替换成该变量的值,也就是说编译器能对宏变量进行宏替换。...final String a = "hello"; final String b = a; final String c = getHello(); a在编译期间就能确定下来,而b、c不行,所以a是宏变量...所以,再回到上面的程序,finalWorld2和finalWorld4是final定义的,也是在编译期间能确定下来的,所以它能被宏替换,编译器就会让finalWorld2和finalWorld4指向字符串池中缓存的字符串

    3.8K50

    整理CC++的可变参数

    .); 但是这种可变参数最早只能应用在真正的函数中,不能使用在宏中。...__用来把参数传递给宏,当宏被调用展开时,实际的参数就传递给了printf()....例如,下面的宏调用在ISO C里是非法的,因为字符串后面没有逗号,: LOG("A message") 虽然在GNU CPP中这种情况可以让你完全的忽略可变参数。...但是在上面的例子中,编译器仍存在问题,因为宏被展开后,里面的字符串后面会多一个逗号, 为了解决这个逗号,问题,CPP提供一个特殊的##操作,其格式为: #define LOG(format, ...)...fprintf(stderr, format, ## __VA_ARGS__) 如果传入的可变参数被忽略或者为空时,##操作会将使得预处理器(preprocessor)去除掉它前面的逗号。

    5.6K00

    聊聊Swift中的宏

    聊聊Swift中的宏 宏,Macros是一种常见的编程技术,传统的C语言中,即包含了宏功能。宏这种功能,简单来说是在代码的预编译阶段进行静态替换,是一种非运行时的特性。...但这也有一些缺陷,相比与C语言的宏,Swift中的宏的定义非常抽象,实现复杂,不太利于开发者进行理解。...Swift中的宏分为两类: 1 - 独立宏 2 - 附加宏 其中,独立宏单独出现,单独使用,不会附加到任何声明(可以理解为原始代码)上。附加宏则需要配合声明一起使用,通常是为了向原代码中增加一些功能。...独立宏 独立宏使用"#"来调用,因此当你在代码中看到#相关的语法时,就要意识到这是一个宏,且是一个独立宏。...附加宏 使用”@“来调用附加宏,附加宏用来补充其所声明的代码,为原始代码添加新的功能,附加宏比较复杂,后面我们再详细介绍。

    68010

    C++中inline和#define的区别总结

    在C++中,inline 和 #define 都用于代码优化,但它们的实现方式和功能有所不同。inlineinline 是一个函数修饰符,在函数定义前加上该关键字可以告诉编译器将该函数内联展开。...也就是说,编译器会将调用这个函数的地方直接替换为这个函数体的内容。因此使用 inline 可以减少程序运行时的调用开销,并提高程序效率。...使用 #define: 在需要定义常量或宏等时使用。...替换方式: 宏定义define只是单纯的字符串替换,而inline是代码嵌入,也就是说编译器在函数调用的地方直接将inline函数代码写进去,这样就不会产生函数的调用跳转(无栈帧消耗) ,因此适用于短小的函数...使用方式: 宏定义define只要定义了就会替换,而inline只是建议,编译器可以拒绝替换,在函数较大的时候,编译器可以选择不展开相应的函数。

    24110

    宏中#和##的用法

    printf(STR(vck)); // 输出字符串"vck"     printf("%d   ", CONS(2,3)); // 2e3 输出:2000     return 0;   }   二、当宏参数是另一个宏的时候...  需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.   1, 非'#'和'##'的情况   #define TOW (2)   #define MUL(a,b) (a*b)  ...2)));   MUL里的参数TOW会被展开为(2).   2, 当有'#'或'##'的时候   #define A (2)   #define STR(s) #s   #define CONS(a,...加多一层中间转换宏.   加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.  ...#define CONS(a,b) _CONS(a,b) // 转换宏   printf("int max: %s   ", STR(INT_MAX)); // INT_MAX,int型的最大值,为一个变量

    1.2K20

    如何忽略 Python 中异常的报错

    在 Python 编程中,异常是一种常见的情况,可能会导致程序中断或产生错误。然而,并非所有的异常都需要立即处理,有时候我们希望忽略某些异常并继续执行程序。...要忽略异常,我们可以在 except 块中不采取任何操作,或者使用 pass 语句来明确表示忽略异常。...当调用 divide 函数并尝试将 10 除以 0 时,ZeroDivisionError 异常会被忽略,函数会返回 None。...应该尽量指定要忽略的具体异常类型,而不是简单地忽略所有异常。这样可以避免忽略了本应该处理的异常。在忽略异常时,应该在代码中添加适当的注释,以说明为什么选择忽略该异常,以及忽略该异常的后果。...在调试程序时,应该避免忽略异常,以便能够及时发现并修复潜在的问题。结论:忽略 Python 中的异常是一种在特定情况下处理异常的方法。

    32610

    Rust中的过程宏

    宏中的x变量是一个表达式(用x:expr标记),所以在展开后它知道如何正确处理,会将其展开为((1 + 1) * (1 + 1))。 然而这只是书本上常见的宏的简单用法。...过程宏(Procedure Macro)是Rust中的一种特殊形式的宏,它将提供比普通宏更强大的功能。方便起见,本文将Rust中由macro_rules!定义的宏称为规则宏以示区分。...{ n in 0..10 { /* ... */ }} 过程宏的原理 以上三种过程宏的定义方法已全部介绍。可以发现,它的定义方式与普通函数无异,只不过其函数调用发生在编译阶段而已。...编译器在编译一段程序时,会首先将输入的文本转换成一系列的Token(标识符、关键字、符号、字面量等),同时忽略注释(文档注释除外)与空白字符等。 例如println!...; // 函数test_hello就生成了,可见性在调用之后 // ... test_hello("hello, proc-macro"); test_hello(10); 可以看出,写一个函数式的过程宏还是不那么复杂的

    2.6K30

    CC++中define定义的常量与const常量

    常量是在程序中不能更改的量,在C/C++中有两种方式定义常量,一种是利用define宏定义的方式,一种是C++中新提出来的const型常变量,下面主要讨论它们之间的相关问题; define定义的常量:...  define是预处理指令的一种,它用来定义宏,宏只是一个简单的替换,将宏变量所对应的值替换,如下面的代码: #define NUM 2 int main() { printf("%d", NUM...2)define定义的常量编译器不会进行任何检查,const定义的常量编译器会进行类型检查,相对来说比define更安全 3)define的宏在使用时是替换不占内存,而const则是一个变量,占内存空间...4)define定义的宏在代码段中不可寻址,const定义的常量是可以寻址的,在数据段或者栈段中。...5)define定义的宏在编译前的预处理操作时进行替换,而const定义变量是在编译时决定 6)define定义的宏是真实的常量,不会被修改,const定义的实际上是一个变量,可以通过相关的手段进行修改

    1.7K10
    领券