首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >while (*p2++ = *p1++);是什么意思?

while (*p2++ = *p1++);是什么意思?
EN

Stack Overflow用户
提问于 2013-05-16 15:07:27
回答 3查看 2.5K关注 0票数 5

我有一个代码块:

代码语言:javascript
运行
复制
int main ()
{
    char *p1 = "Hello";
    char *p2;
    p2 = (char*)malloc (20);
    memset (p2, 0, 20);
    while (*p2++ = *p1++);
    printf ("%s\n", p2);
}

但是我不能解释while (*p2++ =*p1++)这条线的工作原理;你能告诉我这个公式中的运算顺序吗?

EN

回答 3

Stack Overflow用户

发布于 2013-05-16 15:08:48

这是一段经典的C代码,试图通过将所有内容放在一行中而看起来非常聪明。

while (*p2++ = *p1++);等同于

代码语言:javascript
运行
复制
strcpy(p2, p1);
p1 += strlen(p1) + 1;
p2 += strlen(p2) + 1;

换句话说,它复制一个以null结尾的字符串,其中p1指向源字符串的末尾,p2指向目标字符串的末尾。

票数 18
EN

Stack Overflow用户

发布于 2013-05-16 15:11:34

这是一个字符串副本,但您正在丢失原始指针值。您应该保存原始的指针值。

代码语言:javascript
运行
复制
int main ()
{
    char *p1 = "Hello";
    char *p2 = malloc(20);
    char *p3 = p2;
    memset (p2, 0, 20);
    while (*p2++ = *p1++);
    printf ("%s\n", p3);
}

while循环的实际语义解释如下所示:

代码语言:javascript
运行
复制
for (;;) {
    char *q2 = p2;              // original p2 in q2
    char *q1 = p1;              // original p1 in q1
    char c = *q1;               // original *p1 in c
    p2 += 1;                    // complete post increment of p2
    p1 += 1;                    // complete post increment of p1
    *q2 = c;                    // copy character *q1 into *q2
    if (c) continue;            // continue if c is not 0
    break;                      // otherwise loop ends
}

q1q2被保存的顺序以及p2p1被递增的顺序可以互换。在保存q1之后,可以随时将*q1保存到c。在保存c之后,可以随时将c分配给*q2。在我的信封背面,这至少有40种不同的解释。

票数 9
EN

Stack Overflow用户

发布于 2013-05-16 16:12:55

while循环正在计算表达式:*p2++ = *p1++while循环表达式:

使用*p1的结果来评估*p2 = *p1。但是,即使表达式的计算结果为false(0),仍会将此值指定给*p2。重写此代码:

代码语言:javascript
运行
复制
char c;

do
{
    c = *p1; /* read the src byte */
    *p2 = c; /* write to dst byte */

    p2++, p1++; /* increment src, dst pointers */
}
while (c != 0);

您会注意到,读/写操作至少会发生一次。只要C字符串p1是nul结尾的,并且p2有足够的存储空间来存储C字符串,就可以了。也就是说,malloc至少应该分配strlen(p1) + 1字节。在提供的这段代码中,这是真的。

正如其他人所指出的那样,最终的迭代将把p1留在一个结束后的地址上,该地址仍然是一个有效的指针,但在取消引用时会有未定义的结果。p2的地址既是一个有效的指针,也是一个有效的解引用,因为您分配了20个字节。但是,p2不再指向C字符串副本。您想要的等价物是:

代码语言:javascript
运行
复制
char *p1 = "Hello";
char *p2, *tmp;

p2 = (char*)malloc (20);
memset (p2, 0, 20);

tmp = p2;
while (*tmp++ = *p1++);

printf ("%s\n", p2);

大多数操作系统都会在退出main时释放p2中的内存,但通过调用以下命令来释放资源是一种好的做法:

代码语言:javascript
运行
复制
free(p2);

在最后。关于良好实践的主题,您还应该检查malloc的返回值,以确保分配成功。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16581048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档