为什么取消引用 C 中的引用?在 * 旁边使用 &

Why dereference a reference in C? Using & next to *

我看了 this and this and this and 等等。

问题是

EdX 上的基础 C 编程 MOOC 展示了如何在通过指针传递结构时访问函数内的结构成员。 为什么他们在 * 旁边使用 &???

他们显示:scanf("%lf", &(*studptr).aveGrade);

为什么不直接在 scanf 中使用 studptr.aveGrade

(抛开单独的问题,"why use scanf at all")

(被要求提供完整示例)

void readStudent(struct student *studptr) {
    print("\nEnter a new student record: \n");
    printf("First name: ");
    scanf("%s", (*studptr).firstName);
    printf("Last name: ");
    scanf("%s", (*studptr).lastName);
    printf("Birth year: ");
    scanf("%d", &(*studptr).birthYear);
    printf("Average grade: ");
    scanf("%lf", &(*studptr).aveGrade);
}

这两个符号指的是不同的东西。

& 正在获取 aveGrade 成员的地址。

* 正在引用 studptr 以获得结构。


如果由我决定,我会使用 pointers-to-structures:

的箭头运算符来编写它
scanf("%lf", &studptr->aveGrade);

如果你想parens澄清:

scanf("%lf", &(studptr->aveGrade) );

因为&不是指(*stupdtr),而是指(*studptr).aveGrade. 运算符具有更高的优先级。

片段中:

scanf("%lf", &(*studptr).aveGrade);

& 运算符的应用就像有括号一样:

scanf("%lf", &((*studptr).aveGrade));

没有充分理由使用 (*ptr).member 而不是 ptr->member;事实上,显式间接表示法更冗长,而且当存在操作链时更是如此:

(*(*(*ptr).ptrmember).altptr).member

对比:

ptr->ptrmember->altptr->member

所以,代码应该是:

scanf("%lf", &studptr->aveGrade);

是的,这两个是'equivalent',但是箭头符号是惯用的C而另一个不是。

Why not just use studptr.aveGrade in scanf?

因为你写的 studptr 是一个指针,所以这个表达式 studptr.aveGrade 是无效的。

studptr->aveGrade( *studptr ).aveGrade

是正确的

所以scanf的调用可以这样写

scanf("%lf", &studptr->aveGrade);

或喜欢

scanf("%lf", &(*studptr).aveGrade);

考虑到

&(*studptr).aveGrade

( &*studptr).aveGrade

是不同的表达方式。

可以使用更多括号重写第一个表达式,例如

& ( ( *studptr ).aveGrade )

的确,当 & 紧接在 * 之前时,两者相互抵消。然而,这不是这里发生的事情:

&(*studptr).aveGrade

查看每个运算符:

  • * 运算符应用于括号表达式中的 studptr
  • 给定 (*studptr). 运算符的优先级高于 &,因此接下来应用它
  • & 然后应用于 (*studptr).aveGrade)

所以 & 为您提供 studptr 指向的 aveGrade 成员的地址。如果没有括号,&* 会取消,您会收到语法错误,因为 studptr 是指向结构的指针,而不是结构。

在结构中,aveGradedouble,因此如果您想访问它,您需要使用 & 符号 (&) 将 studptr 取消引用到 aveGrade。所以在scanf.

中使用(*studptr).aveGrade是荒谬的