首页
学习
活动
专区
工具
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.1K20

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

62120

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.6K50

聊聊Swift

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

14410

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.4K30

C语言 | offsetofcontainer_of

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

2.1K30

ReactiveCocoa 奇妙无比” 魔法

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

2.5K20

C++枚举

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

28410

PHP源码常用代码定义

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

2.3K50

内核微内核

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

1.9K20

Linux内核container_of详细解释

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

1.2K10

继承、占位符混合

四、继承、占位符混合 很多初学者刚刚接触时候,都容易纠结什么时候用混合,什么时候用继承,然后什么时候用占位符。其实,这3个都有它们自身优缺点。...这一节我们来详细探讨一下这3个在实际开发不同。...继承、占位符混合声明方式调用方式 方法 声明方式 调用方式 继承 .class @extend 占位符 %placeholder @extend 混合...@mixin @include 一、继承与混合 对于继承(包括@extend%placeholder)混合,我们总结出以下几点: (1)继承混合都能实现相同代码块重用,极大提高开发效率...在实际开发过程,对于“功能代码块”(类似于JavaScript函数)我们都是使用混合来实现,因为功能代码块往往是可以通过传递不同参数来满足我们开发不同需求。

83130

JavaScript任务微任务

最近问了大佬一个问题,监听定时器两个性能问题,大佬给我普及了任务微任务概念,于是网上找见了这样一段代码: console.log('script start'); setTimeout(function...,JavaScript事件循环、同步、异步就不多说了,今天分享任务微任务。...先记住两个概念: 宿主环境提供任务,由语言标准提供叫微任务,这是算比较标准也算比较好记忆区分任务微任务了。...global 是 javascript 运行时所在宿主环境提供全局对象,在浏览器,没有实现global对象,而是通过window对象来指向global对象,代替global成为全局对象。...因为浏览器暴露了一系列操作 DOM, Location, History 等 Api 供 javascript 调用,而这些操作对象在global是不存在

36110
领券