二重指针



33.二重指针
二重指针和一重指针在本质上都是指针变量,指针变量的本质都是变量。指针变量本身都占4字节内存空间。在我PC机上指针类型变量占8个字节。
/**************************二重指针******************************/
char **p1; //二重指针
char *p2; //一重指针

printf("sizeof(p1) = %ld.\n", p1);
printf("sizeof(p2) = %ld.\n", p2);
/**************************二重指针******************************/


二重指针的本质也是指针变量,和普通指针的差别就是它指向的变量类型必须是一重指针。二重指针其实也是一种数据类型,编译器在编译时会根据二重指针的数据类型来做静态类型检查,一旦发现运算时数据类型不匹配编译器就会自动报错(C语言编译器的强类型检查)。
理论上如果没有二重指针也是可以的,一重指针完全可以做二重指针做的事情,之所以要发明二重指针(函数指针、数组指针)就是为了让编译器了解这个指针被定义时它的程序员希望这个指针被用来指向什么类型的变量的。于是编译器就可以帮助我们做一些静态类型检查,编译器的这种静态类型检查可以辅助程序员发现一些隐含性的编程错误。
(1)二重指针指向一重指针的地址:
/**************************二重指针用法******************************/
char a;
char **p1; //二重指针
char *p2; //一重指针

p2 = &a; //一重指针指向变量地址。

/*p1是char **类型,&a是char *类型的。左右两边类型不匹配,所以有警告。*/
p1 = &a;

p1 = &p2; //p2本身是char *类型的,取地址之后就变成char **类型,和p1类型一致了。

/**************************二重指针用法******************************/


在实际的编程中,二重指针用的比较少,大部分时候都是和指针数组一起使用。使用二重指针指向指针数组。
/**************************二重指针用法******************************/
int *p1[5]; //指针数组
int *p2;
int **p3;

/*p1是指针数组名,本质上是数组名,数组名做右值时表示首元素的首地址,数组的元素就是int *类型,所以p1做右值就表示一个int * 类型变量的地址,所以p1就是一个int类型变量的指针的指针,所以它就是一个二重指针。*/
p2 = p1; //类型不匹配,p2是一重指针。

p3 = p1; //类型匹配
/**************************二重指针用法******************************/


实际的编程中有时在函数传参时为了通过函数内部改变外部的一个指针变量,回传这个指针变量的地址(也就是二重指针)进去。
/**************************二重指针用法******************************/
void func(int **p)
{
*p = (int *)0x12345567;
}
int main()
{
int a = 4;
int *p = &a;
printf("p = %p.\n", p);
func(&p);
printf("p = %p.\n", p);
*p = 33; //会产生段错误,因为地址修改成0x12345567,是个不可访问的地址。
return 0;
}
/**************************二重指针用法******************************/
二重指针本质上就是指针数组。


  

猜你喜欢

转载自blog.csdn.net/qq_20725221/article/details/51459496