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字符串文字
将其转换为窄字符串文字。窄字符串文字具有类型“数组
nconst 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} ;