| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 919 人关注过本帖
标题:问一个关于const变量的问题
只看楼主 加入收藏
果沫
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:198
专家分:960
注 册:2013-1-30
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:10 
问一个关于const变量的问题
==================================================================================
编译器通常不为普通const 只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。例如:

#define M 3 //宏常量
const int N=5; //此时并未将N 放入内存中
......
int i=N; //此时为N 分配内存,以后不再分配!
int I=M; //预编译期间进行宏替换,分配内存
int j=N; //没有内存分配
int J=M; //再进行宏替换,又一次分配内存!

=================================================================================
const 修饰符也可以修饰函数的返回值,返回值不可被改变。例如:
const int Fun (void);
==================================================================================
以上是我在教程上看到的,有几个问题问一下,int i=N /*此时为什么是为N分配内存,而不是为i ?*/按道理来说定义一个变量,应该是为那个变量分配一段内存空间啊,为什么这个时候是为const变量N分配空间,而不是为i分配


int j=N /*为什么此时没有内存分配?*/ 定义一个变量的时候不是应该要给他分配内存空间的么 为什么他这说没有内存分配


什么叫返回值不可被改变?不能理解这句话,返回值就是返回一个值,为什么说什么改变不改变的?希望明白的能举例说明一下,学C时间还不长,所以存在不少问题,请多指教

[ 本帖最后由 果沫 于 2013-1-30 15:21 编辑 ]
搜索更多相关主题的帖子: 内存 编译器 
2013-01-30 15:09
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:5 
什么教材?
我不是想鄙视其观点的错误,我是想鄙视这种行为本身,就像那些研究++i+++i的家伙
a. 在C中(C++中不是这样),N只是只读,而非编译期常量
b. 混淆了标准和实现的区别
c. 混淆了表观一致性和优化的关系
2013-01-30 15:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
呵呵,这就叫走火入魔,太多人学C进入了这种误区。

授人以渔,不授人以鱼。
2013-01-30 15:35
果沫
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:198
专家分:960
注 册:2013-1-30
收藏
得分:0 
回复 3楼 TonyDeng回复 2楼 rjsp
好吧= =  那能帮忙解释下第二个问题什么意思么,什么叫返回值不可被改变
2013-01-30 15:49
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:15 
const 修饰符也可以修饰函数的返回值,返回值不可被改变。例如:
const int Fun (void);

这种翻译和表述真的很有问题,都不知道是翻译者问题还是表述者本身的问题。所谓返回值,通常是指函数的返回值,所以你也看到举例是函数。对
const int Fun(void);
其实可以等量替换为
const int x;
这是在调用函数Fun()的时候会使用的语句,即
x = Fun();
这样,编译器极可能要求你声明
const int x;
表明x应该是一个只读常量。
通常,这种const返回值,是应用于指针的,它表明返回的指针所指向的数据,不应该被修改——比如函数Fun()是读取ROM中的数据,就会这样向调用者声明,“你不应该试图修改我返回给你的数据,出错了是你的事”。

实际上,const只是一种修饰符,声明为const的变量,只是编译器在编译期间认为这种变量不应该被修改,适时提出警告。但在实际的编程中,程序员是有办法绕开这种修饰而强硬修改数据的(很多C程序员以此炫耀技术)。正确的用法是:你尽量地使用这种修饰符,并遵守它的要求写程序,编译器会帮助你实现目的,那种喜欢强制转换的习惯必须戒掉。

授人以渔,不授人以鱼。
2013-01-30 16:04
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
真实的情形是,函数的返回值只是一个临时变量,这个数据在函数执行结束后就被废弃(假如你不用什么变量接收并储存这个值,它就被当垃圾回收了),不存在什么只读不只读的问题。上面“教程”中的那种说法,本来应该是函数的返回值赋给的变量应是只读量,只是“应该”而已。

所有用const修饰的,都是“应该”、“被视为”。

授人以渔,不授人以鱼。
2013-01-30 16:23
果沫
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:198
专家分:960
注 册:2013-1-30
收藏
得分:0 
回复 6楼 TonyDeng
我刚刚试了一下
fun()为一个被const修饰的函数
int a=fun();
没出错
但按你的说法应该要用
const int a=fun();
才行吧
2013-01-30 16:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
是的,不同编译器有不同的检查水平,有的会提示警告,有的不会。因为把只读的数据赋给可变的变量,在语法上是允许的,不出警告也可以,但作为程序员自己,是必须要警醒函数原型中给出的const是什么意思,如果你觉得可以无视,就能无视它,如果觉得值得注意,就注意它,这取决于你。一旦你确定无视某些东西,就是在假定了点什么前提,那么,如果出了问题,也必定是这些假定出了意外,排查错误的时候,就会返回来知道错误大致在什么地方了。不出错,运气好,程序可以长时间地这样运行下去,不过是带隐患操作罢了——绝大多数运行中的程序都是这种状态,高手与低手的差别,只是谁的隐患更少。人家后期推出的高级语言,为什么会加入大量的保险措施而不惜牺牲效率,就是为了避免隐患,不然都像C这样,假定程序员不会犯错,效率当然高了,不过实际上是程序员犯错是最普遍不过的现象了。

授人以渔,不授人以鱼。
2013-01-30 16:39
果沫
Rank: 8Rank: 8
等 级:蝙蝠侠
帖 子:198
专家分:960
注 册:2013-1-30
收藏
得分:0 
回复 8楼 TonyDeng
  谢谢啦,你这么一说清楚一些了,刚学经常会遇到些理解不了的问题。
2013-01-30 16:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
学习的时候,一定要培养仔细审视函数原型的习惯。比如最经典的陷阱,库函数getchar(),它的函数原型返回值是int,而不是它的名字暗示你的char,一旦你无视这个返回类型,就会把返回值赋给char变量使用,这个时候,错误就埋伏好了。这个例子也是一样的,如果你曾经读到过getchar()陷阱之类的资料,就应该懂得迁移到这方面去。

使用人家写的函数,库函数也好,将来团体合作同伴提供的函数也好,都要遵守这种编程规范,自己写的函数,好好想清楚参数和返回的形式,这就是编程界面(给别人使用的代码界面),不能马虎的。人家明明写着int getchar(void),你无视,出错也只能怪自己,而不要想当然人家多此一举;你写的,别人也同样尊重你。凡事必有因,这点必须牢记!

[ 本帖最后由 TonyDeng 于 2013-1-30 16:55 编辑 ]

授人以渔,不授人以鱼。
2013-01-30 16:53
快速回复:问一个关于const变量的问题
数据加载中...
 
   



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

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