#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "hello";
cout << s[5] << endl;
return 0;
}
在上面的代码中,如果我打印s[5]
,它会正确打印NULL
个字符。但是,如果我将代码更改为:
#include <iostream>
#include <string>
using namespace std;
int main() {
char[] s = {'a','b','c','d','e'};
cout << s[5] << endl;
return 0;
}
它不会打印NULL
个字符,而是随机的。如果我将字符串存储为string
或char*
,则行为与我期望的一致。
但是如果我明确声明了字符数组,那么编译器如何知道数组何时结束?数组的大小是否在编译时存储?
答案 0 :(得分:2)
字符串文字和std::string
存储空终止字符串。
但是5 char
的数组声明如下:
char s[] = {'a','b','c','d','e'};
只包含5个char
,没有空终止符。
但编译器确实知道s
的大小。它是s
类型的一部分。它没有.size()
,std::string
或std::vector
这样的便捷std::array
功能,但你可以这样做:
sizeof(s) / sizeof(s[0])
或者更安全地使用C ++ 11:
std::extent<decltype(s)>::value
或者在C ++ 17中:
std::size(s)
(demo)
阵列有一种腐烂指针的习惯,然后无法获得大小,你必须自己跟踪它。这就是C ++中首选std::string
,std::vector
或std::array
的原因。
答案 1 :(得分:0)
字符串以空值终止,const char*
的处理方式与字符串相同。当你声明一个大小的数组时,它被放在堆栈上并且编译器不知道大小。在编译期间不确定数组越界异常。
答案 2 :(得分:0)
执行char[] s = {'a','b','c','d','e'};
时,它会存储提到的字符,而不会存储任何其他字符。
如果我显式声明了字符数组,编译器如何知道数组何时结束?
大小取决于您提供的字符数。
数组的大小是否在编译时存储?
不,数组的大小由分配给它的内存块决定。 (它不会单独存储在内存中,如果这就是你的意思)
当你使用这个string s = "hello";
时,字符串总是以空值终止。
答案 3 :(得分:0)
c ++中的字符串类具有构造函数,如果没有显式添加,它本身会将null字符添加到传递给它的字符串中。但是在使用char时它只存储传递给它的内容(即)如果你想要一个空字符,你必须在声明或该char的定义中明确添加。
答案 4 :(得分:0)
您的代码为char s[] = {'a','b','c','d','e'};
,因此不会将\0
放在char array
的末尾。它将使用以下三种方法放置\0
:
1. char s[] = {'a','b','c','d','e', '\0'};
2. char s[] = "abcde";
3. string s = "abcde";
因此,如果您使用上述三个中的任何一个,您将获得NULL
个字符。
答案 5 :(得分:0)
“编译器如何知道数组何时结束?”:编译器从其声明中知道该数组有多少元素,并且这些信息可通过sizeof运算符获得。
无论如何,C风格的数组实际上没有大小,因为它们在作为参数传递时被隐式转向指针,并且它们的长度被丢弃(IMO是C语言设计中的一个主要缺陷)。避免溢出是您的责任。
出于这个原因,你不能使用cout&lt;&lt;如果您的字符串不是以空值终止的语句。