我们都知道,指针变量的大小和类型无关,只要是指针变量,在同一平台下,大小都是一样的,那为什么还有各种各样的指针变量呢?
在创建变量时,int类型和double类型的区别在于大小,那么在创建指针变量时,int*和double*大小相同,区别在哪里呢?
区别一:指针的解引用方面
指针类型决定了对指针解引用时有多大的权限(即一次能操作几个字符)
int a = 0x11223344; 此时内存中4个字节分别存放44,33,22,11
int*pa = &a; 把a的地址存到指针变量pa中
*pa = 0; 通过pa内存放的地址找到a并赋值为0,此时内存中的4个字节分别为00,00,00,00
若将上述代码中int*改写为char*有什么区别呢?
int a = 0x11223344; 此时内存中4个字节仍然存放44,33,22,11
char*pa = &a; 此时编译器会报警告,a是整形,取地址a为int*类型,而存入的指针变量是char*类 型,会显示类型不兼容。
*pa = 0; 通过pa内存放的地址找到a并赋值为0,此时内存中的4个字节分别为00,33,22,11
由此可以看出,char*的指针解引用只能访问一个字节,而int的指针解引用能访问四个字节,区别在于一次能操作几个字节,即指针类型决定了对指针解引用时有多大的权限。
区别二:指针+-整数时的差异
int a = 20;
int* pa = &a;
char* pc = &a;
printf("%d\n",&a);
printf("%d\n",pa); 这三行代码输出结果相同,打印的都是a的地址,假设为00D6FDA8
printf("%d\n",pc);
printf("&a+1 = %p\n",&a+1); 输出值为&a+1 = 00D6FDAC
printf("pa+1 = %p\n",pa+1); 输出值为pa+1 = 00D6FDAC
printf("pc+1 = %p\n",pc+1);输出值为pc+1 = 00D6FDA9
下面我们逐一分析,pa+1打印结果00D6FDAC与pa打印结果00D6FDA8相差4,为4个字节,当pa+1时相当于+1*sizeof(int),同理当pa+n时相当于+n*sizeof(int)
而pc+1打印结果00D6FDAC与pc打印结果00D6FDA9相差1,差一个字节,当pc+1时相当于+1*sizeof(char),同理当pa+n时相当于+n*sizeof(char)
指针+-整数时,代表指针向前或向后走了多大距离,由上述结论可知,当pa+1时,相差四个字节,即指针走了四个字节的距离,下面为内存中指针变量int*p
|
*p解引用一次 +1后跳过4个字节
访问4个字节 继续往后读取
通过解引用访问和+-整数的操作,使得内存中的读取是连贯的。
结论:指针的类型决定了指针向前或向后走一步的距离,这个距离的大小为n*sizeof(类型)
区别三:void*(无具体类型指针,也叫泛型指针)
void*用于接收不知道什么类型的地址,它使一个函数能处理多种类型数据。
int a = 10;
char ch = 'w';
void pv1 = &a;
void pv2 = &ch; 无论void*接收什么类型的地址都不会报警告
但是void*类型指针不能直接进行 指针+-整数和解引用运算,解引用运算是通过访问a的地址来找到a,但void不知道访问几个字节,也不知道跳过几个字节,若写出*pv1或pv1+1这样的代码,编译器就会报错误。
以上就是指针类型多种多样的意义的全部内容。