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

C和C++为什么这个宏没有扩展成一个常量?

在C和C++中,宏是一种用于在编译时进行文本替换的预处理指令。它们允许开发人员在代码中定义一些常用的操作或者值,并在编译时将其替换为相应的文本。宏的替换是在编译器进行预处理阶段完成的。

宏没有被扩展为一个常量的主要原因有以下几点:

  1. 宏的替换是简单的文本替换,不进行类型检查:宏只是将文本进行简单的替换,不会进行类型检查。因此,如果将宏定义为一个常量,在使用宏的地方,可能会导致类型不匹配的错误。为了避免这种情况,编译器会将宏作为普通的文本处理,而不是扩展为常量。
  2. 宏的值可以根据上下文进行改变:宏的值可以根据不同的上下文环境进行改变,而常量的值是固定的。如果将宏扩展为一个常量,那么就无法根据上下文环境的改变来调整它的值。这样会失去宏的灵活性和适应性。
  3. 宏的作用域是全局的:宏是在预处理阶段展开的,它的作用域是全局的。如果将宏定义为一个常量,那么在不同的代码模块中可能会出现重复定义的问题。为了避免这种问题,编译器将宏作为文本进行处理,而不是扩展为常量。

总结起来,C和C++中的宏没有扩展为常量是为了避免类型不匹配的错误、保持宏的灵活性和适应性以及避免重复定义的问题。通过将宏作为文本进行处理,开发人员可以根据需要灵活地定义和使用宏。

相关搜索:c++宏扩展(__VA_ARGS__项目名称和值)为什么Java,C#和C++没有范围?为什么在这个map for循环中这个x值没有增加呢?c++C++为char分配一个int - 为什么这个没有至少一个警告?如何在C++中定义一个扩展为条件语句的宏?如何在JavaScript和C/C++之间创建一个常量的公共文件?有没有办法在C++的这个类命名空间中定义某个类的全局常量?C++ 64位整数运算:有人可以解释为什么这个有效而另一个没有?c++当我从常量方法内部的引用成员调用非常量方法时,为什么我没有得到编译错误为什么Windows上的C++类定义在'class'之后通常有一个宏令牌?为什么这个并发代码比另一个慢(两个都是C++)?一个语句中的索引,赋值和增量在C++和C#中表现不同.为什么?在c#中有没有一个等价的带有整数和字符串成员变量的c++联合?为什么这个C++最小和最大货币算法代码不能工作?使用此代码,我想从货币交易中提取最低和最高价格C++;有没有办法让我的开关函数同时拒绝一个有效和无效的答案?当在c++中颠倒一个数组时,为什么我在输入和输出之间得到一个“随机”数字?有没有什么办法可以使用在一个函数中定义的常量变量可以被c++中同一程序中的其他函数使用如果字段和方法是静态的,为什么新建一个类的实例是没有意义的?[C#]为什么C++ auto_ptr有两个复制构造函数和两个赋值运算符但只有一个默认构造函数?
相关搜索:
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

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

尽量避免#define定义常量C++中,定义常量应该尽量避免使用#define来定义一个常量,主要原因定义只做替换,不做类型检查计算,不仅没有作用域限制,而且容易产生错误。...例如上例中,在预编译阶段A全部被替换为数字1020,编译器在编译的时候根本就感知不到A的存在,假如代码确实在这个定义A的地方出现了问题,我们debug的时候,只能看到相应的数字10或20,并不知道从哪里追踪它们的来源...因此,在C++中我们尽量避免使用#define来定义一个常量,应使用constenum来定义常量。 尽量避免形似函数的 #define的另外一个需要注意的地方就是,尽量减少形似函数的使用。...同时,因为我们使用了函数,因此也遵守了作用域访问的规则,使得我们的代码更具标准性规则性。 总结 在C++中,尽量避免#define常量形似函数的使用。...引用《Effective C++》中的话来做总结就是: 对于单纯常量,最好以const对象enum替换#define。 对于形似函数的,最好改用inline函数替换#define。

30210

C++】const 关键字 与 #define 定义 对比 ( 相同点 - 都可定义常量优化性能 | 不同点 - const 常量进行作用域检查类型检查 )

