鱼C论坛

 找回密码
 立即注册
查看: 411|回复: 3

关于指针自增的问题

[复制链接]
发表于 2024-11-9 14:12:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

  5. void test11_13_03()
  6. {
  7.     char str[LIM];
  8.     puts("Please Enter your String:");
  9.     getnchar(str);
  10.     printf("This String is :-----%s\n", str);
  11. }

  12. void getnchar(char *str)
  13. {
  14.     int c, index = 0;
  15.     while ((c = getchar()) != EOF && isspace(c))
  16.     {
  17.     }
  18.     while (!isspace(c))
  19.     {
  20.         str[index++] = c;
  21.         c = getchar();
  22.     }
  23.     str[index] = '\0';
  24. }
复制代码

然后我从 ChatGPT 问了一下,它是这么做的:

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

  3. #define LEN 10
  4. char *getword(char *str);

  5. int main() {
  6.     char word[LEN];

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

  12.     printf("Done.\n");

  13.     return 0;
  14. }
  15. char *getword(char *str) {
  16.     int ch, n = 0;
  17.     char *pt = str;
  18.     while ((ch = getchar()) != EOF && isspace(ch)) {

  19.     }

  20.     if (ch == EOF) {
  21.         return NULL;
  22.     }
  23.     *str++ = ch;
  24.     n++;
  25.     while ((ch = getchar()) != EOF && !isspace(ch) && n < LEN - 1) {
  26.         *str++ = ch;
  27.         n++;
  28.     }

  29.     *str = '\0';
  30.     if (ch != EOF) {
  31.         while (getchar() != '\n') {
  32.         }
  33.     }
  34.     return ch == EOF ? NULL : pt;
  35. }
复制代码

这段代码中

  1.     if (ch == EOF) {
  2.         return NULL;
  3.     }
  4.     *str++ = ch;
  5.     n++;
  6.     while ((ch = getchar()) != EOF && !isspace(ch) && n < LEN - 1) {
复制代码

我没看明白这咕噜:

  1. *str++ = ch;
  2.     n++;
复制代码

为啥 str 不在 while 循环中,但是可以持续自增而不是自增 1 次就结束了 为了 GPT 半天,它也答不出来个所以然,大概就是因为所以自有道理的回答
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-11-9 14:12:27 | 显示全部楼层
让我们来详细解释一下这段代码中的 `*str++ = ch;` 以及它为什么可以连续自增的问题。

### 代码解释

在这段代码中:

  1. *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` 完成了第一次赋值和自增。

**循环中的行为:**

在循环中:

  1. while ((ch = getchar()) != EOF && !isspace(ch) && n < LEN - 1) {
  2.     *str++ = ch;
  3.     n++;
  4. }
复制代码


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

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

### 结论

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

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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-11-9 15:54:04 | 显示全部楼层
本帖最后由 jackz007 于 2024-11-9 16:02 编辑

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

  2. char * getword(char s[])
  3. {
  4.         int c , k                                              ;
  5.         for(k = 0 ; s[k] && (s[k] == ' ' || s[k] == 9) ; k ++) ;
  6.         for(c = 0 ; s[k + c] && s[k + c] != ' ' && s[k + c] != 9 && s[k + c] != '\n' ; c ++) {
  7.                 if(k) s[c] = s[k + c]                          ;
  8.         }
  9.         s[c] = 0                                               ;
  10.         return s                                               ;
  11. }

  12. int main(void)
  13. {
  14.         char s[256]                                            ;
  15.         fgets(s , 256 , stdin)                                 ;
  16.         printf("%s\n" , getword(s))                            ;
  17.         return 0                                               ;
  18. }
复制代码

        编译、运行实况:
  1. D:\[exercise]\C>g++ -o x x.c

  2. D:\[exercise]\C>x
  3.                                         fishC is my site.
  4. fishC

  5. D:\[exercise]\C>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-11-10 20:39:30 | 显示全部楼层
jackz007 发表于 2024-11-9 15:54
ChatGPT 给出的代码是不是过于繁琐?
            请试试下面这个代码如何:

感谢您的回复
研究了半天,第一次知道了for中还可以增加这样的判断,学习了,之前一直只会类似i<LIM这样的判断
学习了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-10 00:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表