简体   繁体   中英

Understanding pointers & memory address

#include<stdio.h>

int g(int *a, int *b);

int main()
{
    int a = 2;
    int b = 7;

    b = g(&b , &a);

    printf("a = %d\n", a);
    printf("b = %d\n", b);

    return 0;
}

int g(int *a, int *b)
{
    (*a) = (*a) + 3;
    (*b) = 2*(*a) - (*b)+5;

    printf("a = %d, b = %d\n", *a, *b);

    return (*a)+(*b);
}

The output is:

a = 10, b = 23
a = 23
b = 33

I'm in an Intro to C programming class and having trouble understanding how this works.

Thanks for the help!

Sequencing the events as presented in question:

 int main() {

Declaration of a and b and value assignment:

 int a = 2; int b = 7;

Here is a trick, the address passed to the parameter int* a is actually of b , and vice-versa on the second parameter:

 b = g(&b , &a);

Here just printing values of a and b :

 printf("a = %d\\n", a); printf("b = %d\\n", b); return 0; }

Since the parameters are pointers, the changes made, in the scope of this function, to the variable addresses pointed by them are permanent:

 int g(int *a, int *b) {

Here, dereferencing the pointer ( *a , the parentheses are not needed in these cases), means you are now working with the value stored in the address pointed by a , so 7 + 3 = 10 , now the value stored in the address pointed by a is = 10 :

 (*a) = (*a) + 3;

Here, the same thing, dereferencing pointers, so 2 * 10 - 2 + 5 = 23 , the value stored in the address pointed by b will be 23 :

 (*b) = 2*(*a) - (*b)+5;

Here printing a = 10 and b = 23 , again, dereferencing pointers means you are working with the values stored in the addresses pointed by them:

 printf("a = %d, b = %d\\n", *a, *b);

The returned value is 10 + 23 = 33 , so for b = g(&b, &a) , b will be assigned the value of 33 , a is already 23 so it stays that way:

 return (*a)+(*b); }

With & you give the address of the variable to the function, instead of the value. With * you can access the value of an address.

With b = g(&b , &a); you give the address of the variable b and a to the function. But you can access the address of b with * a because you declare the function that way: int g (int * a, int * b) :

  • *a points to the address of your b variable.
  • *b points to the address of your a variable.

I think the different variable names are what confuses you.

To make it easier for yourself you could change the declaration to int g (int * b, int * a) In case you want to change it:

  • *b would point to the address of your b variable and
  • *a would point to the address of your a variable.

Remember that C passes all function arguments by value - that means that the formal parameter in the function body is a separate object in memory from the actual parameter in the function call, and the value of the actual parameter is copied to the formal parameter.

For any function to modify the value of a parameter, you must pass a pointer to that parameter:

void foo( T *ptr )  // for any type T
{
  *ptr = new_T_value(); // write a new value to the thing ptr points to
}

void bar( void )
{
  T var;
  foo( &var ); // write a new value to var
}

In the code above, all of the following are true:

 ptr == &var
*ptr ==  var

Thus, when you write a new value to the expression *ptr , it's the same as writing a new value to var .

I think part of what's making this confusing for you is that the names of your formal parameters ( a and b ) and your pointers ( a and b ) are flipped - g:a points to main:b and vice versa.

 g:a == &main:b  // I'm using g: and main: here strictly to disambiguate
*g:a ==  main:b  // which a and b I'm talking about - this is not based on
                 // any real C syntax.  
 g:b == &main:a
*g:b ==  main:a

by using the * you access the object referenced by the pointer. As the pointers are referencing int variables a & b you do the operations on those variables. I think the same variable names are confusing you

int g(int *p1, int *p2)
{
    (*p1) = (*p1) + 3;
    (*p2) = 2*(*p1) - (*p2)+5;

    printf("*p1 = %d, *p2 = %d\n", *p1, *p2);

    return (*p1)+(*p2);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM