使用指向结构的指针从键盘读取而不使用解除引用运算符

时间:2013-09-10 20:47:28

标签: c pointers struct dereference

在下面的示例中,为什么我不能使用

scanf("%s%d%d", p.name, p.age, p.code);

如果变量p已有地址,那么为什么我需要放&p->age而不是p.age? 为什么我需要使用'p-&gt; name'来从键盘而不是p.name&p->name读取字符串? 如果p->name相等(*p).name,并且scanf("%s",&variable)需要地址,那么(*p).name如果将scanf传递给p的值#include <stdio.h> #include <stdlib.h> struct person{ char name[60]; int age; int code; }; void printdata(struct person *p){ printf("%s, %d, %d",p->name, p->age, p->code); } int main(int argc, char *argv[]){ struct person *p; p = (struct person*) malloc(sizeof(struct person)); scanf("%s%d%d", p->name, &p->age, &p->code); printdata(p); free(p); return 0; } ,该怎么办?指向?

{{1}}

2 个答案:

答案 0 :(得分:1)

p是指向结构的指针; p->age取消引用指针并获取age成员,这是一个整数,而不是指针; &p->age的地址为p->age。因此,p没有age成员,但*p确实如此,并且您要传递*p年龄成员的地址进行扫描。

对于(*p).name(即p->name),这是因为字符串无论如何都表示为指向字符数组的指针,因此您可以像以前一样将字符串传递给scanf,它只会覆盖其中的字符。这很危险!因此,如果输入的名称长于60,您的代码可能会缓冲溢出并崩溃。

答案 1 :(得分:1)

关于你的第一个问题:

  

如果变量p已有地址,那么为什么我需要将&p->age代替p.age

您将p声明为指针

struct person *p;

这意味着如果你想访问例如年龄成员,你必须先取消引用指针:

(*p).age

这与符号

完全相同
p->age

然而scanf函数,对于整数,takes a pointer to an int。由于p->age指向int,因此您必须通过其地址传递age成员。由于->运算符的precedence超过&,因此您可以将其简单地写为

&p->age

name p成员的区别在于,因为它被声明为char的数组

 p->name

实际上已经是一个指针,并指向name的第一个元素。因此,当您将&传递给p->name

时,scanf前面不需要{{1}}运算符