晕了,常量竟然不能作为静态数组的大小??

FengPrince 2012-11-29 05:04:25
int i=1;
int j=(int)&i;
int a[(int)&i];
为什么(int)&i作为常量可以为全局变量j初始化,却不能作为静态数组的大小。

好奇怪啊,何解???
...全文
772 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
猴头 2012-11-30
  • 打赏
  • 举报
回复
define 预定义
失散糖 2012-11-30
  • 打赏
  • 举报
回复
奇怪的人,常常会做出一些奇怪的事,这一点都不奇怪
assassin5616 2012-11-30
  • 打赏
  • 举报
回复
引用 21 楼 supermegaboy 的回复:
引用 18 楼 FengPrince 的回复: 引用 17 楼 supermegaboy 的回复:引用 楼主 FengPrince 的回复:int i=1; int j=(int)&i; int a[(int)&i]; 为什么(int)&i作为常量可以为全局变量j初始化,却不能作为静态数组的大小……
确实很牛叉啊,这些东西都怎么记下来的? 工作中遇到这种问题,我都是一句话编辑器就这么做的,但如果能说这么多道理出来,肯定能赢得不少仰慕
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 24 楼 ForestDB 的回复:
地址在编译期向来不是常量,只是相对偏移。连接器的作用才是确定这些地址的最终值。
常量与偏移不偏移没有关系,事实上,连接后生成的二进制程序里的地址仍是相对地址。 只有真正运行时才会得到绝对地址,但编译期相对地址已经固定了。
ForestDB 2012-11-29
  • 打赏
  • 举报
回复
地址在编译期向来不是常量,只是相对偏移。连接器的作用才是确定这些地址的最终值。
飞天御剑流 2012-11-29
  • 打赏
  • 举报
回复
引用 18 楼 FengPrince 的回复:
引用 17 楼 supermegaboy 的回复:引用 楼主 FengPrince 的回复:int i=1; int j=(int)&i; int a[(int)&i]; 为什么(int)&i作为常量可以为全局变量j初始化,却不能作为静态数组的大小。 好奇怪啊,何解??? 你有两个误……
一、对!数值类型和指针类型合称标量类型; 二、打个比方吧,例如A + B,要求A和B是常量表达式,但并不要求A + B的结果也是常量表达式。 例如你自己的例子,int j=(int)&i;是合法的,但int j=(int)&i + ( int )&i;就是非法的,因为(int)&i不是常量表达式。 此外,在标准C/C++中,常量和常量表达式不是同一种东西,常量是常量,常量表达式是常量表达式,最好不要搞混乱了,例如&i是常量表达式,但不是常量。
AnYidan 2012-11-29
  • 打赏
  • 举报
回复
supermegaboy 整天都看什么书!?
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 16 楼 rxin423355541 的回复:
引用 14 楼 FengPrince 的回复:引用 13 楼 l821829886 的回复:正解: 因为(int)&i是i的地址、存储在内存的栈区、并非存储在静态区的常量,非常量不能用来初始化数组的大小,结果导致编译不通过!!! 可以看看栈区、堆区、静态区的存储区别。 静态区与常量有半毛钱关系吗?好像是木有吧。。。 如果你非要说常量存储在……
C语言的全局变量、静态变量是编译期求值吧,至于C++的类对象、部分const变量才是在运行时的main之前求值的。
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 17 楼 supermegaboy 的回复:
引用 楼主 FengPrince 的回复:int i=1; int j=(int)&i; int a[(int)&i]; 为什么(int)&i作为常量可以为全局变量j初始化,却不能作为静态数组的大小。 好奇怪啊,何解??? 你有两个误区,一是以为由常量表达式通过一定运算得出的结果也属于常量表达式,这个观念是……
早就有所耳闻 supermegaboy大神C/C++很牛B,确实名至实归。 针对你提出的两点,我仍有不解: 一,广义来说,数值类型都属于标量类型吧,不止指针吧; 二,也是最关键的,我不明白你说的"常量表达式不一定要作为完整表达式出现"的意思,你说的各个子表达式必须为常量表达式是指,子表达式&i是常量,子表达式(int)强制类型转换也是常量表达式,但整个表达式却不是常量。 恕我愚钝,我不明白你说的意思,能否再详细点?? 万分感谢。。。。
飞天御剑流 2012-11-29
  • 打赏
  • 举报
