| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 11747 人关注过本帖, 8 人收藏
标题:[原创]C的关键字——const的理解和用法
取消只看楼主 加入收藏
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏(8)
 问题点数:0 回复次数:16 
[原创]C的关键字——const的理解和用法

关于C的关键字——const的理解和用法

const在C中的用法很灵活(相信C++中也一样),个人感觉对之既爱又恨,有时候感觉const很好用,同时又经

常会因为它的优点而犯错,犯错的原因除了粗心之外,另一个更重要的,就是以前对const理解不到位。于是今天

自己写成一篇小总结。如果是初学者,建议好好看一下,相信帮助比较大;如果是高手,请不吝赐教!

上面写了一段废话,就算是小序吧:)接下来就是正文;

一、关于const的具体定义:

——个人感觉很难对它下一个标准的定义,因为的用法很灵活,似乎对它定义后总无法让人能够明白它的

意思,而且容易让人产生误解(也许是偶水平太菜了)。例如,把它有定义:一个能够让变量变成无法修改的常量

的关键字。那么,这样的话,就可能让人误解为只要有const在定义变量里面,那变量就无论怎样都无法修改。这

样的理解是很片面的(下面用法方面将对这问题做探讨)。因此,本人在此不敢对它下定义,其他参考书好象也没

有下定义。

二、关于const的具体作用
——const作用就灵活了,一个表达式中const放置的位置不同,效果可能就不一样了。下面分具体情况分

析(当然,所举的情况并非覆盖全部情况)
A。const最经常的用法
1.为了防止传递的函数参数不被修改,在调用函数的形参中用const关键字.
//Example ->

int FindNum(const int array[], int num, int conut);//声明函数

//code...

int FindNum(const int array[], int num, int count)
{
int i;
int flag = 1;

for (i = 0; (i < count) && flag; i++)
{
if (array[i] == num)
{
flag = 0;
break;
}
}
return flag;
}
//code...

上面这例子中,编译器会把array[]当作常量数据的数组看待。所以,假如你不小心给数组赋值,那么

,编译器就会报错了。因此,当你不需要也不想修改数组的数据时,最好用const把数组定义为常量数组。

2.const可以用来创建数组常量、指针常量、指向常量的指针等:
const char ch = 'a';
const int a[5] = {1, 2, 3, 4, 5};
const int *p = a; //a是一个数组的首地址.p是指向常量的指针
int * const p = a; //a是一个数组的首地址.p是指针常量;
const int * const p = a; //a是一个数组的首地址。p是指向常量的指针常量

前两种情况很简单,现在着重分析一下后三种用法,因为这3种情况容易出错,偶就有时候怕用错了

刚脆不用const.

——const int *p = a; //p是指向常量的指针,因此,不可以通过给指针赋值来改变数组

//中的数据,例如:
// *p = 10; /*错误*/
// *(p + 2) = 1; /*错误*/

//假如指向常量指针可以改变值,那么,就等于也改变了数组的数

//据了。假如你不理解,偶倒有一个办法让你理解,你就想你和一

//个人绑在一起,有可能你移动了位置而他不跟着你移动吗!哈哈

——int * const p = a; //看这表达式,const的位置和第一个不同吧!他们的用法和作用

//就完全不一样了。这时候p是指针常量,我们知道,指针是指向

//了一个数组的首地址,那么,它的位置就不可以改变了。但是你

//现在应该和第一个表达式比较了,现在的数组并不是常量数组,

//所以数组的数据是可以改变的,而指针这时候它是不可以移动的

//,指向数组第一个数据,所以它可以而且只可以改变数组第一个

//数据的值。这一点请别误解,指针常量只是它的地址不可以改变

//,并不是它指向的内容一定不可以改变,这一点切记!

//好啦。假如你又不理解,偶又有一个比较形象的例子来说明:

//假如有一个固定的人拉着另外一个人的手,注意,固定的人相当

//于他是不可以由其他人来替换的。但是他可以拉其他人的手啊,

//并不一定规定他必须拉同一个人的手啊。现在你应该可以有个比

//较深的印象和理解吧:P

//下面举几个例子帮助理解:
// *p = 2; /*可以*/
// *(p+1) = 10; /*可以*/
// p++; /*不可以*/

——const int * const p = a; //假如前面两种表达式的本质你理解了,这种表达式你来理解根本

//没有问题,const现在有两个,而且一个const的位置是第一种情

//况的位置,第二个const是第二种情况的位置,所以这表达式的功

//能就是前两种情况的作用总合。这里不多说!

//下面举几个例子帮助理解:
// *p = 2; /*不可以*/
// *(p + 2) = 10; /*不可以*/
// p++; /*不可以*/

