C++ char*和int之间的区别*

C++ char*和int之间的区别*,c++,initialization,string-literals,C++,Initialization,String Literals,char*和int*之间有什么区别?当然,它们是不同类型的,但是我怎么能写呢 char* s1="hello world"; 作为 它不是一个字符,它是一个字符数组,我不能写 *s1 作为 及 区别是什么?非常简单:字符串文本,即“foobar”被编译成一个字符数组,该数组存储在程序的静态部分(即存储所有常量的地方),并以null结尾。然后,将其分配给变量只是将指向该内存的指针分配给变量。例如,const char*a=“foo”将存储“foo”的地址分配给a 简言之,字符串常量已经将内存带

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

char* s1="hello world";
作为

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

*s1
作为


区别是什么?

非常简单:字符串文本,即
“foobar”
被编译成一个字符数组,该数组存储在程序的静态部分(即存储所有常量的地方),并以null结尾。然后,将其分配给变量只是将指向该内存的指针分配给变量。例如,
const char*a=“foo”
将存储
“foo”
的地址分配给
a

简言之,字符串常量已经将内存带到了存储它的位置

相反,没有为指针定义使用初始值设定项列表(即大括号内的元素列表)初始化指针。非正式地说,与字符串文字相反,初始值设定项列表的问题在于它没有“自带内存”。因此,我们必须提供初始值设定项列表可以存储其字符的内存。这是通过声明数组而不是指针来实现的。这很好:

char s1[11]={'h','e','l','l','o',' ','w','o','r','l','d'}
现在,我们通过将
s1
声明为数组来提供存储字符的空间

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

char* c2 = {nullptr};

然而,虽然语法似乎相同,但这是完全不同的,称为统一初始化,它将使用
nullptr

初始化
c2
。在第一种情况下,字符串文本将衰减为指向常量字符的指针。虽然
s1
实际上应该是
const char*
,但有几个编译器允许将另一种形式作为扩展:

const char* s1 = "hello world" ;
sting文本是一个
常量字符数组
,我们可以从
2.14.5节
字符串文本中看到这一点,它表示(重点放在后面):

还引用了普通字符串文字和UTF-8字符串文字 将其转换为窄字符串文字。窄字符串文字具有类型“数组 n
const char
“,
式中,n是如下定义的字符串大小, 并且具有静态存储持续时间(3.7)

数组到指针的转换在
4.2节
array-to-pointer conversion中介绍,该节说明:

[…]将具有类型“”的数组“”的表达式转换为 类型为“指向类型的指针”且指向初始值的表达式 数组对象的元素,并且不是左值。[…]

其他情况不起作用,因为标量可以是算术类型,枚举类型或指针类型只能用括号内的一个元素初始化,这在草案C++标准部分中包含:代码> 5.17代码/赋值>和复合赋值操作符>代码> 8.5.1 < /代码>列表初始化3段,该段表示:

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

然后列举了不同的情况,对于这种情况,仅适用于右侧的项目符号如下:

否则,如果初始值设定项列表有一个类型为E和的元素 T不是引用类型或其引用类型为 与E相关的引用,对象或引用从 该要素;如果需要缩小转换(见下文),则 如果将元素转换为T,则程序格式不正确

这要求列表只有一个元素,否则最后一个项目符号适用:

否则,程序的格式就不正确

在这两种情况下,即使将初始值设定项减少为一个变量,类型也不正确
h
是字符,
2
是不会转换为指针的
int

可以通过将结果分配给如下数组来进行分配:

  char s1[] = { 'h', 'e', 'l', 'l', 'o',' ', 'w', 'o', 'r', 'l', 'd' } ;
  int  a[]  = { 2, 3, 1, 45, 6 } ;
这将在第
8.5.1节
Aggregates中说明:

一个大小未知的数组,用括号初始化 包含n个初始值设定项条款的初始值设定项列表,其中n应为 大于零,定义为具有n个元素(8.3.4)。[示例:

int x[] = { 1, 3, 5 };
将x声明并初始化为具有三个 元素,因为没有指定大小,并且有三个初始值设定项。 -结束示例]空初始值设定项列表{}不得用作 未知绑定的数组的初始值设定项子句。104

注:

如果说没有为指针定义大括号init列表,这是不正确的,它完全可以用于指针:

int x   = 10 ;
int *ip =  &x ;
int *a  = {nullptr} ;
int *b  = {ip} ;

字符串文本的特殊处理,即
“。”
事物。理论上,我认为您也可以将其用于其他类型的初始化(即C99复合文字)。非常相关:@user2485710不,
{..}
不是对象,甚至不是表达式,也没有类型。这是一个大括号的初始化列表。@user2485710例如,请参见,在某些上下文中,大括号的初始化列表可用于构造
初始值设定项\u列表
,但它是一个更一般的构造。实际上,您的第一行也是不允许的。C++用于支持非字符串指针到字符串文本以与C兼容,但不再支持。使用
const
char*s1=“hello world”int*a={1,2,3,4}的工作方式与复合文字类似。但是,字符串文字始终具有静态存储持续时间;所以使用
int*a={1,2,3,4}没有多少好处而不是
inta[]={1,2,3,4}特别是在块范围内(由于易变性,它需要具有自动存储持续时间)。OTOH,
int常量a*={1,2,3,4}可能再次具有静态存储持续时间。我不认为你可以轻易地将其扩展到类类型,
  char s1[] = { 'h', 'e', 'l', 'l', 'o',' ', 'w', 'o', 'r', 'l', 'd' } ;
  int  a[]  = { 2, 3, 1, 45, 6 } ;
int x[] = { 1, 3, 5 };
int x   = 10 ;
int *ip =  &x ;
int *a  = {nullptr} ;
int *b  = {ip} ;