为什么const变量不能修改?从存储位置到内存权限的完整技术链解析

第一章:为什么const变量不能修改?从存储位置到内存权限的完整技术链解析

编译期常量与符号表机制

在C++或Go等静态语言中,const变量通常被视为编译期常量。编译器会在符号表中记录其值,并在所有引用处进行直接替换,而非访问内存地址。例如:
// 示例:Go中的const定义
const MaxRetries = 5

func main() {
    attempts := 0
    for attempts < MaxRetries { // MaxRetries 被替换为字面量 5
        // 执行重试逻辑
        attempts++
    }
}
该代码中,MaxRetries 并不分配独立的可寻址内存空间,因此无法取地址或修改。

存储位置与内存段划分

即使const变量被分配了内存(如C++中使用&取地址),它通常会被放置在只读数据段(.rodata)。操作系统通过页表将该内存区域标记为只读,任何写入操作会触发硬件异常(如SIGSEGV)。
  • .text 段:存放可执行指令
  • .rodata 段:存放const变量和字符串字面量
  • .data 段:存放已初始化的可变全局变量

内存权限的底层保护机制

现代操作系统利用CPU的内存管理单元(MMU)对虚拟内存页设置权限位。以下表格展示了典型内存页属性:
内存段可读可写可执行
.text是否是
.rodata是否否
.data是是否
当程序试图修改位于.rodata段的const变量时,CPU检测到写操作违反页权限,立即中断执行并交由操作系统处理,最终导致进程终止。这种保护贯穿从语言语义、编译器优化到操作系统内存管理的完整技术链。

第二章:C语言中const常量的存储位置

2.1 理论基础:const变量的存储分类与内存布局

在C/C++中,`const`变量的存储位置取决于其作用域和链接属性。全局`const`变量通常被分配在只读数据段(`.rodata`),而局部`const`变量则可能位于栈上,由编译器决定优化策略。
内存分布示例
const int global = 100;        // 存储在.rodata段
void func() {
    const int local = 50;      // 通常分配在栈上
}
上述代码中,`global`为静态存储期,编译后进入只读段;`local`虽为常量,但生命周期限于函数调用,一般置于栈帧中。
存储类型对比
变量类型存储区域访问权限
全局const.rodata只读
局部const栈(或寄存器)只读(逻辑)
编译器可对`const`变量进行常量折叠优化,相同值可能共享同一内存地址,提升空间利用率。

2.2 实践验证:通过地址分析const变量在栈中的行为

在C/C++中,`const`变量是否分配栈空间常引发争议。通过实际地址分析可明确其存储行为。
实验代码与内存布局观察

#include <stdio.h>
void test_const_stack() {
    const int a = 10;
    int b = 20;
    printf("Address of const a: %p\n", &a);
    printf("Address of b:       %p\n", &b);
}
上述代码中,`const int a` 被显式定义在函数栈帧内。两次`printf`输出地址接近且`&a > &b`(取决于栈增长方向),表明`a`确实位于栈上。
关键分析
  • 尽管`const`变量不可修改,编译器仍为其分配栈空间;
  • 若`const`变量被优化为常量折叠,则可能不分配地址,但局部`const`变量通常保留栈位置;
  • 取地址操作`&a`强制变量具象化,确保其在栈中存在。

2.3 深入探究:全局const变量是否真的存放在只读段

在C/C++中,全局`const`变量通常被认为存储在只读数据段(.rodata),但这并非绝对,取决于其使用方式。
编译器优化与存储位置
当`const`变量仅在定义模块内使用时,编译器可能将其优化为常量折叠,甚至不分配内存。例如:

const int global_val = 42;
int get_val() { return global_val; }
上述代码中,`global_val`可能被直接内联为42,不访问内存。
链接可见性的影响
若`const`变量被其他翻译单元引用(extern引用),则必须分配实际地址,此时通常置于.rodata段。
场景存储位置原因
内部链接,未取地址无内存分配常量折叠
外部链接或取地址.rodata需符号导出
因此,`const`变量是否位于只读段,依赖于链接属性与使用上下文。

