初学者对const的认识(常类型变量)

  const也是一个初学者很少会用到的关键字。就像我,看了一些程序,发现好多地方都会加个const。当时不理解啊,写个程序一试,发现果然没什么用(心想,多此一举啊,难道我发现个惊天大秘密?)。随着对C语言的日益了解,我才开始明白const的妙用,在查阅一些资料后也开始尝试使用const,发现其果然还是有大用处啊。

const

  const 是constant 的缩写,是恒定不变的意思,也翻译为常量、常数等,被它修饰的变量将不可作为左值,不可被改变,不可被赋值。但是查阅了一些资料,对const有两种不同的说法。
  第一种是广为人知的说法是,const修饰的数据类型是指常类型,其修饰的变量为常类型变量很多文章都将其定义为常量,据我查阅和分析,不能理解为常量。随后我会进行更加细致的分析。)。常类型的变量或对象的值是不能被更新的。第二种说法是被const修饰的变量为只读,而非常量(不怎么赞同)。

1.修饰一般变量:

const int a=1;

  这应该是看着最为常见的用法了,其意思就是说将a定义为了常类型变量。a将不可作为左值,不可被改变,不可被赋值。

2.修饰指针:

常类型变量指针

const int *p
int const *p

  const在*号左边,此为常类型变量指针。常类型变量是形容词,指针是名词,以指针为中心的一个偏正结构短语。这样看,常类型变量指针本质是指针。

int a=0;

const int *p=&a; 

a=1; //编译通过
*p=1; //编译会报错

  指针指向的地址中的值将不能被这一指针所改变。a为整型变量,所以修改它的值是不会有任何问题的。但是p指针被修饰为了常类型的指针,所以是不能利用p指针修改它所指向的内存中存储的值。

指针常类型变量

int *const p

  const在*号右边,此为指针常类型变量.指针是形容词,常类型变量是名词。这回是以常类型变量为中心的一个偏正结构短语。那么,指针常类型变量的本质是一个常类型变量,而用指针修饰它,那么说明这个常类型变量的值应该是一个指针。

int a=3;
int b=3;
int * const p=&a;

*p=5; //编译通过
p=&b; //编译时报错

  指针也是存在内存中的一个值,它的值就是他所指向的内存空间的地址,所以如果指针的值不能发生改变,那么它就不能指向别的内存地址。

指向常类型变量的指针常类型变量

const int * const p

  顾名思议吧,真要说起来会很绕。相信理解了上面两个的,应该可以无师自通了。

int a=3;
int b=3;
const int *const p=&a;

*p=5; //编译时报错
p=&b; //编译时报错

  集以上两种特性于一身。既不能利用指针修改它所指向的内存中存储的值,也不能指向别的内存地址。

3.修饰字符串常量:

  字符指针是指向一个声明在静态数据区的字符串,它是一个字符串常量,字符串常量是不允许改变,所以其只能整体改变指针指向。但是…

char *pstr=”hello world”;
pstr[0]='A';//编译通过

  不过执行是会报段错误,这样就出大问题了,段错误可是最难处理的了,我们很难找到问题出在哪里。
  如果加上const,那就可以放心了。如果我们再不小心做了这错误的操作(尤其对新手),就不用担心段错误了。他会在编译时直接报错,这也大大增加了程序的健壮性。

const char *pstr=”hello world”;
pstr[0]='A';//编译时报错

4.修饰函数参数:

  给函数的参数加上const修饰,便于编译器进行类型检查,使编译器对处理内容有更多了解,可以保护被修饰的参数,防止意外的修改,消除了一些隐患。增强程序的健壮性。

void func(const int i)
{ 
    i=10;//编译时报错
} 

  如果你不需要修改传进来的参数的值,那就加个const吧。

5.提高了效率:

  编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
  同时还可以节省空间,避免不必要的内存分配。

#define PI 3.14159 //常量宏 
const double Pi=3.14159; //此时并未将Pi放入ROM中

double i=Pi; //此时为Pi分配内存,以后不再分配! 
double I=PI; //编译期间进行宏替换,分配内存 
double j=Pi; //没有内存分配 
double J=PI; //再进行宏替换,又一次分配内存! 

  可以看出const定义的常类型变量在程序运行过程中只有一份拷贝。而#define只是单纯的文本替换,所以每为一个变量赋值就会生成一个拷贝。

注意:

  前面我一直所说的都是常类型变量,也有将其称为常变量的。之所以这么称呼,是因为被const修饰的变量并不为常量。例如:

const int n = 5;
int array[n];//编译时报错

  我们都知道在ANSI C中规定数组定义时长度必须是“常量”。这就证明被const修饰并不会使其成为常量。
  常量是像5, “abc”,等,肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。而只读变量则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。其实const就是用来限定一个变量不允许被改变的修饰符。所以我觉得他也并不是只读变量

总结:

  作为一个菜鸟,感觉con不const都一个样啊,并没有区别,实则不然。如想编程功力有所精进,必先深谙其韵。

  初来乍到,有疏漏的地方望各位大牛多多指教~~

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值