gpt4 book ai didi

c - 使用 memcpy 时出现意外结果

转载 作者:行者123 更新时间:2023-11-30 14:58:17 27 4
gpt4 key购买 nike

嗨,我遇到了这个简单的 C 程序,但我无法理解这段代码是如何工作的:

#include <string.h>
#include <stdio.h>

char *a = "\0hey\0\0"; /* 6 */
char *b = "word\0up yo"; /* 10 */
char *c = "\0\0\0\0"; /* 4 */

int main(void)
{
char z[20];
char *zp = z;
memcpy(zp, a, strlen(a)+1);
memcpy(zp, b, strlen(b)+1);
memcpy(zp, c, strlen(c)+1);
/* now z contains all 20 bytes, including 8 NULLs */
int i;

for(i = 0; i < 20; i++){
if (z[i] == 0){
printf("\\0");
}

printf("%c", z[i]);}
return 0;
}

我期望打印 z 的输出是:

\0hey\0\0\0word\0up yo\0\0\0

但我得到的是:

\0ord\0\0\0\0\0\0\0\0\0\0\0\0???Z

最后,当我打印 a 而不是 z 时,我得到了正确的输出。谁能向我解释为什么会发生这种情况?提前致谢。

编辑:我如何连接这些字符串?

最佳答案

C 中的字符串以零结尾;标准 C 库中的函数具有此属性。特别是,函数 strlen 返回从字符串开头算起的非零字符数。在您的示例中,strlen(a) 等于 0,因为 a 的第一个字符为零。

该代码将具有以下效果:

 memcpy(zp, a, strlen(a)+1);

现在zp仍然包含\0,因为strlen(a)是0,所以复制了1个字符。

 memcpy(zp, b, strlen(b)+1);

现在 zp 包含 word\0:复制了五个字符。

 memcpy(zp, c, strlen(c)+1);

现在仅覆盖 zp 的第一个字符,因此它包含 \0ord\0

Finally , when i print a instead of z i get the right output. Can anyone explain to me why this happens ? Thanks in advance.

这是因为 abc 恰好在内存中按顺序分配。当您打印“从 a 开头开始的 20 个字节”时,您实际上是在查看 a 最新字节之后的内存。该内存恰好包含b。所以你实际上开始阅读bbc 也是如此。请注意,这绝不是保证。回顾一下为 char * 分配的内存,实际上是一个未定义行为的实例。

How i could concatenate such strings?

一般来说,无法在运行时找到此类“字符串”的长度。我不会将它们称为字符串,因为“字符串”在 C 语言中具有特定含义 - 它指的是以零结尾的字符串,而您的字符串只是内存区域。

但是,由于您在编译时知道大小,因此可以使用它。为了避免代码中出现魔数(Magic Number),最好使用 char 数组而不是 char 指针,因为这样您就可以使用 sizeof 运算符。但是,请注意,C 中的所有字符串文字都隐式以零结尾!为了将结果放入 20 字节缓冲区,您需要使用 sizeof(x) - 1:

char a[] = "\0hey\0\0";   /*  6 */
char b[] = "word\0up yo"; /* 10 */
char c[] = "\0\0\0\0"; /* 4 */

memcpy(zp, a, sizeof(a) - 1);
zp += sizeof(a) - 1;
memcpy(zp, b, sizeof(b) - 1);
zp += sizeof(b) - 1;
memcpy(zp, c, sizeof(c) - 1);

关于c - 使用 memcpy 时出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43410386/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com