指针与地址
一个简单的程序,目的是交换a,b的值
#include<stdio.h>
void swap(int *p1,int *p2);
int main( )
{
int a,b;
printf (“input a = b = \n”);
while (~scanf ("%d%d",&a,&b))
{
printf (“a的地址%p,b的地址%p\n”,&a,&b);
swap(&a,&b);
printf (“a = %d b = %d\n”,a,b);
printf (“a的地址%p,b的地址%p\n”,&a,&b);
}
return 0;
}
void swap(int *p1,int *p2)
{
int *temp = p1;
p1 = p2;
p2 = temp;
printf (“a = %d,b = %d\n”,*p1,*p2);
}
图片: https://uploader.shimo.im/f/VVVgrgH3wQfsf2Cw.png
例1:
void swap(int *p1,int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = *temp;
}
该程序将传入的地址对应的参数交换,可实现改变原函数中ab的值交换。
通过取交换前后a,b,两变量的地址发现:
交换前后a,b的地址并未改变。------>交换不是地址的交换,而是对应值的交换。
另发现a的地址与b的地址相差6字节,---->变量的储存不是按 " 顺序 " 储存的;图片: https://uploader.shimo.im/f/zpQtkJsWXtMVoNP1.png
下面,我们尝试将a的地址下移一个单位,并输出下移后的地址:
图片: https://uploader.shimo.im/f/nFo5Vxm4pq3p9Slb.png
a的地址增大了4个字节!
如果我们将temp也定义为指针型变量:
void swap(int *p1,int *p2)
{
int *temp = p1;
p1 = p2;
p2 = temp;
printf (“a = %d,b = %d\n”,*p1,*p2);
}
图片: https://uploader.shimo.im/f/rI5yfvDapnKEBgaG.png
可以发现a和b的值确实交换了,但是这里的交换实际上是我们将2,3交换顺序输出了。在原函数中,a,b的值并没有改变。
图片: https://uploader.shimo.im/f/9nkhWoPUJKROjShV.png
分析swap函数,我们发现指针p1指向a,p2指向b。
于是我们猜想:swap函数运行后,p1指向b,p2
指向b,所以我们将p1,p2地址下的值输出后会得到3和2.
我们将p1,p2的地址分别输出看看:图片: https://uploader.shimo.im/f/b0H4dj4Jkmg5fOLq.png
可以看到,符合猜想。
于是将a,b变量的值交换最好的方法应该是例1所示函数。
我们继续讨论关于地址的问题:
看下面这个程序:
int a [10] = {0,1,2,3,4,5,6,7,8,9};
for (int i = 0;i <10;i++)
printf ("a[%d] = %d ",i,*(a+i));
输出结果图片: https://uploader.shimo.im/f/ASnKdyrRbPOPqKc9.png
可以看到我们成功的将数组a的值全部输出了。
我们取数组a[0],a[1],a[2]的地址:图片: https://uploader.shimo.im/f/xepaTHO0pQyeXhDp.png
可以看到相邻元素之间相处4个字节,说明数组的存储是按照顺序储存的,也就解释了上面的结果。
源函数:
图片: https://uploader.shimo.im/f/SNLjbi4AVFgnLZd3.png