菜鸟联盟:奇怪的数组

kingofark 2000-12-19 01:26:00
加精
请看下面这段C++程序:

#include <iostream.h>

int main()
{
int a[] = {1, 3, 5, 7, 9};
int i;
cin >> i;
int& ref = a[i];
ref = 55;
cout << a[i] << endl;
return 0;
}

其实这只是张国锋的C++教材中说明'引用'的功能的一个简单例子.但是,在 Borland C++ 3.1 上运行时,我发现其中不管变量 i 输入什么合法值,程序都正确得出结果.(当然, i 的输入值必须在其类型所规定的范围内,也要符合数组下标的规定,比如这里的 i 的合法值为 0 - 65534).
照我想,虽然定义数组 a 的时候没有指明大小,但是由于对其赋了初值 {1,3,5,7,9},所以应该还是等于确定了数组的大小。各种C++教材上都没有对这种不确定大小的数组定义讲的很清楚,而其中有一本书上说,不指明大小的数组在定义的时候赋了初值,也就相当于确定了数组的大小。

实在是不明白这是怎么一回事。

又及:这可不是kingofark我出的题目!我也不知道答案的!希望菜鸟联盟的各位能想一想,更希望有高手做一回我们菜鸟联盟的嘉宾,给我们解解惑!谢谢!
...全文
172 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
enterzhuang 2001-05-26
??????
  • 打赏
  • 举报
回复
enterzhuang 2001-05-26
??????
  • 打赏
  • 举报
回复
enterzhuang 2001-05-26
??????
  • 打赏
  • 举报
回复
enterzhuang 2001-05-26
??????
  • 打赏
  • 举报
回复
enterzhuang 2001-05-26
??????
  • 打赏
  • 举报
回复
enterzhuang 2001-05-26
??????
  • 打赏
  • 举报
回复
kingofark 2000-12-20
谢谢bounce和softsprite!! 你们的话非常有价值,给了我很多思考. 当然也谢谢其他鼓励我的人.
  • 打赏
  • 举报
回复
comanche 2000-12-19
倒……
  • 打赏
  • 举报
回复
bounce 2000-12-19
关于数组定义:
int a[]={1,3,5,7,9};定义后,系统默认的值是:
a[0]=1,a[1]=3,a[2]=5,a[3]=7,a[4]=9
按照你所写的程序,不管输入i的值为多少,输出都是55。请看以下例子:
#include <iostream.h>
void main()
{
int a[]={1,3,5,7,9};
int i;
for(i=0;i<=5;i++)
cout<<a[i]<<endl;
}
输出答案为:1 3 5 7 9 但是把for(i=0;i<=5;i++)这一行改为
for(i=0;i<=10;i++)输出的结果变为:1 3 5 7 9 0 373 0 0 0 如果再变为
for(i=0;i<=18;i++)输出的结果变为:1 3 5 7 9 0 373 0 0 0 0 0 30036
25202 8303 11075 8235 8237 28483这样的话,如果在程序尾再加一句:
cout<<a[18]<<endl; 输出的结果最后就多了一个值:28483,也就是说数组的值
是随时会改变的。 如果把你的程序改为:
#include <iostream.h>
int main()
{
int a[] = {1, 3, 5, 7, 9};
int i;
cin >> i;
cout << a[i] << endl;
return 0;
}
若输入18,输出为28483,即a[18]=28483,而你的程序里加了int& ref=a[i];
ref=55后,若输入i=18,a[18]=55,不等于28483了其他情况也一样。
  • 打赏
  • 举报
回复
sxbyl 2000-12-19
Faint!! 那本书难道没说数组越界访问的问题?扔了算了。在C/C++中访问数组一定要小心,在这个例子中你的i最大只能取4,否则鬼知道会出什么事。
btw:这里i最大只能取到32767,因为它是带符号的。
  • 打赏
  • 举报
回复
U皮特U 2000-12-19
c++中数组其实就是内存指针的一种形式,int a[18] 等价 (int*) a+18。从下面的汇编码可以看出,c++没有检查是否越界,直接用首指针加上偏移得到目标地址,如i = a[18]和i=a[3]那两行。

你的程序中a[]已经赋了初值,其实已经是确定大小的数组了,从下面int i = sizeof(a);可以看出在编译的时候已经将大小确定为14h了。如果未赋初值,则必须用new分配指定大小,否则不能通过编译。
int a[] = {1,3,5,7,9};
mov dword ptr [ebp-14h],1
mov dword ptr [ebp-10h],3
mov dword ptr [ebp-0Ch],5
mov dword ptr [ebp-8],7
mov dword ptr [ebp-4],9
int i = sizeof(a);
mov dword ptr [ebp-18h],14h
i = a[3];
mov eax,dword ptr [ebp-8];
mov dword ptr[ebp-18h], eax
i = a[18];
mov ecx,dword ptr [ebp+34h];
mov dword ptr[ebp-18h], ecx
  • 打赏
  • 举报
回复
Winsky 2000-12-19
伙计,你把数据段中的数都改乱了,你的程序怎么没有死机?怪事!C/C++是不检测数组越界的,难道你不知道?
  • 打赏
  • 举报
回复
相关推荐
发帖
C语言

6.6w+

社区成员

C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
帖子事件
创建了帖子
2000-12-19 01:26
社区公告
暂无公告