8

当我使用 MinGW 运行这个程序时,我得到输出为“=”

#include<iostream>

using namespace std;

int main()
{
 char *str1 = "Hello";
 char *str2 = "Hello";

 if(str1==str2)
 cout<<"=";
 else
 cout<<"!=";


 return 0;
}

但是,从逻辑上讲,它应该是!=,因为这些是指针,它们指向不同的内存位置。当我在我的 Turbo C++ 中运行这段代码时,我得到了!=

4

5 回答 5

14

你是对的,因为它们是指针。但是,它们是否指向不同的位置取决于实现。编译器只存储一次字符串文字并在代码中使用它的任何地方使用它的地址是完全有效的。

于 2012-11-22T15:14:08.390 回答
10

不能保证这两个指针指向不同的内存位置。也许是因为优化,或者编译器使用了自己的规则……行为是“实现定义的”。

根据标准(C++11 §2.14.5 字符串文字):

是否所有字符串文字都是不同的(即存储在不重叠的对象中)是由实现定义的。

于 2012-11-22T15:32:18.680 回答
4

这是预期的结果。您可以通过查看底层程序集来验证这一点。例如,如果我构建:

g++ -S ptr.c

然后您可以在文件输出(ptr.s)中看到以下内容:

        .file   "ptr.c"
        .def    ___main;        .scl    2;      .type   32;     .endef
        .section .rdata,"dr"
LC0:
        .ascii "Hello\0"               ; Note - "Hello" only appears once in
                                       ; this data section!
LC1:
        .ascii "=\0"
LC2:
        .ascii "!=\0"
        .text
.globl _main
        .def    _main;  .scl    2;      .type   32;     .endef
_main:
        [... some stuff deleted for brevity ...]
LCFI5:
        call    ___main
        movl    $LC0, -12(%ebp)        ; This sets str1
        movl    $LC0, -8(%ebp)         ; This sets str2
        movl    -12(%ebp), %eax

我已经注释了两个关键位——在底层代码的 rdata 部分中只有一个“Hello”出现,您可以看到 str1 和 str2 设置在最后,都指向同一个标签:LC0。这是因为 'Hello' 是字符串文字,重要的是,它是常量

正如其他人所指出的 - 根据标准,这是完全合法的。

于 2012-11-22T15:58:41.510 回答
3

字符串文字的类型"Hello"const char数组,因此,您将两个指针指向不允许更改的内容。

C++ 标准使编译器可以自由地将相同的常量值合并在一起(请注意,编译器不需要这样做)。

相关:因此声明无效,必须修改为:

const char *str1 = "Hello";
const char *str2 = "Hello";

或者如果你想

char const *str1 = "Hello";
char const *str2 = "Hello";

从右到左阅读时读起来很好:

str1 is a pointer to const char

.

于 2012-11-22T16:13:07.607 回答
0

char *str1 = "Hello";-- 这条线虽然允许(许多编译器),但实际上是一个坏主意。它基本上只允许与 C 向后兼容,并且实际上写入 *str1 会导致未定义的行为。我建议您找到在执行此操作时会向您发出警告的编译器设置,如果您的编译器缺少此类警告,请寻找新的编译器。

C++ 标准在存储位置方面为编译器和执行环境提供了极大的自由度"String literals"。他们可以从字面上使用指向"literal"部分的"String literals"指针作为 的指针值"literal",并将它们存储在内存中,当您尝试编辑它们时会出现段错误并不意外。

请注意,char buf1[] = "Hello";它的作用根本不同于char* str1 = "Hello";:它实际上buf1用字符初始化缓冲区{'H','e','l','l','o','\0'}

于 2012-11-22T15:37:28.780 回答