C语言指针问题

前几日在论坛上看到一个C语言指针的问题,引发的思考和深入

先看下面例子:

	int *p;
	*p = 7;  //段错误

如上例子,若定义指针,只是定义指针的本身,却没有定义指针所指的地址(或者定义指针 = NULL,NULL是宏定义来的,其值为无类型的0,即#define NULL (void*)0),所以赋值其指向地址的值,必定会因为没有指向地址发生内存错误导致程序崩溃。

其正确操作应该为:

	int k;
	int *p;
	printf("%p\n",p);
	p = &k;
	printf("%p\n",p);
	*p = 7;
	printf("*p = %d\n",*p);

进入正题,直接上代码(一级指针传参):

void fun1(int *p){
	printf("--%p\n",p);
	*p = 20;
}

void fun2(int *p){
	printf("--%p\n",&p);
	*p = 20;
}

void fun3(int a)
{
	printf("&a = %p\n",&a);
	a = 10;
}
int main()
{
	#if 1   //实参传递
	int a;
	printf("&a:%p\n",&a);
	fun3(a);
	printf("a = %d\n",a);
	#endif
	
	printf("\n");
		
	#if 1
	int p1;
	printf("%p\n",&p1);
	fun1(&p1);            // 指针&p1和p所指的地址都一样     形参传递
	printf("p1 = %d\n",p1); 
	fun2(&p1);            // 整数p1和指针p本身的地址不一样  类似实参传递
	#endif
	
	printf("\n");
	
	#if 1
	int *p2;
	printf("%p\n",p2);   // p2 指向地址默认为0x0(cygwin64编译环境) 但是有的编译器把不初始化的指针作为野指针
	printf("%p\n",&p2);
	fun1(p2);  //(注意)看似正确,其实不然,段错误  1.由p2和p的指针本身地址可以看出,p2和p是不同的指针,也就是相当于
	           //          p2是按实参方式传递
	           //        2.因为p2指针未初始化,所以没有指向的内存,所以(*p)是不存在的
	           //          所以不存在*p = 20 的操作
	printf("p2 = %d\n",p2);
	
	#endif
	
	return 0;
}

运行结果:

&a:0xffffcbfc
&a = 0xffffcbd0
a = 0


0xffffcbf8
--0xffffcbf8
p1 = 20
--0xffffcbd0


0x0
0xffffcbf0
--0x0

Segmentation fault (核心已转储)


二级指针问题

void fun(int ** p)
{
	printf("p = %p\n",p);
	printf("&p = %p\n",&p);

	int a = 20;
	*p = &a;
}
int main()
{	
	#if 1
	int *p1;
	printf("p1:%p\n",p1);
	printf("&p1:%p\n",&p1);
	fun(&p1);
	printf("%d\n",*p1);
	
	printf("\n");
	
	int **p2;    
	printf("p2:%p\n",p2);
	printf("&p2:%p\n",&p2);
	//fun(p2);   //段错误
	//printf("%d\n",*p2); //段错误
	#endif
	
	printf("\n");
	#if 1
	int a;
	int *b = &a;
	int **p3 = &b;
	printf("&a = %p\n",&a);
	printf("b = %p\n",b);
	printf("&b = %p\n",&b);
	printf("*p3 = %p\n",*p3);
	printf("p3:%p\n",p3);
	printf("&p3:%p\n",&p3);
	fun(p3);
	printf("%d\n",**p3);
	#endif

	return 0;
}

运行结果:

p1:0x0
&p1:0xffffcbf8
p = 0xffffcbf8
&p = 0xffffcbb0
20


p2:0x0
&p2:0xffffcbf0


&a = 0xffffcbec
b = 0xffffcbec
&b = 0xffffcbe0
*p3 = 0xffffcbec
p3:0xffffcbe0
&p3:0xffffcbd8
p = 0xffffcbe0
&p = 0xffffcbb0
20

分析如下图:


猜你喜欢

转载自blog.csdn.net/qq_31930499/article/details/79700299