深入探索 C/C++ 数组与指针的奥秘之五:字符串字面量---一个特殊的数组
字符串字面量(string literal)是一段双引号括起来的多字节字符序列,C/C++ 将其实现为具有静态存储连续性的字符数组。初学者(包括不少书籍)常将其称为字符串常量,但这说法只在 C++ 成立,C 中不成立。C 中的常量只包括下列四种:
6.4.4 Constants
Syntax
constant:
integer-constant
floating-constant
enumeration-constant
character-constant
分别是整数常量、浮点常量、枚举常量和字符常量,并不包括字符串字面量。但由于字符串字面量具有静态存储连续性数组类型,并且在表达式中它会根据数组到指针的隐式转换规则转换为一个代表数组首地址的右值指针,因此 C 中的字符串字面量的首地址及各元素的地址都是地址常量表达式,但字符串字面量本身不是常量,也不是常量表达式。
而 C++ 的情形有所不同,C++ 将字符串字面量归入了常量当中:
2.13 Literals
There are several kinds of literals.21)
literal:
integer-literal
character-literal
floating-literal
string-literal
boolean-literal
21) The term “literal” generally designates, in this International Standard, those tokens that are called “constants” in ISO C.
因此 C++ 中的字符串字面量才可称为字符串常量,而且首地址及各元素地址跟C一样,都是地址常量表达式。
字符串字面量在C中具有数组类型 char[N],在 C++ 中则为 const char[N],在表达式中当发生数组到指针的转换时,对应的等效指针类型分别是 char* 和 const char*,因此,在 C 中,char *p = “ABCDEF” 是合法的,但让人惊奇的是,上述语句在 C++ 中也是合法的!看起来一个 pointer to const char 指针被赋予了 pointer to char 指针,似乎违反了 C++ 中指针转换的 more cv-qualified 原则。其实字符串字面量在 C++ 中存在两种转换,一种转换依据当前上下文环境,另一种遵循数组到指针的转换,C++ 标准的内容:
2.13.4 String literals
……..An ordinary string literal has type “array of n const char” and static storage duration (3.7), where n is the size of the string as defined below, and is initialized with the given characters.
4.2 Array-to-pointer conversion
A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to char”; a wide string literal can be converted to an rvalue of type “pointer to wchar_t”. In either case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [Note: this conversion is deprecated. See Annex D. ] For the purpose of ranking in overload resolution (13.3.3.1.1), this conversion is considered an array-to-pointer conversion followed by a qualification conversion (4.4). [Example: "abc" is converted to “pointer to const char” as an array-to-pointer conversion,
and then to “pointer to char” as a qualification conversion. ]
在具有显而易见的合适指针目标类型的情况下,例如上述 char *p = “ABCDEF”,字符串字面量被转换为 char* 而不是 const char* 类型的指针,这个转换实际上是对旧有代码的兼容,是一个特例,而且被指定为 deprecated 的,将在未来的版本中予以废弃,有些编译器会产生一条提示这是废弃转换的警告。而在函数重载解析中,字符串字面量遵循数组到指针的转换,同时后跟一个限定修饰的转换。
虽然字符串字面量在 C 中类型为 char[N],在 C++ 中类型为 const char[N],但并不说明 C 中的字符串字面量可以修改,C++ 的不可以。字符串字面量是否可以修改与实现数组的类型无关,C 之所以没有规定为 const char[N],还是出于对旧代码的兼容,而 C++ 规定为 const char[N] 的原因之一是比 C 更严格的类型安全。无论 C 与 C++ 都规定对字符串字面量的修改是未定义的,编译器可以自行处理,也的确存在一些允许修改字符串字面量的编译器,例如老一代的编译器 TC,编译器不管是否允许修改字符串字面量,都没有违反标准。
对于那些允许修改字符串字面量的编译器,必须考虑这样一个问题,当代码在不同的上下文中引用了同一个字符串字面量时,如果其中一处修改了该字面量,就会影响其它地方的引用。解决方法是允许同一个字面量的多个实例,这样不同上下文之间不会互相干扰,标准把这个问题的决定权留给了编译器:
6.4.5 String literals
It is unspecified whether these arrays are distinct provided their elements have the appropriate values.
在 C 中,由于字符串字面量不是常量,而且 const 限定的变量不是常量表达式(C 中的常量表达式必须是编译期的),因此所有的常量和常量表达式都是右值。但 C++ 将字符串字面量归入常量,将 const 限定的变量归入常量表达式,这意味着在 C++ 中存在左值常量和左值常量表达式。
C 与 C++ 在这方面的差异反映出两者对待常量的不同视角。C 认为常量是不应该拥有存储空间的,这是非常传统的观点;而 C++ 把常量的概念延伸到了对象模型,是对对象概念的有益扩展,但同时也带来了一些问题,一个具有对象性质的实体,难以避免存在某些合法或不合法的手段去修改其内容,这种行为常常令常量对象的常量性质处于尴尬的境地,由此也催生了常量折叠这一类巧妙的折中。
原文链接:http://blog.csdn.net/supermegaboy/archive/2009/11/23/4854987.aspx。
分享到:
相关推荐
数组与指针的艺术 数组与指针的艺术
指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多 程序设计者就被搞糊涂了。而许多的大学老师,他们在C 语言的教学过程中也错误得给学生讲解:“数组名就是...
C++数组与指针深入剖析C++数组与指针深入剖析C++数组与指针深入剖析C++数组与指针深入剖析
C++课程-3_数组指针与字符串 C++课程-3_数组指针与字符串
C++数组与指针对象数组对象指针C++数组与指针对象数组对象指针
C/C++之数组与指针的艺术 指针是C/C++的灵魂!它是C/C++众多引人入胜的特性中的一朵奇葩。与底层操作的亲密接触是指针与生俱来的优点,利用指针可以写出许多短小精悍、效率极高的代码。它是C/C++一把无可替代的利器...
指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。而许多的大 学老师,他们在C语言的教学过程中也错误得给学生讲解:"数组名就是...
C++数组与指针全面介绍,指针的重要性不言而喻,很多程序员怕指针,越是怕用,越要去用!
详细讲解了指针,指针数组,数组指针,指针的指针等的应用。
C++之 数组 与 指针 的 异同 pdf
主要介绍了C/C++ 避免数组越界的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
1 数组及其简单应用 2 指针及其简单应用 3 指针与数组 4 字符串 5 指针数组与命令行参数 6 引用
//定义一个指向指针的指针,并赋予指针数组首地址所指向的第一个字符串的地址也就是abc\0字符串的首地址 cout*b|"*(b+1)|"*(b+2); //------------------------------------------------------------------------- ...
C/C++ 数组和指针及引用的区别 1.数组和指针的区别 (1)定义 数组是一个符号,不是变量,因而没有自己对应的存储空间。但是,指针是一个变量,里面存储的内容是另外一个变量的地址,因为是变量所以指针有自己的...
C++指针 数组 内存释放 相关说明
C++数组指针与字符串.pdf
c++实验课上做的代码,关于数组、指针与字符窜 整个实验报告都有
Labview调用C++编写的dll实现字符串数组的传递,C++和Labview实现源代码,开发环境:VS2010+Labview2015
C++习题 6数组与指针.doc (填空 选择 解答)