在下面的示例中,为什么我不能使用
scanf("%s%d%d", p.name, p.age, p.code);
如果变量p
已有地址,那么为什么我需要放&p->age
而不是p.age
?
为什么我需要使用'p-> 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}}
答案 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}}运算符