Home > Software design >  confusion of address of a pointer
confusion of address of a pointer

Time:06-20

I see a piece of code like this:

#include<stdio.h>
struct person{
   int age;
   float weight;
};
int main(){
   struct person *personPtr, person1;
   personPtr = &person1;
   printf("Enter age: ");
   scanf("%d", &personPtr->age); // why use &personPtr->age, shouldn't it just be personPtr->age since personPtr is itself a pointer. 
   printf("Enter weight: ");
   scanf("%f", &personPtr->weight); // similarly here: should it be personPtr->weight instead. Why the & in front of personPtr, I thought & means address, so wouldn't it means address of the pointer which seems wrong here if we want to show the weight value. 
   printf("Displaying:\n");
   printf("Age: %d\n", personPtr->age);
   printf("weight: %f", personPtr->weight);
   // however if I do: printf("weight: %f", &personPtr->weight); this doesn't print the value of weight. So it has to do with the scanf function? 
   return 0;
}

the thing I don't understand is what are the difference between: &personPtr->age and personPtr->age

in the code above. I always see peresonPtr->age type of codes when I have a pointer to a struct and want to retrieve the inner variable of that struct.

So say I have a struct

struct A {
   int x;
   int y;
};

struct A f1;
struct A *f2 = &f1;

then I know I can do:

f2->x, f2->y to get the value of x, and y of the x, y variables inside the struct f1. But what does &f2->x, &f2->y?

Or the use of & in &personPtr->age has to do with the scanf function here? (because its use & inside the scanf function here.

could someone explains the difference and why use the &personPtr->age instead of personPtr->age.

Another example here, for example here in the Mutex function, I again see the &


uthread_mutex_t uthread_mutex_create () {
  uthread_mutex_t mutex = malloc (sizeof (struct uthread_mutex));
  mutex->holder = 0;
  mutex->reader_count = 0;
  spinlock_create   (&mutex->spinlock); \\ why &mutex, instead of just mutex?????
  uthread_initqueue (&mutex->waiter_queue);
  uthread_initqueue (&mutex->reader_waiter_queue);
  return mutex;
}

CodePudding user response:

personPtr is a pointer to the whole object person1

personPtr = &person1;

So this expression personPtr->age yields the data member age of the object person1 which you need to pass to scanf by reference that is through a pointer to it

scanf("%d", &personPtr->age);

To make it more clear you may rewrite the expression like

scanf("%d", &( personPtr->age ));

That is the expression &( personPtr->age ) yields the address of the data member age of the object person1. And the function scanf expects as its argument a pointer to the original object. Thus dereferencing the pointer the function will get a direct access to the original object (instead of a copy of the value of the object) that can be changed such a way.

Also consider the following demonstration program.

#include <stdio.h>

void f( int x )
{
    x = 10;
}

void g( int *px )
{
    *px = 10;
}

int main( void )
{
    int x = 0;

    printf( "Before calling f() x = %d\n", x );

    f( x );

    printf( "After  calling f() x = %d\n", x );

    printf( "Before calling g() x = %d\n", x );

    g( &x );

    printf( "After  calling g() x = %d\n", x );
}

The program output is

Before calling f() x = 0
After  calling f() x = 0
Before calling g() x = 0
After  calling g() x = 10

CodePudding user response:

In C scanf() requieres a pointer to be passed to it. Because personPtr is a pointer to a person struct, doing personPtr->age gives scanf the value of person1's age field and not a pointer to it.

By doing &personPtr->age you are passing scanf a pointer to the age field instead of it's value.

  • Related