c指针和数组不同

时间:2022-09-03 10:23:39
主  题:   一道华为面试题
作  者:   Aliens (异形们)
等  级:   c指针和数组不同
信 誉 值:   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(猪头饼) ( c指针和数组不同) 信誉:100 2007-7-30 0:30:25 得分:0
 
 
?

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

Top
 
  回复人:marrco2005(高手前传) ( c指针和数组不同) 信誉:100 2007-7-30 0:55:59 得分:0
 
 
?

mark
Top
 
  回复人:onemansdream() ( c指针和数组不同) 信誉:100 2007-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() ( c指针和数组不同) 信誉:100 2007-7-30 1:09:37 得分:0
 
 
?

array[1] = * array+1
应该是,写错了
Top
 
  回复人:cunsh(村少) ( c指针和数组不同) 信誉:96 2007-7-30 1:27:44 得分:0
 
 
?

楼上. 找个<<c专家编程.pdf>>吧
Top
 
  回复人:Forkerl(清者自清) ( c指针和数组不同) 信誉:100 2007-7-30 7:23:49 得分:0
 
 
?

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

怎么华为就喜欢考这些BT问题?没什么实际用途!
Top
 
  回复人:alps_008(潜水,冒泡,继续潜水) ( c指针和数组不同) 信誉:100 2007-7-30 9:33:08 得分:0
 
 
?

啊,又学到了,呵呵。楼上的讲的挺明白的。
那么最后结论是不应该这么用还是怎么的呢?
Top
 
  回复人:LoveYouJustOneDay(哈哈) ( c指针和数组不同) 信誉:100 2007-7-30 9:33:38 得分:0
 
 
?

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

回答的很好
Top
 
  回复人:csShooter(Sharp Shooter) ( c指针和数组不同) 信誉:100 2007-07-30 13:28:08 得分:0
 
 
?
《C专家编程.pdf》里面就是有:


数组与指针是不一样的!
Top
 
  回复人:BEYOND_Q() ( c指针和数组不同) 信誉:100 2007-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(潜水,冒泡,继续潜水) ( c指针和数组不同) 信誉:100 2007-07-30 14:13:18 得分:0
 
 
?
刚下了一个《C专家编程.pdf》
里面第四章就是:『令人震惊的事实:数组和指针并不相同』
确实就是以这个问题为例,讲的很好
Top
 
  回复人:linuxjackaroo() ( c指针和数组不同) 信誉:100 2007-07-30 14:33:15 得分:0
 
 
?
那个我昨天看了。还没太年懂。。。。郁闷呢。
Top
 
  回复人:lostinger(我终于明白了我还有好多事情不明白!) ( c指针和数组不同) 信誉:100 2007-07-30 14:47:24 得分:0
 
 
?
good