例子一
#include<iostream>
using namespace std;
int main()
{
int a[5]={1,2,3,4,5};
int* ptr = (int*)(a+1);
printf("%d",*(ptr-1));
return 0;
}
输出结果是:1,这个很好理解,数组名即数组的首地址,(a+1)等价于a[1],然后取ptr-1的值,则是a[0]
例子二
#include<iostream>
using namespace std;
int main()
{
int a[5]={1,2,3,4,5};
int* ptr = (int*)(&a+1);
printf("%d",*(ptr-1));
return 0;
}
输出结果是:5,这个我有点疑惑,经过研究,原因是这样的:
将数组 a 的地址加上 1,这会使指针 ptr 指向数组 a 的末尾之后的位置。因为数组 a 的类型是 int[5],所以 (&a+1) 指向的是整个数组 a 之后的位置,即指向的是一个越界的内存地址(未定义行为)。
接着,将指针 ptr 指向的地址减去 1,即指向数组 a 的最后一个元素的地址。最后,通过解引用指针 ptr-1 来访问该地址的值,即 5。
例子三
5、定义int a[8];问下面哪些不可以表示a[1]的地址
1、(int*)(&a+1) //相当于a[last]+1
2、(int*)( (char*) &a+sizeof (int))
3、&a[0]+1 //a[1]
4、a+sizeof (int) //a[4]
答案:1和4
四个选项中,第2个我不理解,经过研究,原理是:
把&a被强制转换成char类型的指针,即指向一个字节的地址,即指向第一个元素的首地址,往下偏移4个单位(一个int,4个单位),就是a[1]的起始地址,再把这个指针强制转换成int类型,就是完全指向a[1]的指针,所以这个也是a[1]的地址。
谨记:指针即地址,题目可解
(char*)&a指向的位置是①,
(char*)&a+4指向的是②
例子四
#include <iostream>
using namespace std;
int main() {
int a =5;
float b;
cout<<sizeof(++a + b)<<' ';//4
cout << a;//5
return 0;
}
答案是4 5,sizeof(++a + b)是4能理解,相当于转换成sizeof(int)了,但是,为什么a还是5?a不是自加了吗?
于是,进行了如下实验:
#include <iostream>
using namespace std;
int main() {
int a =5;
cout << a<<' ';
cout<<sizeof(++a)<<' ';
cout << a<<' ';
++a;
cout << a<<' ';
return 0;
}
答案是: 5 4 5 6 ,这说明sizeof比较特殊,在sizeof()这个运算符中自加不算数