【问题标题】:reverse c style string [duplicate]反向c样式字符串[重复]
【发布时间】:2015-04-20 06:41:10
【问题描述】:

我知道这个问题已经被问过很多次了,但我完全被卡住了。

编辑:这个问题与之前的问题不同,因为问题不在于反向函数的代码,而是可以将哪些类型的值传递给反向函数(即数组与指针).. 请参阅下面的答案了解更多信息。

我只是想反转一个 c 风格的字符串。我直接从破解编码面试中复制并粘贴了代码。 (见下文)

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

这对我不起作用。我对 C 很陌生,所以也许我编译代码错误。我的主要功能如下:

int main(int argc, char *argv[])
{   
    char *string = "foobar";
    reverse(string);
    printf("%s\n", string);

    return 0;
}

我在 Windows 8.1 中使用 Cygwin,并且在我正在运行的命令行上:

gcc ex1.c -Wall -o exe1
./exe1

每次我从窗口弹出“exe1.exe 已停止工作”时。 我尝试在 while 循环中放置一个打印语句来尝试调试并查看发生了什么。在弹出窗口出现之前,它会到达一次while循环。

编辑:阅读 cmets 后,我还尝试将 main 中的代码更改为:

char string[] = "foobar"; 
reverse(string);

当我这样做时,我的程序就会挂起。

我做错了什么?

谢谢!

【问题讨论】:

  • 您将一个常量字符串传递给reverse 函数,然后该函数会尝试对其进行修改。这是无效的,因为常量字符串是只读的。
  • 只需将char *string = "foobar"; 更改为char string[] = "foobar";
  • 这基本上是“只是另一个字符串反转”问题(因此我选择将其作为副本关闭)。它也可能是“只是另一个“不要修改字符串文字””的问题。无论哪种方式,这都不是一个真正的新问题。
  • 我知道这并不新颖。我一开始就这么说了。无论如何,其他答案都没有帮助我弄清楚。似乎这个问题被问了很多,因为有很多事情发生(特别是对于新的编码人员,他们可能还不确定如何阅读代码和提出问题),而不是因为人们没有试图找到答案.

标签: c string pointers cygwin


【解决方案1】:

您的代码的问题与这部分有关char *string = "foobar"; 这里 "foobar" 存储在内存位置,string 保存 "foobar" 的第一个位置,所以现在基本上 string 的行为类似于 const,因此您无法更改其内容。

你可以这样做char string[] = "foobar";

编辑:正如@jonathan-leffler 提到的,我忘了提到内存位置。

char *string = "foobar";
存储在编译时给定内存的数据段上,在运行时尝试修改它会给你一个段错误。

而,
char string[] = "foobar";
存储在堆栈中,可以修改。

EDIT2:阅读下面的 cmets @jonathan-leffler 还有更多要添加的内容

【讨论】:

  • 欢迎来到 Stack Overflow。字符数组和字符串文字都存储在(一系列)内存位置中。不同之处在于修改字符串文字是不合法的——它会导致未定义的行为,这是不惜一切代价避免的事情。在许多(但不是全部)系统上,字符串文字存储在只读内存中,尝试修改它会导致程序崩溃 - 就像问题一样。
  • @JonathanLeffler 编辑了我的答案,谢谢!
  • 嗯;稍微好一点,但是……数据段是可写的,字符串文字通常存储在文本段(不可写)而不是数据段中,至少在现代 C 编译器中是这样。如果您正在使用古老的编译器(意思是上个千年发布的编译器,而不是这个;过度简化,但大致准确),那么您可能会发现字符串文字存储在数据段中并且可以修改,但它修改它们仍然是未定义的行为。
  • @JonathanLeffler 不知道,谢谢。
  • @KarthikNayak this 你可能会感兴趣
【解决方案2】:
 char *string = "foobar";

这里string 是指向字符序列的指针。您不能使用string 修改值foobar。例如试试这个

 string[1]='p';//will throw error

而在您的reverse() 中,您正是这样做的。改用它

char string[]="foobar"; //and now you can modify it

string[1]='p';//wiil work

所以reverse() 也可以工作。

【讨论】:

  • 这并没有真正强调关键点,即不能修改字符串文字。如果你有char data[] = "foobar";char *string = data;,你有string 作为“指向字符序列的指针”,但是序列是可修改的,而当string 指向"foobar" 时,序列是不可修改的。
猜你喜欢
  • 2019-12-09
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 2017-04-10
  • 2011-01-15
  • 1970-01-01
相关资源
最近更新 更多