目录
1,字符串原始字面量
原始的字符串,存在大量的转义字符,比如 \n 代表换行,\t \0 等等大量转义字符。
但有的时候,我们不希望进行转义,希望字符串以最原始的模样输出,于是 c++ 11 有了 原始字面量
javascript
//原始字面量
std::string str1 = R"(D:\nhello\nworld\ntest.txt)";
std::cout << str1 << std::endl;
//会被转义的字面量
std::string str2 = "D:\nhello\nworld\ntest.txt";
std::cout << str2 << endl;

2,nullptr
javascript
#ifndef
#ifdef _cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif
#endif
上面代码可以看出 NULL 这个宏,在 c 语言当中代表的是 void* 指针,而在
c++ 当中则代表字面值 0 。
所以,当我们想让一个指针为空指针时,不应该使用 NULL
所以我们使用 nullptr ,nullptr 可以转换成任何类型的指针类型。
3,constexpr
constexptr 用来修饰常量表达式
c++程序从编写完毕到执行分为四个阶段:预处理,编译,汇编,链接 4个阶段。然而,常量表达式和非常量表达式的计算时机不同,非常量表达式只能在程序运行阶段计算出结果,但常量表达式的计算往往发生在程序的编译阶段,这可以极大提高程序的执行效率。
那么问题来了,编译器如何识别表达式是不是常量表达式呢?
在c++11 中添加了 constexpr 关键字之后就可以在程序中使用它来修改常量表达式,用来提高程序的执行效率。
在使用中建议 将 const 和 constexpr 的功能区分开,即 凡是表达"只读" 语义的场景都使用 const ,表达 "常量" 语义的场景都使用 constexpr 。
在定义常量时,const 和 constexpr 是等价的,都可以在程序的编译阶段计算出结果,例如:
javascript
const int m = f(); //不是常量表达式,m的值只有在运行阶段呢才会获取
const int i = 520; //是一个常量表达式
const int j = i + 1; //是一个常量表达式
constexpr int i = 520; //是一个常量表达式
constexpr int j = i + 1; //是一个常量表达式
对于 c++ 内置类型的数据,可以直接用 constexpr 修饰,但如果是自定义的数据类型(用 struct 或者 class 实现),直接用 constexpr 修饰是不行的。
javascript
//此处的 constexpr 修饰是无效的
constexpr struct test
{
int id;
int num;
};
如果要定义一个结构体
javascript
struct T
{
int a;
};
void func(const int num)
{
constexpr T t;
cout<<t.a<<endl;
}
【注意】const 关键字 和 constexpr 的区别在于
const 用于声明一个常量,其值在初始化后不能被修改。然而,const 变量的值不一定在编译时就已知。它可以在运行时根据程序逻辑进行初始化。
constexpr 不仅表示常量,还要求其值必须在编译时就能确定。这意味着 constexpr 变量或函数的结果必须在编译阶段就可以计算出来,不依赖于运行时的状态。
4,auto
auto 是用来作为自动推导类型而存在的,它并不是一种时机的数据类型,只是一个类型声明的占位符。
使用 auto 声明的变量必须要进行初始化,以让编译器推导出它的实际类型,在编译时将 auto 占位符替换为真正的类型。
javascript
auto x = 3.14; //正确
auto y = 520; //正确
auto nb; //错误,没有进行初始化不能推导
auto double nbl; //错误,不能修改数据类型