##先看看面试题
int numbers[4] = {10, 20, 30, 40};
int *p = (int *)(&numbers + 1);
NSLog(@"%d", *(p - 1));
分析
###1. 分析指针p + N
先看这个数组,其中p是指向numbers数组首元素,p只存储0xff01
这一个字节,但指向 0xff01-0xff04
四个字节
int numbers[4] = {10, 20, 30, 40};
int *p = numbers;
NSLog(@"%p - %p", p, p + 1);
图表展示,大概是这样的,每个int值占4个字节
####控制台打印结果1
0x7fff5fbff650 - 0x7fff5fbff654 // + 4
####结论1
指针 p + N : p里面存储的地址值 + N * p所指向类型所占的字节数
指针 p - N : p里面存储的地址值 - N * p所指向类型所占的字节数
数组名:存储的是数组首元素的地址,等价于是一个指向数组首元素的指针
2. 分析数组名
和数组名 + 1
以及 &数组名
和 &数组名 + 1
再来看看这段代码:
int numbers[4] = {10, 20, 30, 40};
NSLog(@"%p - %p", numbers, numbers + 1);
NSLog(@"%p - %p", &numbers, &numbers + 1);
####控制台打印结果2
0x7fff5fbff650 - 0x7fff5fbff654 // + 4
0x7fff5fbff650 - 0x7fff5fbff660 // + 16
####结论2
1. numbers : 相当于&numbers[0], 等价于指向numbers[0]的指针
用结论1计算,指针p指向numbers[0],numbers[0]所占字节数是 4
2. &numbers : 等价于指向numbers数组的指针
同样用结论1计算,指针p指向numbers数组,number数组所占字节数是4 * 4 = 16
###3. 分析二维数组
int numbers[2][4] = {
{10, 20, 60, 70}, // numbers[0]
{30, 40, 50} // numbers[1]
};
NSLog(@"%p - %p", numbers, numbers + 1);
NSLog(@"%p - %p", &numbers, &numbers + 1);
####控制台打印结果3
0x7fff5fbff640 - 0x7fff5fbff650 // + 16
0x7fff5fbff640 - 0x7fff5fbff660 // + 32
####结论3
1. numbers 相当于&numbers[0], 等价于指向numbers[0]的指针, numbers[0]占 4 * 4 = 16 个字节
2. &numbers : 等价于指向numbers数组的指针, numbers数组占 2 * 4 * 4 = 32 个字节
###4. 分析三维数组
int numbers[2][2][2] = {
{
{10, 20}, // numbers[0][0]
{60, 70} // numbers[0][1]
}, // numbers[0]
{
{30, 40},
{20, 60}
} // numbers[1]
};
NSLog(@"%p - %p", numbers[0], numbers[0] + 1);
NSLog(@"%p - %p", numbers, numbers + 1);
NSLog(@"%p - %p", &numbers, &numbers + 1);
####控制台打印结果4
0x7fff5fbff640 - 0x7fff5fbff648 // + 8
0x7fff5fbff640 - 0x7fff5fbff650 // + 16
0x7fff5fbff640 - 0x7fff5fbff660 // +32
####结论4
numbers[0][0] == &numbers[0][0][0],相当于是一个指向numbers[0][0][0]的指针
numbers[1] == &numbers[1][0],相当于是一个指向numbers[1][0]的指针
numbers == &numbers[0],相当于是一个指向numbers[0]的指针
&numbers == 相当于是一个指向numbers的指针
总结
- 指针 p + N : p里面存储的地址值 + N * p所指向类型所占的字节数
- 指针 p - N : p里面存储的地址值 - N * p所指向类型所占的字节数
面试答案解析
int numbers[4] = {10, 20, 30, 40};
int *p = (int *)(&numbers + 1);
NSLog(@"%d", *(p - 1));
假设指针p0指向数组的首元素
&numbers + 1 = p0 + 16的地址
指针p被强转成int类型指针,所以占4个字节,p - 1 = p0 + 16 - 4 = p0 + 12,也就是数组第四个元素的地址,所以答案是40