char *和int *之间的区别

时间:2014-07-21 20:15:50

标签: c++ initialization string-literals

char*int*之间有什么区别?当然,它们的类型不同,但我怎么写呢

char* s1="hello world";

作为

"hello world"

它不是一个字符,它是一个字符数组,我不能写

*s1

作为

char* s1 = {'h','e','l','l','o',' ','w','o','r','l','d'};

int* a = {2,3,1,45,6};

有什么区别?

2 个答案:

答案 0 :(得分:8)

这非常简单:字符串文字,即"foobar"被编译为一个字符数组,存储在程序的静态部分(即存储所有常量的地方)并且以空值终止。然后,将此赋值给变量只需将指向此内存的指针赋给变量。例如,const char* a = "foo";会将存储"foo"的地址指定给a

简而言之,字符串常量已经将内存存储在其中。

相反,没有为指针定义用初始化列表初始化指针(即花括号内的元素列表)。非正式地,初始化列表的问题 - 与字符串文字形成对比 - 是没有"带来自己的内存" 。因此,我们必须提供初始化列表可以存储其字符的内存。这是通过声明一个数组而不是一个指针来完成的。编译好了:

char s1[11]={'h','e','l','l','o',' ','w','o','r','l','d'}

现在,我们通过将s1声明为数组来提供存储字符的空间。

请注意,您可以使用指针的大括号初始化,例如:

char* c2 = {nullptr};

然而,虽然语法似乎相同,但这种情况完全不同,称为统一初始化,只需使用c2初始化nullptr

答案 1 :(得分:3)

在第一种情况下,字符串文字会衰减为指向 const char 的指针。虽然s1确实应该是const char *,但是一些编译器允许另一种形式作为扩展:

const char* s1 = "hello world" ;

sting文字是const char数组,我们可以从draft C++ standard部分2.14.5 字符串文字中看到这一点说(强调我的前进):

  

也引用普通的字符串文字和UTF-8字符串文字   作为窄字符串文字。窄字符串文字具有类型“数组   of n const char“,其中 n 是下面定义的字符串大小,   并具有静态存储时间(3.7)。

将数组转换为指针的内容将在4.2 数组到指针转换部分中介绍:

  

[...]具有类型''数组类型''的表达式转换为   带有''指向类型'的指针的表达式,指向初始值   数组对象的元素,而不是左值。[...]

您的其他情况不起作用,因为标量可以是算术类型,枚举类型或指针类型只能使用括号内的单个元素进行初始化,这将在草案C ++标准部分 {{1 分配和复合赋值运算符 5.17 列表初始化 3 ,其中说:

  

对象或类型T的引用的列表初始化定义为   如下:

然后列举不同的案例,对于这种情况,唯一适用于右侧的案例是以下子弹:

  

否则,如果初始化列表具有E和E类型的单个元素   T不是引用类型或引用类型   与E相关的引用,对象或引用从中初始化   那个元素;如果要求缩小转换(见下文)   将元素转换为T,程序格式不正确。

要求列表包含单个元素,否则最终的子弹应用:

  

否则,该程序格式不正确。

在您的两种情况下,即使将初始化程序缩减为一个变量,类型也是不正确的 8.5.1是一个字符,h2,不会转换为指针。

通过将结果分配给数组,可以使分配工作:

int

这将在 char s1[] = { 'h', 'e', 'l', 'l', 'o',' ', 'w', 'o', 'r', 'l', 'd' } ; int a[] = { 2, 3, 1, 45, 6 } ; 聚合部分中介绍:

  

使用大括号括起来初始化的未知大小的数组   初始化列表包含n个初始化子句,其中n应为   大于零,定义为具有n个元素(8.3.4)。 [例如:

8.5.1
     

将x声明并初始化为具有三个的一维数组   因为没有指定大小,并且有三个初始值设定项。   -end example]空的初始化列表{}不得用作   初始化子句用于未知bound.104的数组

注意:

说没有为指针定义一个brace-init-list是不正确的,它完全可用于指针:

int x[] = { 1, 3, 5 };