C language pointer: how does a pointer change the address it points to as a formal parameter?

Keywords: C

What does the title mean? The input parameter of a function is a pointer, and the function needs to change the address pointed to by the pointer. For example, there is a global array b, and now it is necessary to write a function. The input parameter is a pointer a, and the pointer a needs to be pointed to array b through the function, that is:

int b[3] = {1,2,3};

void fcn(parameter);

void main()
{
    int* a;
    fcn(input parameter  a)

}

After fcn is executed, how to change the address of the parameter?

First, explain the conclusion: use the secondary pointer.

In order to better understand this problem, let's first learn the most classic example of pointer, exchanging two numbers to illustrate the relationship between formal parameters and arguments of a function.

First, let's explore the relationship between the following arguments and formal parameters.

  1. The formal parameter is a common variable type;
void test1(int a, int b)
{
   printf(">> formal addr a: %d, formal addr b: %d\n",&a,&b); //Print parameter address
   printf(">> formal value a: %d, formal value b: %d\n",a,b); //Print parameter values
}


int main()
{
    int a = 1, b = 2;

    printf(">> actual addr a: %d, actual addr b: %d\n", &a,&b);
    printf(">> actual value a: %d, actual value b: %d\n",a,b);
    test1(a,b);

    return 0;
}

Here are the execution results:

>> actual addr a: 6422300, actual addr b: 6422296
>> actual value a: 1, actual value b: 2
>> formal addr a: 6422272, formal addr b: 6422276
>> formal value a: 1, formal value b: 2

It can be seen that although the values of formal parameters and arguments are the same, their addresses are different. Therefore, when the function is called, the incoming parameters (arguments) are actually copied to another address (formal parameter address). The operation on the incoming parameters in the function is actually the operation on the numbers in the formal parameter address, which has nothing to do with the arguments. Therefore, the following function cannot exchange two numbers.

void swap_1(int a, int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
   printf(">> formal addr a: %d, formal addr b: %d\n",&a,&b);
   printf(">> formal value a: %d, formal value b: %d\n",a,b);
}

int main()
{
    int a = 1, b = 2;
    swap_1(a,b);
    printf(">> actual addr a: %d, actual addr b: %d\n", &a,&b);
    printf(">> actual value a: %d, actual value b: %d\n",a,b);
    return 0;
}

The output is as follows:

>> formal addr a: 6422272, formal addr b: 6422276
>> formal value a: 2, formal value b: 1
>> actual addr a: 6422300, actual addr b: 6422296      
>> actual value a: 1, actual value b: 2

You can see in swap_ The values of a and B in the function are exchanged, but the addresses of a and B in the function are not the same as those of a and B in the main function. A and B in the main function are still the original numbers, so this function cannot exchange two numbers.

Since the relationship between the formal parameter and the argument is that the addresses are different and the values are the same, can we complete the exchange of the two numbers by passing the address of the argument as a parameter to the formal parameter, and then changing the value in the address pointed to by the formal parameter (the address is the address of the argument) in the function?

OK! Let's write a function test:

void swap_2(int* a, int* b)
{
    int temp;
    printf(">> formal addr a: %d, formal addr b: %d\n",&a,&b); //Print parameter address
    printf(">> formal value a: %d, formal value b: %d\n",a,b); //Print the value of the formal parameter
    printf(">> formal addr value a: %d, formal addr value b: %d\n",*a,*b); //Print the value with the formal parameter value as the address
    temp = *a;
    *a = *b;
    *b = temp;
    printf(">> formal addr a: %d, formal addr b: %d\n",&a,&b);
    printf(">> formal value a: %d, formal value b: %d\n",a,b);
    printf(">> formal addr value a: %d, formal addr value b: %d\n",*a,*b);
}

int main()
{
    int a = 1, b = 2;
    swap_2(&a,&b);
    printf(">> actual addr a: %d, actual addr b: %d\n", &a,&b);
    printf(">> actual value a: %d, actual value b: %d\n",a,b);
    return 0;
}

The results are as follows:

>> formal addr a: 6422272, formal addr b: 6422276
>> formal value a: 6422300, formal value b: 6422296
>> formal addr value a: 1, formal addr value b: 2      
>> formal addr a: 6422272, formal addr b: 6422276      
>> formal value a: 6422300, formal value b: 6422296    
>> formal addr value a: 2, formal addr value b: 1      
>> actual addr a: 6422300, actual addr b: 6422296      
>> actual value a: 2, actual value b: 1

As can be seen from the results, this function can exchange the values of input parameters. Let's analyze why this function can realize the exchange function.

