如何反转char *类型的字符串?

how to reverse a string of type char *?

我正在使用 reverse 函数。

void reverse(char s[]) {
    int i, j;
    char c;
 
    for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
        c = s[i]; 
        s[i] = s[j];
        s[j] = c;
    }
}

如果我传递类型为 char a[] = "abcd" 的字符串,那么我会得到输出 dcba.

但是如果我通过 char *a = "abcd" 我得到 bus error.

我能以某种方式完全反转 char * 类型的字符串吗?

源代码:

#include <stdio.h>
#include <string.h>

void reverse(char s[]);

int main() {
    char a* = "abcd";
    reverse(a);
    printf("%s", a);
}

void reverse(char s[]) {
    int i, j;
    char c;
 
    for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { 
        c = s[i]; 
        s[i] = s[j];
        s[j] = c; 
    }
}

你的反向功能没问题。问题是您通过这样做将字符串实例化为文字: char *a = "abcd";(顺便说一句,它是“*a”而不是 'a*')

您不能修改字符串文字。 要测试您的功能,您可以这样做:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void reverse(char s[]);

int main(){
    char *a = malloc(sizeof(char) * 5);
    if (a == NULL)
        return 1;
    a[0] = 'a';
    a[1] = 'b';
    a[2] = 'c';
    a[3] = 'd';
    a[4] = '[=10=]';
    reverse(a);
    printf("%s", a);
    free(a);
}

void reverse(char s[]){
     int i, j;
     char c;

     for (i = 0, j = strlen(s) - 1; i<j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
     }
}

没有 char * 类型的字符串。字符串是以 zero-character '[=16=]'.

结尾的字符序列

在此声明中(有错字 char a* = "abcd";

char *a = "abcd";

声明了一个指向字符串文字的指针。字符串文字本身的类型为 char[5]。但用作初始化表达式时,它会隐式转换为指向其类型 char *.

的第一个元素的指针

并且您正在尝试更改函数 reverse.

中指针指向的字符串文字

但是您不能更改字符串文字。任何更改字符串文字的尝试都会导致未定义的行为。

来自 C 标准(6.4.5 字符串文字)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

你可以做的是创建一个新的字符串,它将以相反的顺序存储源字符串文字的字符。

例如

char * reverse_copy( const char *s )
{
    size_t n = strlen( s );

    char *t = malloc( n + 1 );

    if ( t != NULL )
    {
        t += n;
        *t = '[=11=]';

        while ( *s ) *--t = *s++;
    }

    return t;
}

而且函数可以这样调用

char *s = "abcd";
char *p = reverse_copy( s );
if ( p != NULL ) puts( p );
free( p );

这是一个演示程序。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char *reverse_copy( const char *s )
{
    size_t n = strlen( s );

    char *t = malloc( n + 1 );

    if (t != NULL)
    {
        t += n;
        *t = '[=13=]';

        while (*s) *--t = *s++;
    }

    return t;
}

int main( void )
{
    char *s = "abcd";

    char *p = reverse_copy( s );
    if (p != NULL) puts( p );

    free( p );
}

程序输出为

dcba