为什么我在一个案例中使用字符串文字而不是另一个案例得到一个已弃用的转换警告?

时间:2017-11-04 01:59:02

标签: c++ arrays string pointers string-literals

我正在学习C ++。在此处显示的程序中,据我所知,str1str2存储了每个相关字符串的首字符地址:

#include <iostream>
using namespace std;

int main() 
{
    char str1[]="hello";
    char *str2="world";
    cout<<str1<<endl;
    cout<<str2<<endl;
}

但是,str1没有发出任何警告,而str2我收到此警告:

warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     char *str2="world";

这两个声明在第二种情况下导致警告而不是第一种情况有什么不同?

2 个答案:

答案 0 :(得分:3)

写作时

char str1[] = "hello";

你说的是#34;请给我一个包含字符串char的{​​{1}}数组,并请选择数组"hello"的大小为初始化它的字符串。&#34;这意味着str1最终会存储其自己的字符串str1的唯一副本。 "hello"的最终类型为str1 - char[6]为5,空终结符为1。

写作时

hello

你说的是#34;请给我一个类型为char *str2 = "world"; 的指针,指向字符串文字char *。&#34;字符串文字"world"的类型为"world" - 它是一个包含六个字符的数组(五个用于const char[6],另一个用于空终止符),重要的是这些字符是{{1并且无法修改。由于您使用hello指针指向该数组,因此您失去了const修饰符,这意味着您现在(不安全地)拥有非char *指针指向const位数据的指针。

这里的情况不同的原因是,在第一种情况下,您将获得字符串const副本,因此您的数组不是{&t} t { {1}}不是问题。在第二种情况下,您没有获得const的副本,而是获得指向它的指针,并且由于您正在获取指向它的指针,因此担心修改它可能是真正的问题。

换句话说,在第一种情况下,您将获得一个由六个字符组成的诚实至善的数组,其中包含"hello"的副本,因此如果您没有问题然后决定去改变那些角色。在第二种情况下,您将获得指向您不应修改的六个字符数组的指针,但您使用的指针允许您改变事物。

那么为什么const"hello"呢?作为许多系统的优化,编译器只会将hello的一个副本放入程序中,并使文本"world"的所有副本指向内存中完全相同的字符串。这很好,只要你不改变那个字符串的内容。 C ++语言通过说这些字符是const char[6]来强制执行此操作,因此对它们进行改变会导致未定义的行为。在某些系统上,这种未定义的行为会导致像&#34;哇,我的字符串文字中包含错误的值!&#34;而在其他情况下,它可能只是段错误。

答案 1 :(得分:0)

问题是您正在尝试将字符串文字(类型为const char *)转换为char *。