新手关于指针和数组二问。

Dan1980 2006-05-07 05:28:53
1. 到底有没有办法得到数组的确切长度?我知道数组名代表的是数组首元素的地址,那么数组的长度到底有没有被记录呢?如果没有,那么:

int i[10];
cout << sizeof i; //输出40,即4*10,10个int的长度

好像从数组名中可以直接得到数组的长度嘛。那为什么很少有人用这种方法来检查数组的边界,而通常用常量呢?

2. 用指针访问数组元素是不是确实比用下标访问快?比如:

char s[] = "hello, world!";

for(int i = 0; s[i] != 0; i++)
s[i];

for(char* p = s; *p != 0; p++)
*p;

上面两种在效率上还有没有差别?
...全文
166 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenhu_doc 2006-05-08
  • 打赏
  • 举报
回复
师父把汇编都拉出来了哦
???

师傅?
ugg(逸学堂(exuetang.net)) :收徒弟了??
shenmea00000 2006-05-08
  • 打赏
  • 举报
回复
师父把汇编都拉出来了哦
做鸡真好吃 2006-05-08
  • 打赏
  • 举报
回复
??
jixingzhong 2006-05-08
  • 打赏
  • 举报
回复
第一个问题,
问题在于 数组名 在作为函数参数传递后会退化为一个普通指针,这个时候用 cout << sizeof i;就可以发现输出的东西 ....

所以基本不会用这种方法来检查数组的边界,因为根本不可行 ....
jixingzhong 2006-05-08
  • 打赏
  • 举报
回复
恩 ,第二个问题如 ugg 所言,
下标方式最后还是以指针方式去访问的,
但是这个转变在编译的时候就完成了,所以其实两种方式一样 ....

但是假设没有这个转化的话,
那么,
说用指针方式快一点也是可以理解的 ...
逸学堂 2006-05-07
  • 打赏
  • 举报
回复
好像从数组名中可以直接得到数组的长度嘛。那为什么很少有人用这种方法来检查数组的边界,而通常用常量呢?
~~~~~~~~~~~~~····
检查数组长度是sizeof ( array ) / sizeof (array[0])
对于一个数组都进行这种越界检查是不是很麻烦,这种方式不是做不到,是以牺牲效率为代价的,
当给一个数组赋值时,每次都有检查是否越界。并且当使用一个指针执行数组时,如果指针指向的
起始位置不是数组开始位置,这时候对指针做边界检查,根本就不会起到任何作用。


2. 用指针访问数组元素是不是确实比用下标访问快?
~~~~~~~~~~~
至于说快慢,可以反汇编一下看看代码。不过这不能说明什么,经过编译器优化后,这两种方式
效率是相同的。
两者汇编代码如下(具体问题具体分析,这只是一种情况的汇编代码)
9: for(int i = 0; s[i] != 0; i++)
0040104C mov dword ptr [ebp-14h],0
00401053 jmp main+4Eh (0040105e)
00401055 mov ecx,dword ptr [ebp-14h]
00401058 add ecx,1
0040105B mov dword ptr [ebp-14h],ecx
0040105E mov edx,dword ptr [ebp-14h]
00401061 movsx eax,byte ptr [ebp+edx-10h]
00401066 test eax,eax
00401068 je main+5Ch (0040106c)
10: s[i];
0040106A jmp main+45h (00401055)
11:
12: for(char* p = s; *p != 0; p++)
0040106C lea ecx,[ebp-10h]
0040106F mov dword ptr [ebp-18h],ecx
00401072 jmp main+6Dh (0040107d)
00401074 mov edx,dword ptr [ebp-18h]
00401077 add edx,1
0040107A mov dword ptr [ebp-18h],edx
0040107D mov eax,dword ptr [ebp-18h]
00401080 movsx ecx,byte ptr [eax]
00401083 test ecx,ecx
00401085 je main+79h (00401089)
13: *p;
00401087 jmp main+64h (00401074)



bombwang 2006-05-07
  • 打赏
  • 举报
回复
2好像没什么区别吧
ENOUGH_XU 2006-05-07
  • 打赏
  • 举报
回复
2.其实,两者在效率上是没差别的,就是你如果用数组名,那么你就必须用一个变量来做下标,使地址变化,而你用指针,那么指针是可以变的,如p++,而数组名则不可以,因为他是const的
king_water 2006-05-07
  • 打赏
  • 举报
回复
除了地址以外,绝对没有长度信息
长度正如上述是sizeof计算出的

数组名和其他的变量一样,编译时也加入了符号表,sizeof通过在符号表中找到数组名这个变量,然后看看他占有的空间返回一个值而已
Dan1980 2006-05-07
  • 打赏
  • 举报
回复
1.int arr[10];
sizeof ( array ) / sizeof ( int )才是数组个数,这样岂不麻烦
---------------------------------------------------------------------------------

嗯,说的也是。

那请问数组名中到底存储了些什么呢?除了地址以外,似乎还有长度信息。这是一种什么机制?
king_water 2006-05-07
  • 打赏
  • 举报
回复
1.int arr[10];
sizeof ( array ) / sizeof ( int )才是数组个数,这样岂不麻烦
2. 效率上没有任何差别

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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