回复
引用 楼主 FengPrince 的回复:
int i=1; int j=(int)&i; int a[(int)&i]; 为什么(int)&i作为常量可以为全局变量j初始化,却不能作为静态数组的大小。 好奇怪啊,何解???
你有两个误区,一是以为由常量表达式通过一定运算得出的结果也属于常量表达式,这个观念是错的。&i的结果是地址常量表达式这个没错,但是( int )&i的结果却非整数常量表达式,因为在C中(C++也类似,但有细微差别),显式转换产生的整数常量表达式只能由数值类型转换而来,何谓数值类型?就是整数类型和浮点类型,&i的结果是个指针,属于标量类型,但不是数值类型。即: int a[(int)18.2]是合法的,但int a[ (int)&i ]不是合法的 但是,你可能会产生另一个疑问,既然(int)&i不是常量表达式,为什么可以用来初始化j? 在这里你存在第二个误区,以为具有静态存储周期的变量的初始化器必须是常量表达式(也是很多书的误区),非也。 C仅规定构成静态存储周期变量的初始化器或初始化列表中的所有表达式应为常量表达式,但并无规定必须作为一个完整表达式出现,即,仅要求各个子表达式必须是常量表达式,因此int j=(int)&i是合法的。
rxin423355541 2012-11-29
  • 打赏
  • 举报
回复
引用 14 楼 FengPrince 的回复:
引用 13 楼 l821829886 的回复:正解: 因为(int)&i是i的地址、存储在内存的栈区、并非存储在静态区的常量,非常量不能用来初始化数组的大小,结果导致编译不通过!!! 可以看看栈区、堆区、静态区的存储区别。 静态区与常量有半毛钱关系吗?好像是木有吧。。。 如果你非要说常量存储在静态区,我无话可说。 i的地址编译期就可以确定,比如……
i的地址需要在运行时绝对定位,你自己也说了,再说常量你不是前后矛盾? int j=(int)&i,会这句代码会被内联入main函数之前,所以全局变量是在运行时赋值. 静态数组大小必须要在编译时确定
Lactoferrin 2012-11-29
  • 打赏
  • 举报
回复
i是静态的还是?
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 13 楼 l821829886 的回复:
正解: 因为(int)&i是i的地址、存储在内存的栈区、并非存储在静态区的常量,非常量不能用来初始化数组的大小,结果导致编译不通过!!! 可以看看栈区、堆区、静态区的存储区别。
静态区与常量有半毛钱关系吗?好像是木有吧。。。 如果你非要说常量存储在静态区,我无话可说。 i的地址编译期就可以确定,比如说,0X0CCCCC,就相当于一个字面值,即为常量。 不然,全局变量j何以能够被初始化?
lws_AZ 2012-11-29
  • 打赏
  • 举报
回复
正解: 因为(int)&i是i的地址、存储在内存的栈区、并非存储在静态区的常量,非常量不能用来初始化数组的大小,结果导致编译不通过!!! 可以看看栈区、堆区、静态区的存储区别。
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 8 楼 longburulin 的回复:
没错 i的地址是运行时分配的,连编译都不通过(因为数字中的是变量),所以出现3个errors了
i的地址编译期能够确定,只不过是相对地址罢了,绝对地址只有到运行期才能确定。
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 6 楼 baichi4141 的回复:
第一,4楼的回答是正确的。 第二,看到5楼,我没兴趣解释任何东西。
请你告诉我,4L哪对了? 说了跟没说不一样吗?我肯定知道,编译器提示非常量,我问的是为什么? 在初始化 int j=(int)&i;时是常量,即编译期确定其值,否则编译出错; 既然是常量,用来指定静态数组大小有何不可??
FengPrince 2012-11-29
  • 打赏
  • 举报
回复
引用 9 楼 ForestDB 的回复:
凭什么认为(int)&i是常量?
第一,&i是地址常量,编译时可以确定 ;类型转换编译时仍能完成; 第二,全局变量int j=(int)&i没有错误也可以证明,如果(int)&i不是常量,这条语句就会报错。
ForestDB 2012-11-29
  • 打赏
  • 举报
回复
凭什么认为(int)&i是常量?
longburulin 2012-11-29
  • 打赏
  • 举报
回复
没错 i的地址是运行时分配的,连编译都不通过(因为数字中的是变量),所以出现3个errors了
骁Captain 2012-11-29
  • 打赏
  • 举报
回复
引用 6 楼 baichi4141 的回复:
第一,4楼的回答是正确的。 第二,看到5楼,我没兴趣解释任何东西。
++
加载更多回复(6)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