【问题标题】:When to use arrow and when dot?什么时候用箭头,什么时候用点?
【发布时间】:2021-01-26 12:54:13
【问题描述】:

我已经读过它并且我基本上明白了,但这种情况让我有点困惑。为什么我们不在scanf 中使用箭头运算符->?我知道点用于对象,箭头用于指针,但在这里,g 是指向结构的指针。

DOCUMENT *take(int *pn){
        DOCUMENT *g;
        printf("How much documents? ");
        scanf("%d", pn);
        g = (DOCUMENT *)calloc(*pn, sizeof(DOCUMENT));
        for (int i = 0; i < *pn; i++)
        {
            printf("Type in author, name of document and number of pages: ");
            scanf("%s %s %d", g[i].author, g[i].name, &g[i].s );
        }
        return g;
    }

【问题讨论】:

标签: c pointers struct


【解决方案1】:

数组索引运算符[] 内置了取消引用。

g[i]*(g + i) 完全相同。所以g[i] 指的是DOCUMENT,而不是DOCUMENT *,因此您使用成员访问运算符. 而不是指向成员的指针运算符-&gt;

【讨论】:

    【解决方案2】:

    如果.-&gt; 的左操作数是指针,则使用-&gt;。否则如果它是一个对象(普通变量),那么你使用.

    在这种情况下,g[i] 正在获取一个指针并对其进行数组下标。结果是一个对象(“左值”),而不是一个指针,因此是g[i].


    还要注意&amp;g[i].s 等表达式中的运算符优先级。数组下标运算符[] 和结构成员运算符. 具有相同的运算符优先级——它们属于同一组后缀运算符。但是该组具有从左到右的运算符关联性,因此[] 优先于.。然后在这两个之后跟随&amp;,一元地址运算符,表达式中运算符优先级最低。所以运算符优先级保证表达式等价于&amp;((g[i]).s)

    【讨论】:

      【解决方案3】:

      与指针一起使用的下标运算符产生指针表达式所指向的对象。也就是比如这个表达式

      g[i].author
      

      (其中g[i] 是结构数组的i-th 元素)等价于

      ( g + i )->author
      

      其中g + i 是指向结构数组的i-th 元素的指针。

      下标运算符g[i]等价于表达式*( g + i )

      你可以写

      g[i].author
      

      或喜欢

      ( *( g + i ) ).author
      

      或喜欢

      ( g + i )->author
      

      因此这个 scanf 调用

      scanf("%s %s %d", g[i].author, g[i].name, &g[i].s );
      

      可以像这样重写

      scanf("%s %s %d", ( g + i )->author, ( g + i )->name, &( g + i )->s );
      

      【讨论】:

        【解决方案4】:

        当你写 g[i] 时,这实际上等于 *(g + i)。也就是说,你取消引用指针,它又变成了一个对象,所以你可以用点 (.) 而不是箭头 (->) 来访问它。

        【讨论】:

          猜你喜欢
          • 2011-09-28
          • 2012-08-07
          • 2012-04-05
          • 1970-01-01
          • 2020-01-09
          • 1970-01-01
          相关资源
          最近更新 更多