【问题标题】:Stuck with syntax in c - pointers卡在 c 中的语法 - 指针
【发布时间】:2010-02-21 12:10:41
【问题描述】:

如果我们有一个char *hello - 并且字符串是"hello"

我愿意

char *ptr;
ptr = hello;

那么 ptr 将指向'h',对吗?

现在我刚刚完成了一个assignmnet,并使用以下术语完成了它

如果我想将指针移动到下一个聊天室,我会做ptr++。如果我想使用指针的值进行一些检查,我会使用if(*ptr == '\0')...

当我做assignmnets时,我们的老师给了我们一些预先构建的方法,他们使用了像

这样的东西
*string++ = *s++;

好的,那么我们为什么要这样做 *string(它会得到一个值) - 并将它与 ++ 结合起来

我希望我解释不清楚的地方是有意义的。它只是我设法用 ptr++ 完成整个分配以移动到下一个元素或 *ptr 以检查其值

【问题讨论】:

  • @leo 我假设"hello" 是字符文字,所以我把它放在引号内。如果是变量名,当然不需要引号(但是你的第一个问题没有多大意义)。
  • 只是试图编辑它以使其更有意义

标签: c syntax pointers


【解决方案1】:

成语*s++的意思是“取指向的值,并切换到下一个”。 这样,您可以循环执行检查操作。赋值*p++ = *q++*q 的值复制到p 指向的位置,并将pq 移动到下一个位置,因此下次执行*p++ = *q++ 时下一个字符将是复制到第一个后面。以此类推。

【讨论】:

  • @Vlad,您的 p/q 方向错误。希望你不介意修复。
【解决方案2】:

不完全是。在您最初的问题中,ptr 将被设置为指向与hello 相同的第一个字符,这可能不一定h。你可能已经这样做了:

char *hello = "goodbye";

在这种情况下helloptr 都将指向g。但是,您的编辑现在清楚表明您的意思是:

char *hello = "hello";

您对ptr++ 的评论是正确的。它将移动ptr 使其指向下一个字符,并且根据C 字符串处理约定,'\0' 标记字符串的结尾。

声明:

*string++ = *s++;

是你在字符串复制代码中经常看到的东西(将s复制到string),类似:

char *mystrcpy (char *d, char *s) {
    char *d2 = d;
    while (*s != '\0')
        *d2++ = *s++;
    *d2 = '\0';
    return d;
}

在这种情况下,*d2++ = *s++; 表示:

  • s处的字符复制到内存位置d2
  • 增加d2 以指向下一个目标字符。
  • 增加s 以指向下一个源字符。

换句话说,

*string++ = *s++;

在功能上等同于:

*string = *s;
string++;
s++;

【讨论】:

  • 犯了一个错误 - 我想要一个名为 hello 的 *char 表示字符串“hello”
【解决方案3】:

那么我们为什么要做 *string(它得到一个值) - 并将它与 ++ 结合起来

*string在等号的左边时,它不获取值,它设置值。

语句*string++ = *s++;等价于:

*string = *s;
s++;
string++;

这是因为x++postfix increment operator(而不是++x,它是前缀增量运算符)。指针 x 已更新,但表达式中使用了 x 最初指向的值。

就我个人而言,我会说单行文字更容易阅读,您通常应该尽量避免使用具有副作用的复杂表达式。但在这种情况下,它是 C 中相当标准的习语,所以您不妨习惯它。

【讨论】:

  • 所以我可以用我的分解阶段版本获得相同的结果?
  • 是的,您不必在一条线上完成所有操作 - 您可以将其拆分。但是在处理这种类型的代码时,您需要非常小心地了解前置和后置增量运算符是如何工作的。很容易出错。
  • 感谢 Mark,我正在努力理解它,至少 C 模块比 Haskell 模块更容易理解:D
【解决方案4】:

那么 ptr 将指向 h,对吗?

是的。 不是。见@paxdiablo's answer

*string++ = *s++;

这个语句可以看成

*string = *s;
string ++;
s ++;

这意味着:

  1. s中的字符复制到string指向的位置。
  2. sstring 移动到下一个字符。

【讨论】:

    【解决方案5】:

    那么 ptr 将指向 h,对吗?

    是的,正确。

    好的,那我们为什么要做 *string(它得到一个值)

    “*”不一定获得值:它可能会设置一个值,具体取决于它位于“=”符号的哪一侧。

    char *ptr;
    ptr = "hello";
    char firstLetter = *ptr; //get the value: now firstLetter contains 'h'
    *ptr = 'w'; //set the value: now ptr is pointing to "wello".
    

    将 * 与 ++ 组合意味着你一个接一个地做:

    • 在右侧,'*s++' 表示“获取 s 指向的值,然后递增 s 指针”。
    • 在左侧,'*string++' 表示“设置字符串指向的值,然后递增字符串指针”。

    将它们组合成一个语句只是一种更短、更紧凑(但功能等效)的编写方式:

    *string = *s;
    string++;
    s++;
    

    【讨论】:

      【解决方案6】:

      只是对 Mark Byers 答案的快速补充,他正确指出了后缀增量(“a++”)而不是前缀增量(“++a”)。

      您可能想查看C operator precedence,了解表达式中运算符的处理顺序。

      您始终可以通过使用括号来强制执行您想要的优先级:(a + b) * c != a + b * c。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-05
        • 1970-01-01
        • 2012-12-16
        相关资源
        最近更新 更多