c语言中const修饰的到底是常量还是变量
发布时间:2025-05-14 01:44:26 发布人:远客网络
一、c语言中const修饰的到底是常量还是变量
C语言中const修饰的量是常变量,它与普通变量的编译方式一样,唯一的区别是常变量定义后不能做左值。C++中const修饰的才是常量。
1、 const修饰的变量是常量还是变量
对于这个问题,很多同学认为const修饰的变量是不能改变,结果就误认为该变量变成了常量。那么对于const修饰的变量该如何理解那?
这个比较容易理解,编译器直接报错,原因在于“a= 10;”这句话,对const修饰的变量,后面进行赋值操作。这好像说明了const修饰的变量是不能被修改的,那究竟是不是那,那么下面我们把这个例子修改下:
其中最后一句printf的目的是看下变量a的值是否改变,根据const的理解,如果const修饰的是变量是不能被修改的话,那么a的值一定不会改变,肯定还是0。但是在实际运行的结果中,我们发现a的值已经变为97了。这说明const修饰的变量a,已经被我们程序修改了。
那综合这两个例子,我们来分析下,对于第二例子,修改的原因是buf[4]的赋值操作,我们知道buf[4]这个变量已经造成了buf这个数组变量的越界访问。buf数组的成员本身只有0,1,2,3,那么buf[4]访问的是谁那,根据局部变量的地址分配,可以知道buf[4]的地址和int a的地址是一样,那么buf[4]实际上就是访问了const int a;那么对buf[4]的修改,自然也修改了const int a的空间,这也是为什么我们在最后打印a的值的时候看到了97这个结果。
那么我们现在可以知道了,const修饰的变量是不具备不允许修改的特性的,那么对于第一个例子的现象我们又如何解释那。
第一个例子,错误是在程序编译的时候给出的,注意这里,这个时候并没有生成可执行文件,说明const修饰的变量可否修改是由编译器来帮我们保护了。而第二个例子里,变量的修改是在可执行程序执行的时候修改的,说明a还是一个变量。
综上所述,我们可以得出一个结论,那就是const修饰的变量,其实质是告诉程序员或编译器该变量为只读,如果程序员在程序中显示的修改一个只读变量,编译器会毫不留情的给出一个error。而对于由于像数组溢出,隐式修改等程序不规范书写造成的运行过程中的修改,编译器是无能为力的,也说明const修饰的变量仍然是具备变量属性的。
2、被const修饰的变量,会被操作系统保护,防止修改
如果对于第一个问题,有了理解的话,那么这个问题,就非常容易知道答案了。Const修饰的变量是不会被操作系统保护的。
其原因是操作系统只保护常量,而不会保护变量的读写。那么什么是常量?比如“hello world”这个字符串就是被称为字符串常量。
对于这个问题的另一种证明方法,可以看下面这个程序:
printf(“the&a is%p, the buf is%p\n”,&a, buf);
可以发现buf保存的地址是在0x08048000这个地址附近的,而a的地址是在0xbf000000这个地址附近的,而0x08048000附近的地址在我们linux操作系统上是代码段。这也说明了常量和变量是存放在不同区域的,自然操作系统是会保护常量的。
二、c语言里const int 和int 有什么区别,const的作用是什么。
const int&是返回这个数值的一个常量的引用。
而int是返回这个数值的一个拷贝。
int是进行拷贝构造,而const int&是返回的引用。拷贝构造更消耗时间,与此同时还用析构函数。因为产生了一个拷贝,你就可以轻易地修改拷贝的内容。
const int类型一旦定义以后就不能修改,int类型是随时可以修改的。
在取指针方面,const有略复杂的东西,但是常规的、合理的操作不应该涉及到,因为const int是用来保存一些全局常量的,这些常量在编译期可以改,在运行期不能改。
听起来这像宏,其实这确实就是用来取代宏的:#define PI 3.14 const float Pi= 3.14;如果你的代码里用到了100次PI(宏),你的代码中会保存100个3.14这个常数。
鉴于使用常数进行运算的机器代码很多时候会比使用变量来的长,如果你换用100次Pi(const float),程序编译后的机器码里就不需要出现100次常量3.14,只要在需要的时候引用存有3.14的常量就行了。
特别在复杂的运算里,3.14这个常量(其实是无法修改的变量)会被一直装载在寄存器里带来一些性能提升。
constint* p;//p可变,p指向的内容不可变,int const* p;//p可变,p指向的内容不可变。int* const p;//p不可变,p指向的内容可变const int* const p;//p和p指向的内容都不可变。
1、可以定义const常量,具有不可变性。
例如:const int Max=100; Max++会产生错误;
2、便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
例如: void f(const int i){.........}编译器就会知道i是一个常量,不允许修改;
3、可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变!
如1中,如果想修改Max的内容,只需要它修改成:const int Max=you want;即可!
4、可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。还是上面的例子,如果在函数体内修改了i,编译器就会报错;
例如: void f(const int i){ i=10;//error!}
5、可以节省空间,避免不必要的内存分配。
当const修饰的是指针类型,那么指针的值就不能改变,即不能指向其他地址,但是可以通过指针修改其指向地址里面的值。
当const修饰时指针指向的类型时候,那么指针被指向其他地址,但是不能通过指针修改指针里面的值。
使用const修饰的i我们称之为符号常量。即,i不能在其他地方被重新赋值了。注意:const int i与int const i是等价的,相同的,即const与int的位置无所谓。
p=&i2;//此处,p可以在任何时候重新赋值一个新的内存地址。
i2=80;//这里能用*p=80来代替吗?答案是不能
分析:p的值是可以被修改的,即它可以重新指向另一个地址。但是不能通过*p来修改i2的值。
首先,const修饰的是整个*p(注意,是*p而不是p),所以*p是常量,是不能被赋值的。虽然p所指的i2是变量而不是常量;
其次,p前并没有用const修饰,所以p是指针变量。能被赋值重新指向另一个内存地址。
三、c语言中const 是什么意思
可以定义const常量,具有不可变性。
例如:const int Max=100; Max++会产生错误;
便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
例如: void f(const int i){.........}编译器就会知道i是一个常量,不允许修改;
可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变!
如(1)中,如果想修改Max的内容,只需要它修改成:const int Max=you want;即可!
可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。还是上面的例子,如果在函数体内修改了i,编译器就会报错;
例如: void f(const int i){ i=10;//error!}
可以节省空间,避免不必要的内存分配。例如:
const doublePi=3.14159;//此时并未将Pi放入RAM中......
double i=Pi;//此时为Pi分配内存,以后不再分配!
double I=PI;//编译期间进行宏替换,分配内存
double J=PI;//再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干份拷贝。
编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
扩展资料:const是一个C语言(ANSI C)的关键字,具有着举足轻重的地位。它限定一个变量不允许被改变,产生静态作用。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一定帮助。另外CONST在其它编程语言中也有出现,例如Pascal、C++、PHP5、B#.net、HC08 C、C#等。