我正在学习C ++。在此处显示的程序中,据我所知,str1
和str2
存储了每个相关字符串的首字符地址:
#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";
这两个声明在第二种情况下导致警告而不是第一种情况有什么不同?
答案 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 *。