一、const 关键字 与 #define 定义 相同点 在 C++ 中 , const 可以作为 替代 #define 定义 的手段 ; const 常量定义 : const int a = 10..., 如果数组的大小不是常数 , 在 C 语言 C++ 语言 中都会在编译时报错 ; 在 C/C++ 编译环境中会报错 ; 在编译 Linux 内核时 , 如果出现这种情况 , 编译会通过 , Linux...定义 作为 数组的大小 , 编译会通过 ; 代码示例 : // 包含 C++ 头文件 #include "iostream" // 使用 std 标准命名空间 // 该命名空间中 , 定义了很多标准定义...不同点 ---- 在 C++ 语言中 , const 关键字 与 #define 定义 不同点 : const 常量 是 编译器 在 编译阶段 进行处理 , 会提供 类型检查 作用域检查 ; #..., 在其它函数中是无法调用该常量 b 的 ; 代码示例 : // 包含 C++ 头文件 #include "iostream" // 使用 std 标准命名空间 // 该命名空间中 , 定义了很多标准定义

40940
  • LPCTSTR类型

    P表示这是一个指针 C表示是一个常量 T表示在Win32环境中, 有一个_T 这个用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的,那么这个字符或者字符串将被作为...STR表示这个变量是一个字符串 所以LPCTSTR就表示一个指向常固定地址的可以根据一些定义改变语义的字符串。...原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。 常量字符串ansiunicode的区分是由_T来决定的。...这个地方使用的是强制类型转换,你都强制转换了,C++编译器当然不会拒绝你,但同时他也认为你确实知道自己要做的是什么。因此是不会给出警告的。...,里面对该字符串又没有任何的修改,那么该参数就应该定义 const char*, 但是很多初学者弄不清const地用法,或者是懒, 总之就是随意写成了 char* 。

    67130

    C++特性使用建议

    某些情况下,将一个单元测试类声明待测类的友元会很方便。 友元扩大了(但没有打破)类的封装边界。...变量可以被声明 constexpr 以表示它是真正意义上的常量,即在编译时运行时都不变。函数或构造函数也可以被声明 constexpr,以用来定义 constexpr 变量。...16.预处理 使用时要非常谨慎,尽量以内联函数,枚举常量代替之。 意味着你编译器看到的代码是不同的。这可能会导致异常行为,尤其因为具有全局作用域。...值得庆幸的是,C++ 中,不像在 C 中那么必不可少。以往用展开性能关键的代码,现在可以用内联函数替代。用表示常量可被 const 变量代替。用 “缩写” 长变量名可被引用代替。...优点: 在二〇一四年八月之前,C++11 一度是官方标准,被大多 C++ 编译器支持。它标准化很多我们早先就在用的 C++ 扩展,简化了不少操作,大大改善了性能安全。

    1.9K30

    C++基础知识(入门章2)

    • 所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象, C++中把这个未命名对象叫做临时对象。...inline内联函数 这是一个全新的知识点,我们先来了解一下其概念: • ⽤inline修饰的函数叫做内联函数,编译时C++编译器会在调⽤的地⽅展开内联函数,这样调⽤内联函数就不需要建⽴栈帧了,就可以提...• inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。...• C语⾔实现函数也会在预处理时替换展开,但是函数实现很复杂很容易出错的,且不⽅便调 试,C++设计了inline⽬的就是替代C函数。...C中被定义为⽆类型指针(void*)的常量

    8810

    简述C语言定义的使用

    我们仅需要改变一个定义,就可以改变整个程序中出现的所有该常量的值; 可以帮助避免前后不一致或键盘输入错误; 控制条件编译; 可以对C语法做小的修改; 带参数的 带参数的仍要遵循上述规则,区别只是名后面紧跟的圆括号中放置了参数...feral) foo(wolf); else bin(wolf); 判断语言被扩展: if (!...feral) foo(wolf); else bin(wolf); 被扩展: #define foo(x) do{ bar(x); baz(x); }while(0) if (!...#运算符 #的作用就是将#后边的参数进行字符串的操作,也就是将#后边的参数两边加上一对双引号使其成为字符串。例如a是一个的形参,则替换文本中的#a被系统转化为"a",这个转换过程即为字符串化。...,但是C++/C程序员不要定义很复杂的定义应该简单而清晰。

    1.6K20

    C++ 特性使用建议

    某些情况下,将一个单元测试类声明待测类的友元会很方便。 友元扩大了(但没有打破)类的封装边界。...变量可以被声明 constexpr 以表示它是真正意义上的常量,即在编译时运行时都不变。constexpr 可以定义用户自定义类型的常量,也修饰函数返回值。...16.预处理 使用时要非常谨慎,尽量以内联函数,枚举常量代替之。 意味着你编译器看到的代码是不同的。这可能会导致异常行为,尤其因为具有全局作用域。...值得庆幸的是,C++ 中,不像在 C 中那么必不可少。以往用展开性能关键的代码,现在可以用内联函数替代。用表示常量可被 const 变量代替。用 “缩写” 长变量名可被引用代替。...24.C++11 适当使用 C++11的库语言扩展,在用 C++11 特性前三思可移植性。 优点:在二〇一四年八月之前,C++11 一度是官方标准,被大多 C++ 编译器支持。

    1.7K20

    C语言里面那些你必须知道的常用关键字(详细讲解)

    ✨今天来给大家带来的是C语言中我们常用的关键字静态static的详细讲解typedef 、#define定义常量。   既然是详解想必大家必定是想学一些平常学不到的东西吧!...C/C++中内存大致分的三个区域 2....关键字static 静态局部变量 静态局部变量的作用域生命周期 静态全局变量 静态函数 #define 定义常量 #define 定义常量 #define 定义 那么是怎么调用的呢?...#define 定义 我们来看一下是怎么定义的: 定义函数非常相识 但是没有函数的返回类型参数类型 还是很不一样的,的实现体一般都是表达式 那么是怎么调用的呢?...static #define typedef 总结一下今天学了: 关键字static 关键字static修饰变量的作用域变化 #define定义的常量 关键字typedef 不知道大家掌握了没有

    27710

    我的C++奇迹之旅:内联函数auto关键推导指针空值

    3.没有类型安全的检查 。 C++有哪些技术替代?...常量定义 换用const enum 短小函数定义 换用内联函数 auto关键字(C++11) 在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有人去使用它...这是 C++ 语言的一个特性限制。 在 C++ 中,数组是一种特殊的数据结构,它的大小元素类型在编译时就必须确定。而 auto 关键字是用来进行类型推导的,它无法推导出数组的大小元素类型。...(关于迭代器这个问题,以后会讲,现在提一下,没办法讲清楚,现在大家了解一下就可以了) 指针空值nullptr(C++11) C++98中的指针空值 在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值...如果没有定义,则执行下面的代码块。 #ifdef __cplusplus//这个预处理指令检查是否在 C++ 编译环境下。如果是 C++ 编译环境,则执行下面的代码块。

    16710

    C++篇】迈入新世界的大门——初识C++(下篇)

    +在传值返回时会先把数据拷贝到一份空间中,这个叫做临时对象,C++规定临时对象具有常性,所以不能进行+=操作,会报错。...在这之前我们先回顾一下C中的#define定义的 更多的详细内容请看【C语言篇】编译链接以及预处理介绍(上篇) #define N 10 //实现一个ADD函数的常见问题 #define ADD...,但是替换机制,调用时不用建立栈帧,提效 C语⾔实现函数也会在预处理时替换展开,但是函数实现很复杂很容易出错的,且不⽅便调试,于是祖师爷在C++设计inline⽬的就是替代C函数。...inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。...(C++规定void*类型的指针不能被隐式转换成任何类型的指针(必须显示转换)) 其实根本原因就是:在这之前C/C++标砖规定的NULL既是整数常量,也是空指针常量 所以C++11中引⼊nullptr,

    12910

    【代码规范】详解nullptr、NULL、0

    欢迎大大们纠错~ null NULL CC++语言对大小写是敏感的,也就是说nullNULL本质上是区别对待的。...其实本质上nullNULL都是符号,只是在不同的编译器上NULL被定义指定内容,null没有定义而已。 例如在vs环境中,NULL被指定为0,代码如下。 ?...0的相关 ‘\0’是一个“空字符”常量,它表示一个字符串的结束,它的ASCII码值为0,与’0‘的ASCII码值48是不一样的。...,'\0'是一个常量,等同于0,(这个地方理解的不够深入)。 ‘0’ 代表字符0, ASCII码为48。 “0”代表字符串0,尾部有不可见的’\0‘。...这个地方有一些需要注意的一些使用方法如下,代码如下图: ? 看起来执行结果没有什么问题,你可能会说说来说去,那还不都是 0 嘛。 ? 确实在大部分的情况下是这样的,但背后的事情却异常复杂。

    1.7K20

    C++】入门基础(下)

    所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时创建的一个未命名的对象,C++中把这个未命名对象叫做临时对象。 【第一分点】 //可以引用一个const对象,但是必须用const引用。...(面试点) C++中指针引用就像两个性格迥异的亲兄弟,指针是哥哥,引用是弟弟,在实践中他们相辅相成,功能具有重叠性。...inline对于编译器而言只是一个建议,也就是说,加了inline编译器也可以选择在调用的地方不展开,不同的编译器就关于inline什么情况展开各不相同,因为C++标准没有规定这个。...C语言实现函数也会在预处理时替换展开,但是函数实现很复杂很容易出错,切不方便调试,C++设计inline目的就是为了替代C函数。...__cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针

    6610

    从零开始学C++之从CC++(一):const与#define、结构体对齐、函数重载name mangling、newdelete 等

    二、const 限定符 (1)、用const给字面常量起个名字(标识符),这个标识符就称为标识符常量;因为标识符常量的声明使用形式很像变量,所以也称常变量。...而#define定义的常量作用域为它的定义点到程序结束,当然也可以在某个地方用#undef取消 #define定义的常量,容易产生副作用: //Effective C++ 3rd的一个例子。...+ 菜鸟,这里还得稍微解释一下细节,iostream 是c++标准库的一个io流头文件,跟C语言不太一样的是一般没有.h 后缀,using namespace 表示命名空间,简单理解就是统一的函数前缀,...CC++语言非常灵活,它允许你干涉“内存对齐” 为什么要对齐 性能原因:在对齐的地址上访问数据快。...extern “C” 可以实现CC++混合编程,被extern "C" 修饰的变量函数是按照C语言方式进行编译链接的,即对C语言写的函数不进行改名,一般在 C的头文件中使用,如果头文件被C代码包含并用

    1.2K00

    关于nullptr这篇文章你一定要看

    为什么同样是NULL,在CC++中却有不同的定义呢? C++中有一个很特别的规定就是0既表示整形常量也用来表示空指针常量。...主要规定空指针常量需要被转化成指针类型,同时这个转化为指针类型的值还不能其它的对象指针或者函数指针的值相同。两个空指针常量的值还需要相等。...一个原因是可以让整形0放下重担,0只表示一件事情,它只是一个整数类型0,没有任何其它语义,空指针的活就安排给其它员工,这个员工就是nullptr关键字。...NULL其实就是一个,对于C++之父一直推崇尽量避免使用它,在实际编程中,可以减少的使用,直接使用0。Bjarne Stroustrup语录也给出了解释。...因为需要为空指针常量一个名字,更清晰的表明它表达的是什么含义,就像3.1415926为什么要用π表示一样,尽管宏一直是被各方吐槽的,但为了有名字在当时C++也只能这样,这也是NULL面世的唯一一个理由

    54930

    深入理解C++11(一)

    C编译器用这个的值表示编译器的实现是否C标准一致。...C++11中这个是否定义以及定什么值由编译器决定 STDC_VERSION C编译器通常用这个来表示所支持的C标准的版本。...C++11中这个是否定义以及定什么值由编译器决定 STDC_ISO_10646 这个定义为一个yyyymml格式的整数常量,例如199712L,用来表示C++编译环境符合某个版本的ISO/IEC...在C++中,头文件中提供了assert,用于在运行时进行断言。 ? main函数中对ArrayAlloc的使用没有满足n>0的条件,在运行时,出现Assertion n > 0 failed。...一般情况下,noexcept修饰符有两种形式:(1)void excpt_func() noexcept; (2)void excpt_func() noexcept(常量表达式);第二种形式中的常量表达式的结果会被转换成一个

    1.2K90

    C++入门

    C++的第一个程序         C++ 也就是 c语言plus plus版本 所以兼容很多C语言内容依然可以使用。        ...,这个以后会讲到),其实最重要的是 C++的流能更好的⽀持⾃定义类型对象的输⼊输出。...inline         内联函数,但是可以看作智能的,编译器会根据使用频次的长度决定是否展开 • ⽤inline修饰的函数叫做内联函数,编译时C++编译器会在调⽤的地⽅展开内联函数,这样调⽤...• inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。...•  C语⾔实现函数也会在预处理时替换展开,但是函数实现很复杂很容易出错的,且不⽅便调 试,C++设计了inline⽬的就是替代C函数。

    9310

    C++面试知识总结

    C++程序的内存布局与C程序布局类似,区别是C++不再区分全局变量和静态变量是否已经初始化,全部存储在静态存储区;另外堆中存放new/delete申请释放的资源,而mallocfree申请的资源存放在自由存储区...1.3 内存泄露检测 C++内存泄漏检测内存泄露是指程序中动态分配了内存,但是在程序结束时没有释放这部分内存,从而造成那一部分内存不可用的情况。  ...define用途:是定义,在编译的时候会进行替换,这样做的话可以避免没有意义的数字或字符串,便于程序的阅读。 区别:const定义的数据有数据类型,而常量没有数据类型。...枚举常量则是在编译的时候确定其值。 一般在编译器里,可以调试枚举常量,但是不能调试常量。 枚举可以一次定义大量相关的常量,而#define 一次只能定义一个。...malloc/free用来申请内存释放内存,但是申请和释放的对象只能是内部数据类型。 malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。

    1.7K41

    C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字

    引用指针的区别 在语法概念上 引用就是一个别名,没有独立空间,其引用实体共用同一块空间。...3.没有类型安全的检查 。 C++有哪些技术替代? 1. 常量定义 换用const enum 2....这个特性使得`auto`在C++11及以后的版本中变得非常流行常用。 总结来说,`auto`在早期C/C++中并不是没有人使用,而是因为它是默认行为,所以通常不需要显式使用。...而在C++11及以后的版本中,`auto`的用途被扩展,成为了一个非常实用的特性。...如果一个指针没有合法的指向,我们基本都是按照如下 方式对其进行初始化: NULL实际是一个,在传统的C头文件(stddef.h)中,可以看到如下代码: #ifndef NULL #ifdef

    16510

    C++】内联函数&auto&范围for循环&nullptr

    C语言中,我们为了减少栈帧的开销,我们可以通过函数,没有栈帧消耗,在预处理的阶段就被替换了,就没有栈帧的消耗了 (比如频繁调用小函数的时候) 而在C++中,我们是通过inline内联函数解决这个问题的...为什么C++会将C语言的函数替换掉❓ 那必然是C语言的函数存在着缺点: 不能进行调试,会直接被替换 函数参数不安全,没有类型安全检查 不可否认,太容易写错了 基于C语言的函数的缺点,C+...这里有一个问题❓为什么函数长了以后不展开——代码膨胀 编译好的指令影响的是可执行程序(安装包)的大小 对于第三点:inline不建议声明定义分离,分离会导致链接错误。...---- 指针空值nullptr(C++11) 1.C++98中的指针空值 在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。...在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

    69230

    Google C++ 编程风格指南(五):其他 C++ 特性

    某些情况下, 将一个单元测试类声明待测类的友元会很方便. 友元扩大了 (但没有打破) 类的封装边界....预处理 使用时要非常谨慎, 尽量以内联函数, 枚举常量代替之. 意味着你编译器看到的代码是不同的. 这可能会导致异常行为, 尤其因为具有全局作用域....值得庆幸的是, C++ 中, 不像在 C 中那么必不可少. 以往用展开性能关键的代码, 现在可以用内联函数替代. 用表示常量可被 const 变量代替. 用 “缩写” 长变量名可被引用代替....不要只是对已经存在的使用#undef,选择一个不会冲突的名称; 不要试图使用展开后会导致 C++ 构造不稳定的, 不然也至少要附上文档说明其行为. 不要用 ## 处理函数,类变量的名字。...优点: 在二〇一四年八月之前,C++11 一度是官方标准,被大多 C++ 编译器支持。它标准化很多我们早先就在用的 C++ 扩展,简化了不少操作,大大改善了性能安全。

    1.1K30
    领券