const-只读变量-常量

之所以引出这个问题,是因为最近在看C语言运行时各种变量的内存分区情况,不太明确const 修饰的变量和字符串常量/数字常量等这些量是否存储在一起。

只读变量:const修饰的变量,准确来说是只读变量,其实际上是可读可写的,只不过写的实现需要借助于指针,存储在栈区域,如果是在函数内部定义的。

常量:“hello”这种的才是真正的常量,存储在静态内存中的常量存储区,由系统进行管理。

#include <stdio.h>
#include <string.h>


int main(void)
{
	
	int n = 2;
	int* pn = &n;
	printf("int n address is  %d\n", pn);
	printf("\n");

    const int i = 3;
    //i是只读变量,但仍然是一个变量,存储在堆栈这种动态存储区,由编译器负责
	int* p = &i;//i毕竟是一个变量,初始化后不能通过直接赋值来改变i的值,因为前面加了
//const,C语言语法上不允许再对其进行直接赋值。通过指针可以改变其值,const就是一个限定修
//饰符,不改变i仍然是一个变量的性质。
	*p = 200;//通过指针修改const int i的数值
	printf("const int i aggress is %d\n", p);
    printf("const int i is %d\n", i);
	printf("\n");

	char* c = "helloworld";//这才是真正的常量,是由系统管理的,编译器管不到。
	printf(" helloworld address is %d\n", c);
	
	
	
	return 0;
}

输出结果:

int n address is  15988844

const int i aggress is 15988856 //可以看到const int i和int n是存储在一块区域中的,栈区域。
const int i is 200    //通过指针修改了const int i的数值

 helloworld address is 8215608//字符串常量存储在另一个区域,也就是静态存储区中的常量存储区。由系统负责。

详情参考https://blog.csdn.net/csdn_lsd/article/details/78419203

看完上面这些,基本已经可以说服自己,原来const修饰的变!量!也是可以修改的,下面再看这句话:

const是语言特性,不能通过const修饰的名称去修改对应的内容,但是并不是不能修改。因为编译器实现的时候,并没有规定要放到只读区。举个例子:
int a = 5;
const int* b = &a;
此时不能通过b修改地址&a中的值,但是依旧可以把a重新赋值。地址&a中存放的值就改变了。

可能你会疑惑,常量指针,指针常量,一会能用指针修改const限定的值,已经晕头转向了。其实,也不用过分纠结,为什么一会指针能修改,一会又不能修改了,你可以理解为这就是C语言的语法,之所以看起来有些复杂,是因为要多定一些规则满足各种各样的需求。

//================const修饰的量仍然还是变量,不能用于定义数组=========

在定义数组时,必须明确指明数组大小,或者通过对数组元素进行初始化的方式让编译器获取数组大小,如int a[5]; char a[]={'a','b','c'},不能使用变量作为数组的大小。下面这个例子就可以说明const修饰的量,虽然我们习惯上称之为是常量,但实际上其只是只读变量,是可读可写的,写通过指针进行,之所以是这样,这就是const对变量的限制作用,记住即可。

下面看例子,说明const修饰的量仍然是一个变量而非常量,其不能用来定义数组大小。const修饰的量是只读变量,仍然是存储在动态存储区的栈中。

#include<stdio.h>
#include<string.h>

//#define MAX 3
int main(int argc,char* agrv[])
{
	const int max = 3;
	
	int a[max] = { 1, 2, 3 };

这里提示错误:数组大小应为常量值,不能定义大小为0的数组。
这个错误说明max并不是一个常量,那么max是什么?使用const修饰的只读变量,什么样的才是常量:
int a[3]={1,2,3};//数字3才是真正的常量,其是不可更改的,放在系统存储区中,编译器是无权管理的。


	return 0;
}


改成下面的代码,用预定义define的方式可以引入一个真正的常量,下面的代码就是正确的。

#include<stdio.h>
#include<string.h>

#define MAX 3
int main(int argc,char* agrv[])
{
	
	int a[MAX] = { 1, 2, 3 };//MAX表示的3这个数字,才是真正意义上的常量
	return 0;
}

 再次明确:const修饰的量实际上不是真正意义上的常量,是一个只读变量,存储在栈中,可以通过地址修改数值。数组大小的定义,一定要用常量,这个常量是真正意义上的常量,就是不可改变的数字,或者不知名大小,对元素进行初始化来定义数组。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小哇123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值