B。const并不会阻止参数的修改

之所以把这作为一点来谈,就是因为有一些朋友可能会以为在函数参数中用了const就一定不可以改变

参数,这实际上是错误的理解,因为,它并不阻止参数的修改,下面举个简单的例子来阐述一下;

#include<stdio.h>
#include<ctype.h>

void ChangeStr(const char *String);

int main(void)
{
char str[] = "The C programme";

Change(str);
printf(str);

system("Pause");
return 0;
}

void ChangeStr(const char *String)
{
char *Source = (char *)String;

while (*Source)
{
*Source = toupper(*Source);
Source++;
}
}

//end

上面的程序把字符串中的每个字符都转换成大写字母了。因为*String把地址给了*Source,而

*Source的值的改变编译器并不干涉,可能有的编译器会发出警告之类。上面的程序只是为了说明const并不会阻止

参数的修改,如果象上面程序那样,个人感觉没什么意义,只会让人容易混乱而已。

关于CONST的用法和理解本人也就只能说这么多了,当然,很可能有更多高级或者少用的用法,由于水平

和经验有限,确实不能再说些什么。

三、参考文献
——《C primer plus 5th》

ID: lj_860603
整理于2006.5.21

搜索更多相关主题的帖子: const 用法 关键 
2006-05-21 16:30
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 

小小总结而已``希望对需要的朋友有帮助


我的原则很简单:不做不喜欢的事!
2006-05-21 17:08
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
以下是引用xxygdufs在2006-5-21 17:57:00的发言:
楼上帖子是楼主逼 我发的

晕,我只是说你学习到东西如果不帮顶我就踩死你```
禁止灌水``


我的原则很简单:不做不喜欢的事!
2006-05-21 18:13
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 

对不起,有个地方写错了 ==》
——int * const p = a;
// *p = 2; /*可以*/

// *(p+1) = 10;/*可以*/ --》这里应该是不可以,改正一下,指针不能移动

// p++; /*不可以*/


我的原则很简单:不做不喜欢的事!
2006-05-22 10:17
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 

谢谢12楼的兄弟。但是最后一点错误,就这句:
注意:pt=&b后, pt的值虽为常量b的地址,但输出却是*pt==3,b==0
==》当你再输入一个数给pt,b也跟着改变;参考下面代码:
--------------
#include<stdio.h>

int main(void)
{
const int a = 2;
const int b=0;
const int *pt=&a;

printf("%d\n", *pt); //2
scanf ("%d",pt); // pt = 4;

printf("%d\n", *pt); // pt = 4;

pt = &b; // pt = 0;

scanf("%d", pt); // pt = 6;
printf("%d %d\n", *pt, b); // pt = 6, b = 6

system("pause");
return 0;
}


我的原则很简单:不做不喜欢的事!
2006-05-22 18:13
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
我认为也没有改变,但是我在DEV-CPP和VC下运行结果都改变了。
这是啥回事?!

我的原则很简单:不做不喜欢的事!
2006-05-22 19:02
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
这帖子咋的又被顶上来啦?
谢谢穆扬提出的宝贵意见
其实,我发现我写的这篇文章这些内容远远没有把const的用法写出来,因为我又发现了在另外一些情况下const的用法。

我的原则很简单:不做不喜欢的事!
2006-06-03 16:16
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
scanf ("%d",pt); //可以。输出*pt==3,b==0。 我认为这是编译器编译时对代码进行了优化造成的
---------------------------------
对,这个我也有想过,不然不同编译器结果应该是一样的。但我的看法是这种用法尽量不要用。

我的原则很简单:不做不喜欢的事!
2006-06-03 16:27
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
以下是引用soft_wind在2006-6-3 17:09:00的发言:
写得还是挺好的,
下面这个更详细些:
http://www.bc-cn.net/Article/kfyy/cyy/jszl/200603/3821.html

都是自己平时没事积累一下经验而已。
汗一个,到今天才知道这个BBS上有其他方面的资料,本来还以为只是一个纯粹的论坛而已。。。


我的原则很简单:不做不喜欢的事!
2006-06-03 17:28
lj_860603
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:714
专家分:0
注 册:2006-1-25
收藏
得分:0 
至于第二个有什么不对吗?
-----------------
第2个问题是指那个转大写那代码吧?
那个和编译器无关的。只是定义了一个临时变量把*String的首地址赋给*Source;
再把*String的每个字符转化为大写,如此而已,只是个人觉得那段代码在实际运用中没啥意义。

我的原则很简单:不做不喜欢的事!
2006-06-03 18:03
快速回复:[原创]C的关键字——const的理解和用法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.016851 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved