反向功能未按预期工作

Reverse function is not working as expected

我正在尝试找出程序:"Write a function reverse(s) that reverses the characte string s. Use it to write a program that reverses its input a line at a time."

我认为像下面这样的伪代码应该可以工作:

"复制字符串s到tmp,同时增加迭代器。 将字符串 tmp 复制到 s,同时减少初始迭代器,增加 new

#include <stdio.h>

void reverse(char []);

int main(){
    char string[50]="HelloWorld";
    printf("Consider Given string: %s\n",string);
    reverse(string);
    printf("The same string, reversed: %s\n",string);
}

void reverse(char s[]){
    char tmp[50];
    int i,j;
    for (i=0;(tmp[i]=s[i])!='[=10=]';++i);
    for (j=0;i>0;i--,j++)
        s[j]=tmp[i];
}

作为输出,我得到:

pi@readonly:~/new$ a.out
Consider Given string: HelloWorld
The same string, reversed: 

在使用gdb调试的时候,发现如下:

Breakpoint 5, reverse (s=0x7efff5a4 "HelloWorld") at 1.c:18
18                              s[j]=tmp[i];
1: j = 0
2: i = 10
3: tmp = "HelloWorld", '[=12=]0' <repeats 15 times>, "07v457~023v[=12=]0[=12=]0[=12=]0[=12=]0457~,[=12=]6[=12=]1[=12=]00[=12=]4"
4: s = 0x7efff5a4 "HelloWorld"
(gdb) n
17                      for (j=0;i>0;i--,j++)
1: j = 0
2: i = 10
3: tmp = "HelloWorld", '[=12=]0' <repeats 15 times>, "07v457~023v[=12=]0[=12=]0[=12=]0[=12=]0457~,[=12=]6[=12=]1[=12=]00[=12=]4"
4: s = 0x7efff5a4 ""
(gdb) n

Breakpoint 5, reverse (s=0x7efff5a4 "") at 1.c:18
18                              s[j]=tmp[i];
1: j = 1
2: i = 9
3: tmp = "HelloWorld", '[=12=]0' <repeats 15 times>, "07v457~023v[=12=]0[=12=]0[=12=]0[=12=]0457~,[=12=]6[=12=]1[=12=]00[=12=]4"
4: s = 0x7efff5a4 ""

问题:

1) 为什么字符串tmp中列出的字符串元素在i=0时突然从字符串s中消失了,但是,在那之前步?也就是说,字符串s发生了什么,在断点17,for (j=0;i>0;i--,j++)?

2) 是否可以在同一个 for 循环中使用逗号声明和分配不同的函数类型?换句话说,为什么下面的构造在尝试编译时会出错?有没有办法在单一循环中混合不同的标识符类型?

建设:

void reverse(char s[]){
    for (char tmp[50],int i=j=0;(tmp[i]=s[i])!='[=13=]';++i);
    for (j=0;i>0;i--,j++)
        s[j]=tmp[i];
}

错误:

pi@readonly:~/new$ cc 1.c
1.c: In function ‘reverse’:
1.c:14:21: error: expected identifier or ‘(’ before ‘int’
for (char tmp[50],int i=j=0;(tmp[i]=s[i])!='[=14=]';++i);
                 ^~~
1.c:14:36: error: ‘i’ undeclared (first use in this function)
for (char tmp[50],int i=j=0;(tmp[i]=s[i])!='[=14=]';++i);
                                ^
1.c:14:36: note: each undeclared identifier is reported only once for each function it appears in
1.c:15:8: error: ‘j’ undeclared (first use in this function)
for (j=0;i>0;i--,j++)
    ^
1.c:16:9: error: ‘tmp’ undeclared (first use in this function)
s[j]=tmp[i];

在这个循环的开始:

for (j=0;i>0;i--,j++)
    s[j]=tmp[i];

tmp[i] 包含字符串末尾的终止空字节。因此,您将该空字节复制到 s 的开头,得到一个空字符串。

索引tmpi的值减1。这样,您将从最后一个常规字符开始并在第一个常规字符结束。

for (j=0;i>0;i--,j++)
    s[j]=tmp[i-1];

C 字符串由 [=11=] 字符终止,您的 reverse 函数将此字符串终止字符从源字符串的末尾复制到目标字符串的开头。目标字符串将是 "empty",因为它在开头就终止了。

您必须考虑两件事:

首先,在访问tmp时先开始一个结束:

for (j=0;i>0;i--,j++)
    s[j]=tmp[i-1];

其次,确保目标字符串已终止。如果目标字符串与源字符串相同,则无需执行任何操作,因为 [=11=] 已经就位。

如果你以某种方式复制到不同的目标,你必须在循环后写 [​​=15=]。