查看原文
其他

a是一个数组,那么&a是什么?&a+1的值又是什么?

Editor's Note

欢迎大家关注【嵌入式Linux】,看篮球哥分享Linux、Android、程序人生等精彩文章。

The following article is from 嵌入式Linux Author 写代码的篮球球痴

如题,这道题确实是一道嵌入式的高频面试题,本人也遇到过。下面看看关于这道题的一些详细解释及拓展题目。以下转原文


今天,在我们的一个小群里,一个同学发了一道题目给我看,这道题目应该是C语言面试的一股清流了,各种招聘笔试上都可以看到,我试着发到我的大群里去,发现有人对这个理解不是很深刻,所以再发出来,知识总是在不断的碰撞中提高的,同理,球技也是一样。

大家可以先猜测一下这两个程序的输出是什么?

什么是指针?

书籍看得比较多了,这个指针那个指针,但是我认为如果说到指针,不说变量,就有点耍流氓,所以我认为理解指针的基础就要理解它是一个变量,所以指针,可以理解为指针变量,再延伸出来,就是地址变量,可以存地址的一个变量,而且存的这个地址指向的类型也是有要求的

#include "stdio.h"
int main(){ int i = 12; int *p = &i; printf("%d\n",sizeof(int *)); printf("%d\n",sizeof(p)); printf("%p\n",&p);}

看上面的代码,p是一个指针变量,p存的是一个地址,p存的这个地址存的类型是 int 类型。有点拗口,我们画个图。

上图中 我们定义了一个变量 p ,所以编译器就必须要给这个p分配内存,如上图所示,这个p的内存是 0x1000,p是什么类型呢?从定义可以看,p的类型是 int *,所以说p只可以存 int * 类型的值,也就是一级指针,就是一级地址,也就是 i 的地址。

i 也是一个变量,这个变量的地址是 0x1001, 这个地址上存的值是 12。

地址本来是没有名字的,因为定义了变量,所以地址就对应有了一个别名,这个名字就代表了这个内存地址

弱弱问一句,声明有没有分配内存呢?

什么是数组?

我觉得指针和数组是不用比较的,我们比较的是指针变量和数组名,这两个东西才有比较的意义,数组是一类数据的集合,指针变量只能是一个地址变量,没必要折腾自己的大脑了。

#include "stdio.h"
int main(){ int array[5] = {1,2,3,4,5}; return (0);}

我们定义了一个 array的数组,这个数组是个什么鬼东西,我们知道,内存可以起一个别名,数组是连续几个同类型内存块的别名

好了,我们再说下一个问题 ,array 是数组的名字,&array 获取的是这个数组的地址,而且这个地址的值等于 &array[0] 「首元素的地址」。

虽然数值相等,但是他们的含义是不一样的。

如果 &array +1 这个时候,地址偏移的是 &array + sizeof(array)

如果 &array[0] +1 这个地址偏移是 &array[0] + sizeof(array[0]) ,也就是偏移到地址 &array[1]上。

再看看上面的两个题目

我们再看看上面的题目

int *p = (int*)(&a +1);

这句代码执行后,p的值应该是 &a +sizeof(a)了。

但是下面这句代码就不一样了。

#include "stdio.h"
int main(){ int a[5] = {1,2,3,4,5}; int *p = &a; int *q = a; printf("%d %d\n",*(q+1),*(p+1)); return (0);}

&a 赋值给 p 后,这个意义就不一样了,这时候,它的类型是 int* ,p+1 就是 p + sizeof(int *) 。只能偏移到数组的下一个位置。

所以这样说之后,大家都知道上面的输出结果了吗?

2,5

2,2







扫码关注,陪你一起成长!


猜你喜欢:

一道简单但易错的C语言面试题

C语言代码优化的一些技巧(一)

C语言代码优化的一些技巧(二)

C语言代码优化的一些技巧(三)

C语言代码优化的一些技巧(四)

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存