【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 )

这篇具有很好参考价值的文章主要介绍了【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。





一、C 语言 const 关键字简介 - 左数右指原则



【C 语言】const 关键字用法 ( 常量指针 - const 在 * 左边 - 修饰数据类型 - 内存不变 | 指针常量 - const 在 * 右边 - 修饰变量 - 指针不变 )


1、const 关键字左数右指原则


普通类型数据的常量定义时 , const 关键字 在 数据类型 的 左边 和 右边 其作用 是相同的 ;

    // 下面两种 const 用法效果相同
    // 定义普通类型 ( 非指针类型 ) 的常量 const 在 类型左右 都是相同的
    const int a = 10;
    int const b = 20;

指针数据的相关常量类型 :

  • const 关键字在 指针符号 * 左侧 表示该定义的事 常量指针 ( 指向的内存不能修改 )
    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面两种情况 const 在指针左边 , 数据是常量 , 内存中的数据不能修改
    //      但是 , c 和 d 指针的指向可以修改
    // 下面两种情况是相同的
    const int* c;
    int const* d;
  • const 关键字在 指针符号 * 右侧是 表示定义的事指针常量 ( 指针本身不能被修改 ) ;
    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面的情况 const 在指针右边 , 指针是常量 , 指针地址不能修改 
    //      但是 , 指针指向的内存中的数据可以修改
    int* const e = (int*)malloc(10);

指针常量与常量指针 : 需要查看 const 修饰的是 指针变量 , 还是 修饰 指针变量 指向的内存空间 ;

  • const 在 * 右边 ( 指针常量 | const 修饰的是变量 ) : 如果 const 修饰的是 指针变量 , 如 char * const d , const 修饰的是 char * , 指针不能被修改 ; 这是 指针常量 ;

  • const 在 * 左边 ( 常量指针 | const 修饰的是数据类型 ) : 如果 const 修饰的是 指针变量 指向的内存空间 ,const char *c , const 修饰的是 char , char 数据不能被修改 , 这是 常量指针 , 指向常量的指针 ;


2、代码示例 - const 关键字左数右指原则


下面的代码中 , 列出了 const 关键字的所有情况 , 看注释即可理解左数右指原则 ;


代码示例 :

// 导入标准 io 流头文件
// 其中定义了 std 命名空间
//#include <iostream>
// 导入 std 命名空间
//using namespace std;

#include <stdio.h>
#include <malloc.h>

int main() {

    // 下面两种 const 用法效果相同
    // 定义普通类型 ( 非指针类型 ) 的常量 const 在 类型左右 都是相同的
    const int a = 10;
    int const b = 20;

    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面两种情况 const 在指针左边 , 数据是常量 , 内存中的数据不能修改
    //      但是 , c 和 d 指针的指向可以修改
    // 下面两种情况是相同的
    const int* c;
    int const* d;

    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面的情况 const 在指针右边 , 指针是常量 , 指针地址不能修改 
    //      但是 , 指针指向的内存中的数据可以修改
    int* const e = (int*)malloc(10);

    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面两种情况 const 在指针左边和右边 , 数据和指针是常量 , 都不能修改
    // 下面两种情况是相同的
    const int* const f = (int*)malloc(10);
    int const* const g = (int*)malloc(10);

    return 0;
}

3、const 关键字使用场景


const 关键字 一般用于修饰 函数参数 , 给函数传入的参数 如果不想 用户在方法中 修改 数据 或 指针 , 可以使用 const 关键字修饰 形参 ;

定义结构体 :

struct Student
{
    char name[64];
    int age;
};

函数接收上述结构体类型变量作为参数 , 如果参数中 const 在 * 左边 , const Student *pS , 根据 左数右指原则 , 指针指向的数据是常量 , 不能被修改 ;

下面是错误示范 :

// 左数右指 , const 在指针左边 , 指针指向的数据不能被修改
int fun0(const Student *pS) {
    pS->age = 20;
    return 0;
}

如果强行修改指针指向的数据值 , 就会在编译时报错 :

表达式必须是可修改的左值

【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 ),C++,c++,c语言,左数右指,const,符号表,原力计划

