c指针和数组不同

主  题: 一道华为面试题
作  者: Aliens (异形们)
等  级: 
信 誉 值: 100
所属论坛: C/C++ C语言
问题点数: 20
回复次数: 17
发表时间: 2007-7-30 0:07:29
   
 
   

文件1里声明全局变量:int array[5];
文件2里声明全局变量:extern int *array;
问在运行时会不会报错,如果会,是在编译时还是在链接时?

  我当时想:两个不一样呀,一个是数组一个是指针,可能会在编译时出错,面试官没说对还是错,接着说,我们的面试就到这儿,等通知吧。
  郁闷呀,回家上机一试,仅仅是声明变量,没有给它们赋值,编译和链接竟然顺利通过,看了一下它们有地址,是相同的。不过还是觉得这题很诡异,于是在文件2里加了一条语句,array[0] = 1;
照旧编译和链接顺利通过,可是运行时发生了错误:

“try.exe 中的 0x004114c1 处未处理的异常: 0xC0000005: 写入位置 0x00000005 时发生访问冲突”

我call,这题不是人做的,谁能解释这是怎么回事?是编译器和链接器都没查出来的错误还是其他原因?
 
 回复人:R9R9R9(猪头饼) ( 二级(初级)) 信誉:1002007-7-30 0:30:25得分:0
 
 
?

楼主去看<<C专家编程.pdf>>这本书吧,这里面关于这个问题,有很深的解释

Top
 
 回复人:marrco2005(高手前传) ( 一级(初级)) 信誉:1002007-7-30 0:55:59得分:0
 
 
?

mark
Top
 
 回复人:onemansdream() ( 一级(初级)) 信誉:1002007-7-30 1:08:47得分:0
 
 
?

int array[5];
int *array;
是一回事
因为数组array存储的时候就是按array的基指针存放的
所以int array[5]; = int *array;
比如array[0] = * array
array[0] = * array+1
extern在多文件中就是来声明外部变量的
extern int *array; = extern int array[5];
声明之后该文件就可以使用了
小概念,呵呵
Top
 
 回复人:onemansdream() ( 一级(初级)) 信誉:1002007-7-30 1:09:37得分:0
 
 
?

array[1] = * array+1
应该是,写错了
Top
 
 回复人:cunsh(村少) ( 一星(中级)) 信誉:962007-7-30 1:27:44得分:0
 
 
?

楼上. 找个<<c专家编程.pdf>>吧
Top
 
 回复人:Forkerl(清者自清) ( 一级(初级)) 信誉:1002007-7-30 7:23:49得分:0
 
 
?

三言两语不好说,专家编程里讲了小半章呢。
大概意思就是先生命数组数组访问array+偏移量(array本身是地址),
声明成指针array编译器就当作指针了,要取array里保存的地址然后,用他保存的地址再加偏移量。而array本身就是地址,对地址再取址报错很正常。你第二个文件里array[0],此时的array就被当成指针了。
Top
 
 回复人:LoveYouJustOneDay(哈哈) ( 三级(初级)) 信誉:1002007-7-30 8:39:57得分:0
 
 
?

//extern int array[5]; a[4]=123;
movl $123, array+16
声明成 数组时, array是个地址,array[i]实际上就是array+i


//extern int *array; a[4]=123
movl array, %eax
addl $16, %eax
movl $123, (%eax)
声明成指针时,需要对指针进行解引用
就是 先把指针里存放的值+偏移 然后解引用


C语言语法给人的感觉是 数组跟指针几乎一样 但是内部实现是完全不同的

上面的情况跟下面的是有区别的
int a[10];
int *p=a;
p本身的地址跟a不同,p中存储的是a的值
p[5] == (p中存储的值 + 5*sizeof(int)) 这个地址中存储的值 p中存储的值是a的值

而int a[10];
extern int *a;
此处a的地址和a相等,是同一个数值
a[5]== (a中存储的值+5*sizeof(int))这个地址存储的值 第二个a中存储的值 就是a[0]的值
Top
 
 回复人:superyys(无血野人) ( 一级(初级)) 信誉:992007-7-30 9:18:30得分:0
 
 
?

怎么华为就喜欢考这些BT问题?没什么实际用途!
Top
 
 回复人:alps_008(潜水,冒泡,继续潜水) ( 一级(初级)) 信誉:1002007-7-30 9:33:08得分:0
 
 
?

啊,又学到了,呵呵。楼上的讲的挺明白的。
那么最后结论是不应该这么用还是怎么的呢?
Top
 
 回复人:LoveYouJustOneDay(哈哈) ( 三级(初级)) 信誉:1002007-7-30 9:33:38得分:0
 
 
?

华为做底层开发 问这类问题很有实际意义
对C和汇编理解的透彻是做好底层的前提
Top
 
 回复人:csShooter(Sharp Shooter) ( 二级(初级)) 信誉:1002007-07-30 11:55:10得分:0
 
 
?
好贴
Top
 
 回复人:changke18() ( 一级(初级)) 信誉:1002007-07-30 13:25:43得分:0
 
 
?
回复人:onemansdream() ( 一级(初级)) 信誉:100

回答的很好
Top
 
 回复人:csShooter(Sharp Shooter) ( 二级(初级)) 信誉:1002007-07-30 13:28:08得分:0
 
 
?
《C专家编程.pdf》里面就是有:


数组与指针是不一样的!
Top
 
 回复人:BEYOND_Q() ( 一级(初级)) 信誉:1002007-07-30 14:12:19得分:0
 
 
?
我个人认为在文件1中的int array[5] 和 文件2中的extern int *array 没什么关系。
在C语言里,如果extern 是全局变量的声明它只是告诉编译器,这个变量可以在外部引用。而是在一个函数内部,则是告诉编译器这个变量是在外部定义的。总的来说就是扩张这个变量的使用范围。
所以编译连接都没问题。
但是,你没有为你的*extern开辟内存空间。如果你使用*(array + 1)或者array[1](文件2中的指针变量)。就会出现非法内存访问。而使用文件1中的array是没有问题的。

呵呵。个人见解。如有错误还请指正。
Top
 
 回复人:alps_008(潜水,冒泡,继续潜水) ( 一级(初级)) 信誉:1002007-07-30 14:13:18得分:0
 
 
?
刚下了一个《C专家编程.pdf》
里面第四章就是:『令人震惊的事实:数组和指针并不相同』
确实就是以这个问题为例,讲的很好
Top
 
 回复人:linuxjackaroo() ( 一级(初级)) 信誉:1002007-07-30 14:33:15得分:0
 
 
?
那个我昨天看了。还没太年懂。。。。郁闷呢。
Top
 
 回复人:lostinger(我终于明白了我还有好多事情不明白!) ( 一级(初级)) 信誉:1002007-07-30 14:47:24得分:0
 
 
?
good
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值