目录
1.指针简述——存放地址的变量
2.指针p所存放的值与指针本身的存储地址&p
3.从C语言函数值传递传参角度理解指针的地址&p和指针存储的值p
3.1c语言函数传参都是值传递的理解
3.2.简单地传入一个数的值传递代码理解
3.3 传入地址的值传递 代码理解
4.数组首元素的地址和数组地址的共同点和区别
#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
#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则是这个‘存放地址的变量’的地址
c++中有引用传递和值传递。
而c语言中函数传参都是值传递(我们听到的址传递,其实是将地址本身这个值,以值传递方式传入,在函数内部通过这个地址值去操作这个地址所存放的数据),过程为参数 z 传入函数后,会被拷贝一份。
具体怎样个拷贝法:
1.拷贝的是变量 z 所存储的值z_value (便于理解,将这个值称为z_value)。
2.不严谨的解释,C语言会在函数内部自动地、隐式地声明一个和传入参数 z 同样数据类型的变量去存放这个z_value,这个新声明的 ‘和传入参数 z 同样数据类型的变量’ 的名字就是函数定义时的形参名。
#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没半毛钱关系。
#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指针的地址: 63fdf0int_()中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了
#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的首元素地址: 63fc70main()中指针b1的地址: 63fe08
&b1[0]相当于&(*b1): 63fe04
main()中b1指针所存放的地址值: 63fe04
从结果可以看出a1与&a1 输出值是一样的,但它们所代表的含义是不一样的,a1代表的是&(p[0])即数组首元素的地址,而&a1代表着整个数组,这就导致了(a+1) 与 (&a+1)是不一样的参考点击讲解
头疼的指针 and 强大的指针.......·