函数接收上述结构体类型变量作为参数 , 如果参数中 const 在 * 右边 , Student* const pS , 根据 左数右指原则 , 指针本身是常量 , 指针指向不能被修改 ;

下面是错误示范 :

// 左数右指 , const 在指针右边 , 指针本身的指向不能被修改
int fun2(Student* const pS) {
    pS = NULL;
    return 0;
}

如果强行修改指针指向 , 就会在编译时报错 :

表达式必须是可修改的左值

【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 ),C++,c++,c语言,左数右指,const,符号表,原力计划


上述完整代码示例 :

// 导入标准 io 流头文件
// 其中定义了 std 命名空间
//#include <iostream>
// 导入 std 命名空间
//using namespace std;

#include <stdio.h>
#include <malloc.h>

struct Student
{
    char name[64];
    int age;
};

// 左数右指 , const 在指针左边 , 指针指向的数据不能被修改
int fun0(const Student *pS) {
    //pS->age = 20;
    return 0;
}

// 左数右指 , const 在指针右边 , 指针本身的指向不能被修改
int fun2(Student* const pS) {
    //pS = NULL;
    return 0;
}


int main() {

    // 下面两种 const 用法效果相同
    // 定义普通类型 ( 非指针类型 ) 的常量 const 在 类型左右 都是相同的
    const int a = 10;
    int const b = 20;

    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面两种情况 const 在指针左边 , 数据是常量 , 内存中的数据不能修改
    //      但是 , c 和 d 指针的指向可以修改
    // 下面两种情况是相同的
    const int* c;
    int const* d;

    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面的情况 const 在指针右边 , 指针是常量 , 指针地址不能修改 
    //      但是 , 指针指向的内存中的数据可以修改
    int* const e = (int*)malloc(10);

    // 左数右指 : const 在指针左边 数据是常量 , const 在指针右边 指针是常量
    // 下面两种情况 const 在指针左边和右边 , 数据和指针是常量 , 都不能修改
    // 下面两种情况是相同的
    const int* const f = (int*)malloc(10);
    int const* const g = (int*)malloc(10);


    return 0;
}




二、C 语言 const 关键字原理分析




1、C 语言中常量的原理和缺陷


C 语言中的 const 关键字 并不是 真正的 " 常量 " , 是一个 " 冒牌货 " ;

C 语言中的 const 关键字定义的常量 , 其本质是在 内存 中分配的空间 ;

C 语言 中 , 会为 const 常量 单独分配内存 , 导致 用户可以 通过取地址符 & 获取该内存的地址指针 , 通过该指针可以修改内存中的数据 ;


2、代码示例 - C 语言中直接改变常量值报错


定义一个常量 const int a = 10; , 为该常量值 a 赋值 , 会报错 error: assignment of read-only variable 'a' ;

代码示例 :

#include <stdio.h>

int main() {

    // 定义常量
    const int a = 10;

    // 下面的代码会报错 , 貌似 a 是常量
    a = 20;

    return 0;
}

编译时的报错信息 :

C:\Users\octop\Desktop>gcc hello.c
hello.c: In function 'main':
hello.c:9:7: error: assignment of read-only variable 'a'
     a = 20;
       ^

C:\Users\octop\Desktop>

【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 ),C++,c++,c语言,左数右指,const,符号表,原力计划


3、代码示例 - C 语言中使用常量地址修改常量值


如果使用 指针 变量 , 接收 常量 a 的地址 , 然后通过该指针修改 指针指向的 内存空间的值 , 然后再打印 常量 a 的值 , 发现 常量 a 的值发生了改变 ;

因此 , C 语言中的常量 , 是可以通过指针进行修改的 ;

代码示例 :

#include <stdio.h>

int main() {

    // 定义常量
    const int a = 10;

    // 下面的代码会报错 , 貌似 a 是常量
    //a = 20;

    // 定义一个指针
    int* p = NULL;
    // 将 常量 a 的地址赋值给指针
    p = (int *)&a;

    // 通过指针修改 常量 a 的值
    *p = 20;

    // 打印 a 的值
    printf("a = %d\n", a);

    return 0;
}

执行结果 :

C:\Users\octop\Desktop>gcc hello.c

