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

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

语法错误 当使用参数调用宏时,会将参数替换为宏主体,并与其他输入文件一起检查结果,以进行更多的宏调用,可以将部分来自宏主体和部分自变量的宏调用组合在一起。...(int); 如果我们将宏定义为 #define ceil_div(x,y)((x)+(y)-1)/(y) 可能导致另一种情况,sizeof ceil_div(1,2)是一个C表达式,可以计算ceil_div...实际上,每当在运行文本中使用预处理器时,预处理器都会将其单独保留。 如果宏x扩展为使用宏y,而y的扩展引用了宏x,则这是x的间接自引用。...参数预扫描处理 宏参数在被替换为宏主体之前必须经过完全宏扩展,替换后,将再次扫描整个宏主体,包括替换的参数,以查找要扩展的宏。...如果按照给定的方式替换了参数,并且没有进行预扫描,则剩余的单个扫描将找到相同的宏调用并产生相同的结果。 预扫描处理在以下三种特殊情况下有大的作用。

1.3K20

CC++ 预处理器

翻译程序 这个操作是 预处理之前 的操作,在 预处理 之前,编译器会对源代码会进行一些翻译操作: 将源代码中出现的字符映射到 源字符集。...) 宏的名字中不允许有空格,而且必须遵循C变量命名规则 替换列表(replacement list)或叫 主体(body), (这个地方可以省略,说明只是定义了这个一个宏) 预处理器在程序中发现了宏的实例后...一般而言,预处理器发现程序中的宏后,会用它的等价替代文本代替宏,如果该 文本中 还包括宏,则继续替换这些宏。 如果宏存在与双引号内,则不予替换。...语言符号 从技术方面看,系统将 宏的 主体 当作语言符号(token)类型字符串,而不是字符型字符串。 C预处理器中的 语言符号 是宏定义主体中 单独的词(空格分割开的词)。...C++ 宏中,# 与 ## 的用法 # 的作用 #的功能是将其后面的 宏参数 进行字符串化操作, 就是:宏变量替换后,左右各加一个双引号。

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

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

    tips:宏的名称中不允许有空格,而且必须遵守C变量的命名规则:只能使用字符,数字和下划线( _ )字符,而且首字符不能是数字. 第3部分 (指令行的其余部分)称为替换列表或替换体....一旦预处理器在程序中找到宏的示实例后,就会用替换体代替该宏. 从宏变成最终替换文本的过程称为宏展开. 注意,可以在#define行使用标准C注释.每条注释在预处理后都会被一个空格代替....通过指定结构体类型和成员名称作为参数,offsetof宏会返回该成员在结构体中的偏移量。 (不懂如何计算结构体成员偏移量的可以移步我的这篇博客:【C语言】结构体的大小是如何计算的?...表达式的求值结果更容易预 测。 带 有 副 作 用 的 参 数 参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果。...参 数 类 型 宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型。 函数的参数是与类型有关的,如 果参数的类型不同,就需要不同 的函数,即使他们执行的任务是 不同的。

    66110

    Objective-C 中 9 种避免使用 Xcode 预处理器宏的方法

    除了极少数例外,使用 Xcode 预处理器宏是一种代码气味。C++ 程序员们已经深有体会:" "。不幸的是,还有很多的 Objective-C 程序员尚未领悟到这一点。...本文是Objective-C 中的代码气味系列文章中的一篇。 这是一个可以在终端运行的便捷命令。它可以检查并显示当前目录下的源文件,预处理器宏的使用情况,你应该仔细检查。...以下是一些常见的 Xcode 预处理器宏,以及如何替换它们: 1、#include 让我们从传统 C 中的一个简单例子开始: Smell #include "foo.h" 除非您提供的是平台无关的 C...我们赋予常量一个明确的类型,增加了它的语义。如果你愿意,数字字面的表达也可以更简单,因为显式类型明确了可接受的值域。...但如果将这些值作为参数传递,就需要定义一个类型名,以增加编译器检查和语义。

    14610

    C++内联函数

    一、内联函数概念 在c++中,预定义宏的概念是用内联函数来实现的,而内联函数本身也是一个真正的函数。 内联函数具有普通函数的所有行为。...这些事预 处理器无法完成的。 内联函数的确占用空间,但是内联函数相对于普通函数的优势只是省去了函数调用时候的压 栈,跳转,返回的开销。我们可以理解为内联函数是以空间换时间。...二、宏函数和内联函数区别 宏函数的替换是发生在预处理阶段 内联函数的替换是发生在编译阶段 宏函数容易出错,但是内联函数不会 我们希望的是 c = (10 +20 )* 5,但是用宏函数出现的却会为...<< endl; } } 三、内联函数和编辑器 对于任何类型的函数,编译器会将函数类型(包括函数名字,参数类型,返回值类型)放入到 符号表中。...类型检查和类型转换、包括在合适位置放入对象this指针这些都是预处理器不能完成的。

    1.2K40

    【C语言】宏定义在 a.c 中定义,如何在 b.c 中使用?

    C语言中宏定义的使用教程 宏定义是 C 语言中的一种预处理器指令,广泛用于定义常量和宏函数。宏定义在编译之前由预处理器展开,可以提高代码的可读性、维护性和灵活性。...本文将详细讲解宏定义的概念、使用原理,以及如何在多个源文件中共享宏定义。 1. 宏定义的概念和使用原理 1.1 宏定义的基本概念 宏定义通过 #define 指令实现,它允许我们定义常量和宏函数。...宏的基本形式如下: #define 宏名 替换文本 对象宏:用于定义常量。对象宏将一个名字映射到一个固定的值。...例如,使用 #define MAX_BUFFER_SIZE 1024 可以明确表示缓冲区的大小,而不是在代码中直接写数字 1024。 便于维护:将常量定义放在宏中可以集中管理这些值。...总结 通过将宏定义放在头文件 macros.h 中,并在多个源文件中包含该头文件,我们能够在多个文件中共享宏定义。这种方法不仅提高了代码的重用性和一致性,还简化了维护和管理工作。

    12010

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

    修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,预处理器不会改动源文件。...修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,,预处理器不会改动源文件。...#define预处指令 #define 宏 替换体 一旦预处理在程序中找到宏后,就会用替换体替换该宏。 宏的命名规则遵循C语言标识符的命名规则:只能使用字母、数字、下划线,且首字符不能是数字。...区别 预处理中的#if: 预处理指令将在编译前,由预处理器处理。预处理器根据预处理指令的意图,修改代码。类似于#define指令,替换代码中出现的宏。...编译main.c时,将无法识别标识符Person。 所以,我们将Person结构类型的定义与符号常量NAME_LENGTH,在文件person.h中也写了一遍。

    1.1K40

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

    修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,预处理器不会改动源文件。...修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,,预处理器不会改动源文件。...#define预处指令 #define 宏 替换体 一旦预处理在程序中找到宏后,就会用替换体替换该宏。 宏的命名规则遵循C语言标识符的命名规则:只能使用字母、数字、下划线,且首字符不能是数字。...区别 预处理中的#if: 预处理指令将在编译前,由预处理器处理。预处理器根据预处理指令的意图,修改代码。类似于#define指令,替换代码中出现的宏。...编译main.c时,将无法识别标识符Person。 所以,我们将Person结构类型的定义与符号常量NAME_LENGTH,在文件person.h中也写了一遍。

    1.3K00

    【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )

    , 程序被强行从一个固定的内存地址执行, 每个种类的异常都有对应的一固定内存地址, 这个内存地址就是异常向量 ; ---- (2) 异常类型简介 ---- 异常类型 : ARM 架构 支持 七种类型的异常...Abort (instruction fetch memory abort) : 预取指令失败, ARM 在执行指令的过程中, 要先去预取指令准备执行, 如果预取指令失败, 就会产生该异常; 5.Data...; 使用 普通 向量 还是 高位向量, 可以使用 CP15 协处理器进行配置; 3.异常 与 地址 一一对应 : 每个异常都对应着一个地址, 出现指定类型的异常时, 就会跳转到该异常对应的地址执行异常处理程序...:start.S @ @异常处理框架 @**************************** .text @ 宏...^ %.o : %.c #通用规则, 如 start.o 是由 start.c 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ .PHONY:

    3.7K10

    C语言中的宏定义

    (j):(k)))); 2) 、宏参数没有类型检查。当一个函数被调用时,编译器会检查每一个参数来确认它们是否是正确的类型。如果不是,或者将参数转换成正确的类型,或者由编译器产生一个出错信息。...预处理器不会检查宏参数的类型,也不会进行类型转换。 3) 、无法用一个指针来指向一个宏。如在17.7节中将看到的,C语言允许指针指向函数。这一概念在特定的编程条件下非常有用。...宏会有唯一的参数type,它表示形式参数和返回值的类型。这里还有个问题,如果我们是用宏来创建多个max函数,程序将无法编译。(C语言不允许在同一文件中出现两个同名的函数。)...接着,预处理器会重新检查替换列表,看它是否包含其他宏的调用(在这个例子中,调用了宏PI)。预处理器会不断重新检查替换列表,直到将所有的宏名字都替换掉为止。...进值的数字 #define HEXCHK(c) (((c) >= '0' && (c)c)>='A' && (c)<= 'F') \ ((c)>='a' && (c)<='f'

    6.5K10

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

    由于它只是一个 C++ 类型,因此可以为目标语言容器编写类型映射以映射到 std::initializer_list。...预处理器支持标准的预处理器指令和宏扩展规则。但是,已经进行了许多修改和增强。本章描述了其中的一些修改。...与普通的 C 预处理器宏不同,没有必要用连续字符 (\) 终止每一行——宏定义扩展到 %enddef 的第一次出现。此外,当这些宏被扩展时,它们会通过 C 预处理器重新解析。...特别是对 int 和 double 等原始类型映射到目标语言中的相应类型。对于其他一切,指针用于引用结构、类、数组和其他用户定义的数据类型。...* }; “数字”和“指针”的特殊类型可以分别应用于任何数字和指针变量类型。

    2.3K20

    实时Linux内核的实现

    ,硬实时要求绝对保证响应时间不超过期限,如果超过期限,会造成灾难性的后果,例如汽车在发生碰撞事故时必须快速展开安全气囊;软实时只需尽力使响应时间不超过期限,如果偶尔超过期限,不会造成灾难性的后果,例如数字电视机顶盒...HRTIMER_MODE_REL_PINNED_HARD = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_HARD, 22 }; 软中断到期模式的高精度定时器,到期的时候在类型为...在内核主线中,4.16版本以前高精度定时器总是在硬中断里面执行定时器回调函数,4.16版本增加HRTIMER_MODE_SOFT:如果把到期模式指定为HRTIMER_MODE_SOFT,那么在类型为HRTIMER_SOFTIRQ...(1)local_lock(&llock)映射到preempt_disable()。 (2)local_unlock(&llock)映射到preempt_enable()。...(6)local_unlock_irqrestore(&llock)映射到local_irq_restore()。 实时内核把local_lock映射到一个每处理器自旋锁。

    6.7K40

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

    所以宏比函数在程序的规模和速度方面更胜一筹。 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以用于 > 来比较的类型。...宏的参数是与类型无关的。 利用宏的执行速度短,那是不是以后就只用宏了呢?这明显是不明智的,函数也有着宏所没有的优点: 3. 每次使用宏的时候,⼀份宏定义的代码将插入到程序中。...注意:使用 # 运算符时,应确保宏参数两侧有空格或其他非字母数字字符,否则可能会导致字符串化不正确。...2.2 ##运算符 在C语言中,## 是预处理器的标记粘贴运算符。这个运算符可以将两个标识符拼接成一个更长的标识符。...头文件包含的方式 在C语言中,头文件的包含方式主要有两种:直接包含和间接包含。这两种方式都是为了在当前文件中引入其他文件中定义的函数、变量、类型声明等,以便在当前文件中使用它们。

    17510

    C语言入门基础知识3

    C编译系统使用4个连续的字节(即32位)存储在float类型数据。..."hello, dear""hello, \ dear""hello, " "d" "ear" 定义常量 在 C 中,有两种简单的定义常量的方式: 使用 #define 预处理器。...#define 预处理器 下面是使用 #define 预处理器定义常量的形式: #define identifier value const 关键字 您可以使用 const 前缀声明指定类型的常量,如下所示...(2) 类型和安全检查不同 #define 宏没有类型,不做任何类型检查,仅仅是展开。 const 常量有具体的类型,在编译阶段会执行类型检查。...double a; a = (float)N/(float)2; 在编译时我们预想 a=2.5,实际打印结果是 3.5 原因是在预处理阶段,编译器将 a=N/2 处理成 a=2+3/2,这就是 define

    90720

    程序环境和预处理

    反之这个宏怎可以适用于整形、长整型、浮点型等可以 用于>来比较的类型。 宏是类型无关的。 宏的缺点:当然和函数相比宏也有劣势的地方: 1....每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。 2. 宏是没法调试的。 3. 宏由于类型无关,也就不够严谨。 4....//使用 MALLOC(10, int);//类型作为参数 //预处理器替换之后: (int *)malloc(10 * sizeof(int)); 宏和函数的一个对比 属 性 #define...表达式的求值结果更容易预 测。 带 有 副 作 用 的 参 数 参数可能被替换到宏体中的多个位置,所以带有副作 用的参数求值可能会产生不可预料的结果。...参 数 类 型 宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型。 函数的参数是与类型有关的,如 果参数的类型不同,就需要不同 的函数,即使他们执行的任务是 相同的。

    8410

    C语言 第八章 函数、指针与宏

    2.3、指针的初始化 // 定义int类型的变量a int a = 10; // 定义一个指针变量p int *p; // 将变量a的地址赋值给指针变量p,所以指针变量p指向变量a p = &a;...当预处理器遇到一个宏定义时,会做一个 “标识符”代表“替换列表”的记录。在文件后面的内容中,不管标识符在任何位置出现,预处理器都会用替换列表代替它。...在宏的名字和左括号之间必须没有空格。如果有空格,预处理器会认为是在定义一个简单的宏,其中(x1,x2,…,xn)是替换列表的一部分。...((c) – 0×20) : (c)) 13: 判断字符是不是10进值的数字 #define DECCHK(c) ((c)>='0' && (c)<='9') 14: 判断字符是不是16进值的数字 #...时间用字符串表示,其形式为: 分:秒 __STDC__ 宏指令的意义是编译时定义的。一般来讲,如果__STDC__已经定义,编译器将仅接受不包含任何非标准扩展的标准C/C++代码。

    92250

    滴滴前端一面必会面试题汇总

    预加载指的是将所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。 通过预加载能够减少用户的等待时间,提高用户的体验。...我了解的预加载的最常用的方式是使用 js 中的 image 对象,通过为 image 对象来设置 scr 属性,来实现图片的预加载。CSS预处理器/后处理器是什么?为什么要使用它们?...JavaScript 使用 Number 类型来表示数字(整数或浮点数),遵循 IEEE 754 标准,通过 64 位来表示一个数字(1 + 11 + 52)1 符号位,0 表示正数,1 表示负数 s11...指数位(e)52 尾数,小数部分(即有效数字)最大安全数字:Number.MAX_SAFE_INTEGER = Math.pow(2, 53) - 1,转换成整数就是 16 位,所以 0.1 ===...因为宏任务中包括了 script ,浏览器会先执行一个宏任务,接下来有异步代码的话就先执行微任务。

    47820

    基于DPDK(x86平台)应用性能优化实践

    如上图所示,一个运行在core0上的应用访问数字标号处数据的速度快慢从高到低为1 > 2 > 3 > 4。...char c; }; 结构体s1的大小为8字节,结构体s2为12字节,在定义时不考虑padding的话,每个结构体变量会浪费4字节。...可以在定义数据结构时用宏__rte_cache_aligned或加入padding成员。...一般访问CPU的cache效率最高,提前将需要处理的数据load到cache可以提高性能,但预取必须在合适的时间点发起,过早发起预取会导致数据还没有被使用就被替换出cache,最终适得其反,所以需要根据实际应用场景和多次尝试找到最合适的预取时间点...将目录拷贝到windows下,用VTune打开文件r000hs.amplxe 5.jpg VTune打开后,出现的是一个关于hotspots的视图(因为之前指定收集的类型为hotspots,如果指定其他收集类型比如

    4.3K40
    领券