[C++] C++ 的常量究竟是什么? 它与 C# 和 Java 中的常量有什么区别? 应该如何理解常量?

本文介绍了C++中const常量的特性,包括可以在运行时赋值、一旦初始化后不可直接更改以及通过指针强制更改。讨论了编译时赋值的const常量的特殊行为,并解释了const在函数参数中的作用,强调其用于表明函数不会修改变量。文章提醒读者注意C++与C#/Java中const常量的差异,并鼓励在编写函数时使用const以提高代码可读性。
摘要由CSDN通过智能技术生成

在 C++ 中, const 虽然是常量, 然而这个常量比起 C#/Java 中的常量, 似乎又有点不对劲

文章面向的人群是拥有 C#/Java 基础的程序员

运行时赋值

C++ 的常量不是在编译时就直接确定值的, 你在运行时也可以初始化它, 下面是示例代码:

#include <iostream>

int main()
{
    int input;
    std::cin >> input;

    const int unchangable_integer = input;
    std::cout << unchangable_integer << std::endl;
}

不可直接变更

const 变量一旦初始化之后, 就不再可以直接更改 (直接对其赋值)

#include <iostream>

int main()
{
    int input;
    std::cin >> input;

    const int unchangable_integer = input;
    
    unchangable_integer = 114514;           // 这里编译错误
}

强制更改常量

如果一个常量是在运行时确认值的, 那么可以通过指针强制更改, 并且在二次取值的时候也能够拿到更改后的值.

#include <iostream>

int main()
{
    int input;
    std::cout << ":";
    std::cin >> input;                                     // 输入 123

    const int unchangable_integer = input;

    std::cout << unchangable_integer << std::endl;         // 输出 123

    int* changable_integer = (int*)&unchangable_integer;   // 转为指针
    *changable_integer = 114514;                           // 赋值
    
    std::cout << unchangable_integer << std::endl;         // 输出 114514 (值被成功更改了)
    std::cout << *changable_integer << std::endl;          // 输出 114514
}

如果一个常量是在编译时就确认值了, 虽然也可以更改, 但是却有些奇怪表现…

#include <iostream>

int main()
{
    const int integer = 123;
    int* mutable_integer = (int*)&integer;        // 取可更改的指针

    *mutable_integer = 114514;                    // 改值

    const int* p_integer = &integer;

    std::cout << integer << std::endl;               // 直接输出, 结果是 123
    std::cout << *mutable_integer << std::endl;      // 输出指针目标值, 结果是 114514

    std::cout << *&integer << std::endl;             // 取地址然后输出目标值, 结果是 13
    std::cout << *p_integer << std::endl;            // 取保存为变量的地址的目标值, 结果是 114514
    
    std::cout << &integer << std::endl;              // 取地址, 结果是 0073FDE0
    std::cout << mutable_integer << std::endl;       // 打印之前的指针, 结果是 0073FDE0
}

对于上面这些奇怪的表现, 笔者认为, 在编译时直接确认值的常量, 对其的直接引用会被编译器优化为常量, 而不会去取存储了的常量值.

甚至, 如果这个常量压根就没有取地址操作, 那么在程序编译后压根就不会有存储这个变量的, 栈上的内存空间, 它直接就是字面量, 存储在程序 rdata 段(只读数据段), 完全无法变更.

我不会对它进行赋值

如果你在一个函数中声明一个参数, 而这个参数是 const, 那在这里, const 表示的是, 你不打算对这个变量进行赋值(更改).

#include <iostream>

void print_int(const int number)
{
    printf("%d\n", number);
}

int main()
{
    const int integer = 123;
    int mutable_integer = 123;

    print_int(integer);            // 可以传入只读整数
    print_int(mutable_integer);    // 也可以传入普通整数
}

标记了参数为 const 的参数, 就表示函数不会对他进行变更, 这时调用方也能放心的使用它.

所以, 对于我们平常所编写的函数, 如果不会对参数进行变更, 也可以加上 const 修饰符来使函数的功能更加清晰可读.

结语

希望这些简短的介绍能够帮助你更好的认识 C++, 毕竟 C#/Java 和 C++ 的差别还是非常非常大的

另外, 如果上述内容有错误, 欢迎在评论区指出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值