【问题标题】:Syntax and pointer arithmetic语法和指针算法
【发布时间】:2014-07-25 22:40:16
【问题描述】:

只是从我的教科书中查看一个词频计数程序,我有 理解几个片段有点麻烦。

我得到了函数的一般要点,我们从标准输入得到一个词并返回 如果我们找到一个单词,则为 1,否则为 0。

现在,if (strchr(wordChars,ch)) break; 这行只是说,“如果我们 从 stdin 中抓取的是我们要打破循环的字母表的一部分?

接下来,*c++ = ch;这行让我很困惑,这是设置第一个字符吗 到字符串的第二个元素?为什么要这样做?

while ((ch = getchar()) != EOF) {
    ch = tolower(ch);
    if (!strchr(wordChars,ch)) break;
    *c++ = ch;

这是函数的核心,是吗?我们在哪里形成实际的单词。还, if (c == buf) return 0;我假设这条线是在什么都没有或 读取非字母输入。

这里的语法很混乱,\'是一个字符吗?在我看来,这 字符串的元素尚未初始化。如果我们离开那个, 代码的其余部分是我们将单词移回一个元素的地方,这个 对我来说真的没有意义。

if (buf[0] == '\'') {
    for (c = buf+1; *c != '\0'; c++)
        *(c-1) = *c;
    *(c-1) = '\0';
}

接下来,这不是访问和替换吗 单词的最后一个字母?这对我来说很有意义 如果 strlen 包含空字符,但不正确?

n = strlen(buf)-1;

我想我真正想从中得到的就是“\”要传达的意思。

感谢您的帮助!**

int getWord(char *buf){

    int ch, n;
    char *c = buf;
    const char *wordChars = "abcdefghijklmnopqrstuvwxyz'";

    while ((ch = getchar()) != EOF) {
        ch = tolower(ch);
        if (strchr(wordChars,ch)) break;
    }
    if (ch == EOF) return 0;
    *c++ = ch;
    while ((ch = getchar()) != EOF) {
        ch = tolower(ch);
        if (!strchr(wordChars,ch)) break;
        *c++ = ch;
    }
    *c = '\0';
    if (c == buf) return 0;
    if (buf[0] == '\'') {
        for (c = buf+1; *c != '\0'; c++)
            *(c-1) = *c;
        *(c-1) = '\0';
    }
    n = strlen(buf)-1;
    if (buf[n] == '\'') {
        buf[n] = '\0';
    }
    else if (buf[n-1] == '\'' && buf[n] == 's') {
        buf[n-1] = '\0';
    }
    return 1;
}

【问题讨论】:

  • '\'' 表示单引号。 \ 符号的意思是“后面的字符不是字面上的那个字符,而是具有特殊含义”。在这种情况下,特殊含义是因为' 通常表示字符常量的结尾,即'' 将是一个错误。 \ 表示以下 ' 是分隔符内的内容,而不是分隔符本身。
  • 后缀++返回变量的原始值,因此*c++ = ch;这行实际上等价于:*c = ch; c += 1;

标签: c pointers syntax


【解决方案1】:

哇,这么多问题!我会尽力一一解答。

Now, is 'if (strchr(wordChars,ch)) break;' this line just saying, "if the char we grabbed from stdin is part of the alphabet we're breaking the loop?

是的。来自documentation:“如果找不到字符,则函数返回一个空指针。”因此,如果在wordChars 中找不到ch,则strchr 返回NULL,相当于0

Following, '*c++ = ch;' this line confuses me, is this setting the first character to the second element of the string? Why would you want to do this?

没有。这会将第一个字符设置为字符串的 first 元素,然后 then 递增字符串指针。 (从技术上讲,这并不完全正确——实际上发生的事情是指针正在递增,但随后运算符返回 old 指针,这就是正在设置的内容。)这种情况反复发生,写作新的ch 到字符串的末尾。

Also, 'if (c == buf) return 0;' I'm assuming this line is to catch when nothing or a non-alphabetic input is read.

没错。

The syntax here is confusing, is \' a character? It would seem to me that this element of the string hasn't been initialized yet.

如果你输入''',编译器会怎么想?它会看到'',这是一个无效字符(因为撇号之间没有任何内容),然后是另一个',它将保持不匹配。 \ 是转义字符。 \' 基本意思是“编译器,不要把这个撇号当作字符的结束分隔符——把它当作字符!”

If we leave that, the rest of the code is where we shift the word we got back an element, this doesn't really make sense to me.

基本上,您在这里所做的就是从字符#1 一直到单词的末尾,并将字符一个一个地移回一个索引。然后,您必须使用\0 以空值结尾您的字符串。 (请注意,此处的 \ 也是转义字符。您可能需要查看此内容以查看更多示例。Here 是一个参考。)

Next, isn't this accessing and replacing the last letter of the word? It would make sense to me if strlen include the null character, but it doesn't right?

正在替换单词的最后一个字符。具体来说,它用空终止符替换它,有效地删除了最后一个字符。基本上,这段代码和最后一段代码只是从单词的开头和结尾删除了一个撇号。

我希望这会有所帮助!请再问您有什么问题! :)

【讨论】:

  • 没关系,我只是重新阅读了您的答案,您已经回答了我的问题,非常感谢!完美解释。
【解决方案2】:

解决这个代码sn-p:

if (strchr(wordChars,ch)) break;

你的猜测是正确的。这意味着如果在字符串 wordChars 中找到字符 ch,则 strchr() 将返回指向该字符位置的指针。上面的 sn-p,在这种情况下,可以简化为:

if (!NULL) break;

因为返回了一个非空指针。该语句的计算结果为 true(因为 NULL == 0 的计算结果为 false,而 !false 的计算结果为 true),然后触发了一个 break 语句。

为了解决您关于反斜杠的问题,C 中的反斜杠“\”字符表示escape sequence。从链接:

转义序列是在字符或字符串字面量中使用时不代表自身的字符序列,但被翻译成可能难以或不可能直接表示的另一个字符或字符序列。

在这种情况下,'\0' 表示以空字符结尾的字符串的结尾,称为空字符

【讨论】:

  • 非常感谢您的回答,我会阅读更多关于转义序列的内容。我遇到的问题是这个转义序列, if (buf[0] == '\'') { '\'' 代表什么?我确定这不是字符串文字。如果您有时间回复,再次感谢。
  • 因为单引号是 C 中的一个特殊字符,任何时候你想将它用作文字(在这种情况下,在字符串文字中查找单引号的实例) 你需要用反斜杠转义它。 \' 基本上意味着“将该单引号视为文字单引号,而不是 C 中的特殊字符”。因此,语句 if (buf[0] == '\'') {...} 的意思是“如果 buf 的第 0 个索引处的字符是单引号,则执行此 if 语句主体中的内容” .
  • 太棒了,非常感谢 David 澄清了这一点,这是我不必再担心的另一种语法。
  • 很高兴能帮上忙 :)
猜你喜欢
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2010-12-12
相关资源
最近更新 更多