声明:
本文是阅读周立功老师的程序设计与数据结构后所写,很多内容其实是书中的内容,所以如果您想了解更多这方面的知识,您可以阅读这本书。
在调用函数时我们通常会向调用的函数传递参数,而这里的参数有两种方式传递进入函数,一种是将实参的变量名直接传递给调用函数,这种被称为是参数传值,而另一种是将实参的地址传递给调用函数,这种方式被称为是参数传址。
参数传值:
参数传值相对来说使用比较多,而参数传值其实就是将调用函数中的实参的值复制给了被调函数的形参,而对于被调函数来说他并不能真正的操作调用函数中的实参。
参数传址:
相对于传值,传址函数就可以对被调函数的实参进行操作了,因为是传址,而在程序中一个变量的地址是唯一的,当我们找到这个地址并对这个变量进行操作就会容易很多。下面我们以一个例子程序及其运行结果来说明这两者的不同。
#include <stdio.h>
#include <stdlib.h>
void changeValue(int num)
{
num = num++;
printf("the num = %x \n\r",num);
}
int changePoint(int *ptr1)
{
if((ptr1=(int *)malloc(sizeof(int)))==NULL)
{
return -1;
}
printf("the ptr1'address is %p \n\r",ptr1);
return 0;
}
int changePoints(int **ptr1)
{
if((*ptr1=(int *)malloc(sizeof(int)))==NULL)
{
return -1;
}
printf("the *ptr1'address is %p \n\r",*ptr1);
return 0;
}
int main(int argc,int **argv)
{
int iNum = 0x54;
int *ptr = &iNum;
/* 分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
/* 对iNum进行函数changeValue操作后,分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
changeValue(iNum);
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
/* 对ptr进行函数changePoint操作后,分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
changePoint(ptr);
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
/* 对ptr的地址进行函数changePoints操作后,分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
changePoints(&ptr);
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
return 0;
}
下面我们分析程序及其运行结果:
1,未进行任何前指针ptr所指向的地址,变量iNum的地址以及变量iNum的值为:
int iNum = 0x54;
int *ptr = &iNum;
/* 分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
2,changeValue函数后:
void changeValue(int num)
{
num = num++;
printf("the num = %x \n\r",num);
}
/* 对iNum进行函数changeValue操作后,分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
changeValue(iNum);
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
虽然在被调函数中num的值改变了,但是在主调函数中iNum的值并没有改变。因此参数传值并不能改变实参的值。
3,对指针进行传值操作:
int changePoint(int *ptr1)
{
if((ptr1=(int *)malloc(sizeof(int)))==NULL)
{
return -1;
}
printf("the ptr1'address is %p \n\r",ptr1);
return 0;
}
/* 对ptr进行函数changePoint操作后,分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
changePoint(ptr);
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
我们在上面的函数中同样对指针进行了传值操作,即将指针ptr的值传递给被调函数changePoint,而并没有将指针ptr的地址传递过去,因此虽然我们申请了新的地址,但是对指针ptr进行改址操作是失败的。
4,对指针进行传址操作:
int changePoints(int **ptr1)
{
if((*ptr1=(int *)malloc(sizeof(int)))==NULL)
{
return -1;
}
printf("the *ptr1'address is %p \n\r",*ptr1);
return 0;
}
/* 对ptr的地址进行函数changePoints操作后,分别打印指针ptr所指向的地址,变量iNum的地址以及变量iNum的值 */
changePoints(&ptr);
printf("the ptr = %p ,&iNum = %x ,iNum = %x \n\r",ptr,&iNum,iNum);
这里我们将指针ptr的地址传递给被调函数,在被调函数中对指针的地址 进行操作就可以实现对调用函数实参的操作了。因此我们发现指针ptr的地址改变了。