指针的运算是我找工作面试的过程中最常见的类型之一。
先来一个题:
#include<iostream>
using namespace std;
void main()
{
int a = 100;
int* p = &a;
printf("地址是:%p\n", p);
p++;
printf("地址是:%p\n", p);
p--;
printf("地址是:%p\n", p);
}
假设第一行打印出来的是 012FFD3C,那么后两行的结果是什么呢?
这个结果其实很简单的,指针每进行一次加1或者减1操作,地址不是加一个或者减一个字节,而是加上或者减上指针数据类型所占的字节宽度,这里为int型,因此是加减4。字节宽度的获取可以通过sizeof函数来获得。
还有一些比较特殊的,比如空指针和空类型指针。空类型指针可以接受任何类型的数据,定义为:void *p;,在使用的时候可以将其强制转换为所对应的数据类型;空指针是int *p=NULL;p就是一个空指针。
空指针:空指针指向的地址不保存数据,不允许程序访问,这是因为空指针的指向的地址比较特殊。
空类型指针:也就是void *p这样的,这个类型的指针指向了可以保存数据的地址,但是存放的数据内容以及类型我们不知道。
举个例子:
#include<iostream>
using namespace std;
int main()
{
int* p = NULL;//空指针
cout << "i的地址赋给p前p的地址为:" << p << endl;
int i = 4;
p = &i; //将i的地址赋给p
float f = 3.333f;
cout << "f的地址为:" << &f << endl;
void* p1 = NULL;//空类型指针
cout << "i的地址赋给p后p的地址为:" << p << endl;
cout << "空类型指针p1的地址为:" << p1 << endl;
cout << "依次赋值给空类型指针p1" << endl;
p1 = p;
cout << "p1 = p---------p1的地址" << p1 << endl;
cout << "p1 = p---------转为int类型指针" << *(int*)p1 << endl;
cout << "p1 = p---------转为float类型指针" << *(float*)p1 << endl;
p1 = &f;
cout << "p1 = p---------p1的地址" << p1 << endl;
cout << "p1 = &f---------转为float类型指针" << *(float*)p1 << endl;
cout << "p1 = &f---------转为int类型指针" << *(int*)p1 << endl;
return 0;
}
运行结果如图:
可以看出来,对空类型指针赋值之后,需要对其进行对应的指针类型进行转换才可以得到所期望的结果。并且我们看到,空指针对应的地址为0。