2.4 编译器视角:不同编译器对const变量存储的优化策略

在C/C++中,const变量是否分配内存取决于其使用场景和编译器优化策略。现代编译器如GCC、Clang和MSVC会根据上下文决定是否将const变量替换为立即数,避免内存访问。
常见编译器行为对比
  • GCC:在-O2优化下,局部const整型量通常被内联为立即数
  • Clang:积极进行常量传播,消除冗余存储
  • MSVC:对const全局变量可能保留符号以支持跨模块引用
const int size = 1024;
int buffer[size]; // 可能不分配实际内存
上述代码中,size作为编译时常量,多数编译器不会为其生成静态存储空间,而是直接将其值嵌入符号表用于数组大小计算。
存储决策影响因素
因素影响
取地址操作强制分配内存
跨翻译单元引用需保留符号
非基础类型通常分配存储

2.5 运行时观察:利用反汇编工具查看const变量的实际存放位置

在程序运行时,`const` 变量是否真的“不可变”以及其存储位置常引发争议。通过反汇编工具如 `objdump` 或 `gdb`,可深入观察其真实存放区域。
编译器优化与存储分配
常量可能被存储在只读段(`.rodata`)或直接内联到指令中。例如:

const int size = 100;
int arr[size];
上述代码中,`size` 通常不占用实际内存单元,而是作为立即数参与编译,反汇编后可见其值嵌入指令流。
使用 GDB 查看符号地址
通过以下命令可验证常量地址:
  • gdb ./program 启动调试器
  • info address size 查询符号位置
  • disassemble main 观察指令中是否包含立即数
若系统反馈“symbol has no debug info”,说明该 `const` 已被完全内联,未分配独立存储空间。

第三章:内存权限机制与const的关联

3.1 理解只读段(.rodata)的内存保护原理

在程序的内存布局中,.rodata 段用于存储编译期确定的常量数据,如字符串字面量和全局 const 变量。该段被映射为只读权限,防止运行时意外或恶意修改。
内存段权限控制机制
操作系统通过页表项中的权限位(如 x86 的 R/W 位)对内存区域进行保护。.rodata 所在页面标记为“可读不可写”,任何写操作将触发 CPU 的页错误异常。
示例:访问违规触发保护

const char *msg = "Hello, World!";
// msg 指向 .rodata 段
*(char *)msg = 'h'; // 运行时将触发 SIGSEGV
上述代码试图修改 .rodata 中的字符串,CPU 检测到对只读页的写入,立即中断执行并抛出段错误,从而保障内存安全。
  • 提高程序稳定性:防止常量被篡改
  • 增强安全性:阻断某些类型的攻击(如字符串注入)
  • 支持共享:多个进程可共享同一物理页

3.2 实验演示:尝试修改位于.rodata中的const变量引发的异常

在C语言中,被声明为const的全局变量通常存储在只读段(.rodata)中。尝试修改该区域的数据将触发内存保护机制。
实验代码

#include <stdio.h>
int main() {
    const int value = 42;
    int *ptr = (int*)&value;
    *ptr = 100; // 非法写入
    printf("%d\n", value);
    return 0;
}
上述代码通过指针强制修改const变量value。虽然编译通过,但在运行时可能产生SIGSEGV信号。
异常分析
操作系统将.rodata映射为只读内存页。当CPU执行写操作时,MMU触发页错误,内核发送段错误信号。此机制保障了程序的内存安全边界。

3.3 操作系统层面:MMU如何通过页表权限阻止写操作

现代操作系统利用内存管理单元(MMU)与页表协同工作,实现对内存访问权限的精细控制。当进程尝试写入只读页面时,硬件会触发页错误异常,由内核决定是否终止或修正该操作。
页表项中的权限位
页表项(PTE)包含若干标志位,用于控制访问权限:
  • Present (P):页面是否在物理内存中
  • Read/Write (R/W):是否允许写操作(0 = 只读,1 = 可写)
  • User/Supervisor (U/S):用户态是否可访问
