鱼C论坛

 找回密码
 立即注册
查看: 796|回复: 7

[已解决]*zstr2++; *zstr1++;和*zstr2++ = *zstr1++;的区别是?

[复制链接]
发表于 2024-9-3 21:39:35 | 显示全部楼层 |阅读模式

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

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

x
如下,第32行 为什么写成
*zstr2++;
*zstr1++;

会出错惹

#include <stdio.h>
#include <unistd.h>

#define MAX 1024

int main()
{
        char str1[MAX];
        char str2[MAX];
        char *zstr1 = str1;
        char *zstr2 = str2;
        char ch;//修改
        int n;
       
        printf("请输入一个字符串:");
        fgets( str1, MAX, stdin);
       
        printf("请输入需要拷贝的字符个数:");
        scanf("%d", &n);
       
       
        while( n-- )//
        {
                ch = *zstr2++ = *zstr1++;
                if  (ch == '\0')
                {
                        break;
                }
               
                if ( (int)ch < 0 )
                {
                        *zstr2++ = *zstr1++;
                }
        }       
       
        *zstr2 = '\0';//补上?
       
        printf("开始拷贝 str1的内容到 str2 中....\n");
        sleep(2);
        printf("拷贝完毕!\n");
        printf("现在str2的内容是:%s\n",str2);
       
        return 0;
}
最佳答案
2024-9-3 22:16:06
纪叶 发表于 2024-09-03 22:15
没有想要替换啦
我的意思是
ch = *zstr2++ = *zst ...


在这段代码中,`ch = *zstr2++ = *zstr1++;` 这一行已经完成了从 `zstr1` 到 `zstr2` 的字符复制,并将复制的字符赋值给 `ch`。如果遇到多字节字符(如中文字符),通常会需要更多处理。

多字节字符(如UTF-8编码的中文字符)可能由多个字节组成,而许多字符使用负值来表示UTF-8序列的一部分。因此,`if ((int)ch < 0)` 这个条件用来判断当前字符是否可能是多字节字符的一部分。如果是,那么为了完整复制整个字符,通常需要覆盖或继续复制后续字节。

以下是关于代码中涉及的逻辑的简单解释:

- **`ch = *zstr2++ = *zstr1++;`**:复制当前字符并移动指针。
  
- **`if ((int)ch < 0)` 判断**:如果字符是一个多字节字符的一部分(通常在UTF-8编码下负值为标识),那么仅复制一个字节不足以完整复制该字符。

- **`*zstr2++ = *zstr1++;`**(第二次的复制):确保完整复制多字节所需的后续字节。

复制多字节字符需要保证足够的字节被读取和写入。因此,通过再次执行 `*zstr2++ = *zstr1++;`,你可以确保整个字符(假设两个字节是可接受的范围)被完整复制。

直接使用 `*zstr2++; *zstr1++;` 并不会满足这个要求,因为这样只会移动指针而不进行复制。保持在这个检查中使用两次的赋值操作,可以保证对多字节字符的完整性进行处理。

注意:这还假设是一个双字节字符的简单情况。对于UTF-8,实际上可能有更多字节构成一个字符,此时需要更复杂的逻辑来完全处理各种可能性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-9-3 21:52:47 | 显示全部楼层
这个代码片段中,`*zstr2++ = *zstr1++;` 和
*zstr2++;
*zstr1++;
的区别主要在于它们的语义和作用。

1. **`*zstr2++ = *zstr1++;`**:

   - 等价于:`*zstr2 = *zstr1; zstr2++; zstr1++;`
   - 这一行代码完成了以下操作:
     - 将`zstr1`指向的字符复制到`zstr2`指向的位置。
     - 然后同时将`zstr1`和`zstr2`指向下一个字符。
   - 这个语句实质上是在进行字符的拷贝。

2. **`*zstr2++; *zstr1++;`**:

   - 分解为两个独立的操作:
     - `*zstr2++;`:只是将`zstr2`向后移动一位,但没有对`zstr2`所指向的内容进行任何赋值。
     - `*zstr1++;`:同样只是将`zstr1`向后移动一位,不读取或使用`zstr1`所指向的值。
   - 这两行代码并没有进行任何复制操作,仅仅是将指针向后移动。因此,`str2`的内容不会被更改,从而导致结果不正确或不可预测的行为。

### 问题分析:

- 在你的代码中,`str1`和`str2`的定义应为字符数组,而非单个字符,这样才能用于存储字符串。可能的正确定义方式应为:
  
char str1[MAX];
  char str2[MAX];

- `*zstr2++ = *zstr1++;` 正确地执行了字符复制,同时移动了指针。
- 使用`*zstr2++; *zstr1++;`没有执行任何有效的字符复制,导致指针的移动实际没有改变字符串`str2`的内容。

