C++学习笔记5 常量和字符串

5 常量和字符串

5.1 常量变量

在编程中,常量是在程序执行期间可能不会改变的值。

C++支持两种不同类型的常量:

  • 命名常量是与标识符关联的常量值。
  • 字面量是与标识符无关的常量值。

5.1.1 命名常量

在 C++ 中有三种方法可以定义命名常量:

  • 常量变量。
  • 带有替换文本的类似对象的宏。
  • 枚举常量。
声明常量变量

初始化后其值不能改变的变量被称为常量变量

要声明常量变量,我们将关键字const(称为“const 限定符”)放在对象类型旁边:

const double gravity { 9.8 };  // preferred use of const before type
int const sidesInSquare { 4 }; // "east const" style, okay but not preferred

尽管 C++ 可以接受在类型之前或之后使用const限定符,但在类型之前使用更为常见,因为它更好地遵循了标准英语语言惯例,即修饰符位于被修改的对象之前。

const变量必须初始化

Const 变量在定义时必须进行初始化,并且不能通过赋值来改变其值:

int main()
{
    const double gravity; // error: const variables must be initialized
    gravity = 9.9;        // error: const variables can not be changed

    return 0;
}

请注意,const 变量可以从其他变量(包括非常量变量)初始化:

#include <iostream>

int main()
{
    std::cout << "Enter your age: ";
    int age{};
    std::cin >> age;

    const int constAge { age }; // initialize const variable using non-const value

    age = 5;      // ok: age is non-const, so we can change its value
    constAge = 6; // error: constAge is const, so we cannot change its value

    return 0;
}
const变量的命名

在 C++ 中,常见的是使用首字母大写、前缀为 ‘k’ 的变量名,例如kEarthGravity

然而,由于 const 变量的行为与普通变量类似(除了不能被赋值),因此它们不需要特殊的命名约定。因此,我们倾向于使用与非常量相同的命名约定(例如earthGravity)。

不要将const用于函数参数

在c++标准中,函数参数可以通过关键字设为常量const

#include <iostream>

void printInt(const int x)
{
    std::cout << x << '\n';
}

int main()
{
    printInt(5); // 5 will be used as the initializer for x
    printInt(6); // 6 will be used as the initializer for x

    return 0;
}

请注意,我们没有为 const 参数提供显式初始化器x——函数调用中的参数值将用作初始化器x

然而,在现代 C++ 中,我们不会将值参数设为常量,因为我们通常不关心函数是否会更改参数的值(因为它只是一个副本,无论如何都会在函数结束时被销毁)。该const关键字还会给函数原型带来一些不必要的混乱。

按值返回时请勿使用const

对于基本类型,返回类型的const限定符会被忽略(您的编译器可能会生成警告)。

对于其他类型(我们稍后会介绍),通常没有必要按值返回 const 对象,因为它们是临时副本,无论如何都会被销毁。返回 const 值还会妨碍某些类型的编译器优化(包括移动语义),从而导致性能下降。

5.1.2 带有替换文本的类似对象的宏

带有替换文本的类对象宏,例如:

#include <iostream>

#define MY_NAME "Alex"

int main()
{
    std::cout << "My name is: " << MY_NAME << '\n';

    return 0;
}

当预处理器处理包含此代码的文件时,它会将MY_NAME第 7 行的 替换为"Alex"。注意,MY_NAME是一个名称,而替换文本是一个常量值,因此带有替换文本的对象类宏也是命名常量。

优先使用常量变量而不是预处理器宏

最大的问题是宏不遵循正常的 C++ 作用域规则。一旦宏被 #defined 定义,当前文件中所有后续出现的宏名称都将被替换。如果该名称在其他地方使用,就会在不想要的地方发生宏替换。这很可能会导致奇怪的编译错误。

其次,使用宏调试代码通常更加困难。虽然源代码中会有宏的名称,但编译器和调试器永远无法看到该宏,因为它在运行之前已经被替换了。许多调试器无法检查宏的值,并且在处理宏时通常功能有限。

第三,宏替换的行为与 C++ 中的其他操作不同。因此,很容易出现无意的错误。

5.1.2 在多文件程序中使用常量变量

在 C++ 中,有多种方法可以实现在多文件程序中使用常量变量。

5.1.3 字面量

字面量是直接插入到代码中的值。例如:

return 5;                     // 5 is an integer literal
bool myNameIsAlex { true };   // true is a boolean literal
double d { 3.4 };             // 3.4 is a double literal
std::cout << "Hello, world!"; // "Hello, world!" is a C-style string literal
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值