第五章 字符串字面量---一个特殊的数组
2015-05-21 09:43
218 查看
字符串字面量(string literal)是一段双引号括起来的多字节字符序列,C/C++将其实现为具有静态存储连续性的字符数组。初学者(包括不少书籍)常将其称为字符串常量,但这说法只在C++成立,C中不成立。C中的常量只包括下列四种:
6.4.4 Constants
Syntax
constant:
integer-constant
floating-constant
enumeration-constant
character-constant
分别是整数常量、浮点常量、枚举常量和字符常量,并不包括字符串字面量。但由于字符串字面量具有静态存储连续性数组类型,并且在表达式中它会根据数组到指针的隐式转换规则转换为一个代表数组首地址(应改为数组首元素地址,2011年4月)的右值指针,因此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
,在C++中则为const char
,在表达式中当发生数组到指针的转换时,对应的等效指针类型分别是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
,在C++中类型为const char
,但并不说明C中的字符串字面量可以修改,C++的不可以。字符串字面量是否可以修改与实现数组的类型无关,C之所以没有规定为const char
,还是出于对旧代码的兼容,而C++规定为const char
的原因之一是比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++把常量的概念延伸到了对象模型,是对对象概念的有益扩展,但同时也带来了一些问题,一个具有对象性质的实体,难以避免存在某些合法或不合法的手段去修改其内容,这种行为常常令常量对象的常量性质处于尴尬的境地,由此也催生了常量折叠这一类巧妙的折中。
6.4.4 Constants
Syntax
constant:
integer-constant
floating-constant
enumeration-constant
character-constant
分别是整数常量、浮点常量、枚举常量和字符常量,并不包括字符串字面量。但由于字符串字面量具有静态存储连续性数组类型,并且在表达式中它会根据数组到指针的隐式转换规则转换为一个代表数组首地址(应改为数组首元素地址,2011年4月)的右值指针,因此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
,在C++中则为const char
,在表达式中当发生数组到指针的转换时,对应的等效指针类型分别是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
,在C++中类型为const char
,但并不说明C中的字符串字面量可以修改,C++的不可以。字符串字面量是否可以修改与实现数组的类型无关,C之所以没有规定为const char
,还是出于对旧代码的兼容,而C++规定为const char
的原因之一是比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++把常量的概念延伸到了对象模型,是对对象概念的有益扩展,但同时也带来了一些问题,一个具有对象性质的实体,难以避免存在某些合法或不合法的手段去修改其内容,这种行为常常令常量对象的常量性质处于尴尬的境地,由此也催生了常量折叠这一类巧妙的折中。
相关文章推荐
- 第五章 字符串字面量---一个特殊的数组
- 第五章 字符串字面量---一个特殊的数组
- 数组与指针的艺术 第五章 字符串字面量---一个特殊的数组
- 把一个逗号分开的字符串转化为数组的两个方法
- 字符串数组排序+一个字符串在另一字符串中出现的次数
- C++ string字符串分割成一个数组
- C语言将多个字符串合并为一个字符串例如:数组[a,bbb,ccc]->字符串"a,bbb,ccc"
- Join函数:将数组中的字符串连接为一个字符串
- 【字符串操作之】将一个字符串拆分成数组→→split方法
- 11.5 排序后的字符串数组,其中散布着空字符串,编写一个方法,找出给定字符串的位置。
- 如果将一维数组编程一个字符串
- 给定一个固定长度的数组,将递增整数序列写入这个数组。当写到数组尾部时,返回数组开始重新写,并覆盖先前写过的数,请在这个特殊数组中找出给定的整数
- 字符串替换空格: 请实现一个函数,把字符数组中的每个空格替换成“%20”。 例如输入“we are happy.”,则输出“we%20are%20happy.”。
- 设置radio的值,要设置一个数组,而不能简单的设置为一个字符串
- 将s所指字符串的反序和正序进行连接形成一个新串放在t所指的数组中
- 写一个函数对字符串数组进行排序,排序的规则是根据每个字符串中……
- php字符串与数组的特殊情况
- http_build_query()就是将一个数组转换成url 问号?后面的参数字符串,并且会自动进行urlencode处理,及它的逆向函数
- 创建一个字符串数组,总共5个元素,每个元素最多保存30个字符,写一个函数排序整个数组。
- fileread函数:IDL中将文本文件读入一个字符串数组中,每一行作为一个元素