尽量避免#define定义常量 在C++中,定义常量应该尽量避免使用#define来定义一个常量,主要原因宏定义只做替换,不做类型检查和计算,不仅没有作用域限制,而且容易产生错误。...例如上例中,在预编译阶段A全部被替换为数字10和20,编译器在编译的时候根本就感知不到A的存在,假如代码确实在这个宏定义A的地方出现了问题,我们debug的时候,只能看到相应的数字10或20,并不知道从哪里追踪它们的来源...因此,在C++中我们尽量避免使用#define来定义一个常量,应使用const和enum来定义常量。 尽量避免形似函数的宏 #define的另外一个需要注意的地方就是,尽量减少形似函数宏的使用。...同时,因为我们使用了函数,因此也遵守了作用域和访问的规则,使得我们的代码更具标准性和规则性。 总结 在C++中,尽量避免#define常量和形似函数宏的使用。...引用《Effective C++》中的话来做总结就是: 对于单纯常量,最好以const对象和enum替换#define。 对于形似函数的宏,最好改用inline函数替换#define。
一、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 标准命名空间 // 该命名空间中 , 定义了很多标准定义
P表示这是一个指针 C表示是一个常量 T表示在Win32环境中, 有一个_T宏 这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为...STR表示这个变量是一个字符串 所以LPCTSTR就表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串。...原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。 常量字符串ansi和unicode的区分是由宏_T来决定的。...这个地方使用的是强制类型转换,你都强制转换了,C++编译器当然不会拒绝你,但同时他也认为你确实知道自己要做的是什么。因此是不会给出警告的。...,里面对该字符串又没有任何的修改,那么该参数就应该定义成 const char*, 但是很多初学者弄不清const地用法,或者是懒, 总之就是随意写成了 char* 。
某些情况下,将一个单元测试类声明成待测类的友元会很方便。 友元扩大了(但没有打破)类的封装边界。...变量可以被声明成 constexpr 以表示它是真正意义上的常量,即在编译时和运行时都不变。函数或构造函数也可以被声明成 constexpr,以用来定义 constexpr 变量。...16.预处理宏 使用宏时要非常谨慎,尽量以内联函数,枚举和常量代替之。 宏意味着你和编译器看到的代码是不同的。这可能会导致异常行为,尤其因为宏具有全局作用域。...值得庆幸的是,C++ 中,宏不像在 C 中那么必不可少。以往用宏展开性能关键的代码,现在可以用内联函数替代。用宏表示常量可被 const 变量代替。用宏 “缩写” 长变量名可被引用代替。...优点: 在二〇一四年八月之前,C++11 一度是官方标准,被大多 C++ 编译器支持。它标准化很多我们早先就在用的 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程序员不要定义很复杂的宏,宏定义应该简单而清晰。
某些情况下,将一个单元测试类声明成待测类的友元会很方便。 友元扩大了(但没有打破)类的封装边界。...变量可以被声明成 constexpr 以表示它是真正意义上的常量,即在编译时和运行时都不变。constexpr 可以定义用户自定义类型的常量,也修饰函数返回值。...16.预处理宏 使用宏时要非常谨慎,尽量以内联函数,枚举和常量代替之。 宏意味着你和编译器看到的代码是不同的。这可能会导致异常行为,尤其因为宏具有全局作用域。...值得庆幸的是,C++ 中,宏不像在 C 中那么必不可少。以往用宏展开性能关键的代码,现在可以用内联函数替代。用宏表示常量可被 const 变量代替。用宏 “缩写” 长变量名可被引用代替。...24.C++11 适当使用 C++11的库和语言扩展,在用 C++11 特性前三思可移植性。 优点:在二〇一四年八月之前,C++11 一度是官方标准,被大多 C++ 编译器支持。
✨今天来给大家带来的是C语言中我们常用的关键字静态static的详细讲解和typedef 、#define定义常量和宏。 既然是详解想必大家必定是想学一些平常学不到的东西吧!...C/C++中内存大致分的三个区域 2....关键字static 静态局部变量 静态局部变量的作用域和生命周期 静态全局变量 静态函数 #define 定义常量和宏 #define 定义常量 #define 定义宏 那么宏是怎么调用的呢?...#define 定义宏 我们来看一下宏是怎么定义的: 和定义函数非常相识 但是宏没有函数的返回类型和参数类型 还是很不一样的,宏的实现体一般都是表达式 那么宏是怎么调用的呢?...static 和 #define typedef 总结一下今天学了: 关键字static 关键字static修饰变量的作用域变化 #define定义的宏和常量 关键字typedef 不知道大家掌握了没有
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++ 编译环境,则执行下面的代码块。
欢迎大大们纠错~ null 和 NULL C和C++语言对大小写是敏感的,也就是说null和NULL本质上是区别对待的。...其实本质上null和NULL都是符号,只是在不同的编译器上NULL被宏定义指定内容,null没有定义而已。 例如在vs环境中,NULL被指定为0,代码如下。 ?...0的相关 ‘\0’是一个“空字符”常量,它表示一个字符串的结束,它的ASCII码值为0,与’0‘的ASCII码值48是不一样的。...,'\0'是一个常量,等同于0,(这个地方理解的不够深入)。 ‘0’ 代表字符0, ASCII码为48。 “0”代表字符串0,尾部有不可见的’\0‘。...这个地方有一些需要注意的一些使用方法如下,代码如下图: ? 看起来执行结果没有什么问题,你可能会说说来说去,那还不都是 0 嘛。 ? 确实在大部分的情况下是这样的,但背后的事情却异常复杂。
二、const 限定符 (1)、用const给字面常量起个名字(标识符),这个标识符就称为标识符常量;因为标识符常量的声明和使用形式很像变量,所以也称常变量。...而#define定义的常量作用域为它的定义点到程序结束,当然也可以在某个地方用#undef取消 #define定义的常量,容易产生副作用: //Effective C++ 3rd的一个例子。...+ 菜鸟,这里还得稍微解释一下细节,iostream 是c++标准库的一个io流头文件,跟C语言不太一样的是一般没有.h 后缀,using namespace 表示命名空间,简单理解就是统一的函数前缀,...C、C++语言非常灵活,它允许你干涉“内存对齐” 为什么要对齐 性能原因:在对齐的地址上访问数据快。...extern “C” 可以实现C与C++混合编程,被extern "C" 修饰的变量和函数是按照C语言方式进行编译和链接的,即对C语言写的函数不进行改名,一般在 C的头文件中使用,如果头文件被C代码包含并用
为什么同样是NULL,在C和C++中却有不同的定义呢? C++中有一个很特别的规定就是0既表示整形常量也用来表示空指针常量。...主要规定空指针常量需要被转化成指针类型,同时这个转化为指针类型的值还不能和其它的对象指针或者函数指针的值相同。两个空指针常量的值还需要相等。...一个原因是可以让整形0放下重担,0只表示一件事情,它只是一个整数类型0,没有任何其它语义,空指针的活就安排给其它员工,这个员工就是nullptr关键字。...NULL其实就是一个宏,对于宏,C++之父一直推崇尽量避免使用它,在实际编程中,可以减少宏的使用,直接使用0。Bjarne Stroustrup语录也给出了解释。...因为需要为空指针常量起一个名字,更清晰的表明它表达的是什么含义,就像3.1415926为什么要用π表示一样,尽管宏一直是被各方吐槽的,但为了有名字在当时C++也只能这样,这也是NULL宏面世的唯一一个理由
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(常量表达式);第二种形式中的常量表达式的结果会被转换成一个
C++程序的内存布局与C程序布局类似,区别是C++不再区分全局变量和静态变量是否已经初始化,全部存储在静态存储区;另外堆中存放new/delete申请释放的资源,而malloc和free申请的资源存放在自由存储区...1.3 内存泄露和检测 C++内存泄漏检测内存泄露是指程序中动态分配了内存,但是在程序结束时没有释放这部分内存,从而造成那一部分内存不可用的情况。 ...define用途:是宏定义,在编译的时候会进行替换,这样做的话可以避免没有意义的数字或字符串,便于程序的阅读。 区别:const定义的数据有数据类型,而宏常量没有数据类型。...枚举常量则是在编译的时候确定其值。 一般在编译器里,可以调试枚举常量,但是不能调试宏常量。 枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。...malloc/free用来申请内存和释放内存,但是申请和释放的对象只能是内部数据类型。 malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。
引用和指针的区别 在语法概念上 引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。...3.没有类型安全的检查 。 C++有哪些技术替代宏? 1. 常量定义 换用const enum 2....这个特性使得`auto`在C++11及以后的版本中变得非常流行和常用。 总结来说,`auto`在早期C/C++中并不是没有人使用,而是因为它是默认行为,所以通常不需要显式使用。...而在C++11及以后的版本中,`auto`的用途被扩展,成为了一个非常实用的特性。...如果一个指针没有合法的指向,我们基本都是按照如下 方式对其进行初始化: NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码: #ifndef NULL #ifdef
在C语言中,我们为了减少栈帧的开销,我们可以通过宏函数,没有栈帧消耗,在预处理的阶段就被替换了,就没有栈帧的消耗了 (比如频繁调用小函数的时候) 而在C++中,我们是通过inline内联函数解决这个问题的...为什么C++会将C语言的宏函数替换掉❓ 那必然是C语言的宏函数存在着缺点: 不能进行调试,宏会直接被替换 函数参数不安全,没有类型安全检查 不可否认,宏太容易写错了 基于C语言的宏函数的缺点,C+...这里有一个问题❓为什么函数长了以后不展开——代码膨胀 编译好的指令影响的是可执行程序(安装包)的大小 对于第三点:inline不建议声明和定义分离,分离会导致链接错误。...---- 指针空值nullptr(C++11) 1.C++98中的指针空值 在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。...在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。
某些情况下, 将一个单元测试类声明成待测类的友元会很方便. 友元扩大了 (但没有打破) 类的封装边界....预处理宏 使用宏时要非常谨慎, 尽量以内联函数, 枚举和常量代替之. 宏意味着你和编译器看到的代码是不同的. 这可能会导致异常行为, 尤其因为宏具有全局作用域....值得庆幸的是, C++ 中, 宏不像在 C 中那么必不可少. 以往用宏展开性能关键的代码, 现在可以用内联函数替代. 用宏表示常量可被 const 变量代替. 用宏 “缩写” 长变量名可被引用代替....不要只是对已经存在的宏使用#undef,选择一个不会冲突的名称; 不要试图使用展开后会导致 C++ 构造不稳定的宏, 不然也至少要附上文档说明其行为. 不要用 ## 处理函数,类和变量的名字。...优点: 在二〇一四年八月之前,C++11 一度是官方标准,被大多 C++ 编译器支持。它标准化很多我们早先就在用的 C++ 扩展,简化了不少操作,大大改善了性能和安全。
其次宏没有类型检查,也就不安全,容易出错且不易发现。 C++从C而来,也对C做出了一些改进。那么C++是否选择了C语言的这种采用宏的方法呢?...来看这个错误: 为什么? 为什么内联函数不能像普通函数那样声明和定义分离呢?...声明和定义分离,就会找不到内联函数的地址了。 ---- 代替宏的方式 C++中除了可以用内联函数代替宏定义之外,还可以使用const常变量、enum常量来代替宏常量。...定义的宏常量,一般用于为没有有效指向的指针赋值,表示指针空值。...+并不好修改这个问题,只能保留这个问题,因为有很多人和企业使用这C++。
在C和C++中,可以使用NULL宏定义表示空指针。当使用NULL赋值给一个指针时,表示该指针不指向任何内存地址。 使用空指针可以用于以下情况: 初始化指针变量,避免野指针的问题。...为了解决这个问题,C++11引入了新的空指针常量nullptr。nullptr是一个特殊的关键字,它的类型是std::nullptr_t,表示一个空指针常量。...C++98中的指针空值 在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。...如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化: void TestPtr() { int* p1 = NULL; int* p2 = 0; // …… } NULL实际是一个宏...由于NULL是一个宏定义,而宏展开是在编译阶段进行的,因此无法对NULL进行重载。 可读性:nullptr更加明确地表示空指针的含义,更易于阅读和理解。
命名空间 在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全 局作⽤域中,可能会导致很多冲突。...,这个以后会讲到),其实最重要的是C++的流能更好的⽀持⾃定义类型对象的输⼊输出 缺省参数 缺省参数分为:全缺省,半缺省参数(默认参数)。...请注意: C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值 ; 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参; 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现...因为inline被展开,就没有函数地 址,链接时会出现报错。 内联函数比较于宏 宏的回顾 #define ADD(a, b) ((a) + (b)) // 为什么不能加分号?...为什么要加里面的分号? 如果使用宏 ADD(a++, b),没有括号的情况下,宏会展开成 a++ + b,这将导致 a 被递增两次:一次是因为宏展开,另一次是因为 a++ 本身。
一个私有变量域 ---- 有一些字段,我这个地方没有读太懂.继续读 ? 这个是setting库的内容 ---- 一个宏一堆枚举 ? 将来传到这些地方 ? ? ? ?...首先解决这个问题. ? ? C++变量前面加下划线和不加下划线都不会影响对变量的定义,只是风格问题,更喜欢将成员变量或者私有成员变量的前面加上下划线。以表示该变量是某个类的属性。...枚举元素只能是标识符,而不是数字常量或字符常量。枚举在C/C++/c#中,是一个被命名的整型常数的集合, 枚举在日常生活中很常见。...扩展资料使用枚举类型注意:枚举中每个成员(标识符)结束符是"," 不是";", 最后一个成员可省略","。初始化时可以赋负数, 以后的标识符仍依次加1。枚举变量只能取枚举说明结构中的某个标识符常量。...不知道你们有没有看懂我为什么还在这里研究,就是我觉得枚举值不对, 看下面的这些东西应该是枚举值得基础上再加1????为什么
领取专属 10元无门槛券
手把手带您无忧上云