c++ - 带分号的 while 循环内的指针递减与不带分号的比较

标签 c++ c pointers while-loop

void* My_memmove(void *dest, const void *src, size_t size)
{
    char *p1 = (char *)dest;
    char *p2 = (char *)src;

    if(NULL == p1 || NULL == p2)
    {
        return NULL;
    }
    p2 += size;

    while(p2 != src &&  --p2 != dest)
    if(p2 != src)
    {
        printf("inside IF \n");
        p1 += size;
        p2  = (char *)src + size;

        while(size--)
        {
            *(--p1) = *(--p2);
        }
    }
    else
    {
        printf("inside ELSE \n");
        while(size--)
        {
            *(p1++) = *(p2++);
        }
    }

    return dest;
}

int main(void)
{
   char dest[15];
   memset(dest, 0, 15);

   printf("Enter the string : ");
   scanf("%s", dest);

    My_memmove(dest+3, dest, strlen(dest));
    printf("dest+3 : %s \n", dest+3);

    return (0);
}

请解释一下当 while(p2 != src && --p2 != dest) 后面没有分号时会发生什么 因为上面的程序适用于除了大小为 4 的输入之外的所有输入

结果:

输入字符串:12

IF内

目的地+3:12

输入字符串:123

IF内

目的地+3:123

输入字符串:1234

目的地+3:4

输入字符串:12345

IF内

目的地+3:12345

输入字符串:123456

IF内

目的地+3:123456

size为7时p2+size后的内存布局

                      p2+--+
                           | 
        src+-+ dst++       |
             |     |       |
             v     v       v
            ++-----+-------+--------+
            |0|1|2|3|4|5|6|7|8| ... |
            +-----------------------+
dest[15] -> |a|b|c|d|e|f|g|0|0| ... |
            +-----------------------+

最佳答案

使用while(或forif),您对正文有两种选择。您可以将花括号用于多语句主体:

while(condition) {
    multi;
    statement;
    body;
}

或者您可以省略大括号,下一条语句将被视为循环体。对于短正文来说,如果有良好的格式设置,这可能会很好:

if(condition)
    return thing;

但它也可能与错误的格式混淆:

if(condition)
    thing += thing2;
    return thing;

只有第一条语句 (thing += thing2) 实际上位于 if 的主体中。无论如何,return 每次都会运行。

分号本身就是空语句。它本身就是一个完整的声明,但它什么也没做。所以

while(condition);

与相同

while(condition) {
    ;
}

不带分号的另一个示例将提取代码中找到的下一条语句并将其用作循环体。

<小时/>

为了响应您的更新,让我们通过运行输入“abcd”的函数来查看字符串的内存:

        src--+ dst-+
             |     |
             v     v
            ++-----+----------------+
            |0|1|2|3|4|5|6|7|8| ... |
            +-----------------------+
dest[15] -> |a|b|c|d|0|0|0|0|0| ... |
            +-----------------------+

请注意,这里的 size 是 4,因此当您执行 char *p2 = (char *)src;p2 += size; 时>,您的指针如下所示:

       p2+--+
            |
src+-+ dst++|
     |     ||
     v     vv
    ++-----+----------------+
    |0|1|2|3|4|5|6|7|8| ... |
    +-----------------------+
    |a|b|c|d|0|0|0|0|0| ... |
    +-----------------------+

然后你就可以:

while(p2 != src &&  --p2 != dst)

好吧,猜猜看,--p2 正是 dst!因此,您的循环结束时不会运行一次,您只需返回 dst,它是指向字符串中最后一个字符的指针。

这是尝试在其内部复制字符串的众多问题之一。您的来源和目的地重叠!

关于c++ - 带分号的 while 循环内的指针递减与不带分号的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59181383/

相关文章:

c++ - 多重继承中的指针相等

c++ - VS2008 是否支持 C++0x?

c++ - 正确使用 exec 命令在 unix 中调用 wget

c++ - 编译非常简单的 boost::spirit 语法时出错

c - 有没有办法禁止linux上的gnu malloc分配某些内存区域?

c - 当 C 函数指针具有 void 参数时,这意味着什么?

c++ - 从 C 在 Linux 中的帧缓冲区上绘制文本

arrays - 语: Construct an array from a pointer and length

由 2 个文件共享的 C++ 变量

c++ - 使用 tcp 套接字执行 async_write 时,何时调用处理程序?