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

宏中的#和##

在C语言中,宏是一种预处理指令,用于在编译之前对代码进行文本替换。宏中的#和##是宏操作符,用于对宏参数进行字符串化和连接操作。

  1. #操作符:字符串化操作符 在宏定义中,#操作符用于将宏参数转换为字符串常量。它将参数的值转换为一个以双引号括起来的字符串,并在宏展开时插入到相应的位置。

示例:

代码语言:c
复制

#define STR(x) #x

printf("%s\n", STR(Hello)); // 输出 "Hello"

代码语言:txt
复制

推荐的腾讯云相关产品:腾讯云函数(SCF)

  1. ##操作符:连接操作符 在宏定义中,##操作符用于将两个参数连接成一个标识符。它将两个参数的内容进行连接,并在宏展开时插入到相应的位置。

示例:

代码语言:c
复制

#define CONCAT(x, y) x##y

int CONCAT(num, 1) = 10; // 定义一个名为num1的变量,其值为10

代码语言:txt
复制

推荐的腾讯云相关产品:腾讯云容器服务(TKE)

宏中的#和##操作符在C语言中广泛应用于代码生成、模板化编程等场景,可以提高代码的灵活性和可重用性。在使用时需要注意宏参数的类型和展开后的语法正确性,避免出现意外的错误。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

###用法

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