C:\Users\octop\Desktop>a.exe
a = 20

C:\Users\octop\Desktop>

【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 ),C++,c++,c语言,左数右指,const,符号表,原力计划


将相同的代码 , 拷贝到 C++ 环境中 , 编译运行的结果 , 与 C 语言环境中的编译运行结果不同

a = 10

Y:\002_WorkSpace\002_VS\HelloWorld\HelloWorld\Debug\HelloWorld.exe (进程 18604)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 ),C++,c++,c语言,左数右指,const,符号表,原力计划

出现上述问题 , 是因为 C 语言 中 , 会为 const 常量 单独分配内存 , 导致 用户可以 通过取地址符 & 获取该内存的地址指针 , 通过该指针可以修改内存中的数据 ;





三、C++ 语言 const 关键字 - 符号表存储常量




1、C++ 语言中常量原理


C++ 语言中 使用 const 关键字 定义的常量 , 是真正的 " 常量 " ;

C++ 编译器 对 const 关键字 修饰 的常量 , 进行了 特殊处理 ;

C++ 编译器 扫描到 const int a = 10; 代码后 , 发现 const 常量 , 不会为其单独分配内存 , 而是 将 常量 a 放在 符号表 中 ,

符号表 中的数据是以 " 键值对 " 的形式存在的 , 一个 键 Key , 对应一个值 Value ;

反映到 const int a = 10; 代码中 , 键 Key 是 a , 值 Value 是 10 , 在之后的代码 使用 常量 a 时 , 会直 从 符号表 中取出 10 ;

在下面的代码中 , 使用指针 p 获取 常量 a 的地址 , 获取的并不是 符号表 中 常量 a 的地址 , 而是 从 符号表中 取出常量 const int a = 10 , 为其 分配一个内存空间 , 将 10 存进去 , 然后将首地址返回 赋值给指针 p ;

实际上 指针 p 指向的是一个内存空间 , 内存空间中的值是 常量 a 的值 , 但是此时与常量 a 没有关系了 , 该值可以被修改 ;

    // 定义常量
    const int a = 10;

    // 下面的代码会报错 , 貌似 a 是常量
    //a = 20;

    // 定义一个指针
    int* p = NULL;
    // 将 常量 a 的地址赋值给指针
    p = (int *)&a;

    // 通过指针修改 常量 a 的值
    *p = 20;

对比 C 语言 中 , 会为 const 常量 单独分配内存 , 导致 用户可以 通过取地址符 & 获取该内存的地址指针 , 通过该指针可以修改内存中的数据 ;


2、代码示例 - 分析指针指向的值和实际常量值


修改上述代码 , 在不同的时间获取 *p 指向的内存空间值 和 常量 a 的值 ;

发现 使用指针 接收 常量 a 的地址 , 是在内存中重新分配内存并赋值为 10 , 并没有获取到符号表的内存地址 ;

修改内存中的值 , 不会影响到 符号表 中常量 a 的值 ;

代码示例 :

#include <stdio.h>

int main() {

    // 定义常量
    // 该常量定义在了 符号表 中
    // 符号表 不在内存四区中 , 是另外一种机制
    const int a = 10;

    // 下面的代码会报错 , 貌似 a 是常量
    //a = 20;

    // 定义一个指针
    int* p = NULL;
    // 将 常量 a 的地址赋值给指针
    // 在 堆内存中重新 分配一个 4 字节的空间 
    // 将 常量 a 的值 10 存储进去
    p = (int *)&a;

    // 打印 a 和 *p 的值
    // 此时 还没有修改 *p 的值 , 两个值都是 10
    printf("a = %d , *p = %d\n", a, *p);

    // 通过指针修改 常量 a 的值
    *p = 20;

    // 打印 a 和 *p 的值
    // 此时 通过你指针修改了 *p 的值 , *p 是 20 , 常量 a 仍为 10
    printf("a = %d , *p = %d\n", a, *p);

    return 0;
}

执行结果 :

【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 ),C++,c++,c语言,左数右指,const,符号表,原力计划文章来源地址https://www.toymoban.com/news/detail-665684.html

