在C中反转阵列的功能(K& R 2nd ed。)

时间:2017-07-23 13:22:47

标签: c kernighan-and-ritchie

尝试练习K& R 2nd ed。的练习1-19,例如编写一个函数来反转字符串。我以为我管理了,但打印输出看起来很奇怪:-)如果我使用STRINGSIZE 5输出是 Original String: hello Reversed String: ollehhello。如果我使用STRINGSIZE 6来记住'\0'字符串结尾字符并将while循环修改为while ((outputString[STRINGSIZE - (i + 2)] = inputString[i]) != '\0'),那么我得到Original String: hello Reversed String: olleh?hello,我想{{1}来自?的一些随机字符添加到位置5的while循环中的反向字符串;但是再次添加了'\0'。任何人都可以解释为什么hello被添加到hello的末尾,我怎样才能摆脱它以便我只得到正确的反向字符串?

以下是代码:

olleh

2 个答案:

答案 0 :(得分:2)

首先,字符数组reversedString[]没有足够的空间来存储字符串"hello"的空终止符。一种选择是在这里使用可变长度数组:

char reversedString[strlen(stringToReverse) + 1];

VGA在C99中引入,并在C11中可选。我记得它,K& R不包括可变长度阵列的覆盖范围,因为即便是第二版也是在此之前发布的。

与C89兼容的另一个选项是使用sizeof运算符:

char stringToReverse[] = "hello";
char reversedString[sizeof stringToReverse];

这里,sizeof运算符的结果在编译时是已知的,并且可以用于声明固定大小的数组。与strlen("hello")的结果相比,此大小包含空终止符的空间。请注意,这不适用于char *stringToReverse = "hello";,因为sizeof运算符会给出指针的大小。如果先将stringToReverse传递给函数,这也不会起作用,因为那时数组名称将衰减为指向stringToReverse的第一个元素的指针。

reverseString()函数中,需要确定inputString的长度(因为不再使用STRINGSIZE);这可以使用strlen()或循环来完成。然后,关键的是,函数必须确定在返回之前向\0添加空终止符(outputString[])。另请注意,在return的末尾添加了main()语句,以使其真正与C89兼容:

#include <stdio.h>

void reverseString (char inputString[], char outputString[]);

int main(void) {
    char stringToReverse[] = "hello";
    char reversedString[sizeof stringToReverse];

    reverseString(stringToReverse, reversedString);
    printf("Original String: %s\nReversed String: %s\n",
           stringToReverse, reversedString);

    return 0;
}

void reverseString(char inputString[], char outputString[])
{
    int length = 0;
    int i = 0;

    /* Get inputString length; or use strlen() */
    while (inputString[length] != '\0') {
        ++length;
    }

    /* Copy to outputString[] in reverse */
    while (i < length) {
        outputString[i] = inputString[(length - i) - 1];
        ++i;
    }

    /* Add null terminator */
    outputString[i] = '\0';
}

答案 1 :(得分:1)

首先,我建议您更改此行:

    char reversedString[STRINGSIZE]; 

char reversedString[strlen(stringToReverse) + 1];  // + 1 to make room for the string termination

然后我会做类似的事情:

void reverseString (char inputString[], char outputString[]) {
    int i;
    int len = strlen(inputString);
    for(i=0; i<len; ++i)
    {
        outputString[len-i-1] = inputString[i];
    }
    outputString[len] = '\0';  // Terminate the string
}