【指针】对于指针的地址、指针所存储的地址值与对于c语言函数参数传递的理解

目录

1.指针简述——存放地址的变量

2.指针p所存放的值与指针本身的存储地址&p

3.从C语言函数值传递传参角度理解指针的地址&p和指针存储的值p 

3.1c语言函数传参都是值传递的理解

3.2.简单地传入一个数的值传递代码理解

3.3 传入地址的值传递 代码理解

 4.数组首元素的地址和数组地址的共同点和区别


1.指针简述——存放地址的变量

#include
#include

int main()
{
	int a=6;
	int *p = &a;
	printf("%d",*p);
	return 0; 
}

int* p解释1:声明一个指向int型数的指针变量

int* p解释2:也可以说是声明一个存放int型变量地址的指针变量

注意:int* p是声明int*型的p ; 而printf("%d",*p)是使用*通过p中存放的地址找到所对应int型变量a

2.指针p所存放的值与指针本身的存储地址&p

【指针】对于指针的地址、指针所存储的地址值与对于c语言函数参数传递的理解_第1张图片

#include
#include

int main()
{
	int a=6;
	int* p = &a;
	printf("0x%.2X\n",p);//p所存放的值,即a的地址 
	printf("0x%.2X\n",&a);//a的地址 
	printf("0x%.2X\n",&p);//int*型变量,即整型指针p这个变量的地址 
	printf("%d",*p);//p存放的地址所对应的int型变量a 
	return 0; 
}

输出: 

0x63FE1C
0x63FE1C
0x63FE10
6

 由此可以看出可以p与&p所对应的值是不一样的,而&a和p是一样的。

p可以理解为一个仅仅存放地址的变量,而&p则是这个‘存放地址的变量’地址

3.从C语言函数值传递传参角度理解指针的地址&p和指针存储的值p 

3.1c语言函数传参都是值传递的理解

        c++中有引用传递和值传递。

        而c语言中函数传参都是值传递(我们听到的址传递,其实是将地址本身这个值,以值传递方式传入,在函数内部通过这个地址值去操作这个地址所存放的数据)过程为参数 z 传入函数后,会被拷贝一份。

具体怎样个拷贝法:

