一、二重指针的本质
- 二重指针与一重指针本质上都是指针变量,指针变量的本质也就是变量,都是用来指向别的东西的,在
32位机
上都是占4字节
内存空间 - 二重指针指向的变量类型是一个一重指针
1.1 测试代码段
int a = 1;
int *p1 = NULL; //一重指针
int **p2 = NULL; //二重指针
printf("sizeof(p1) = %d\nsizeof(p2) = %d\n",\
(int)sizeof(p1), (int)sizeof(p2));
p1 = &a;//一重指针指向普通变量类型
p2 = &a;//尝试将二重指针指向普通变量类型
p2 = &p1;
1.2 测试结果分析
- 我这里用的是
64位处理器上64位操作系统上的64位编译器
,所以指针大小8字节
。即sizeof(p1)
与sizeof(p2)
的结果都是8
- 我们可以发现在第二次编译过程中有一个
warning:
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
p2 = &a;
^
即p2 = &a;
之间存在不兼容指针类型的转换,具体分析如下:
p2 = &a;
:p2
是int **
类型,而&a
是int *
类型。int **
类型就是指针指向的变量是int *
类型的,int *
类型表示指针指向的变量是int
类型的;所以在这之间存在不兼容的指针类型转换。p2 = &p1
:p2
是int **
类型,p1
是int *
类型,再取地址变成int **
类型;所以在这之间的转换类型是兼容的,即二重指针指向的变量类型是一个一重指针
二、二重指针的用法
2.1 二重指针指向一重指针的地址
char *p1 = NULL; //一重指针
char **p2 = NULL; //二重指针
p2 = &p1;//二重指针指向一重指针的地址
2.2 二重指针指向指针数组
char *p1[5];
char **p2;
p2 = p1;
p1
是指针数组名,本质是数组名,做右值时表示数组首元素首地址。
指针数组的元素是char *
类型的,p1
做右值表示一个char *
类型变量的地址,所以p1
就是一个char
类型变量的指针的指针,所以p1
就是一个二重指针char **
2.3 通过函数改变函数外部的指针变量
#include <stdio.h>
void func(int **p)
{
*p = (int *)0X00000000;
}
int main(void)
{
int a = 1;
int *p = &a;
printf("p = %p.\n", p);
func(&p);
printf("p = %p.\n", p);
*p = 23;
return 0;
}
通过测试结果我们可以看出通过二重指针成功改变了一重指针p
的指向,由于0X00000001
在计算机内部是不可访问的,所以会触发段错误。