8. C language uses pointers to realize the problem of reverse transmission of formal parameters

8. Using pointers to realize the problem of reverse transmission of formal parameters

The use of pointer-type formal parameters for reverse transfer requires the following points:
1. External actual parameters should be defined as entities rather than pointers, because external actual parameters need to use the space of the entity to store the data passed inside and out. (If the pointer must be used externally, see 9. Use two-dimensional pointer to realize the reverse value transfer of the formal parameter)
2. The internal formal parameter gets the address of the external space, so the internal address of the formal parameter cannot be lost , The parameter must always store the address of the external space.
3. When the value is reversed, the transferred data is put into the space of external actual parameters. In order to obtain the space of external actual parameters, it is necessary to address the formal parameters and then pass the values.
E.g:

/*
fun执行时,e自身有个地址————&e。
因为e是指针所以e存储的是一个另外空间的地址,由于函数调用时外部使用了a作为实参,所以e存储的是外部a的地址,*e则是外部a的存储空间
*/
void fun(int* e)
{
    int num = 7;
    

    /*
    如果下面反向传值的赋值语句写为:
        e = #
    则是将num的地址赋值给e,而e原本存储的外部a的地址就被覆盖了,所以达不到反向传值的效果。
    所以
    正确反向传值赋值语句写法为:
        *e = num;
    这样,e存储的一直是a的地址,*e是a的空间,这句赋值语句就将num中的7拷贝到了外部a的空间中
    */
    *e = num;
}

int main()
{
    //外部定义为实体,不能定义为指针int* a;定义为实体则a的空间可以用于接收外传的数据
    int a = 3;
    /*
    调用过程中,形参获取到实参传递的值
    因为fun函数形参e是指针类型,于是这里实参a向形参e传递的是a的地址————&a,而非a的值————3
    */
    fun(a);
    
    return 0;
}

9. Use the two-dimensional pointer to realize the reverse transmission of formal parameters

Let us first review 8. The use of pointers to realize the reverse value of formal parameters.
The specific ideas are as follows:
1. The external is defined as an entity, and the entity address is passed in.
2. The internally defined formal parameter is a one-dimensional pointer, so that the formal parameter points to an external entity.
3. Address the formal parameters to obtain the external entity space, and assign the value to be returned to the external entity space to realize the external value transfer.

Here all parts are "more one-dimensional pointer" to realize the use of two-dimensional pointer to reverse the value operation.
The specific ideas are as follows:
1. Define a one-dimensional pointer externally, and pass in the address of the pointer.
2. The internal formal parameter is defined as a two-dimensional pointer, pointing to the external one-dimensional pointer.
3. Addressing the formal parameters to obtain the external pointer, and then further addressing to obtain the space pointed to by the external pointer. Through the assignment statement, the value transfer operation to the space pointed by the external pointer is realized.

E.g:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/*************************************定义部分*************************************/
typedef struct Node {
    int number;
}Elem;

void fun(Elem** e)
{
    //进入函数,形参通过拷贝手段获取到实参的值,于是e存储a的地址&a,实现二维指针e指向一维指针a,一维指针a目前指向空
    //于是对e寻址就获取了a空间,所以对*e进行赋值,就相当于对a赋值

    //maloc函数申请空间,并将空间地址返回出来,假设malloc返回的地址是0x00000001
    //因为对*e进行赋值,就相当于对a赋值,于是将0x00000001赋值给了a
    *e = (Elem*)malloc(sizeof(Elem));

    //完成赋值语句后,二维指针e指向一维指针a,一维指针a指向空间0x00000001

    //对二维指针e寻址(即:*e)获取一维指针a,对一维指针a寻址(即:(*(*e)))获取空间0x00000001,
    //于是赋值语句实现将7放入0x00000001内
    (*(*e)).number = 7;
}
/*************************************使用部分*************************************/
int main()
{
    SetConsoleOutputCP(65001);
    
    //定义一个指针a,作为实参传入fun函数,用于接收fun函数形参(e)反向传出的实际空间的地址0x00000001
    Elem* a = NULL;//定义指针变量,并进行初始化

    //至此我们获取了一个指针a,她没有指向(或者说指针a指向空)
    
    //将a的地址传入
    fun(&a);
    //函数执行完成后,栈内存释放,函数fun内的形参e被释放。但是a已经存储到malloc空间的地址0x00000001,
    //于是a指向0x00000001,通过指向符号“->”就可以获取被指向空间0x00000001内所存的值7
    printf("%d\n",a->number);//显然输出的是:7
    //当然,不通过指向符号“->”的话,也可以通过对a寻址(即:*a)获取空间0x00000001,进而通过“点操作”获取该空间内部存储的值7
    printf("%d\n",(*a).number);//显然输出的依然是:7
    

    free(a);

    system("pause");
    return 0;
}

At this point, you can optimize the code of LinkList and let the GetElem function parameter use a two-dimensional pointer, so that the actual parameter can be defined as a pointer instead of an entity when external calls can save certain space performance. At the same time, the pointer of the inner loop body cursor will save performance.

Observing the code of question 8 and question 9 found that a common point is that when the function is called, the parameters passed are not the values ​​stored by the external variables, but the addresses of the external variables, and the internal parameters are defined External variables are higher-dimensional pointers. This common point reflects the core idea of ​​using formal parameters for back-value transfer-let the formal parameters inside the function point to the outer space! By addressing the formal parameters to pass values ​​to the external space.

Based on this core idea, it is possible to use three-dimensional (or higher-dimensional) pointers to realize the reverse value-passing operation of formal parameters.

This idea is similar to the transfer of "references" in other high-level languages ​​(the value is not the value but the reference).

Published 23 original articles · Like1 · Visits 20,000+

Guess you like

Origin blog.csdn.net/shenjie_xsj/article/details/102823812