Explanation of value passing and address passing

When learning C language, we will encounter two difficult concepts in subroutine parameter passing: " value passing " and " address passing " . This article is dedicated to explaining this seemingly "persistent" problem. First of all, I declare that most of the following content is not written by me, I only make some supplementary explanations on the original work.

Before reading the following content, you need to be clear about a very basic knowledge point in C language: when the calling function calls the called function, it will open up corresponding parameters according to the number of parameters in the stack space (generally speaking, "stack" actually refers to "stack", "heap" and "stack" are two different things, which need to be distinguished. A section of space is used to store parameters. If you haven’t figured it out or even heard of this stuff, I advise you not to look down .

In fact, because the address itself can also be used as a special " value " , the address transfer is also a special value transfer. Just to emphasize its particularity, it is called " address transfer " . We can treat it differently depending on the form of the parameter during the learning process. For example, if the parameter is passed a value of a simple data type, it is classified as a value transfer method; if the parameter is passed an address of a variable, it is regarded as an address transfer method. In the process of value transfer, the formal parameters of the called function are treated as local variables of the called function, that is, a space is opened in the memory stack to store the value of the actual parameter put in by the calling function, thus becoming a copy of the actual parameter. The characteristic of value transfer is that any operation of the called function on the formal parameters is performed as a local variable, and will not affect the value of the actual parameter variable of the calling function. In the process of address transfer, although the formal parameters of the called function are also used as local variables to open up memory space in the stack , what is stored at this time is the address of the actual parameter variable put in by the calling function. Any operation of the called function on the formal parameters is processed as indirect addressing ( that is, we do not find the value based on the address at once, but we do not even know the address of the value at first, but we know where the address of the value is placed. We first find the address of the value there, and then find the value based on the address. This is the meaning of "indirect"), that is, access the actual parameter variable in the calling function through the address stored in the stack . Because of this, any operation done by the called function on the formal parameters affects the actual parameter variables in the calling function. Next, we use a program that appears most frequently in the book to realize the value transfer process and address transfer process respectively.
      


   

首先是值传递:

void swap(int x,int y)
{   int  temp;
    temp=x;
    x=y;
    y=temp;
printf("/n(swap)
%d,%d/n",x,y);
}
void main()
{   int a,b;
    scanf("%d,%d",&a,&b);
       if(a<b)  swap(a,b);
    printf("/n(main)
%d,%d/n",a,b);
}


假设我们从键盘输入两个数据:59,先来看一下运行结果:


        (swap)
95
        (main)
59

按照值传递的特点,我们可以很清楚的看到,虽然在swap函数中暂时使得运行结果显示了交换后的数据,即达到了交换的目的,但实际情况却是随着swapAt the end of the function, the formal parameters x and y used as local parameters and the local parameter temp of the swap function itself will end their lifetime, and the storage space in the memory will be released. Therefore, the actual parameters a and b are not affected, and still maintain the original value. From this program, we can also learn a method. For example, sometimes there is no need to modify the actual parameters, but the work done by the called function needs to be reflected, so we can flexibly use the print statement in the called function. Therefore, the above program can be rewritten as: void swap(int x,int y) { int temp; temp     =x;     x=y;     y=temp; printf("/n is arranged in descending order: %d,%d/n",x,y); } main () { int a,b;     scanf("%d,%d",&a,&b);        if(a<b) swap (a,b); } After inputting the two numbers 5 and 9 , the execution result obtained is: the sequence from big to small is: 9 ,
      
















   
5
你看这样就可以使用相对容易理解的值传递方式,巧妙的解决问题了,并得到了想要的答案,虽然我们并未真正的让主函数中的两个变量发生改变。


再来看地址传递方式,地址传递有两种形式。在理解这两种形式之前,首先要清楚C语言中的两个符号:“*”和“&”是分别是什么意思,它们的有什么样的区别和联系,用法如何,如果不甚了解,请找本C语言的教程搞明白后在往下看。

形式一:

void swap(int *p,int *q)
{   int  temp;
    temp=*p;
    *p=*q;
    *q=temp;
}
void main()
{   int a,b;
    int *pointer_1=&a,*pointer_2=&amp;
    scanf("%d,%d",&a,&b);
       if(a&lt;b)  swap(a,b);
    printf("/n%d,%d/n",a,b);
}

假设我们从键盘输入两个数据:59,先来看一下运行结果:
        
9
5
      
在这个程序中用指针变量作参数,注意这地方的子程序声明是:int*p,int *q,比值传递多了两个星号。虽然传送的是变量的地址,但实参和形参之间的数据传递依然是单向的值传递,即调用函数不可能改变实参指针变量的值。但它不同于一般值传递的是,它可以通过指针间接访问的特点来改变指针变量所指变量的值,即最终达到了改变实参的目的。

形式二:

形式二与形式一的区别仅仅在被调用的子程序上,其他部分与形式一完全相同:

voidswap(int &p,int &q)
{   int  temp;
    temp=p;
    p=q;
    q=temp;
}

形式二把形式一中的星号“*”换成了“&”。而在子程序内部对参数pq的使用和值传递时形式是一样的。对于形式二我们可以这样对比形式一去理解:形式一中用int*p表示传递过来的是变量的地址,在内部用*p去取这个地址中的数据,从而达到修改原来数值的目的;而形式二中用int&p表示传递过来的就是一个数值,但是这个数值并不是像值传递一样是原变量的拷贝了,而它就是原变量本身。所以内部直接修改p,也达到了修改原变量的目的。

形式二的表示方法不是很好理解,在这儿讲述主要是想让大家知道,有这么一种方式,以后碰到了不会觉得奇怪罢了,强烈建议使用形式一。

对于以上内容如有问题,请不吝赐教,非常感谢!
   
这一部分内容对初学者来说理解起来有一定的难度,所以在学习过程中一定要多想多练多思考,希望以上的讲解能对初学者有所帮助。

Guess you like

Origin blog.csdn.net/u013020969/article/details/39610443