BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #17155同步于 2008/12/6
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

[合集] 问道C++笔试题? 关于数组的

Xer
2008/12/6镜像同步0 回复
☆─────────────────────────────────────☆ lblz (砺剑) 于 (Sun Oct 26 10:42:39 2008) 提到: int main(int argc, char *argv[]) { int a[]={1,2,3,4,5}; int* p=(int*)(&a+1); cout << "a = " << *(a+1) << endl; //2 cout << "p = " << *(p-1)<< endl; //5 return 0; } 答案是2,5 为啥? ☆─────────────────────────────────────☆ Xer (SL小分队|小x|benogy) 于 (Sun Oct 26 10:59:24 2008) 提到: 因为a的类型是int[5],所以&a+1相当于a+5*sizeof(int),而p为int*,p-1就是a+4,所以为5 【 在 lblz (砺剑) 的大作中提到: 】 : int main(int argc, char *argv[]) : { : int a[]={1,2,3,4,5}; : ................... ☆─────────────────────────────────────☆ corndolly (corndolly) 于 (Sun Oct 26 11:06:45 2008) 提到: &a和a不都是取得数组的首地址吗?有什么区别? ☆─────────────────────────────────────☆ lblz (砺剑) 于 (Sun Oct 26 11:07:23 2008) 提到: 【 在 Xer 的大作中提到: 】 : 因为a的类型是int[5],所以&a+1相当于a+5*sizeof(int),而p为int*,p-1就是a+4,所以为5 &不是取地址吗? &a取的是数组的首地址的地址,&a+1 这样一加就是加一个类型的长度么? 那我定义: int *b; &b+1 是什么呢? ☆─────────────────────────────────────☆ Xer (SL小分队|小x|benogy) 于 (Sun Oct 26 11:08:55 2008) 提到: a本身是数组的首地址,&a[0]是取首地址,&a是取地址的地址,不要混淆了 【 在 corndolly (corndolly) 的大作中提到: 】 : &a和a不都是取得数组的首地址吗?有什么区别? ☆─────────────────────────────────────☆ Xer (SL小分队|小x|benogy) 于 (Sun Oct 26 11:11:32 2008) 提到: 那就是b+sizeof(int*) 【 在 lblz (砺剑) 的大作中提到: 】 : &不是取地址吗? &a取的是数组的首地址的地址,&a+1 这样一加就是加一个类型的长度么? : 那我定义: int *b; &b+1 是什么呢? ☆─────────────────────────────────────☆ corndolly (corndolly) 于 (Sun Oct 26 11:14:23 2008) 提到: #include<iostream.h> int main(int argc, char *argv[]) { int a[]={1,2,3,4,5}; int* p=(int*)(&a+1); cout << "a = " << *(a+1) << endl; //2 cout << "p = " << *(p-1)<< endl; //5 cout<<"&a="<<&a<<",a="<<a<<endl; cout<<"&a+1="<<&a+1<<",p-1="<<p-1<<endl; cout<<"int:"<<sizeof(int)<<endl; return 0; } 运行结果: a=2 p=5 &a=0x22ff50, a=0x22ff50 ... a和&a的结果一样 ☆─────────────────────────────────────☆ Xer (SL小分队|小x|benogy) 于 (Sun Oct 26 11:30:14 2008) 提到: 这个是不是需要强制转换一下?就像要得到char* p="abc"的地址,不能直接写cout<<p而要写cout<<static_cast<void*>(p)一样 其实cout<<typeid(&a).name()<<endl<<typeid(a).name()就可以看到两者的确是不同的类型。 【 在 corndolly (corndolly) 的大作中提到: 】 : #include<iostream.h> : int main(int argc, char *argv[]) : { : ................... ☆─────────────────────────────────────☆ chopin19 (肖邦在世) 于 (Sun Oct 26 11:53:16 2008) 提到: 这道题考德蛮细的阿,学习了 ☆─────────────────────────────────────☆ corndolly (corndolly) 于 (Sun Oct 26 11:58:59 2008) 提到: 强制转换以后结果依然相同,不过利用typeid确实两者是不同的类型 ☆─────────────────────────────────────☆ lvwei811 (DaiDaI) 于 (Sun Oct 26 13:18:31 2008) 提到: int* p=(int*)(&a+1); 主要的疑惑在这吧 我觉得是这样的,a是数组首地址,当&a+1的时候,由于指针的加减运算不是简单的算术运算,而是基于类型所占字节,所以&a+1,实际上是把地址值a加上了整个数组a所占所有字节,现在的a=a+5*sizeof(int),然后进行强制类型转换,转换为int *,减1,就是a=a-1*sizeof(int),最后a指向a[4]=5; 以上只是小菜的猜想,没有在环境下验证 ☆─────────────────────────────────────☆ derkaiser (剑痞忆秋年) 于 (Sun Oct 26 13:43:42 2008) 提到: 个人对地址的地址这个说法保持怀疑 【 在 lvwei811 (DaiDaI) 的大作中提到: 】 : int* p=(int*)(&a+1); 主要的疑惑在这吧 : 我觉得是这样的,a是数组首地址,&a是取数组首地址的地址,当&a+1的时候,由于指针的 : 加减运算不是简单的算术运算,而是基于类型所占字节,所以&a+1,实际上是把地址值a加上 : 了整个数组a所占所有字节,现在的a=a+5*sizeof(int),然后进行强制类型转换,转换为 : int *,减1,就是a=a-1*si : 以上只是小菜的猜想,没有在环境下验证 : ................... ☆─────────────────────────────────────☆ ken1234 (江南) 于 (Sun Oct 26 14:04:09 2008) 提到: *(a+1)就是a[1],*(p-1)就是a[4],执行结果是2,5 &a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int) int *p=(int *)(&a+1);(其实前面那个加不加括号无所谓,加了看着整洁明了一些~~) 则p实际是&(a[5]),也就是a+5 原因如下: &a是数组指针,其类型为 int (*)[5];而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同。a是长度为5的int数组指针,所以要加 5*sizeof(int),所以p实际是a[5]。但是p与(&a+1)类型是不一样的(这点很重要)所以p-1只会减去sizeof(int*) 注意:a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]. ☆─────────────────────────────────────☆ smartbird (smartbird) 于 (Sun Oct 26 14:06:33 2008) 提到: 【 在 derkaiser 的大作中提到: 】 : 个人对地址的地址这个说法保持怀疑 我也怀疑啊,不过加上 5*4,没有错。a和&a都是数组的首地址。 类型不一样而已,a 是 int *,&a是int *[5],如果把 (int *)(&a+1)中的强制转换去掉,vc 6.0 会报错,说 不能从 int *[] 转化为 int * ☆─────────────────────────────────────☆ ken1234 (江南) 于 (Sun Oct 26 14:09:45 2008) 提到: 各种情况我在vc下都试过了,最终发现问题的关键在于&a和a一个值,但是意义不一样~~ ☆─────────────────────────────────────☆ xiaokaimail (King) 于 (Sun Oct 26 14:09:46 2008) 提到: 非常同意您的理解~~ 不知这样想一下可以不: 其实a,&a都是一个指针(地址),只不过它们的基类型不同, a的基类型是int,&a的基类型是int[5]。 因此a的步进为sizeof(int) ,而&a的步进为sizeof(int[5]); 这样a+1指向的便是2,而&a指向的是5的下一个单元(未定义) 因此*(a+1)=2;*(&a+1)=不定值; 再看p 他的基类型是int,因此他的步进为sizeof(int),所以 *(p-1)=5;*p=8(&a+1)=不定值; 以上是个人小结式的想法,见笑了 【 在 lvwei811 的大作中提到: 】 : int* p=(int*)(&a+1); 主要的疑惑在这吧 : 我觉得是这样的,a是数组首地址,&a是取数组首地址的地址,当&a+1的时候,由于指针的加减运算不是简单的算术运算,而是基于类型所占字节,所以&a+1,实际上是把地址值a加上了整个数组a所占所有字节,现在的a=a+5*sizeof(int),然后进行强制类型转换,转换为int *,减1,就是a=a-1*sizeof(int),最后a指向a[4]=5; : 以上只是小菜的猜想,没有在环境下验证 [em21] ☆─────────────────────────────────────☆ xiaokaimail (King) 于 (Sun Oct 26 14:12:55 2008) 提到: 嗯,就是这个意思 理解指针(地址)时要注意两个方面: 1.该指针指向的谁 2.该指针的基类型是什么 其中 指针的基类型决定了他的步进,也就是++p的位置。。步进=sizeof(基类型) 【 在 ken1234 的大作中提到: 】 : 各种情况我在vc下都试过了,最终发现问题的关键在于&a和a一个值,但是意义不一样~~ ☆─────────────────────────────────────☆ ken1234 (江南) 于 (Sun Oct 26 14:13:12 2008) 提到: 这个问题以前我也是没太在意,总以为&a和a对于数组来说是一样的。相同道理我们可以拓展到多维数组的。大家可以在vc下试试~~ 【 在 xiaokaimail 的大作中提到: 】 : 非常同意您的理解~~ : 不知这样想一下可以不: : 其实a,&a都是一个指针(地址),只不过它们的基类型不同, : ................... ☆─────────────────────────────────────☆ byrmaster (byrmaster) 于 (Sun Oct 26 14:29:47 2008) 提到: 领教了 ☆─────────────────────────────────────☆ Xer (SL小分队|小x|benogy) 于 (Sun Oct 26 15:01:31 2008) 提到: 嗯,我觉得应该是这样。&a应该是int (*)[5],也就是指向int[5]类型的指针,上面是我望文生义理解错了…… 【 在 xiaokaimail (King) 的大作中提到: 】 : 非常同意您的理解~~ : 不知这样想一下可以不: : 其实a,&a都是一个指针(地址),只不过它们的基类型不同, : ................... ☆─────────────────────────────────────☆ PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 于 (Sun Oct 26 15:24:31 2008) 提到: C陷阱缺陷有讲类似的东西 我突然有个疑问: &a+1,实际跳过的是sizeof(a)?成立么? ☆─────────────────────────────────────☆ prating (竹下生|久夜) 于 (Sun Oct 26 15:25:25 2008) 提到: 看这个例子,好像是这样。。试验一下 【 在 PtwCJ (鲜的每日C|头像不是我,我是长毛贼~~) 的大作中提到: 】 : C陷阱缺陷有讲类似的东西 : 我突然有个疑问: : &a+1,实际跳过的是sizeof(a)?成立么? : ................... ☆─────────────────────────────────────☆ ken1234 (江南) 于 (Sun Oct 26 16:35:23 2008) 提到: ---对的,这里主要看a代表的是那个对象! 【 在 PtwCJ 的大作中提到: 】 : C陷阱缺陷有讲类似的东西 : 我突然有个疑问: : &a+1,实际跳过的是sizeof(a)?成立么? ☆─────────────────────────────────────☆ lvwei811 (DaiDaI) 于 (Sun Oct 26 17:54:55 2008) 提到: 【 在 PtwCJ 的大作中提到: 】 : C陷阱缺陷有讲类似的东西 : 我突然有个疑问: : &a+1,实际跳过的是sizeof(a)?成立么? 这个是成立的 ps:我没验证,但是理论上肯定是这样 ☆─────────────────────────────────────☆ lvwei811 (DaiDaI) 于 (Sun Oct 26 17:56:38 2008) 提到: 【 在 derkaiser 的大作中提到: 】 : 个人对地址的地址这个说法保持怀疑 其实也可以这样理解: 指针是有级别的,&a是a的上一级,而上一级就是一个数组,计算机和c内部的机制太复杂,只要结果对,怎么理解都无所 ☆─────────────────────────────────────☆ lvwei811 (DaiDaI) 于 (Sun Oct 26 17:58:01 2008) 提到: 【 在 xiaokaimail 的大作中提到: 】 : 非常同意您的理解~~ : 不知这样想一下可以不: : 其实a,&a都是一个指针(地址),只不过它们的基类型不同, : ................... 我就是这么理解的,也可能和c内部的内存管理不一样,但是只要和结果一致,就暂且这么理解吧 不怎么来这个版,看了几页,受益非浅 ☆─────────────────────────────────────☆ Axler (gnraxlash) 于 (Sun Oct 26 18:46:14 2008) 提到: 恩,这个家伙的理解还是有些道理的~~ 【 在 lvwei811 的大作中提到: 】 : int* p=(int*)(&a+1); 主要的疑惑在这吧 : 我觉得是这样的,a是数组首地址,&a是取数组首地址的地址,当&a+1的时候,由于指针的加减运算不是简单的算术运算,而是基于类型所占字节,所以&a+1,实际上是把地址值a加上了整个数组a所占所有字节,现在的a=a+5*sizeof(int),然后进行强制类型转换,转换为int *,减1,就是a=a-1*sizeof(int),最后a指向a[4]=5; : 以上只是小菜的猜想,没有在环境下验证 ☆─────────────────────────────────────☆ ayu (来世做流氓) 于 (Sun Oct 26 19:21:37 2008) 提到: 【 在 PtwCJ 的大作中提到: 】 : C陷阱缺陷有讲类似的东西 : 我突然有个疑问: : &a+1,实际跳过的是sizeof(a)?成立么? 这个说法比较符合逻辑[em68] ☆─────────────────────────────────────☆ Sherice (S.H.E) 于 (Sun Oct 26 23:33:21 2008) 提到: 原来如此…… ☆─────────────────────────────────────☆ passionguo (passionguo) 于 (Mon Oct 27 00:06:33 2008) 提到: 学习了,谢谢 ☆─────────────────────────────────────☆ calmsea (CPPMM) 于 (Mon Oct 27 09:51:09 2008) 提到: a的类型是int [],所以&a的类型是int (*) [],一个指向数组的指针,&a+1指向数组下一行,p的类型是int *,所以指向&a+1(a的第二行)的首地址,p-1则指向a的第一行的最后一个元素 ☆─────────────────────────────────────☆ Flameshark (有盐在先) 于 (Mon Oct 27 11:36:52 2008) 提到: 【 在 calmsea 的大作中提到: 】 : a的类型是int [],所以&a的类型是int (*) [],一个指向数组的指针,&a+1指向数组下一行,p的类型是int *,所以指向&a+1(a的第二行)的首地址,p-1则指向a的第一行的最后一个元素 这个解释仿佛更适合我的理解方式,赞~~~ 学习~~ ☆─────────────────────────────────────☆ xiaolanhaitj (小懒孩) 于 (Mon Oct 27 12:49:15 2008) 提到: 学习。。 ☆─────────────────────────────────────☆ derkaiser (剑痞忆秋年) 于 (Mon Oct 27 13:29:47 2008) 提到: 个人感觉这是这楼里最靠谱的解释 【 在 calmsea (CPPMM) 的大作中提到: 】 : a的类型是int [],所以&a的类型是int (*) [],一个指向数组的指针,&a+1指向数组 : 下一行,p的类型是int *,所以指向&a+1(a的第二行)的首地址,p-1则指向a的第一行 : 的最后一个元素 ☆─────────────────────────────────────☆ nbgaohu (我又很多坏习惯。。。) 于 (Mon Oct 27 17:15:43 2008) 提到: 受教了 ☆─────────────────────────────────────☆ tianma25 (鱼木水杉) 于 (Mon Oct 27 23:37:05 2008) 提到: 问个题外话: 定义int a[]={1,2,3,4,5};输出a是一个地址,但为什么定义char m2[]={'c','+','+','\0'};输出m2是c++,而不是一个地址值? 【 在 lblz 的大作中提到: 】 : int main(int argc, char *argv[]) : { : int a[]={1,2,3,4,5}; : ................... ☆─────────────────────────────────────☆ ericyosho (ericyosho) 于 (Mon Oct 27 23:45:08 2008) 提到: <<被重载 对于int*就是输出地址值,对于char*就是输出数组内容。
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。