到了这里,关于【C++】C 语言 和 C++ 语言中 const 关键字分析 ( const 关键字左数右指原则 | C 语言中常量的原理和缺陷 | C++ 语言中常量原理 - 符号表存储常量 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在C++和C中static关键字的用法,在C++和C中const关键字的用法

    1、在C++和C中static的用法 答:static表示存储类型,修饰数据类型。在C语言中,static修饰局部变量,内存分配在静态区,生命周期延长,作用域不变。static修饰全局变量,内存分配在静态区,作用域被局限于本文件,不能被extern引用。static修饰函数,不能被exter

    2024年02月10日
    浏览(28)
  • 【C++】const、static关键字和构造函数初始化

    💗个人主页💗 ⭐个人专栏——C++学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 1. const修饰成员函数 1.1 语法格式 1.2 权限放大缩小 1.3 思考 1.4 解答 2. 再谈构造函数 2.1 构造函数体赋值 2.2 初始化列表 2.3 explicit 3. static成员 3.1 静态变量 3.2 静态函数 3.3 静态成员变量

    2024年02月19日
    浏览(34)
  • 嵌入式C语言关键字(const、static、volitatile)

    C语言中const修饰通常是用来声明常量,并声明常量的值不能修改。当涉及 指针变量 时情况就会变得更加有趣,需要特别注意。因为有两样东西都有可能成为常量— 一种是用来限定指向的空间的值不可修改;另一种是限定指针不可修改 。下面是几个声明的例子: 总结:cons

    2024年02月06日
    浏览(30)
  • C++面试八股文:static和const的关键字有哪些用法?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第7面: 面试官:C++中, static 和 const 的有哪些用法? 二师兄: satic 主要用在以下三个方面:1.用在全局作用域,修饰的变量或者函数为静态的,限制在本文件内使用。2.方法内修饰修饰静态局部变量,在第一次访问

    2024年02月08日
    浏览(35)
  • 关于c++中mutable、const、volatile这三个关键字及对应c++与汇编示例源码

    这哥三之间的关系是有趣的,不妨看看这个: cv (const and volatile) type qualifiers - cppreference.com permits modification of the class member declared mutable even if the containing object is declared const. 即便一个对象是const的,它内部的成员变量如果被mutable修饰,则此成员变量依旧可以被修改。 很常见,

    2024年02月13日
    浏览(26)
  • C语言中volatile/register/const/static/extern/auto关键字的作用

    目录 一、volatile 二、register详解 三、const详解 四、static详解 五、extern详解 语法 作用 六、auto详解 突然想总结一下这些的作用,灵活使用这些对程序的可靠性和速率都有提高 volatile是防止编译器优化,如果是高频繁的变量编译器会自动将变量放到寄存器中,但是有的变

    2024年02月07日
    浏览(52)
  • 【C++干货基地】面向对象核心概念 const成员函数 | 初始化列表 | explicit关键字 | 取地址重载

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 : 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活!   哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作

    2024年04月23日
    浏览(34)
  • 【C语言趣味教程】(5) 常量:字面常量 | 类型常量 | const 关键字 | const 的声明 | 程序中的只读概念 | const 保护机制 | 如何巧妙区分 “指针常量“ 和 “常量指针“

        🔗 《C语言趣味教程》👈 猛戳订阅!!! ✨ 专栏介绍 / 总目录: 【C语言趣味教程】(0) 导航篇 ​ —— 热门专栏《维生素C语言》的重制版 —— 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人

    2024年02月15日
    浏览(35)
  • 详解const、static关键字

    目录   一、static 二、const 在c语言中: static是用来修饰变量和函数的         1.修饰局部变量——称为静态局部变量         2.修饰全局变量——称为静态全局变量         3.修饰函数——称为静态函数 有关内存相关知识补充: 程序的所有数据,也就是所有的

    2024年02月06日
    浏览(36)
  • C# const关键字学习

    你居然不知道const?今天在做项目的时候别人问我的,我确实不知道这个,今天我们就来一起学习一下const定义局部变量,这个对于常数变量非常的友好的,可以提高程序的运行效率,因为它是在编译时的操作,所以我们必须要学习一下,这不就是提

    2024年01月22日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包