写保护触发机制示例

// 假设页表项设置为只读
pte_t pte = PTE_PRESENT | PTE_USER | PTE_READONLY; // R/W = 0

// CPU执行写操作时,MMU检查R/W位
if (!(pte & PTE_WRITE) && is_write_access()) {
    raise_page_fault(FAULT_WRITE_PROTECTION); // 触发缺页异常
}
上述代码模拟了MMU的权限检查逻辑。当CPU发起写请求时,MMU解析对应虚拟地址的页表项,若发现R/W位为0,则拒绝写入并抛出页错误,交由操作系统处理。

第四章:从编译到运行的技术链剖析

4.1 编译阶段:const变量的语义检查与符号表处理

在编译器前端处理中,`const`变量的语义分析是类型安全的关键环节。编译器需验证其声明合法性、初始化完整性及后续不可变性。
语义检查流程
  • 检查`const`变量是否在声明时初始化
  • 验证初始化表达式的常量性(如字面量或编译期可计算表达式)
  • 禁止后续赋值操作的语法结构
符号表中的处理
编译器将`const`变量作为符号插入符号表,并标记为“只读”属性:
字段值
名称PI
类型double
存储类别const
值3.14159
const double PI = 3.14159;
该声明触发编译器在语法树中标记节点为常量,在后续遍历中拒绝任何修改PI的赋值表达式,确保语义一致性。

4.2 链接过程:节区合并与const数据的最终定位

在链接阶段,多个目标文件的相同类型节区被合并为统一的可执行节区。例如,所有 `.rodata` 节区(存储 const 数据)被归并至最终的只读段中,确保常量数据的内存布局得以确定。
节区合并规则
  • .text 合并为可执行代码段
  • .rodata 汇集为只读数据段
  • .data 合并初始化数据
const 数据的重定位示例

// file1.c
const int version = 100;

// file2.c
extern const int version;
void print() { printf("%d", version); }
链接器将两个文件中的 `version` 符号解析并指向同一地址,完成跨文件引用绑定。
符号地址分配表(简化)
符号名节区最终地址
version.rodata0x400500
print.text0x400300

4.3 加载机制:程序映像如何映射到虚拟内存并设置权限

程序加载时,操作系统将可执行文件的各个段(如代码段、数据段)映射到进程的虚拟地址空间。这一过程由加载器(Loader)完成,通常在调用 execve() 系统调用后触发。
段映射与内存权限
每个程序段根据其属性被赋予不同的内存保护权限。例如,代码段设为只读和可执行,防止运行时修改;数据段设为可读写但不可执行,增强安全性。
段类型虚拟内存权限对应标志(Linux)
.text只读、可执行PROT_READ | PROT_EXEC
.data, .bss可读写PROT_READ | PROT_WRITE
加载过程中的mmap调用
加载器通过 mmap() 系统调用将文件偏移映射到虚拟地址:
mmap((void*)0x400000, 
     file_size, 
     PROT_READ | PROT_EXEC, 
     MAP_PRIVATE | MAP_FIXED, 
     fd, 
     0);
该调用将文件从偏移0映射到虚拟地址0x400000,设置只读可执行权限。参数MAP_PRIVATE表示私有映射,避免影响其他进程;fd为程序文件描述符。

4.4 运行时防护:SIGSEGV信号的触发与调试分析

信号机制与内存访问违规
SIGSEGV(Segmentation Violation)是Linux运行时最常见的崩溃信号,通常由非法内存访问引发。当进程试图访问未映射或受保护的内存区域时,内核通过中断触发该信号,默认行为为终止程序。
典型触发场景与代码示例

#include <signal.h>
#include <stdio.h>

void segv_handler(int sig) {
    printf("捕获到SIGSEGV信号: %d\n", sig);
}

