C语言进阶教程(const定义的变量真的不能被改变吗?)

简介: C语言进阶教程(const定义的变量真的不能被改变吗?)

前言

本篇文章将为大家讲解const定义的变量到底能不能被改变。


一、const定义的变量属性是常量吗

很多同学会误认为const定义的变量就是常量,那么常量是不可被修改的,所以说const定义的变量也是不可被修改的,这是一个错误的观点,其实const定义的变量属性是一个只读的变量属性,而不是常量。

const定义的变量本质还是变量是可变的,不是常量。

const修饰的变量只是告诉编译器改变量不能出现在赋值符号的左边。


二、如何改变const定义变量的值

既然const定义的变量不能出现在赋值符号左边,那么这里我们使用指针来修改const定义的变量值,这样就能够成功将const定义的变量值进行修改了。

#include <stdio.h>
int main()
{
    const int num = 0;
    int* p = &num;
    *p = 2;
    printf("num = %d\n", num);
    return 0;
}

注意点:

对于const定义的全局变量和使用static修饰的局部const变量,它们都具有不可修改的属性。这意味着它们的值在初始化后不能再进行修改。

在全局作用域下,使用const定义的变量被视为全局常量。这些变量在程序执行期间保持不变,无法通过任何方式修改它们的值。

使用static修饰的局部const变量也具有类似的特性。这些变量在第一次声明和初始化后,其值会在其所在作用域内保持不变,无法在后续的代码中修改。

然而,对于使用const定义的局部变量,它们并不具有不可修改的属性。const关键字仅指示编译器在声明时要求变量为只读,但这并不意味着它们的值不可变。在执行过程中,const局部变量的值仍然可以被修改,只是编译器不会提供安全性检查。

存储区域:

对于全局const变量和使用static修饰的局部const变量,它们的存储位置通常是在静态数据区(static data segment)。

局部const变量通常被存储在栈(stack)中。栈是一种用于存储局部变量、函数参数和其他临时数据的内存区域。局部const变量的生命周期与其所在的作用域相对应,在其作用域结束时会自动释放。


三、const和指针相遇

让我们逐个解释这些声明中指针的类型和指针指向的内容是否为常量(const):

const int* p;: 这里声明的是一个指向 int 类型的指针 p,并且指针所指向的内容是不可修改的(常量)。也就是说,你可以修改指针 p 指向其他 int 变量,但不能通过指针 p 来修改所指向的 int 变量的值。

int const *p;: 这里也声明了一个指向 int 类型的指针 p,并且指针所指向的内容是不可修改的(常量)。与第一个声明相同,你可以修改指针 p 指向其他 int 变量,但不能通过指针 p 来修改所指向的 int 变量的值。

int* const p;: 这里声明的是一个常量指针 p,指针本身是不可修改的。也就是说,你不能修改指针 p 指向的地址,但是可以通过指针 p 来修改所指向的 int 变量的值。

const int* const p;: 这里既声明了一个常量指针 p,又声明了指针所指向的内容是不可修改的(常量)。这意味着你不能修改指针 p 指向的地址,也不能通过指针 p 来修改所指向的 int 变量的值。

总结起来,const int* p; 和 int const p; 是等价的,表示指向常量的指针;int const p; 表示常量指针;const int* const p; 表示指向常量的常量指针。

总结

本篇文章解决了大家一直以来对const产生的误解,const定义的变量并不是无法被修改的,使用指针可以修改const定义的局部变量。


相关文章
|
1月前
|
存储 编译器 C语言
【C语言】C语言的变量和声明系统性讲解
在C语言中,声明和定义是两个关键概念,分别用于告知编译器变量或函数的存在(声明)和实际创建及分配内存(定义)。声明可以多次出现,而定义只能有一次。声明通常位于头文件中,定义则在源文件中。通过合理组织头文件和源文件,可以提高代码的模块化和可维护性。示例包括全局变量、局部变量、函数、结构体、联合体、数组、字符串、枚举和指针的声明与定义。
58 12
|
1月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
156 14
|
1月前
|
C语言
【C语言】全局搜索变量却找不到定义?原来是因为宏!
使用条件编译和 `extern` 来管理全局变量的定义和声明是一种有效的技术,但应谨慎使用。在可能的情况下,应该优先考虑使用局部变量、函数参数和返回值、静态变量或者更高级的封装技术(如结构体和类)来减少全局变量的使用。
41 5
|
1月前
|
安全 程序员 编译器
【C语言】const 关键字详解
`const`关键字在C语言中用于定义常量,提供只读的变量。这意味着一旦初始化,`const`变量的值不能再被修改。下面详细介绍`const`关键字的用法、作用以及其在不同上下文中的应用。
50 2
|
1月前
|
编译器 C语言
【C语言】宏定义在 a.c 中定义,如何在 b.c 中使用?
通过将宏定义放在头文件 `macros.h` 中,并在多个源文件中包含该头文件,我们能够在多个文件中共享宏定义。这种方法不仅提高了代码的重用性和一致性,还简化了维护和管理工作。本文通过具体示例展示了如何定义和使用宏定义,帮助读者更好地理解和应用宏定义的机制。
56 2
|
2月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
143 4
|
3月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
3月前
|
存储 C语言
【c语言】数据类型和变量
本文介绍了C语言中的数据类型和变量。数据类型分为内置类型和自定义类型,内置类型包括字符型、整型、浮点型等,每种类型有不同的内存大小和取值范围。变量分为全局变量和局部变量,它们在内存中的存储位置也有所不同,分别位于静态区和栈区。通过示例代码和图解,详细阐述了这些概念及其应用。
64 1
|
3月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
3月前
|
存储 C语言
C语言:设置地址为 0x67a9 的整型变量的值为 0xaa66
在C语言中,可以通过指针操作来实现对特定地址的访问和赋值。要将地址为 0x67a9 的整型变量值设为 0xaa66,可以先定义一个指向该地址的指针,并通过该指针对该内存位置进行赋值操作。需要注意的是,直接操作内存地址具有一定风险,必须确保地址合法且可写。代码示例应考虑字节序及内存对齐问题。