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.