1.拷贝的是变量 z 所存储的值z_value (便于理解,将这个值称为z_value

2.不严谨的解释,C语言会在函数内部自动地、隐式地声明一个和传入参数 z 同样数据类型的变量去存放这个z_value,这个新声明的 ‘和传入参数 z 同样数据类型的变量’ 的名字就是函数定义时的形参名。

3.2.简单地传入一个数的值传递代码理解

#include
#include

void change_a(int a) {
	a=9;
	printf("change_a()的值:                        %d\n",a);
	printf("change_a()中a的地址:                   %.2x\n",&a);
	return ; 
}

int main()
{
	int a = 10;
	printf("main()中调用函数change_a()前a的值:    %d\n",a); 
	change_a(a);
	printf("main()中调用函数change_a()后a的值:    %d\n",a); 
	printf("main()中a的地址:                      %.2x\n",&a);
}

输出:

main()中调用函数change_a()前a的值:      10
change_a()的值:                                        9
change_a()中a的地址:                             63fdf0
main()中调用函数change_a()后a的值:     10
main()中a的地址:                                      63fe1c

        从结果可以看出 ,函数change_a()中的a和main()函数中a的地址不一样,证明两个a变量存放的内容是相互独立的,自然的导致了change_a()中a被赋了9,而主函数main()中a一直是10。

        注意此时参数传递传递进去的仅仅是10这个数 即a=10,而当执行a=9后,10被覆盖了。当change_a()执行完,这个函数里的a就被销毁了,和主函数中a没半毛钱关系。

3.3 传入地址的值传递 代码理解

#include
#include

void int_(int* p) {
	printf("%.2x\n",&p);
	*p=9;
	printf("int_()中p所存储的地址值为:                     %.2x\n",p);
	printf("int_()中p所指向的变量的值为:                   %d\n",*p);
}

int main()
{
	int* b1;
	int c1=10;
 	b1=&c1;//b1指针存放c1的地址 
	
	printf("调用int_()前main()中b1所指向的变量的值为:       %d\n",*b1);
	printf("main()中b1指针的地址:                            %.2x\n",&b1);
	printf("main()中以b1起始第0个sizeof(int)字节的地址:      %.2x\n",&b1[0]);
	printf("main()中b1指针所存放的地址值:                    %.2x\n",b1);
	printf("int_()中p指针的地址:                            ");int_(b1);
	printf("调用int_()后main()中b1所指向的变量的值为:       %d\n",*b1);

	return 0; 
}

 输出:

调用int_()前main()中b1所指向的变量的值为:       10
main()中b1指针的地址:                                           63fe18
main()中以b1起始第0个sizeof(int)字节的地址:       63fe14
main()中b1指针所存放的地址值:                            63fe14
int_()中p指针的地址:                                               63fdf0

int_()中p所存储的地址值为:                                 63fe14
int_()中p所指向的变量的值为:                              9
调用int_()后main()中b1所指向的变量的值为:       9

        此时,传递进去的就p的值,即是c1的地址值 。(其实也可以看出值传递,只不过这个值是地址)。

         可以看出,调用 int_() 函数后,主函数中 b1 指针指向的变量的值确实发生了改变,这是因为执行 int_(b1) 时将指针 b1 存放的值,也就是 c1 变量的地址值传入函数 int_()。

        正如 3.1 所说的,int_() 内部隐式的声明一个和主函数中 b1 一样数据类型的变量(即指向int的指针类型——int*),并命名为 p(与形参名一样)。

        此时 p 的地址是 63fdf0 而 b1的地址为 63fe18 ,二者的地址不一样证明 p 和 b1 是两个相互独立的存储空间,是相互独立的两个指针类型变量。但是它们两个指针所存放的地址值确实一样的 63fe14

        所以,所谓址传递就是把要操作的变量 c1 的地址(c1地址存放在指针b1中)传入函数,即int_(b1);通过函数内指针 p 存储该值的地址,可以理解为c1的控制权有 b1 转移向 p ;等该函数执行完成,p会自动销毁。

如下图: p和b1都可以操做c1了

【指针】对于指针的地址、指针所存储的地址值与对于c语言函数参数传递的理解_第2张图片

 4.数组首元素的地址和数组地址的共同点和区别

#include
#include

int main()
{
	int a1[100]={1,2,3,4};
	int* b1;
	int c1=10;
 	b1=&c1;//b1指针存放c1的地址 

	printf("main()中数组a1的地址:                             %.2x\n",&a1);
	printf("main()中数组a1第0个元素的地址:                   %.2x\n",&a1[0]);
	printf("main()中数组a1的首元素地址:                       %.2x\n\n",a1);

	printf("main()中指针b1的地址:                            %.2x\n",&b1);
	printf("&b1[0]相当于&(*b1):                                %.2x\n",&b1[0]);
	printf("main()中b1指针所存放的地址值:                    %.2x\n",b1);
	return 0; 
}

输出:

main()中数组a1的地址:                                  63fc70
main()中数组a1第0个元素的地址:                   63fc70
main()中数组a1的首元素地址:                        63fc70

main()中指针b1的地址:                               63fe08
&b1[0]相当于&(*b1):                                    63fe04
main()中b1指针所存放的地址值:                  63fe04

从结果可以看出a1与&a1 输出值是一样的,但它们所代表的含义是不一样的,a1代表的是&(p[0])即数组首元素的地址,而&a1代表着整个数组,这就导致了(a+1) 与 (&a+1)是不一样的参考点击讲解

头疼的指针 and  强大的指针.......·

你可能感兴趣的:(c++,数据结构,开发语言)