Take variable a as an example. First, from the first line of the result, it can be seen that the parameter of the incoming function is the address (i.e. the address of argument a: 6420300), which is stored as a value in formal parameter a (address: 6422272), then an int variable is defined to store the value 6422300 (the address of argument a) in address 6422272 (the address of formal parameter a), and then point to 6422296 (address of argument b) the value in the address is assigned to point to 6422300 (address of argument a). The value in the start address 6422300 address is 2, and now the value of the address becomes 1. Similarly, after executing the function, the value in address 6422296 becomes 1, so as to realize the exchange of two numbers.

In this process, the function calls the addresses of a and b values and changes the values in the two addresses in the function. The essential difference from the previous function is that the previous function swap1 only copies the values of a and B into two new addresses and changes the values in the new address, which is independent of the A and B addresses. While swap_2 directly operates the values in the A and B addresses to realize the intersection The function of changing two numbers.

Note: arguments and formal parameters are at two different addresses. Although the names are the same, of course, the names can be chosen at will. In order to more clearly explain that arguments and formal parameters are two things, I will change the variable names of formal parameters:

void swap_2(int* formal_a, int* formal_b)
{
    int temp;
    printf(">> formal addr a: %d, formal addr b: %d\n",&a,&b);
    printf(">> formal value a: %d, formal value b: %d\n",a,b);
    printf(">> formal addr value a: %d, formal addr value b: %d\n",*a,*b);
    temp = *formal_a;
    *formal_a = *formal_b;
    *formal_b = temp;
    printf(">> formal addr a: %d, formal addr b: %d\n",&a,&b);
    printf(">> formal value a: %d, formal value b: %d\n",a,b);
    printf(">> formal addr value a: %d, formal addr value b: %d\n",*a,*b);
}

int main()
{
    int a = 1, b = 2;
    swap_2(&a,&b);
    printf(">> actual addr a: %d, actual addr b: %d\n", &a,&b);
    printf(">> actual value a: %d, actual value b: %d\n",a,b);
    return 0;
}

The results are as follows:

>> formal addr a: 6422272, formal addr b: 6422276
>> formal value a: 6422300, formal value b: 6422296
>> formal addr value a: 1, formal addr value b: 2      
>> formal addr a: 6422272, formal addr b: 6422276      
>> formal value a: 6422300, formal value b: 6422296
>> formal addr value a: 2, formal addr value b: 1      
>> actual addr a: 6422300, actual addr b: 6422296      
>> actual value a: 2, actual value b: 1

Like the previous results, we can know that when the function is executed, it actually cares about the address no matter how your name is given, and the name you give is actually just the code of that address.

The above example has made clear the difference between the shape of a function and its arguments. Now let's solve the problem raised at the beginning of the article

How to change the address of an incoming pointer as an argument through a function is actually very easy to understand the formal parameters and arguments of the function above.

First, let's look at the following example

int b[3] = {1,2,3};


void fcn(int* *a)
{
    *a = b;
}


int main()
{
    unsigned int i = 0;
    int* a;

    for(i=0;i<3;i++)
     {
         printf(">> %d \n",a[i]);
     }

     fcn(&a);

     for(i=0;i<3;i++)
     {
         printf(">> %d \n",a[i]);
     }
}

The function output is:

>> 0 
>> -1
>> 4194304
>> 1
>> 2
>> 3

In the main function, we defined a pointer A and did not initialize it. After that, we can not directly assign a value to the address it points to, because now its address is random. Operating on this address may cause the program to crash. If we want to use it, we can only operate on its own value, that is, the address it points to. The function fcn passes through the form Parameter to change the value of the input argument?

First look at the formal parameters of the function   (int **a), what does it mean? That is, an incoming secondary pointer, a pointer to a pointer, what does it mean?   For example, you have a treasure map. It says that the treasure is in place A. after you get to place a, you only get a treasure map. The treasure map says that the treasure is in place b. you can get the treasure only when you reach place b. This is a secondary pointer. The first address is a, and the content of a is also a pointer. The real content is under the address of b and b.

We define a pointer a in the main function and let it pass into the function fcn. Let's analyze this process:

The function opens up the address of a formal parameter. The content of the address is the value pointing to the address of the incoming parameter. In the function, we assign the first address of array b to this address, that is, we change the address of the actual parameter to the first address of array b.

The article is really too convoluted. I think the most important point is to find out the relationship between the pointer and the address and the value of the address, as well as the relationship between formal parameters and arguments.

Posted by Brian Swan on Sun, 24 Oct 2021 20:41:35 -0700