解释此C代码以反转字符串

解释此C代码以反转字符串,c,string,algorithm,reverse,C,String,Algorithm,Reverse,我真的不明白最后一个while循环在做什么,有人能解释一下吗 void reverse(char *str) { char * end = str; char tmp; if (str) { while (*end) { ++end; } --end; while (str < end) { tmp = *str; *

我真的不明白最后一个while循环在做什么,有人能解释一下吗

void reverse(char *str) { 
    char * end = str; 
    char tmp; 

    if (str) {
        while (*end) { 
            ++end;
        }
        --end; 
        while (str < end) {
            tmp = *str; 
            *str++ = *end;
            *end-- = tmp;
        }
    }
}
void reverse(char*str){
char*end=str;
char-tmp;
如果(str){
while(*end){
++结束;
}
--结束;
while(str

有人能带我看一下“hello”这个例子吗?

在最里面的while循环中基本上发生的是,在每次迭代中,
str
end
指向的字符被交换,
str
递增,指向下一个字符,并且
end
递减,以指向上一个

以“hello”为例:

v   v
hello
 v v 
oellh
  v
olleh
 H e l l o
 ^       ^
 |       |
str     end

 o e l l H
   ^   ^
   |   |
  str end

 o l l e H
     ^
     |
  str end

然后循环结束,当第一个字符找到最后一个字符时,循环结束;因此,在它之后,
end
将指向它

第二个while将
str
指向的字符与
end
指向的字符交换,并将
str
向前移动1个字符,将
end
向后移动1个字符。这样,字符从字符串的外部交换到内部

end
开始指向
str
之前的一个字符时,查找结束,这意味着我们到达了字符串的中心,并且所有字符都已交换

“你好”示例:


此代码背后的基本思想是分两步进行:

  • 在第一个过程中,我们以指向字符串最后一个字符的指针结束
  • 在第二遍中,我们在知道绳子的末端的帮助下将绳子转过来
  • 第一次通过由以下逻辑给出:

    char *end = str;
    while (*end) { 
        ++end;
    }
    --end; 
    
    while
    循环以指向字符串开头的
    end
    指针开始。然后,它将
    结束
    指针向前移动一步,直到循环条件
    *结束
    不再计算为真。因为C字符串是空的,所以只要是端>代码>指针在字符串中间某个地方,而不是在字符串末尾的null终止符中,则循环条件将被评估为true。因此,当这个循环结束时,
    end
    指针将一直走到字符串的末尾,并在空终止符处停止。然后执行
    --end
    将指针备份一步。此时,
    end
    指针指向字符串中的最后一个字符。下面是一个“你好”的例子:

    现在我们有了这个
    end
    指针,我们实际上运行逻辑来反转字符串。这由该代码给出:

    while (str < end) {
        tmp = *str; 
        *str++ = *end;
        *end-- = tmp;
    }
    
    char *end = str;
    while (*end) { 
        ++end;
    }
    --end; 
    
    此时,两个指针相遇,我们已经正确地反转了字符串

    请注意,这里我们必须考虑一个不寻常的边缘情况,这就是当字符串为空字符串时发生的情况。如果发生这种情况,那么第一个循环的行为将有点奇怪。特别是,该代码:

    while (str < end) {
        tmp = *str; 
        *str++ = *end;
        *end-- = tmp;
    }
    
    char *end = str;
    while (*end) { 
        ++end;
    }
    --end; 
    
    将永远不会执行循环体,因为
    end
    指针将开始指向空终止符。因此,循环什么也不做,我们在字符串开始之前备份
    end
    一步!这是一个无效指针,取消引用它将产生未定义的结果。但幸运的是,在这种情况下,什么也不会发生,因为反转字符串的循环具有以下条件:

    while (str < end)
    
    while(str
    如果
    end
    是字符串开始之前的一个步骤,那么这将立即为false,因此不会发生任何事情


    希望这有帮助

    好的,它是这样做的

    void reverse(char *str) { 
        char * end = str;  // copy the pointer 
        char tmp; 
    
        if (str) {
            // Now step through the string until you get to the last character.
            // which will be the null terminator \0
            while (*end) { 
                ++end;
            }
            // One step back, and we're pointing at the last actual character.
            --end; 
            // Now.  Move the start at either end and work your way inwards until
            // they meet in the middle.
            while (str < end) {
                // take copy of left character into tmp
                tmp = *str; 
                // copy right character into left position and move left pointer right
                *str++ = *end;
                // copy tmp character into right position and move right pointer left
                *end-- = tmp;
            }
        }
    }
    
    void reverse(char*str){
    char*end=str;//复制指针
    char-tmp;
    如果(str){
    //现在逐步遍历字符串,直到找到最后一个字符。
    //哪个将是空终止符\0
    while(*end){
    ++结束;
    }
    //退一步,我们指向最后一个真实的角色。
    --结束;
    //现在,移动两端的起点,然后向内移动直到
    他们在中间相遇。
    while(str
    #包括
    #包括
    main()
    {
    int i=0,长度j;
    char-str[100],st[100];
    printf(“\n输入字符串”);
    scanf(“%s”,str);
    长度=strlen(str);
    对于(i=0,j=(长度-1);str[i]!='\0',j>=0;i++,j--)
    {
    st[j]=str[i];
    }
    st[i]='\0';
    printf(“\n反转的字符串是%s\n”,st);
    }
    
    你试过在纸上画出来吗?试着在一张纸上写出
    hlo\0
    ,然后在代码的每个步骤中遍历
    str
    end
    点以及
    tmp
    包含的内容。是否有一段特定的代码让您感到困惑?它从每一端交换字符,向中间移动…很高兴看到一个不调用
    strlen()
    的解决方案,在调试器中单步执行代码如何。
    void reverse(char *str) { 
        char * end = str;  // copy the pointer 
        char tmp; 
    
        if (str) {
            // Now step through the string until you get to the last character.
            // which will be the null terminator \0
            while (*end) { 
                ++end;
            }
            // One step back, and we're pointing at the last actual character.
            --end; 
            // Now.  Move the start at either end and work your way inwards until
            // they meet in the middle.
            while (str < end) {
                // take copy of left character into tmp
                tmp = *str; 
                // copy right character into left position and move left pointer right
                *str++ = *end;
                // copy tmp character into right position and move right pointer left
                *end-- = tmp;
            }
        }
    }
    
    #include<stdio.h>
    #include<string.h>
    main()
    {
      int i=0,lenght,j;
      char str[100],st[100];
      printf("\nEnter a string");
      scanf("%s",str);
      lenght=strlen(str);
      for(i=0,j=(lenght-1);str[i]!='\0',j>=0;i++,j--)
       {
          st[j]=str[i];
       }
      st[i]='\0';
      printf("\nThe reversed string is %s\n",st);
     }