1. 数组
数组的声明应指出以下三点
- 存储在每个元素中的值的类型;
- 数组名;
- 数组中的元素数。
在 C++ 中,可以通过修改简单变量的声明(如:int num
),添加中括号(其中包含元素数目)来完成数组声明(如:int num[20]
)。
通用格式如下:
typeName arrayName[arraySize]
表达式 arraySize 指定元素数目,它必须是整型常数或者 const,也可以是常量表达式,即其中所有的值在编译时都是已知的,不能是变量,因为变量的值实在程序运行时设置的。
初始化规则
- 只有在定义数组时才能使用初始化,此后就不能使用了,也不能讲一个数组赋给另一个数组;
- 可以使用下表分别给数组中的元素赋值;
- 初始化时提供的值可以少于数组元素数目,如
float hotelTips[5] = {5.0, 2.5}
; - 如果只对数组的一部分进行初始化,编译器将把其他元素设置为 0;
- 如果要将数组中的所有元素都初始化为 0, 只要显式的将第一个元素初始化为 0,如
long totals[500] = {0}
; - 如果初始化数组时方括号内为空,编译器将计算元素个数;
- 初始化可以省略等号;
- 禁止缩窄转换。
2. 字符串
C++ 处理字符串的方式有两种,第一种来自 C 语言,常被称为 C-风格字符串;另一种基于 string 类库的方法。
C-风格字符串具有一种特殊的性质:以空字符结尾,空字符被写作 \0,其 ASCII 码为 0,用来标记字符串的结尾。
char dog[8] = {'b', 'e', 'a', 'u', 'x', ' ', 'I', 'I'} // not a string
char cat[8] = {'f', 'a', 't', 'e', 's', 's', 'a', '\0'} // a string
将数组初始化为字符串的操作可以简化为:
char bird[11] = "Mr.Cheeps" // the \0 is understand
char fish[] = "Bubbles"; // let the compiler count
注意:确定存储字符创所需要的最短数组时,需要将结尾的空字符计算在内。
2. 1 拼接字符串常量
C++ 允许拼接字符串字面值,即将两个用引号括起来的字符串合并为一个。任何两个有空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。
以下输出语句等效:
cout << "I'd give my right arm to be" " a great violinist.\n";
cout << "I'd give my right arm to be a great violinist.\n";
cout << "I'd give my right ar"
"m to be a great violinist.\n";
注意:拼接时不会在被连接的字符串之间添加空格,第二个字符串的第一个字符将紧跟在第一个字符串的最后一个字符后面(不考虑 \0)。第一个字符串中的 \0 字符将被第二个字符串的第一个字符取代。
2. 2 在数组中使用字符串
将字符串存储到数组中,最常用的方法有两种:
- 将数组初始化为字符串常量(使用引号);
- 将键盘或文件输入读入到数组中(使用 cin)。
char name1[20] = "Cowboy";
char name2[20];
cin >> name2;
可以使用 strlen ( ) 计算可见字符数目,而 sizeof 可以指出整个数组的长度,以字节为单位。
2. 3 字符串的输入
cin 使用空白(空格、制表符和换行符)来确定字符串的结束位置,因此 cin 在获取字符数组输入时只读取一个单词。读取该单词后,cin 将该字符放到数组中,并自动在结尾添加空字符。
cin 不能防止输入的字符串比目标数组长。
面向行的输入:getline ( )
getline ( ) 函数读取整行,使用通过回车键输入的换行符来确定输入结尾。
可以使用 cin.getline()
, 该函数有两个参数,第一个参数是用来存储输入行的数组名称,第二个参数是要读取的字符数。
getline ( ) 函数每次读取一行,他通过换行符来确定结尾,但不保存换行符。在存储的时候,使用空字符来替换换行符。
面向行的输入:get ( )
get ( ) 函数有几种变体,其中一种接受两个参数,与 getline ( ) 相同,解释参数的方式也相同,并且都读取到行尾。但 get 并不再读取并丢弃换行符,而是将其留在队列中。假如两次调用 get ( ):
cin.get(name, ArSize);
cin.get(dessert, ArSize); // a problem
由于第一次调用,换行符留在输入队列中,因此在第二次调用时看到的第一个字符便是换行符。因此 get ( ) 认为已经达到行尾,而没有发现任何可读取的内容。如果不借助帮助,get ( ) 将不能跨过该换行符。
get ( ) 的另一种变体,不带任何参数的 cin.get ( ) 可以读取下一个字符(即使是换行符),因此可以用来处理换行符。
cin.get(name, ArSize);
cin.get ( );
cin.get(dessert, ArSize);
也可以
cin.get(name, ArSize).get ( );
之所以可以这样,是由于 cin.get(name, ArSize)
返回一个 cin 对象,该对象随后将被用来调用 get ( ) 函数。
同样可以连续两次调用 getline:
cin.getline(name1, ArSize).getline(name2, ArSize)
混合输入字符串和数字
示例代码:
cout << "What year was your house built?\n";
int year;
cin >> year;
cout << "What is its street address?\n";
char address[80];
cin.getline(address, 80);
cout << "Year built: " << year << endl;
cout << "Address: " << address << endl;
cout << "Done!\n";
运行结果
What year was your house built?
2018
What is its street address?
Year built: 2018
Address:
Done!
用户没有机会输入地址,因为 cin 将回车键产生的换行符留在了输入队列中,后面的 getline ( ) 看到换行符后认为这是一个空行,并将空字符串赋给 address 数组。可以在 cin 之后使用 cin.get ( ) 来读取并丢弃换行符。
3. string 类
3. 1 string 类初始化
- 可以使用 C-风格字符串来初始化 string 对象。
- 可以使用 cin 来将键盘输入存储到 string 对象中。
- 可以使用 cout 来显示 string 对象。
- 可以使用数组表示法来访问存储在 string 对象中的字符。
例如:
string str1 = {"The Bread Bowl"};
string str2 {"Hank's Fine Eats"};
3. 2 复制,拼接和附加
在使用 string 类时,某些操作比数组简单,可以将一个 string 对象赋给另一个 string 对象。
char charr1[20]
char charr2[20] = "jugar";
string str1;
string str2 = "panther";
charr1 = charr2; // invalid
str1 = str2; // valid
可以使用运算符 + 将两个 string 对象合并起来.
string str3;
str3 = str1 + str2;
可以使用运算符 += 将字符串附加到 string 对象的末尾。
str1 += str2;
3. 3 其他操作
strcpy ( )
可以使用函数 strcpy ( ) 将字符串复制到字符数组中。
strcpy(charr1, charr2); // copy charr2 to charr1
strcat ( )
可以使用函数 strcat ( ) 将字符串复制到字符数组中。
strcat(charr1, charr2); // append contents of charr2 to charr1
size ( )
size ( ) 可以返回 string 类对象中字符的数量。
int len1 = str1.size(); // obtain length of str1
int len2 = strlen(charr2); // obtain length of charr1
3. 4 其他形式的字符串字面值
对于不同类型的字符串,如 wchar_t、char16_t 和 char32_t。可以使会用对应的前缀 L、u 和 U表示
wchar_t title[] = L"Chief Astrogator"; // wchar string
char16_t name[] = u"Felonia Ripova"; // char_16 string
char32_t car[] = U"Humber Super Snipe"; // char_32 string
C++ 11 可以使用原始字符串 (raw)。
使用前缀 R 来表示原始字符串,使用 "(
和 )"
作为定界符
cout << R"(Jim "King" Tutt uses "\n" instead of endl.)";
而使用标准字符串字面值,代码如下
cout << "Jim \"King\" Tutt uses \"\\n\" instead of endl.)";
如果原始字符串中包含 “( 或者 )” ,可以使用 R"+*(
以及 )+*"
作为定界符
cout << R"+*("(Who wouldn't?)", she whispered.)+*" << endl;