【问题标题】:What is the difference between *s and s[i] in this function?此函数中的 *s 和 s[i] 有什么区别?
【发布时间】:2014-05-03 11:27:05
【问题描述】:

我正在阅读“The C Programming Language”(Kernighan & Ritchie),在关于指针的章节中,它提供了“strcpy”函数的两个副本。一种用于数组,另一种用于指针。我相信这两个版本的显示是为了说明数组和指针之间的区别,但我看不出是什么。

数组版本为:

void strcpy(char *s, char *t) {
    int i = 0;
    while ((s[i] = t[i]) != '\0') {
        i++;
    }
}

指针版本为:

void strcpy(char *s, char *t) {
    while ((*s = *t) != '\0') {
        s++;
        t++;
    }
}

然而,这本书还指出“......在评估 a[i] 时,C 立即将其转换为 *(a+i)”。在哪种情况下,这两个函数肯定在做完全相同的事情?

N.B 我知道有更优雅的方式来编写这段代码,我只是按照书中的原样复制了它。

【问题讨论】:

  • 我想说,这些函数更能说明数组和指针的等价性,因为它们解决了同样的问题。
  • “显示这两个版本是为了说明数组和指针之间的区别” - 并非如此。它们只是向您展示如何使用数组语法和简单的指针语法来做到这一点。
  • 虽然数组和指针是不等价的。 “array-pointer equivalence”是一个用词不当,会引起很多人的注意,而这一切都只是基于s 为您提供一个与@987654324 值相等的右值@,在右值上下文中。
  • @MattMcNabb 它也适用于左值上下文,*s = X 等效于 s[0] = X,即使对于数组 s
  • 作为* 的操作数正在请求s 上的左值到右值转换,这就是我的意思

标签: c arrays pointers


【解决方案1】:

我相信显示这两个版本是为了说明数组和指针之间的区别。

不,不是真的。这两个版本用于证明可以使用a[i] 语法或直接指针算法来实现数组索引。

正如您正确指出的那样,这两个版本执行完全相同的操作。毕竟,它们都是strcpy 的实现。关键是作者试图展示不同的方法来实现相同的最终结果。

【讨论】:

    【解决方案2】:

    在哪种情况下,这两个函数肯定在做同样的事情?

    没错。

    一个版本保持指针不变,并在每次访问时添加一个偏移量i,该偏移量不断增加。

    另一个版本修改了指针变量,直接指向我想要的地方。

    【讨论】:

      【解决方案3】:

      *ss[0] 的替代语法。看看这个版本:

      void my_strcpy(char *s, char *t)
      {
          int i = 0;
          while ((s[i] = t[i]) != '\0')
          {
              if ( rand() % 2 )
                   ++i;
              else
                   ++s, ++t;
          }
      }
      

      这是为了说明两个例子的区别是一个增加索引,一个增加基数;但这两者都实现了相同的目标。无论使用a[b] 还是*(a+b) 形式的语法都没有区别,它们的定义是相同的。考虑s[i]*(s+i) 是同一事物的替代语法也可能会有所帮助。递增s 与递增i 的效果相同。

      【讨论】:

        【解决方案4】:

        在数组版本中,要访问数组,您正在使用 s[i] 并通过增加索引 i 您可以访问字符串中的字符。 在指针方法的情况下,您不使用索引变量并通过递增指针即 s 和 t ,您正在访问字符串中的字符。这就是上述程序中的区别。这里 *s 表示 *(s+0) 等价于 s[0] 并且 s[i] 在内部表示 *(s+i)。

        【讨论】:

          猜你喜欢
          • 2020-02-26
          • 2010-12-14
          • 2021-02-26
          相关资源
          最近更新 更多