1.2K20
  • DragonOSREAD_ONCE()WRITE_ONCE()

    DragonOS实现了与Linux相似的READ_ONCE()以及WRITE_ONCE(),主要目的在于解决并行计算场景下,编译器错误优化导致数据访问错误问题。...下面进行简单介绍: 这两个主要是为了解决并行访问问题。编译器在优化代码时候,会对一些操作进行重排序,或者删掉一些它认为无用操作。...为了保证代码之间不乱序,我们可以使用READ_ONCE()WRITE_ONCE(),告知编译器涉及到操作之间不能乱序。...他们之间区别 细心小伙伴会发现:对于读取一个变量值,好像这两个都能实现哦!对于这个问题,我们需要回到最开始出发点:我们到底是要保护哪个操作不被乱序?...WRITE_ONCE(a[0], x); WRITE_ONCE(a[1], x); 以上就是对READ_ONCE()WRITE_ONCE()简单介绍,如果有任何疑问或意见,可以通过邮件联系我:longjin

    69020

    Java变量,替换详解。

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

    3.8K50

    聊聊Swift

    聊聊Swift ,Macros是一种常见编程技术,传统C语言中,即包含了功能。这种功能,简单来说是在代码预编译阶段进行静态替换,是一种非运行时特性。...但元编程能力可以大大提高编程灵活性复用性,Swift在5.9版本重新引入了功能,并且是以一种全新方式来定义实现,在提供灵活性同时保证代码安全性可靠性。...但这也有一些缺陷,相比与C语言,Swift定义非常抽象,实现复杂,不太利于开发者进行理解。...但却不同,必须进行声明,声明主要作用是指定名称、参数以及类型使用场景。...,除了上述示例场景外,我们也可以对某个指定多个角色,例如member角色accessor角色,可以同时为所修饰原结构增加内部属性外部访问器方法。

    58810

    Rust过程

    x变量是一个表达式(用x:expr标记),所以在展开后它知道如何正确处理,会将其展开为((1 + 1) * (1 + 1))。 然而这只是书本上常见简单用法。...强大远不至此,在一些开源库框架中常见一些高级用法。当然也有点儿黑魔法味道了,但封装后确实可以简化代码,方便使用。...对于编程,Rust中提供了几种过程库操作支持,即: 1、Syn 它是基于TokenStream一种语法分析过程,它并不很强大,需要自定义扩展一些,比如Rust函数闭包等。...3、proc_macro2 更好proc_macro更方便接口,能syn、quote一起更好配合应用。 什么是过程?...过程(Procedure Macro)是Rust一种特殊形式,它将提供比普通更强大功能。方便起见,本文将Rust由macro_rules!定义称为规则以示区分。

    2.6K30

    C语言 | offsetofcontainer_of

    今天分享C语言中两个,这两个包含了指针结构体知识,非常具有代表性。另外,这个题目曾经是大疆无人机一道笔试题,可见,这两个对C语言基础还是有一定要求。...废话不多说,今天要说两个分别是offsetofcontainer_of,第一个是用来计算结构体某个成员相对于结构体偏移量,第二个是已知指向结构体某个成员指针,来计算结构体指针。...没错,这就是这个思路。...下面是我用这个在gcc上做实验: ? ? 这个作用是已知某个结构体成员变量指针,反过来得到结构体地址。其实有了上面的那个基础,这个会更简单一些。...这里要注意就是这个偏移量是int类型,上面说到计算偏移量时可以不强制转化为int型,但是这里做加减时就必须转化为int型了,因为char*类型不能指针相加减,只能和数字相加减。

    2.2K30

    ReactiveCocoa 奇妙无比” 魔法

    在ReactiveCocoa ,封装了很多非常实用”,使用这些“”为我们开发带来了很多便利。 今天就来盘点一下RAC是如何实现。...ReactiveCocoa,如果不查看源码分析,会觉得那些都像魔法一样奇妙无比,接下来就来解开“”魔法神秘面纱。 二. ReactiveCocoa ?...它们在元编程,处理计数index方面及其有用。VAL值域都是[0,20]。...这三个在ReactiveCocoa一定是使用最多,那么就先来分析这三个。这三个定义在RACEXTScope.h。 关于weakify(...)strongify(...)... RACTupleUnpack(...) 这两个在ReactiveCocoa也是非常常见,专门用在RACTuple。 先看RACTuplePack(...)

    3K30

    C++枚举

    大家好,又见面了,我是全栈君 我们计算器程序,用1234对应加减乘除,对于人阅读很产生一点障碍。...隔一个月后再看此代码可能想不起是0123还是1234了,还得去代码查找,如果能为代表四则运算四个数取个有意义别名就好了,一看是知道对应什么。没问题,用啊。...实质就是替换。在编译时,第一步就是把代码用实际值代替。用还一个好处,当你把对值改动的话,程序其余地方不用动。比如你可以把1234,改成0123,程序照样运行不出错。...枚举每一项就是为一个整数取了个名字,每一项都是一个常量,而不是的成员变量。枚举用处更像是把表示某种东西相关值组织到一起,而就做不到了。...比如四则运算,每一项都可以随意找位置放,它们不紧邻也没有语法错误。而枚举是强制把相关项放在一起。 枚举名字一般不大写,当然你可以像一样大写。只要你整个工程中都能坚持统一风格就行了。

    32910

    PHP源码常用代码定义

    PHP源码常用代码定义: #define 名 字符串 #表示这是一条预处理命令,所有的预处理命令都以#开头。define是预处理命令。名是标识符一种,命名规则标识符相同。...在编译预处理时,对程序中所有出现名”,都用定义字符串去代换,这称为“代换”或“展开”。 1....在定义参数称为形式参数,在调用参数称为实际参数,这点函数有些类似。 1....ZEND_NAMED_FUNCTION(ZEND_FN(name)) 会把ZEND_FUNCTION(count) 替换成 ZEND_NAMED_FUNCTION(ZEND_FN(count)) 参数字符串化参数连接...: 在定义中使用#用来将参数转换为字符串,也就是在参数开头末尾添加引号。

    2.4K50

    内核微内核

    微内核 把操作系统分成多个独立功能模块,每个功能模块之间访问需要通过消息来完成,因此效率没那么高。 内核微内核架构图如下: ?...内核微内核架构图 现代操作系统 windows 采用就是微内核方式,内核保留操作系统最基本功能,进程调度,内存管理,通信等模块,其他功能放到用户态来实现。...Linus当初在设计Linux操作系统时采用内核架构。但是Linux在20年来发展,不断融入微内核一些精华设计,如模块化设计,抢占式内核,动态加载内核模块等。...Linux内核很多核心实现或者设备驱动实现都可以编译成一个个单独模块。模块是被编译成一个目标文件,并且可以在运行时内核上动态加载卸载。...微内核实现模块化不一样,它和静态编译内核函数一样,运行在内核

    2.1K20

    COM开发Win32 SDK头文件、定义HRESULT

    在组件对象模型(COM)开发,Win32 SDK头文件、定义HRESULT扮演着至关重要角色。...它们不仅为开发者提供了与Windows操作系统交互必要接口,还确保了COM组件可移植性互操作性。本文将深入探讨这些概念,并提供实际开发使用指导。...在COM开发,以下几个头文件尤为重要: Unknwn.h:定义了IUnknown接口相关。 Wtypes.h:包含了COM使用数据结构。...例如,当你定义一个COM接口时,需要包含Unknwn.h以获取IUnknown接口定义。 定义 在Win32 SDK定义用于条件编译配置应用程序行为。...使用HRESULT 在COM,HRESULT使用遵循以下规则: 成功与失败:使用SUCCEEDEDFAILED来判断函数调用是否成功或失败。

    89900

    Linux内核container_of详细解释

    0xffffcbd4//偏移地址 +24   我们可以看到,结构体地址结构体第一个成员地址是相同。...我们可以看到,结构体成员变量在内存存储其实是偏移地址。也就是说结构体A地址+成员变量偏移地址 = 结构体成员变量起始地址。...因此,我们也可以根据结构体变量起始地址成员变量偏移地址来反推出结构体A地址。...container_of作用是通过结构体内某个成员变量地址该变量名,以及结构体类型。找到该结构体变量地址。...这里使用是一个利用编译器技术小技巧,即先求得结构成员在结构偏移量,然后根据成员变量地址反过来得出主结构变量地址。

    1.3K10

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

    除了编译语言中这个概念也被广泛应用于其他环境,比如键盘语言。键盘是将一系列小命令或动作转化为一系列指令,以简化日常工作。...(x++) : (y++)); 在这个例子,xy都被传递给了MAX,并且它们都带有递增副作用。由于MAX条件运算符(a) > (b) ?...所以输出结果是:x=6 y=10 z=9 六、替换规则​ 在程序扩展#define定义符号时,需要涉及几个步骤。​ 1....最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义符号。如果是,就重复上述处理过程。 注意: 1. 参数#define 定义可以出现其他#define定义符号。...用于调用函数从函数返回代码可能比实际执行这个小型计算工作所需要时间更多。所以比函数在程序规模速度方面更胜一筹。 2. 更为重要是函数参数必须声明为特定类型。

    67010
    领券