数组与指针
Posted wshl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组与指针相关的知识,希望对你有一定的参考价值。
序:天气逐渐转冷了,各位IT界的朋友,注意保暖,爱惜自己身体~~
最近在浏览某篇博文的时候,看到了大概两年前看到过的一个问题,是一个面试题,因为两年前那时候没有搞懂,所以当时也没有过多地纠结,最近再次看到这个问题,颇有感慨,因此,就结合自己最近两年左右的经验,简单总结一下。
面试题大概是这样:
int main(int argc, const char * argv[]) { @autoreleasepool { int numbers[4] = {10, 20, 30, 40}; int *p = (int *)(&numbers + 1); NSLog(@"%d", *(p - 1)); }
// 请问打印结果。
换作在两年前,我看到这种问题,连吃午饭的胃口都没有了。。。。
但是现在再重新来看这个问题,虽然需要经过一点时间的思考,但还是可以得出正确结果为40。
下面咱们就一步一步来整理一下:
首先来看
// numbers数组装有4个int类型的元素,由于一个int类型占4个字节,因此,numbers数组总共占有16个字节。 int numbers[4] = {10, 20, 30, 40};
然后,咱们来打印一下内存地址
// 数组的内存地址、数组中第一个元素的内存地址,这二者其实是同一个值,如下: NSLog(@"%p", numbers); // 这种写法是在获取 数组的内存地址,也叫做数组名 NSLog(@"%p", &numbers[0]); // 这种写法是在获取 数组中第一个元素的的内存地址
紧接着,咱们来定义一个指针
int *p; // 这种写法,代表p将要指向int类型的数据
然后给它赋值
p = &numbers[0]; // 这种写法,表示p指向了数组中第一个元素的内存地址。即指向第一个元素所占用的4个字节(因为int为4个字节)
这里,p只会存储4个字节中的第一个字节(下面的打印就可以验证),这就是int的意义所在,因为已经提前声明了p是指向int类型的数据,因此只要根据p存储的
那个字节,依次按序往下再算3个字节,那么这4个字节就是p所指向的这个数据所占用的内存。同理double、float、long。
NSLog(@"%p", p);
咱们再来看p 和 p + 1的结果比较
NSLog(@"%p", p); // 0x7ffeefbff590 NSLog(@"%p", p + 1); // 0x7ffeefbff594
结果显示,p + 1增加了4。
其实,可以简单的推出一个结论:
// 指针数据 + 1,表示当前指针指向的地址值 + 指向类型所占用的字节数(如下打印验证)。
因此,可以推导出:
指针p + n 表示 p指向的地址值 + n * p指向的类型所占用的字节数。
同理,亦可得出:
指针p + n 表示 p指向的地址值 - n * p指向的类型所占用的字节数。
紧接着,再来看下面这种写法表达的意思
NSLog(@"%d", *p);
这种写法,结果为指针p指向的数据的值(结果为10,因为p指向的是第一个元素)。
上面提到,由于数组名(数组的内存地址)其实就是数组中第一个元素的内存地址,因此,数组名的另外一层含义即为:数组中第一个元素的内存指针。所以,下面
这种写法所得到的结果,就是数组中第一个元素的值。
NSLog(@"%d", *numbers); // 10
再来几句代码比较一下就会更加有理解
NSLog(@"%d", *(&numbers[0])); // 10 NSLog(@"%d", *(&numbers[0] + 1)); // 20 NSLog(@"%d", *(&numbers[0] + 2)); // 30 NSLog(@"%d", *(&numbers[0] + 3)); // 40
说到这里,其实可以得出一个常识:&a就代表一个指针。上面用到的&numbers[0]其实就是一个指针,只不过为了简单化,所以用p代替了。
刚才也说了,数组名的意义,其实就是&numbers[0],即指向数组中第一个元素的指针。那么顾名思义,&numbers的意义即为:指向这个数组的指针。看如下打
印:
NSLog(@"%p", &numbers); // 0x7ffeefbff590
NSLog(@"%p", numbers); // 0x7ffeefbff590
不难看出,&numbers的打印结果同numbers,其实就是数组中第一个元素的内存地址,也为数组的内存地址。那么看一下&numbers + 1得到的结果是否遵循刚
才得出的结论:
NSLog(@"%p", &numbers); NSLog(@"%p", &numbers + 1);
根据结果可以看出,&numbers + 1得到的地址也遵循之前的结论,因为&numbers指针指向的数据类型所占用的位数是16(numbers数组中存有4个int类型),因此&numbers + 1的结果就增加了16。
通过上面一连串的规整,那么再回到文章一开始列出的面试题,就不难得到正确答案是40了。
有兴趣的童鞋可以再尝试练习一下二维、甚至三维数组,可以进一步加深理解。
以上是关于数组与指针的主要内容,如果未能解决你的问题,请参考以下文章