我看到这样一段代码:
#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: %dn", 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;
}
我不明白的是:&personPtr->年龄和personPtr->年龄
在上面的代码中。我总是看到peresonPtr->当我有一个指向结构的指针并想要检索该结构的内部变量时,代码的年龄类型。
假设我有一个结构
struct A {
int x;
int y;
};
struct A f1;
struct A *f2 = &f1;
然后我知道我可以做:
f2->x、 f2->y来获取结构f1内x,y变量的x和y的值。但是什么是&f2->x、 &f2->y
或者使用&在&personPtr->年龄和scanf函数有关吗?(因为它在这里的scanf函数内部使用。
有人能解释一下区别以及为什么使用&personPtr->年龄而不是人Ptr->年龄
这里的另一个例子,例如在Mutex函数中,我再次看到&
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;
}
personPtr
是指向整个对象person1
的指针
personPtr = &person1;
因此,这个表达式personPtr->age
产生对象person1
的数据成员age
,您需要通过引用(即通过指向它的指针)将其传递给scanf
scanf("%d", &personPtr->age);
为了更清楚,你可以像一样重写表达式
scanf("%d", &( personPtr->age ));
即表达式CCD_ 7产生对象CCD_ 9的数据成员CCD_。函数scanf需要一个指向原始对象的指针作为其参数。因此,取消引用指针,函数将直接访问可以通过这种方式更改的原始对象(而不是对象值的副本)。
还要考虑以下演示程序。
#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 = %dn", x );
f( x );
printf( "After calling f() x = %dn", x );
printf( "Before calling g() x = %dn", x );
g( &x );
printf( "After calling g() x = %dn", x );
}
程序输出为
Before calling f() x = 0
After calling f() x = 0
Before calling g() x = 0
After calling g() x = 10
由于函数g
通过引用接受变量x
(&x
),因此取消引用指针可以改变原始变量x
。另一方面,函数f
处理原始变量x
的值的副本。因此,更改副本对原始变量x
没有影响。
在C中,scanf()
需要一个要传递给它的指针。因为personPtr
是一个指向person结构的指针,所以简单地传递它personPtr->age
会给scanf
一个person1年龄字段的值,而不是一个指向它的指针,因此编译器会抱怨scanf
需要一个指针,但被传递了一个整数。
通过执行&personPtr->age
,您将向scanf
传递person1
中年龄字段的地址。因为这次传递给它的是一个地址,而不是一个整数,所以没有编译错误。
然后我知道我可以做:
f2->x、 f2->y来获得x的值,以及内部x,y变量的y结构f1。但是什么是&f2->x、 &f2->y
&f2->x
、&f2->y
将分别为您提供x和y字段的地址。相反,f2->x
和f2->y
会给您它们的值。
类似地,在您的上一个例子中,
uthread_mutex_t mutex = malloc (sizeof (struct uthread_mutex));
因为malloc
返回一个指向已分配内存块开始的指针,所以mutex
只是一个指向未初始化的uthread_mutex
结构的指针。
功能
spinlock_create(&mutex->spinlock);
将指针作为参数。这就是为什么您必须将其传递给&mutex->spinlock
或以不同的格式传递:&(mutex->spinlock)
。
这同样适用于函数uthread_initqueue();
和uthread_initqueue();