int main() {
    signal(SIGSEGV, segv_handler);
    int *p = NULL;
    *p = 42;  // 触发SIGSEGV
    return 0;
}
上述代码注册了SIGSEGV信号处理器,并故意对空指针解引用。系统在检测到无效写入时发送信号,控制权转移至segv_handler,实现异常捕获。
调试辅助信息收集
可通过struct siginfo_t和ucontext_t获取崩溃上下文,包括出错地址、指令指针等,结合gdb与core dump可精确定位内存错误根源。

第五章:总结与思考:const的本质是语法约束还是硬件保护?

编译期的语义检查机制
在C/C++中,const关键字主要作用于编译阶段,为变量提供不可变性语义。它并非直接映射到内存硬件保护,而是由编译器插入额外检查,防止非法赋值操作。
const int value = 42;
// value = 100; // 编译错误:assignment of read-only variable
int* ptr = (int*)&value;
*ptr = 100; // 危险!绕过const,行为未定义
上述代码展示了const的局限性:通过指针强制转换可绕过限制,说明其本质仍是语法层面的约束。
运行时保护的实现可能性
尽管const本身不触发硬件保护,但链接器和操作系统可通过段属性实现运行时防护。例如,将const全局变量放入只读段(如.rodata):
  1. 编译器生成目标文件时,标记const数据所属节区
  2. 链接器将其归入只读内存段
  3. 加载程序时,操作系统设置该内存页为只读(PROT_READ)
  4. 若程序尝试写入,触发SIGSEGV信号
实际案例:嵌入式系统中的常量保护
在STM32等MCU中,可将关键配置常量置于Flash存储器,并通过写保护位防止运行时修改:
变量类型存储位置保护机制
const int configFlash硬件写保护
const int localRAM仅编译检查
[ Flash Memory ] --(写保护启用)--> [ 拒绝写入操作 ] | v [ CPU Write Request ] ---> [ MMU/MPU Check ] ---> [ Fault Exception ]
Speedtree学习笔记(案例)——拥有多种材质的植物如何导入使用(以草为例) 注:Speedtree无论保存还是导入模型其存储路径不可有中文。 第一步拆分草的模型 根据所需的材质去拆分(例:假若草的果实,茎秆和叶子是不同的材质那么就需拆分为三份;假若画的全部颜色及材质一样就没有必要去拆分模型) 第二步导入草的模型 在Mesh面板中依次导入草的模型——Do nothing additional right now 第三步扩大草的生长区域范围(可省略)... 阅读详情

相关推荐

深入解析PCIe Retimer:工作原理与典型应用场景

本文深入解析了PCIe Retimer的工作原理与核心价值。作为高速信号的中继再生器,Retimer通过时钟数据恢复和信号再生技术,有效解决长距离或复杂通道中的信号衰减与完整性问题,从而极大地扩展了PCIe链路的有效传输距离。文章详细阐述了其内部架构、自动与手动两种工作模式,并重点介绍了在长距离板间互连、复杂背板设计等典型应用场景中的关键作用。

weixin_29195615的博客 506

告诉你为什么const定义的内容不能更改

我们都知道const定义的是一个常量,不可以改变的 let var都是可以改变的, 为什么呢 其实const 他定义的只是一个,在内存中的地址是不能改变的, 也就是说我们的内存不改变就可以对const定义的内容进行赋值 比如:复杂数据类型就可以 Array,Object const name='孔小弟' name="葫芦娃" 这时候会报错 name 存放的是一个地址,如果要赋值成葫芦娃就会在内存中开辟一个新的空间来保存葫芦娃,这样是不行的 但是数组本身存放的就是一个地址,所以可进行增加和更改操.

weixin_46095200的博客 2414

用Matlab机器人工具箱搞定六轴机械臂建模:从DH参数到3D可视化(附完整代码)

本文详细介绍了如何使用Matlab机器人工具箱进行六轴机械臂建模,从DH参数输入到3D可视化全流程解析。通过正运动学验证、逆运动学求解和交互控制等实战技巧,帮助工程师快速掌握机械臂建模核心方法,并提供完整代码示例解决常见问题。