确保定义字符数组,并使用`*zstr2++ = *zstr1++;`格式来实现逐个字符的逐步复制,这是拷贝字符串的标准方式。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-3 21:58:13 | 显示全部楼层
FishC 发表于 2024-9-3 21:52
这个代码片段中,`*zstr2++ = *zstr1++;` 和

但是不是在前面有:
ch = *zstr2++ = *zstr1++;
这行的操作不就是复制str1去str2嘛
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-3 22:05:05 | 显示全部楼层
纪叶 发表于 2024-09-03 21:58
但是不是在前面有:
ch = *zstr2++ = *zstr1++;
这 ...


是的,代码中的 `ch = *zstr2++ = *zstr1++;` 确实完成了从 `str1` 到 `str2` 的字符复制,而且将当前复制的字符存储在变量 `ch` 中。这行代码实际上可以分解为以下几个步骤:

1. 从 `zstr1` 当前指向的位置读取一个字符。
2. 将该字符赋值给 `zstr2` 当前指向的位置,同时赋值给变量 `ch`。
3. 移动 `zstr1` 和 `zstr2` 指针,使它们分别指向下一个位置。

因此,`ch = *zstr2++ = *zstr1++;` 已经完成了字符的复制操作,并且移动了指针。

### 原因为什么不能仅仅用 `*zstr2++; *zstr1++;`

如果将这行替换为:
*zstr2++;
*zstr1++;

则将不会有实际的字符复制发生。每一行仅仅是对指针进行了递增操作,而没有执行赋值。因此,这会导致 `str2` 不会被正确填充,这就是为什么这种写法会出错或导致结果不符合预期。

### 需要注意的地方

确保 `str1` 和 `str2` 是字符数组而不是单个字符,以便能够存储字符串。同时,要确保在程序中合理处理字符串的结束标记 `'\0'`,以避免拷贝超过字符串长度的内容,导致未定义行为。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-3 22:15:55 | 显示全部楼层
FishC 发表于 2024-9-3 22:05
是的,代码中的 `ch = *zstr2++ = *zstr1++;` 确实完成了从 `str1` 到 `str2` 的字符复制,而且将当前 ...

没有想要替换啦
我的意思是
ch = *zstr2++ = *zstr1++;
                if  (ch == '\0')
                {
                        break;
                }
               
                if ( (int)ch < 0 )
                {
                        *zstr2++ = *zstr1++;
                }

这里 第一行就对zstr2所指向的赋值了, 那什么在最后那里 判断该字符是不是中文那里,需要再赋值一次,而不是直接让zstr1和zstr2 跳去下一个位置
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-3 22:16:06 | 显示全部楼层    本楼为最佳答案   
纪叶 发表于 2024-09-03 22:15
没有想要替换啦
我的意思是
ch = *zstr2++ = *zst ...


在这段代码中,`ch = *zstr2++ = *zstr1++;` 这一行已经完成了从 `zstr1` 到 `zstr2` 的字符复制,并将复制的字符赋值给 `ch`。如果遇到多字节字符(如中文字符),通常会需要更多处理。

多字节字符(如UTF-8编码的中文字符)可能由多个字节组成,而许多字符使用负值来表示UTF-8序列的一部分。因此,`if ((int)ch < 0)` 这个条件用来判断当前字符是否可能是多字节字符的一部分。如果是,那么为了完整复制整个字符,通常需要覆盖或继续复制后续字节。

以下是关于代码中涉及的逻辑的简单解释:

- **`ch = *zstr2++ = *zstr1++;`**:复制当前字符并移动指针。
  
- **`if ((int)ch < 0)` 判断**:如果字符是一个多字节字符的一部分(通常在UTF-8编码下负值为标识),那么仅复制一个字节不足以完整复制该字符。

- **`*zstr2++ = *zstr1++;`**(第二次的复制):确保完整复制多字节所需的后续字节。

复制多字节字符需要保证足够的字节被读取和写入。因此,通过再次执行 `*zstr2++ = *zstr1++;`,你可以确保整个字符(假设两个字节是可接受的范围)被完整复制。

直接使用 `*zstr2++; *zstr1++;` 并不会满足这个要求,因为这样只会移动指针而不进行复制。保持在这个检查中使用两次的赋值操作,可以保证对多字节字符的完整性进行处理。

注意:这还假设是一个双字节字符的简单情况。对于UTF-8,实际上可能有更多字节构成一个字符,此时需要更复杂的逻辑来完全处理各种可能性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-3 22:22:07 | 显示全部楼层
FishC 发表于 2024-9-3 22:16
在这段代码中,`ch = *zstr2++ = *zstr1++;` 这一行已经完成了从 `zstr1` 到 `zstr2` 的字符复制,并将 ...

好的我懂了w

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-3 22:39:32 | 显示全部楼层


很高兴能帮到你!如果还有其他问题或需要进一步的帮助,请随时问我。祝你编码顺利!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 02:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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