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

避免这7个误区,才能让【宏】削铁如泥

语法错误 当使用参数调用宏时,会将参数替换为宏主体,并与其他输入文件一起检查结果,以进行更多的宏调用,可以将部分来自宏主体和部分自变量的宏调用组合在一起。...参数预扫描处理 宏参数在被替换为宏主体之前必须经过完全宏扩展,替换后,将再次扫描整个宏主体,包括替换的参数,以查找要扩展的宏。...如果按照给定的方式替换了参数,并且没有进行预扫描,则剩余的单个扫描将找到相同的宏调用并产生相同的结果。 预扫描处理在以下三种特殊情况下有大的作用。...预扫描会导致发生预期的结果。 如果没有预扫描,f(1)本身将被替换为参数,并且f的内部使用将在主扫描期间作为间接自引用出现,并且不会扩展。...调用其他可进行字符串化或连接的宏的宏 如果参数是字符串化或串联的,则不会进行预扫描。 如果要扩展宏,然后对其扩展进行字符串化或串联,则可以通过使一个宏调用进行该字符串化或串联的另一宏来实现。

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

    谈一谈字节序的问题

    而C语言也针对整型数据提供了一组接口,htonl、htons用于本地序转网络序,以及ntohl、ntohs用于网络序转本地序。 示例 我们通过一个例子来观察大端序和小端序,本地序和网络序的不同。...示例程序做的事情很简单,定义整型变量a,将a的每一个字节的地址和值打印出来,将其转换为网络序之后,再打印观察。...使用htonl宏将a转为网络序(大端序)之后,a的低位存储在高位之后。 转换前后,打印a的数值大小截然不同。 为什么不统一字节序 既然每次都发送网络数据之前都要转换,为什么不统一字节序呢?...数据从本地传输到网络,需要转换为网络序,接收到的网络数据需要转换为本地序后使用。 C提供了一组接口用于整型数据在本地序和网络序之间的转换。...多字节数据对象才需要转字节序,例如int,short等,而char不需要。 由于处理器是按照IEEE标准处理float和double的(参考:对浮点数的一些理解),因此也不需要转字节序。

    82230

    SWIG 官方文档第二部分 - 机翻中文人肉修正

    接口文件可以根据需要查看这些符号,以更改生成接口的方式或将 SWIG 指令与 C 代码混合。...#endif 以下运算符可以出现在宏定义中: • #x 将宏参数x转换为由双引号 ("x") 包围的字符串。...与普通的 C 预处理器宏不同,没有必要用连续字符 (\) 终止每一行——宏定义扩展到 %enddef 的第一次出现。此外,当这些宏被扩展时,它们会通过 C 预处理器重新解析。...事实上,SWIG 的许多高级功能和库都是使用这种机制构建的(例如 C++ 模板支持)。 8.6 C99 和 GNU 扩展 SWIG-1.3.12 和更新版本支持可变参数预处理器宏。...(0, 10): c[i] = 2*i # 赋值example.print_array(c) # 传递给 C 注意:这些宏没有将 C 数组封装在特殊的数据结构或代理中。

    2.3K20

    提高代码逼格的利器:宏定义-从入门到放弃

    (); #ifdef __cplusplus } #endif 这样的代码几乎在每个开源库中都可能见到,主要的目的就是 C 和 C++ 混合编程,具体来说就是: 如果使用 gcc 来编译...宏扩展最大的好处有如下几点: 减少重复的代码; 完成一些通过 C 语法无法实现的功能(字符串拼接); 动态定义数据类型,实现类似 C++ 中模板的功能; 程序更容易理解、修改(例如:数字、字符串常亮)...此时,使用宏来实现的优势就体现出来了:因为宏中没有类型的概念,调用者传入任何数据类型都可以,然后在后面的比较操作中,大于或小于操作都是利用了 C 语言本身的语法来执行。...在 C++ 中,这样的操作可以通过参数模板来实现,所谓的模板也是一种代码动态生成机制。当定义了一个函数模板后,根据调用者的实参,来动态产生多个函数。...所以,从代码的动态生成角度看,宏定义和 C++ 中的模板参数有点神似,只不过宏定义仅仅是代码扩展而已。

    1.2K40

    C语言预处理详解

    本文将详细介绍C语言中的预处理指令,包括它们的用法、作用和注意事项。 一、预处理器的基本概念 预处理器是C语言编译器的一部分,它负责处理源代码中的预处理指令。...预处理指令以井号(#)开头,它们不是C语言的语句,因此不需要以分号(;)结尾。  二、预定义符号 在C语言中,预处理器提供了一些预定义符号(预定义宏),这些符号在编译过程中由编译器自动定义。...#运算符(字符串化) 功能:将宏参数转换为字符串字面量。这个过程称为“字符串化”。 用法:在宏定义中,使用 # 运算符将宏参数转换为字符串。...STRINGIFY 中,#x 将宏参数 x 转换为字符串字面量。...然而,宏的使用需要谨慎,避免复杂的宏和潜在的副作用,以保持代码的清晰性和可维护性。 希望这篇博客能帮助你深入理解C语言的预处理器,提升你的编程技巧!

    15410

    条件编译 #和##运算符

    正文开始 前言: 本章为C语言语法完结撒花, 下文将进行C语言中#和##操作符以及条件编译的讲解, 来进一步让我们了解C语言. 作者主页: 酷酷学!!! 1....#运算符 #运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。 #运算符所执⾏的操作可以理解为”字符串化“。...,就出现了#a,⽽#a就是转换为"a",时⼀个字符串 代码就会被预处理为: printf("the value of ""a" " is %d", a); 运⾏代码就能在屏幕上打印: the value...n", ret); return 0; } 运行结果: 代码分析: //Struct是结构体类型名,MenberName是成员名. //1、先将0转换为一个结构体类型的指针, // 相当于某个结构体的首地址是...写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

    6310

    预处理指令、typedef、条件编译、多文件代码

    修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,预处理器不会改动源文件。...修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,,预处理器不会改动源文件。...#define预处指令 #define 宏 替换体 一旦预处理在程序中找到宏后,就会用替换体替换该宏。 宏的命名规则遵循C语言标识符的命名规则:只能使用字母、数字、下划线,且首字符不能是数字。...#define 宏(参数1, 参数2,...,参数n) 替换体 虽然由带参数的#define定义的宏函数,在使用方法上很像函数。但是,它的本质依然是将宏替换为对应的替换体。...若定义了该宏,则删除指令块内的代码。否则,则保留代码块内的代码。 多文件代码 预处理:执行预处理指令,修改源代码。 编译:将预处理后的源代码转换为二进制目标文件。

    1.1K40

    预处理指令、typedef、条件编译、多文件代码

    修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,预处理器不会改动源文件。...修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,,预处理器不会改动源文件。...#define预处指令 #define 宏 替换体 一旦预处理在程序中找到宏后,就会用替换体替换该宏。 宏的命名规则遵循C语言标识符的命名规则:只能使用字母、数字、下划线,且首字符不能是数字。...#define 宏(参数1, 参数2,...,参数n) 替换体 虽然由带参数的#define定义的宏函数,在使用方法上很像函数。但是,它的本质依然是将宏替换为对应的替换体。...编译:将预处理后的源代码转换为二进制目标文件。 链接:将需要用到的目标文件合并成可执行文件。 对于源文件来说,编译器是单个独立编译的,并生成对应的目标文件。

    1.3K00

    C语言中的宏定义

    带参数的宏不仅适用于模拟函数调用。他们特别经常被作为模板,来处理我们经常要重复书写的代码段。如果我们已经写烦了语句 printf("%d"\n, x); 因为每次要显示一个整数x都要使用它。...j); //转换为 printf("%d\n", i/j); 3....考虑下面的宏: 如下例子:当MK_ID被调用时(比如MK_ID(1)),预处理器首先使用自变量(这个例子中是1)替换参数n。接着,预处理器将i和1连接成为一个记号(i1)。...接着,预处理器会重新检查替换列表,看它是否包含其他宏的调用(在这个例子中,调用了宏PI)。预处理器会不断重新检查替换列表,直到将所有的宏名字都替换掉为止。...与标准c++不一致的编译器将使用具有5位或更少的数值。

    6.5K10

    C语言从入门到实战——预处理详解

    C语言预处理的主要功能有: 宏替换:通过使用#define定义宏,可以将一段代码或表达式抽象成一个标识符,在编译时将标识符替换成对应的代码或表达式。...C语言预处理的工作原理如下: 预处理器扫描源文件,遇到以#开头的指令时,按照指令的要求进行处理。 对于宏替换指令,预处理器将标识符替换成对应的代码或表达式。...1.2__LINE__ 在 C 语言中,__LINE__ 是一个特殊的预处理器宏,用于获取当前代码行的行号。 __LINE__ 宏可以在程序中使用,它会在编译时被替换为当前代码行的行号。...* 5 警告: 这个宏存在一个问题: 观察下面的代码段: int a = 5; printf("%d\n" ,SQUARE( a + 1) ); 乍一看,你可能觉得这段代码将打印36,事实上它将打印11...调试 宏是不方便调试的 函数是可以逐语句调试的 递归 宏是不能递归的 函数是可以递归的 七、 #和## 7.1 #运算符 #运算符将宏的一个参数转换为字符串字面量。

    60711

    C++内联函数

    一、内联函数概念 在c++中,预定义宏的概念是用内联函数来实现的,而内联函数本身也是一个真正的函数。 内联函数具有普通函数的所有行为。...这些事预 处理器无法完成的。 内联函数的确占用空间,但是内联函数相对于普通函数的优势只是省去了函数调用时候的压 栈,跳转,返回的开销。我们可以理解为内联函数是以空间换时间。...二、宏函数和内联函数区别 宏函数的替换是发生在预处理阶段 内联函数的替换是发生在编译阶段 宏函数容易出错,但是内联函数不会 我们希望的是 c = (10 +20 )* 5,但是用宏函数出现的却会为...当调用一个内联函数的时候,编译器首先确保传入参数类型是正确匹配的,或者如果类型不 正完全匹配,但是可以将其转换为正确类型,并且返回值在目标表达式里匹配正确类型,或 者可以转换为目标类型,内联函数就会直接替换函数调用...类型检查和类型转换、包括在合适位置放入对象this指针这些都是预处理器不能完成的。

    1.2K40

    【C语言基础】:预处理详解(一)

    五、宏替换的规则 宏替换是C语言预处理器的一个重要功能,它在编译之前进行文本替换。...宏替换遵循一定的规则,这些规则确保了宏能够在正确的上下文中被替换为定义的文本,需要涉及几个步骤: 文本替换: 宏定义中的所有文本都将被直接替换到宏名出现的任何位置。...宏参数的保留: 当宏名被替换时,宏参数将保持其原始的括号结构。这是为了避免改变操作符的优先级和结合性,确保代码的逻辑不变。...宏展开的顺序: 当宏参数中包含其他宏时,预处理器会按照它们在宏定义中出现的顺序进行替换。如果宏A中使用了宏B,而宏B又使用了宏C,那么预处理器首先会替换宏C,然后是宏B,最后是宏A。...字符串化运算符可以将宏参数转换为字符串字面量,而标记粘贴运算符可以将两个宏参数连接成一个单一的标识符。

    20810

    offset宏定义_vba offset 用法

    宏的声明因供应商而异,并且取决于处理器体系结构。 浏览各种编译器,找到了一些清单示例声明。...为了更好地理解offset宏的魔力,进一步来看定义的细节,宏中的各种运算符按顺序计算,以便执行以下步骤: ((s *)0): 取整数零并将其转换为指向 s 的指针。...(size_t)&(((s *)0)->m): 将结果转换为适当的数据类型。 根据定义,结构本身驻留在地址 0。...Demo, c), (long)offsetof(struct Demo, d)); exit(EXIT_SUCCESS); } 知识点:结构填充字节 大多数 16 位和更大的处理器要求在多字节...在后一种情况下,之所以提供灵活性,是因为设计人员认识到,您可能希望将内存访问时间与其他相互竞争的问题(如内存大小和传输能力(可能通过通信链路或直接内存访问)进行权衡。

    60240

    【C语言】什么是宏定义?(#define详解)

    在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”. 宏定义是由源程序中的宏定义命令完成的,宏代换是由预处理程序自动完成的....tips:宏的名称中不允许有空格,而且必须遵守C变量的命名规则:只能使用字符,数字和下划线( _ )字符,而且首字符不能是数字. 第3部分 (指令行的其余部分)称为替换列表或替换体....一旦预处理器在程序中找到宏的示实例后,就会用替换体代替该宏. 从宏变成最终替换文本的过程称为宏展开. 注意,可以在#define行使用标准C注释.每条注释在预处理后都会被一个空格代替....一般而言,预处理器发现程序中的宏后,会用宏等价的替换文本进行替换,如果替换的字符串中还包含宏,则继续替换这些宏....表达式的求值结果更容易预 测。 带 有 副 作 用 的 参 数 参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果。

    66110

    Visual C++ 中的重大更改

    catch(D& d) { }            后面是宏的字符串文本 编译器现在支持用户定义的文本。 因此,宏之前没有任何干预空格的字符串文本被视为用户定义的文本,这可能会产生错误或意外结果。...\t331.cpp(10):备注:请参阅对正在编译的类模板实例化“std::is_base_of”的引用         替换为         [             T=D,            ...如果将 snprintf 或vsnprintf 在包括 之前定义为宏,则现在编译将因出错而失败,该错误指示定义了宏的位置。...因此,在使用 C++ 标准库时,使用不同版本编译的对象文件和静态库不能混合在同一二进制文件(EXE 或 DLL)中,并且不能在使用不同版本编译的二进制文件之间传递 C++ 标准库对象。...此检查无法检测 DLL 混合,也无法检测涉及 Visual C++ 2008 或早期版本的混合。           STL 包含文件 对 STL 标头中的 include 结构进行了一些更改。

    5.3K10
    领券