苍霖若水 发表于 2024-11-9 14:12:19

关于指针自增的问题

现在再看 Cprimerplus ,第 11 章的练习 3 题目是: 设计并测试一个函数,从一行输入中把一个单词读入一个数组中,并丢弃输入行中的其余字符。该函数应该跳过第 1 个非空白字符前面的所有空白。将一个单词定义为没有空白、制表符或换行符的字符序列。 我写了一版:

#define LIM 81
#include <ctype.h>
#include <stdio.h>
void getnchar(char *str);

void test11_13_03()
{
    char str;
    puts("Please Enter your String:");
    getnchar(str);
    printf("This String is :-----%s\n", str);
}

void getnchar(char *str)
{
    int c, index = 0;
    while ((c = getchar()) != EOF && isspace(c))
    {
    }
    while (!isspace(c))
    {
      str = c;
      c = getchar();
    }
    str = '\0';
}
然后我从 ChatGPT 问了一下,它是这么做的:

#include <stdio.h>
#include <ctype.h>

#define LEN 10
char *getword(char *str);

int main() {
    char word;

    printf("Please enter a word (EOF to quit):\n");
    while (getword(word) != NULL) {
      printf("Result: %s\n", word);
      printf("You can enter a word again (EOF to quit):\n");
    }

    printf("Done.\n");

    return 0;
}
char *getword(char *str) {
    int ch, n = 0;
    char *pt = str;
    while ((ch = getchar()) != EOF && isspace(ch)) {

    }

    if (ch == EOF) {
      return NULL;
    }
    *str++ = ch;
    n++;
    while ((ch = getchar()) != EOF && !isspace(ch) && n < LEN - 1) {
      *str++ = ch;
      n++;
    }

    *str = '\0';
    if (ch != EOF) {
      while (getchar() != '\n') {
      }
    }
    return ch == EOF ? NULL : pt;
}
这段代码中

    if (ch == EOF) {
      return NULL;
    }
    *str++ = ch;
    n++;
    while ((ch = getchar()) != EOF && !isspace(ch) && n < LEN - 1) {
我没看明白这咕噜:

*str++ = ch;
    n++;
为啥 str 不在 while 循环中,但是可以持续自增而不是自增 1 次就结束了 为了 GPT 半天,它也答不出来个所以然,大概就是因为所以自有道理的回答

FishC 发表于 2024-11-9 14:12:27

让我们来详细解释一下这段代码中的 `*str++ = ch;` 以及它为什么可以连续自增的问题。

### 代码解释

在这段代码中:

*str++ = ch;

这里有两部分要理解:

1. `*str = ch;`:将当前字符 `ch` 存储在指针 `str` 所指向的内存位置,也就是把 `ch` 赋给了 `str` 所指的位置。

2. `str++`:自增指针 `str`,使其指向下一个内存位置。

### 工作机制

**第一次赋值并自增:**

- `*str = ch;`:假设 `str` 指向一个数组的起始位置,比如位置 0,这个语句把 `ch` 的值放在数组的第一个位置。
- `str++`:把指针 `str` 移到下一个位置,比如位置 1。

这样在 `if (ch == EOF)` 之后的代码,已经对 `*str = ch` 完成了第一次赋值和自增。

**循环中的行为:**

在循环中:

while ((ch = getchar()) != EOF && !isspace(ch) && n < LEN - 1) {
    *str++ = ch;
    n++;
}

- 在循环中,每执行一次 `*str++ = ch;` 都是相同的逻辑,它把当前字符 `ch` 存储在当前指针 `str` 指向的位置,然后自增 `str`,以便下一次迭代时存储下一个字符到数组的下一个位置。

- 每次循环,使指针 `str` 移动到下一个存储位置,并通过 `n++` 记录已经存储的字符数。

### 结论

所以,尽管 `*str++ = ch;` 不在循环条件中,它在每次循环体执行的时候都会执行。这就是为什么它可以持续自增,并在数组中存储连续字符。

如果还有不明白的地方,可以结合打印每次 `str` 的地址和计算的位置观察指针是如何移动的,这样有助于理解指针的自增过程。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

jackz007 发表于 2024-11-9 15:54:04

本帖最后由 jackz007 于 2024-11-9 16:02 编辑

            ChatGPT 给出的代码是不是过于繁琐?
            请试试下面这个代码如何:
#include <stdio.h>

char * getword(char s[])
{
      int c , k                                              ;
      for(k = 0 ; s && (s == ' ' || s == 9) ; k ++) ;
      for(c = 0 ; s && s != ' ' && s != 9 && s != '\n' ; c ++) {
                if(k) s = s                        ;
      }
      s = 0                                             ;
      return s                                             ;
}

int main(void)
{
      char s                                          ;
      fgets(s , 256 , stdin)                                 ;
      printf("%s\n" , getword(s))                            ;
      return 0                                             ;
}
      编译、运行实况:
D:\\C>g++ -o x x.c

D:\\C>x
                                        fishC is my site.
fishC

D:\\C>

苍霖若水 发表于 2024-11-10 20:39:30

jackz007 发表于 2024-11-9 15:54
ChatGPT 给出的代码是不是过于繁琐?
            请试试下面这个代码如何:



感谢您的回复
研究了半天,第一次知道了for中还可以增加这样的判断,学习了,之前一直只会类似i<LIM这样的判断
学习了{:5_106:}
页: [1]
查看完整版本: 关于指针自增的问题