浅谈const和constant(常量)

常量被存储在常量区,并且表示常量不能被修改

当我们在定义一个字符串时 正确的规范应该是
const char*str="hello";

它代表我们这个字符串常量不能被修改,但是你会发现如果str="world";编译也是正确的,为什么可以被修改?而*(str+1)='w';却不能被编译;
实际上"hello"这个字符串属于常量有自己的内存空间(也就是有单独的内存地址),所谓的不能被修改 ,实际上是不能修改此地址上的常量,所以类似
*(str+1)='w';就不能被编译;//*(str+1)仍在"world"这个字符的内存空间
同理 "world"这个字符串常量实际上是拥有一个新的地址空间,所以str="world";并未修改字符串(原地址的值)

`const char*str="hello";//地址为 0x010ffc00 {0x00257b30 "hello"}
 str="world";           //地址为 0x010ffc00 {0x00257b38 "world"}

而对于

指针常量 int* const a

常量指针const int* a

常量指针常量const int* const a

的区别

指针常量表示 此指针指向的对象(地址)不能被修改

int x = 10, y = 10;
int* const p1 = &x; //常量 p1的类型是  (int*)
*p1= 10;     // correct 指针常量可以改变指向对象的值
p1 = &y;      // Error! 指针常量不能更改指向对象(地址)

常量指针表示 此指针指向的对象的值不能修改

const int x = 10;
const int* p1;
p1 = &x;      //指针 p1的类型是  (const int*)
*p1 = 15;     // Error!(改变原来x地址上空间的值了)

常量指针常量表示 此指针指向的对象的值和指向的对象(地址)皆不能被修改

int x = 10, y = 10;
const int* const p1 = &x;
*p1= 10;     //Error!
p1 = &y;      // Error! 
<think>好的,用户的问题是关于全局const常量局部const常量的区别及作用域规则。我需要先理解这两个概念,然后结合提供的引用资料来组织回答。 首先,全局const常量是在全局作用域中声明的,作用范围是整个程序,而局部const常量则是在函数或代码块内部声明的,作用域仅限于其所在的块内。根据引用[3],使用let/const声明变量具有块级作用域,这可能也适用于const常量。但要注意,全局常量的作用域是全局的,而局部的只能在块内访问。 接下来,生命周期方面,全局const常量在程序整个运行期间存在,而局部的则随着作用域的结束而释放。引用[4]提到,全局变量(包括const)需要是常量表达式,在编译时确定,而局部const可能允许某些运行时计算的值?不过根据引用[4],const必须是在编译时可计算的值,不管全局还是局部。这点可能需要确认。 初始化方面,全局const必须在声明时初始化,且使用常量表达式。局部const同样需要声明时初始化,但可能允许更复杂的表达式,只要在编译时能确定?比如函数内部的const是否可以由函数参数计算?或者是否必须是编译时常量?根据引用[4],全局的必须使用编译时可计算的值,而局部的可能允许某些情况,但可能还是需要编译时确定,比如在Rust中,但用户的问题可能不特定于Rust,而是通用的。需要区分不同语言的规则,但用户可能指的是JavaScript或一般编程概念,但根据引用资料,引用了RustJavaScript的内容,可能需要综合说明。 内存分配方面,全局const可能在程序的只读数据区,而局部的可能在栈上?或者是否会被编译器内联优化?例如,引用[4]提到全局变量需要处理线程安全,但const是不可变的,所以可能没有这个问题。 作用域规则方面,全局const可以被整个程序访问,但需要注意可能的命名冲突。局部const仅在块内有效,避免污染全局空间。引用[3]强调了块作用域的重要性,推荐使用let/const,这可能适用于局部const的优势。 然后需要总结它们的区别,包括作用域、生命周期、初始化要求、内存分配使用场景。同时,根据引用中的内容,比如引用[2]提到const在调试时保留类型作用域信息,这可能适用于局部const的好处,而全局const在程序全局可用。 最后生成相关问题,可能需要涵盖应用场景、选择建议、不同语言中的差异等。</think>### 全局 `const` 常量与局部 `const` 常量的区别及作用域规则 #### 1. **作用域范围** - **全局 `const` 常量** 在全局作用域(如文件顶层或全局代码块)中声明,作用域覆盖整个程序或文件。例如在 JavaScript 中: ```javascript const GLOBAL_CONST = 100; // 全局常量 function example() { console.log(GLOBAL_CONST); // 可访问 } ``` 引用[3]指出,全局作用域中声明的变量(包括 `const`)可在任意位置访问[^3]。 - **局部 `const` 常量** 在函数、代码块(如 `if`、`for`)或模块内部声明,作用域仅限于其所在的块。例如: ```javascript function example() { const LOCAL_CONST = 10; // 局部常量 if (true) { const BLOCK_CONST = 5; // 块级常量 console.log(BLOCK_CONST); // 可访问 } // console.log(BLOCK_CONST); // 报错:超出作用域 } ``` 根据引用[3],块级作用域通过 `const` 实现,变量仅在当前块内有效。 --- #### 2. **生命周期** - **全局 `const` 常量** 生命周期与程序运行周期一致,在程序启动时初始化,结束时释放。 - **局部 `const` 常量** 生命周期随作用域结束而终止。例如函数内的 `const` 常量在函数执行完毕后被销毁。 --- #### 3. **初始化要求** - **全局 `const` 常量** 必须在声明时初始化,且值必须是**编译期常量表达式**(如字面量或数学表达式)。例如在 Rust 中: ```rust const GLOBAL_PI: f32 = 3.1415; // 合法 // const INVALID: f32 = calculate_value(); // 非法:非编译期可计算值 ``` 引用[4]强调,全局常量需通过常量表达式初始化[^4]。 - **局部 `const` 常量** 同样需在声明时初始化,但某些语言(如 JavaScript)允许通过运行时表达式赋值: ```javascript function calc() { const result = 10 * Math.random(); // 合法(JavaScript 中允许) return result; } ``` (注:Rust 等强静态语言中局部 `const` 仍需编译期确定值。) --- #### 4. **内存分配** - **全局 `const` 常量** 通常存储在程序的**只读数据段**,不可修改且无内存分配开销。 - **局部 `const` 常量** 可能存储在栈或寄存器中,编译器可能直接内联优化。 --- #### 5. **典型应用场景** - **全局 `const` 常量** 用于定义跨模块共享的固定值(如数学常数、配置参数)。 - **局部 `const` 常量** 用于限制作用域,避免命名冲突或临时计算(如循环中的固定步长)。 --- ### 总结对比 | 特性 | 全局 `const` 常量 | 局部 `const` 常量 | |---------------------|-----------------------------------|----------------------------------| | **作用域** | 全局 | 块级(函数、代码块) | | **生命周期** | 程序运行期间 | 随作用域结束终止 | | **初始化要求** | 必须为编译期常量表达式 | 允许运行时表达式(视语言而定) | | **内存分配** | 只读数据段 | 栈/寄存器(可能被内联优化) | | **线程安全** | 隐式安全(不可变) | 隐式安全(不可变) | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值