weixin_27372101的博客 394

浅析JS中的var,let及const的区别

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效 { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // 1 var a = []; for (var i = 0; i < 10; i++) { a[...

613

智能车图像处理9-进阶篇1--中线的提取

(1)10-50行 基础扫线 (2)56-71 断行0 ,就是比如遇到十字,十字路口下方 第一次断线的地方。 (3)83-124 按照原先有效行,拟线作为中值,然后从中值向左右扫线,同时计算赛道宽度。 (4)125-138 如果出现赛道宽度小于先前有效行,则找到二次扫线的起点,从二次扫线起点处,继续向下扫线,直至结束,同时记录最后的有效行。 (5) 310-- 最后计算左右边线类似于方差的值,用于环岛的判断 ***这里着重描述一下二次扫线,希望大家可以理解的深刻

taiyuezyh的博客 1万+

Simulink开发项1000例实战专栏--实例161:基于Simulink实现电动汽车电机驱动系统的建模与仿真

通过上述步骤,我们成功实现了基于Simulink的电动汽车电机驱动系统的建模与仿真。该系统能够全面评估电机驱动系统的性能,验证控制策略的有效性,并通过优化设计提高车辆的动力性和效率。引入智能预测:结合人工智能技术,实现更智能的控制策略。扩展功能:增加对多种电机类型的支持,提升系统通用性。实验验证:将仿真模型应用于实际硬件,进行实验验证,评估其在实际工况下的表现。

xiaoheshang_123的博客 189

const的值可不可以被更改

当const定义的常量是基本数据类型的时候不可以被更改 当const定义的常量是引用数据类型的时候,其值可以被更改。 const定义的常量实际上是栈内存地址中的保存的值,const常量的值不可以被更改就是栈内存中保存的数据不可以被更改。基本数据类型直接存储在栈内存中,所以不可以更改。而引用数据在栈内存中存储的是一个指针,真正的数据存储在指针指向的堆内存中,不可改变的是指针,真正的数据是可以更改的。 参考:https://blog.youkuaiyun.com/qq_41797950/article/detai

做一个优秀的小前端 5540

信号与电源完整性5:轨道塌陷噪声/电源轨道噪声分析及降低解决方案

经过上一节关于串扰的分析,我们已经清楚,噪声问题不仅仅来源于信号网络;电源和地网络所产生的噪声,被反馈到其所在的元器件和信号网络时,其破坏力也是巨大的;本节所讨论的轨道塌陷噪声就是一个典型的实例。在经过电源的地网络的电流发生改变时,在电源和地之间的阻抗上将产生一个压降;由于该压降的产生,用电元件的电压将直接被拉低,甚至可能对电路产生功能性的错误。接下来硬小二将详细的分析电源轨道噪声和降低其的解决方法。...

fydar的博客 2241

JavaScript中const常量值为什么不可更改?对象属性又可以更改?

​const​ 并不等于不可变:对于引用类型(数组、对象等),const​ 并不意味着对象或数组本身不可变,只是锁定了栈中引用的内存地址。可以修改引用类型对象中的内容(如数组元素或对象属性),但不能让 const​ 变量引用一个新的对象或数组。

2301_82331378的博客 695

基于YOLOv8的野生菌菇检测、识别与分类系统

YOLOv8是YOLO系列模型的最新版本,继承了YOLO系列高效、精确的特点。YOLOv8采用了新的网络架构,并优化了推理速度和检测精度。与传统的目标检测算法(如Faster R-CNN)不同,YOLO模型通过一次前向传播同时完成目标定位与分类,因而具有非常高的计算效率。

YOLO 1284

使用 Simulink Real-Time 搭建一个完整的实时信号采集与滤波系统模型

本文详细介绍了基于Simulink Real-Time构建实时信号采集与滤波系统的完整流程。主要内容包括:系统配置(模型创建与参数设置)、信号采集模块搭建(模拟信号源或真实硬件连接)、实时滤波器设计(浮点/定点)、输出可视化(Scope/ToWorkspace等)、模型编译与下载到目标机、外部模式在线调试及数据保存方法。系统可实现微秒级实时信号处理,适用于工业控制、航空航天等对时间确定性要求高的场景。文章还提供了优化建议(多速率建模、优先级调度等)和应用场景说明,帮助读者快速掌握实时系统开发的核心技能。

amy_mhd的博客 304

c语言中的常量(const变量),在任何情况下都不能修改吗?

从如下截图中可以看出,目标文件主要包括代码段 .text,数据段 .data, .bss 段,只读数据段 .rodata。其中只读数据段的长度是 8,正好和上边的代码相匹配,两个 int 类型,长度是 8。但是如果把变量的地址取出来,然后通过地址操作来间接修改 const 变量,这个时候可以编译通过。“c 语言中 const 修饰的变量是一个常量,常量在程序运行时不能修改,只能在变量声明的时候初始化。const 变量直接赋值,不管是全局变量还是局部变量,编译的时候会报错,编译不通过。用下边的代码来做实验。

weixin_38184628的博客 1263

8、对比 LightGBM、XGBoost 和深度学习

本文对比了LightGBM、XGBoost和深度学习模型(特别是TabTransformer)在处理表格数据时的性能差异。从模型复杂度、数据准备、训练时间、准确性和适用场景等方面进行分析,重点探讨了三者在人口普查收入预测任务中的表现。文章详细介绍了XGBoost与LightGBM的核心特性与区别,深入讲解了TabTransformer的架构与实现,并涵盖了分类特征编码、缺失值处理和类别不平衡等关键数据预处理技术,为选择合适的表格数据建模方法提供了实践指导。

julia4scientist的博客 120

const变量通过指针修改 详解

本来以为const变量是无法修改的,今天发现“错了”(其实没错,通过const变量本事是无法修改其值的,但是在“某些情况下”可以通过指向它的指针来间接修改) 一、const变量可以通过指针修改的情况 例子: #include <stdio.h> void main(void) { int const a = 10; int b = 20; int *p = (int*)

hyqsong的专栏 5586

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C语言 const变量能不能修改?

笔者在跟同事讨论变量存放的分区问题时,讨论到了const标识符所标记的变量能不能修改这个问题。 按直观理解,const关键字标识的变量,意味不能修改的变量,引申理解,猜测其可能存放在.rodata分区(只读)。 ======================================================================== 来实际操作验证一下,一看便知。 环境:选用Ubuntu平台,x86 gcc工具。 一、局部的const变量 代码验证:首先是局部的con.

weixin_42771216的博客 1764

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C++ 常量的定义方式与内存存储位置全解析

这是最常用的方式,参考回答中的“top-level const”即此类(const修饰整个对象,而非指针/引用的底层数据)。常量定义方式const(运行期只读)、constexpr(编译期常量);#define(预处理替换,不推荐)、枚举常量;规则:const/constexpr常量定义时必须初始化。内存存储位置局部const常量:默认栈区,编译期常量可能优化为立即数;全局/静态const常量、字符串字面量:常量区(.rodata,只读);

weixin_51287424的博客 413

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

const,static深度总结——c++穿透式分析

编译不通过。这是因为使用const修饰的变量相当于放在了常量区。

strive_mianyang的博客 4016

C语言Const变量

附上代码一份,const修饰的局部变量,指针,以及全局变量的权限问题。 /*const变量*/ #include <stdio.h> #define uint unsigned int const int globalVar = 10; /*const定义的全局变量,在.data的只读区域,该区域内存地址不能够访问, 所以一定是不能够修改的*/ /*const 定义的局部变量并不是存在.data段中;所以变量的地址是可以访问的; 但是const修饰的全局变量,因为是全局变

qq_35480173的博客 601

学习笔记——内存,变量,输入输出缓冲区

内存: 程序在内存中的分段 当程序开始运行后会加载到内存中,会把内存分成若干段(60)。  每一段的功能和权限不同。     代码段(txt):程序中的二进制指令存储在此段,只读权限。     只读段:存储常量,字符串字面值。(有时和txt合并)     bss段:静态数据段,程序运行时会清理。     全局段(data):存储全局变量。     txt,bss,data当程序编译完成后大小就确定...

yxt0505的博客 459

C语言中const到底存哪?90%面试者答错的高频问题深度拆解

揭秘C语言中const常量的存储位置,彻底搞懂常量在内存中的真实分布。涵盖全局与局部const变量的存储差异、只读段与栈区的应用场景,深入解析编译器优化机制。理解本质,避免常见误区,值得收藏。

ByteVein的博客 678

只读段还是栈空间?一文说清C语言const变量的真正归宿(含汇编级验证)

深入解析C语言中const常量的存储位置,揭示其究竟位于只读段还是栈空间。通过编译原理与汇编代码验证,阐明不同场景下的内存分布机制,帮助开发者优化程序性能。内容硬核实用,值得收藏。

ProcePerch的博客 1040

地址修改const变量真的不能修改吗?

在本篇文章中,我们主要介绍地址修改的内容,自我感到有个不错的建议和大家分享下 昨天在写程序时,突然想到了一个问题:const变量真的不可改变吗?如果能改,应当怎么改?于是乎,就决定着手操作一番,结果程序的结果有点出其不意。但是终究还是得出了结论。若有不当,欢送各位拍砖! 下面就来看一下这个简略的程序: #include <iostream> usi...

weixin_30852419的博客 223

【MCU】const修饰指针真的能省RAM?深入解析存储分配机制

本文深入解析了在MCU开发中const修饰符与RAM节省的真实关系。澄清了常见误解,指出const主要约束访问权限而非强制存储位置。通过分析编译器、链接器工作机制及哈佛与冯·诺依曼架构差异,揭示了const变量如何通过被分配至.rodata段而存入Flash,从而节省RAM的关键条件,并强调了指针声明形式对存储分配的决定性影响。

weixin_29158413的博客 498

编程变量全景深度解析:本质、机制、分类与实战核心逻辑/数据的存储、传递、运算与修改/变量名、内存空间、数据值

本文系统拆解变量的底层原理与全维度知识体系,从本质定义、内存机制、类型分类、作用域规则到跨语言差异,全景解析变量作为“内存别名”的核心逻辑。揭示变量不仅是数据容器,更是程序动态性的基石。通过对比表格厘清变量、常量、字面量区别,深入值类型与引用类型的内存差异,剖析新手常见误区,提出初始化、作用域控制、避免全局污染等实战准则。最终强调:掌握变量的本质,在于理解其内存存储、生命周期与运行机制,而非语法表层,这是进阶编程与高效调试的核心基础。

snow的博客 563

C++中的const和static关键字

C++中关键字的理解

weixin_44535934的博客 465

C语言指针常量与常量指针:从内存权限到实战应用

在C语言编程中,指针是访问和操作内存的核心机制,而`const`关键字则用于定义数据的不可变性。理解`const`与指针的结合,本质上是厘清内存访问权限:是限制指针变量本身的指向(指针常量),还是限制通过指针修改其所指向的数据(常量指针)。这一区分对于编写安全、健壮的代码至关重要,尤其在函数参数传递、硬件寄存器访问和字符串处理等场景中。掌握指针常量与常量指针的正确使用,能有效避免运行时错误和编译陷阱,提升代码的可维护性。本文将通过清晰的内存模型和实战示例,帮助你彻底理解这两个关键概念,并自然融入`const

weixin_30437847的博客 458
上一篇: 为什么你的C程序解析JSON这么慢?3个关键优化点你必须知道
下一篇: 【requests会话机制揭秘】:构建高性能爬虫系统的底层逻辑(仅限专业人士)
ByteChat
博客等级 码龄1年 157粉丝 1991原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值