文章目录
3.2
#include<iostream>
#include <string>
using std::cin, std::cout, std::string, std::getline,std::endl;
int main() {
//一次读入一整行
// string buffer_words{0};
// while (getline(cin, buffer_words)) {
// cout << "输入:" << buffer_words << endl;
// }
//一次读入一个词
string buffer_word{0};
while (cin>>buffer_word){
cout<< "输入:" <<buffer_word<<endl;
}
return 0;
}
3.3
标准库 string 的输入运算符自动忽略字符串开头的空白(包括空格符、换行符、制表符等),从第一个真正的字符开始读起,直到遇见下一处空白为止。
如果希望在最终的字符串中保留输入时的空白符,应该使用 getline 函数代替原来的 >> 运算符,getline 从给定的输入流中读取数据,直到遇到换行符为止,此时换行符也被读取进来,但是并不存储在最后的字符串中
3.4
输出较大的字符串
#include<iostream>
#include <string>
using std::cin, std::cout, std::string, std::getline,std::endl;
int main() {
string str1,str2;
cin>>str1>>str2;
if(str1>str2){
cout<< str1 <<endl;
}else if(str1<str2){
cout<< str2 <<endl;
} else{
cout<< "相等" <<endl;
}
return 0;
}
输出长度较长的字符串
#include<iostream>
#include <string>
using std::cin, std::cout, std::string, std::getline, std::endl;
int main() {
string str1, str2;
cin >> str1 >> str2;
auto slen1 = str1.size();
auto slen2 = str2.size();
if (slen1 == slen2)cout << "长度相等" << endl;
else if (slen1 > slen2)cout << str1 << "-长度更长" << endl;
else cout << str2 << "-长度更长" << endl;
return 0;
}
3.5
连接多个字符串的程序如下所示:
#include<iostream>
#include <string>
using std::cin, std::cout, std::string, std::getline, std::endl;
int main() {
cout<<"请输入字符串:";
string buf,result;
while (cin>>buf){
result+=buf;
char flag;
cout<< "是否继续输入y/n";
cin>>flag;
if(flag=='n'||flag=='N'){
break;
} else{
cout<<"请输入字符串:";
}
}
cout<< result <<endl;
return 0;
}
连接多个字符串并以空格分隔的程序如下所示:
#include<iostream>
#include <string>
using std::cin, std::cout, std::string, std::getline, std::endl;
int main() {
cout<<"请输入字符串:";
string buf,result;
while (cin>>buf){
result+=buf+" ";
char flag;
cout<< "是否继续输入y/n";
cin>>flag;
if(flag=='n'||flag=='N'){
break;
} else{
cout<<"请输入字符串:";
}
}
cout<< result <<endl;
return 0;
}
3.6
字符串内所有字符用X替换
#include<iostream>
#include <string>
using namespace std;
int main() {
string s{"xadsadasdq2eqdasc"};
for (auto &item: s)
item='X';
cout<< s <<endl;
return 0;
}
3.7
就本题而言,将循环控制变量的类型设为 char 不会对程序运行结果造成影响,因为我们使用 auto 自动推断字符串 s 的元素类型,结果同样是 char。
#include<iostream>
#include <string>
using namespace std;
int main() {
string s{"xadsadasdq2eqdasc"};
for (char &item: s)
item='X';
cout<< s <<endl;
return 0;
}
3.8
while循环写一遍
#include<iostream>
#include <string>
using namespace std;
int main() {
string s{"xadsadasdq2eqdasc"};
int index{0};
while(s[index]!='\0')
s[index++] = 'X';
cout<< s <<endl;
return 0;
}
3.9
string s;
cout<<s[0];
该程序的原意是输出字符串 s 的首字符,但程序是错误的。因为初始状态下没有给 s 赋任何初值,所以字符串 s 的内容为空,当然也就不存在首字符,下标 0 是非法的。
但是在某些编译器环境中,上述语句并不会引发编译错误。
3.10
删除标点符号
#include<iostream>
#include <string>
#include<cctype>
using namespace std;
int main() {
string s;
cout<< "请输入字符串:";
cin>>s;
auto len=s.size();
for (int i = 0; i < len; ++i) {
if(ispunct(s[i])){
s.erase(i,1);
}
}
cout<< s <<endl;
return 0;
}
3.11
判断是否合法
const string s = "Keep out!";
for(auto &c:s){/*...*/}
合法,c的类型是const char&
3.12
(a)是正确的,定义了一个名为 ivec 的 vector 对象,其中的每个元素都是 vector 对象。
(b)是错误的,svec 的元素类型是 string,而 ivec 的元素类型是 int,因此不能使用 ivec 初始化 svec。
(c)是正确的,定义了一个名为 svec 的 vector 对象,其中含有 10 个元素,每个元素都是字符串 null。
3.13
(a)的元素数量为 0;
(b)的元素数量为 10,每一个元素都被初始化为 0;
(c)的元素数量为 10,每一个元素都被初始化为 42;
(d)的元素数量为 1,元素的值为 10;
(e)的元素数量为 2,两个元素的值分别是 10 和 42;
(f)的元素数量为 10,每一个元素都被初始化为空串;
(g)的元素数量为 10,每一个元素都被初始化为"hi"。
3.14
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<int>v;
int i{0};
char flag{'n'};
while(cin>>i){
v.push_back(i);
cout<< "是否继续输入y/n" <<endl;
cin>>flag;
if(flag=='n'||flag=='N')break;
}
for (const int &j : v) {
cout<< j <<endl;
}
return 0;
}
3.15
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<string>v;
string i{0};
char flag{'n'};
while(cin>>i){
v.push_back(i);
cout<< "是否继续输入y/n" <<endl;
cin>>flag;
if(flag=='n'||flag=='N')break;
}
for (const string &j : v) {
cout<< j <<endl;
}
return 0;
}
3.16
如上
3.17
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<string>v;
string s;
int sum{0};
cout<< "请输入要输入词的个数:";
cin>>sum;
for (; sum>0;--sum) {
cin>>s;
s[0]= toupper(s[0]);
v.push_back(s);
}
for (auto &item: v) {
cout<< item <<endl;
}
return 0;
}
3.18
不合法
vector<int> ivec;
ivec.push_back(42);
3.19
vector<int>v1(10,42);
vector<int>v2{42,42,42,42,42,42,42,42,42,42};
vector<int>v3;
for (int i = 0; i < 10; i++)
v3.push_back(42);
3.20
求相邻元素和的程序如下所示:
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<int>v;
int num;
int sum{0};
cout<< "请输入要输入整数的个数:";
cin>>sum;
for (; sum>0;--sum) {
cin>>num;
v.push_back(num);
}
auto len = v.size();
for (int i = 0; i < len-1; ++i) {
cout<< v[i]+v[i+1] <<endl;
}
return 0;
}
求首尾元素和的程序如下所示:
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<int>v;
int num;
int sum{0};
cout<< "请输入要输入整数的个数:";
cin>>sum;
for (; sum>0;--sum) {
cin>>num;
v.push_back(num);
}
auto len = v.size();
for (int i = 0; i < len/2; ++i) {
cout<< v[i]+v[len-1-i] <<endl;
}
if(len % 2 != 0){
cout<< v[len/2] <<endl;
}
return 0;
}
3.21
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<int>v;
int num;
int sum{0};
cout<< "请输入要输入整数的个数:";
cin>>sum;
for (; sum>0;--sum) {
cin>>num;
v.push_back(num);
}
for (auto normalIterator = v.begin(); normalIterator != v.end(); ++normalIterator) {
cout<< *normalIterator <<endl;
}
return 0;
}
3.22
#include<iostream>
#include <vector>
#include<cctype>
using namespace std;
int main() {
vector<string>v;
string s;
while (getline(cin,s)){
if(s!="EOF"||s!="eof")v.push_back(s);
else break;
}
for (auto it = v.begin(); it != v.end(); ++it) {
for (auto it2 = it->begin(); it2 != it->end(); ++it2) {
*it2 = ::toupper(*it2);
}
}
for (auto &item: v) {
cout<< item <<endl;
}
return 0;
}
3.23
#include<iostream>
#include <vector>
#include<cctype>
#include<ctime>
using namespace std;
int main() {
vector<int>v(10);
srand(time(nullptr));
for (int i = 0; i < 10; ++i)
v[i]=(rand()%100);
cout<< "原先:" <<endl;
for (auto item = v.begin(); item != v.end(); ++item)
cout<< *item <<" ";
for (auto it = v.begin(); it != v.end(); ++it)
(*it)*=2;
cout<<"\n";
cout<< "×2后:" <<endl;
for (auto item = v.begin(); item != v.end(); ++item)
cout<< *item <<" ";
return 0;
}
3.24
#include<iostream>
#include <vector>
#include<cctype>
#include<ctime>
using namespace std;
int main() {
vector<int>v;
int number{0};
cout<< "请输入要输入几个数字:";
cin>>number;
v.reserve(number);
for (int i = 0; i < number; ++i) {
int num{0};
cout<<"请输入数字:";
cin>>num;
v.push_back(num);
}
//相邻之和
for (auto it = v.begin(); it != v.end()-1; ++it)
cout<< *it+*(it+1) <<endl;
//头尾之和
auto itb = v.begin();
auto ite = v.end();
for (auto it = v.begin(); it !=itb+(ite-itb)/2; ++it) {
cout<< *it+ *(itb+(ite-it)-1)<<endl;
}
if((ite-itb)%2!=0)cout<< *(itb+((ite-itb)/2)) <<endl;
return 0;
}
3.25
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 该 vector 对象记录各分数段的人数,初始值为 0
vector<unsigned> vUS(11);
auto it = vUS.begin();
int iVal;
cout << "请输入一组成绩(0 ~ 100):" << endl;
while (cin >> iVal)
if (iVal < 101) // 成绩应在合理范围之内
++*(it + iVal / 10); // 利用迭代器定位到对应的元素,加 1
cout << "您总计输入了 " << vUS.size() << " 个成绩" << endl;
cout << "各分数段的人数分布是(成绩从低到高):" << endl;
// 利用迭代器遍历 vUS 的元素并逐个输出
for (; it != vUS.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
3.26
因为迭代器的加法不存在,所以 mid = (beg + end) / 2; 不合法。mid = beg + (end - beg) / 2; 的含义是,先计算 end - beg 的值得到容器中的元素个数,然后控制迭代器与整数( (end - beg) / 2 )进行运算,从开始处向右移动二分之一容器的长度,从而定位到容器中间的元素。
3.27
(a)是非法的,buf_size 是一个普通的无符号数,不是常量,不能作为数组的维度。
(b)是合法的,4*7-14 = 14 是一个常量表达式。
(c)是非法的,txt_size() 是一个普通的函数调用,没有被定义为 constexpr,不能作为数组的维度。
(d)是非法的,当使用字符串初始化字符数组时,默认在尾部添加一个空字符 \0,算上这个符号该字符串共有 12 个字符,但是字符数组 st 的维度只有 11,无法容纳题目中的字符串。
需要指出的是,在某些编译器环境中,上面的个别语句被判定为合法,这是所谓的编译器扩展。不过一般来说,建议读者避免使用非标准特性,因为含有非标准特性的程序很可能在其他编译器上失效。
3.28
对于string有默认构造函数,无论是在函数体内部还是在函数体外部,默认初始化为空串。
对于int,在函数体内部ia2将不被初始化,如果程序试图拷贝或输出未初始化的变量,将遇到未定义的奇异值。 在函数体外部ia2将被初始化为0
3.29
数组与 vector 的相似之处是都能存放类型相同的对象,且这些对象本身没有名字,需要通过其所在位置访问。
数组与 vector 的最大不同是,数组的大小固定不变,不能随意向数组中增加额外的元素,虽然在某些情境下运行时性能较好,但是与 vector 相比损失了灵活性。
具体来说,数组的维度在定义时已经确定,如果我们想更改数组的长度,只能创建一个更大的新数组,然后把原数组的所有元素复制到新数组中去。数组也无法像 vector 那样使用 size 函数直接获取数组的维度。如果是字符数组,可以调用 strlen 函数得到字符串的长度;如果是其他数组,只能使用 sizeof(array) / sizeof(array[0]) 的方式计算数组的维度。
3.30
数组下标从0开始,上述出现了 数组下标越界的现象
3.31
#include<iostream>
using namespace std;
int main() {
int arr[10]={0};
for (int i = 0; i < 10; ++i) {
arr[i] = i;
}
return 0;
}
3.32
数组拷贝
#include<iostream>
using namespace std;
int main() {
int arr[10]={0};
for (int i = 0; i < 10; ++i) {
arr[i] = i;
}
int arr2[10]={0};
::memcpy(arr2,arr,10*sizeof(int));
for (auto item: arr2) {
cout<< item <<endl;
}
return 0;
}
vector实现
#include<iostream>
#include <vector>
using namespace std;
int main() {
vector<int>v1(10);
for (int i = 0; i < 10; ++i)
v1[i] = i;
vector<int>v2(v1);
for (auto item: v1) {
cout<< item <<endl;
}
return 0;
}
3.33
如果不初始化 scores,则该数组会含有未定义的数值,这是因为 scores 是定义在函数内部的整型数组,不会执行默认初始化。
3.34
如果 p1 和 p2 指向同一个数组中的元素,则该条语句令 p1 指向 p2 原来所指向的元素。
从语法上来说,即使 p1 和 p2 指向的元素不属于同一个数组,但只要 p1 和 p2 的类型相同,该语句也是合法的。
但是如果p1和p2指向元素的类型不同,那么就是非法的
3.35
int main() {
int arr[10];
int *p = arr;
for (int i = 0; i < 10; ++i) {
*(p+i)=0;
}
return 0;
}
3.36
#include<iostream>
#define MAXLEN 5
using namespace std;
int main() {
int arr1[MAXLEN]={1,1,2,3,4},
arr2[MAXLEN]={10,1,2,3,4};
bool isEqual{true};
for (int i = 0; i < MAXLEN; ++i) {
if(arr1[i]!=arr2[i]){
isEqual= false;
break;
}
}
if(isEqual)cout<< "两个数组相等" <<endl;
else cout<< "两个数组不相等" <<endl;
return 0;
}
3.37
是一个字符数组而不是字符串,会一直寻找 直至找到字符串的结尾标志
3.38
指针的值是它所指对象的内存地址,如果我们把两个指针加在一起,就是试图把内存中两个对象的存储地址加在一起,这显然是没有任何意义的。与之相反,指针的减法是有意义的。如果两个指针指向同一个数组中的不同元素,则它们相减的结果表征了它们所指的元素在数组中的距离。
3.39
比较string
#include <iostream>
#include <string>
using namespace std;
int main() {
string str1, str2;
cout << "请输入两个字符串:" << endl;
cin >> str1 >> str2;
if (str1 > str2)
cout << "第一个字符串大于第二个字符串" << endl;
else if (str1 < str2)
cout << "第一个字符串小于第二个字符串" << endl;
else
cout << "两个字符串相等" << endl;
return 0;
}
比较c语言风格的字符串
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char str1[80], str2[80];
cout << "请输入两个字符串:" << endl;
cin >> str1 >> str2;
// 利用 cstring 头文件中定义的 strcmp 函数比较大小
auto result = strcmp(str1, str2);
if (result > 0)
cout << "第一个字符串大于第二个字符串" << endl;
else if (result < 0)
cout << "第一个字符串小于第二个字符串" << endl;
else
cout << "两个字符串相等" << endl;
return 0;
}
3.40
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char str1[] = "Welcome to ";
char str2[] = "C++ family!";
// 利用 strlen 函数计算两个字符串的长度,并求得结果字符串的长度
char result[size(str1) + size(str2) - 1];
// char result[strlen(str1) + strlen(str2) + 1]; // 也可
strcpy(result, str1); // 把第一个字符串拷贝到结果字符串中
strcat(result, str2); // 把第二个字符串拼接到结果字符串中
cout << "第一个字符串是:" << str1 << endl;
cout << "第二个字符串是:" << str2 << endl;
cout << "拼接后的字符串是:" << result << endl;
return 0;
}
3.41
#include<iostream>
#include <vector>
using namespace std;
int main() {
int a[]={1,2,3,4,5,6};
vector<int>v(begin(a), end(a));
for (auto &item: a) {
cout<< item <<endl;
}
return 0;
}
3.42
#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
using namespace std;
int main() {
const int sz = 10; // 常量 sz 作为 vector 对象的容量
vector<int> vInt;
srand((unsigned) time(NULL)); // 生成随机数种子
cout << "vector 对象的内容是:" << endl;
// 利用 for 循环遍历 vector 对象的每个元素
for (int i = 0; i != sz; i++) {
vInt.push_back(rand() % 100); // 生成一个 100 以内的随机数
cout << vInt[i] << " ";
}
cout << endl;
auto it = vInt.cbegin();
int a[vInt.size()];
cout << "数组的内容是:" << endl;
// 利用范围 for 循环遍历 vector 的每个元素
for (auto &val : a) {
val = *it;
cout << val << " ";
it++;
}
cout << endl;
return 0;
}
3.43
#include<iostream>
using namespace std;
int main() {
int ia[3][4] = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
范围for
for (int (&pInt)[4]: ia) {
for (int &i: pInt) {
cout << i << " ";
}
cout << endl;
}
//普通for 下标
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++j) {
cout << ia[i][j] << " ";
}
cout << endl;
}
//普通for 指针
for (int (*p)[4] = ia; p != ia+3; ++p) {
for (int *q = *p; q != *p+4; ++q) {
cout << *q << " ";
}
cout << endl;
}
return 0;
}
3.44
#include <iostream>
using namespace std;
using int_array = int[4];
int main() {
int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
cout << "利用范围 for 语句输出多维数组的内容:" << endl;
for (int_array &row : ia) {
for (int &col : row)
cout << col << " ";
cout << endl;
}
cout << "利用普通 for 语句和下标运算符输出多维数组的内容:" << endl;
for (int i = 0; i != 3; i++) {
for (int j = 0; j != 4; j++)
cout << ia[i][j] << " ";
cout << endl;
}
cout << "利用普通 for 语句和指针输出多维数组的内容:" << endl;
for (int_array *p = ia; p != ia + 3; p++) {
for (int *q = *p; q != *p + 4; q++)
cout << *q << " ";
cout << endl;
}
return 0;
}
3.45
#include <iostream>
using namespace std;
int main() {
int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
cout << "利用范围 for 语句输出多维数组的内容:" << endl;
for (auto &row : ia) {
for (auto &col : row)
cout << col << " ";
cout << endl;
}
cout << "利用普通 for 语句和下标运算符输出多维数组的内容:" << endl;
for (auto i = 0; i != 3; i++) {
for (auto j = 0; j != 4; j++)
cout << ia[i][j] << " ";
cout << endl;
}
cout << "利用普通 for 语句和指针输出多维数组的内容:" << endl;
for (auto p = ia; p != ia + 3; p++) {
for (auto q = *p; q != *p + 4; q++)
cout << *q << " ";
cout << endl;
}
return 0;
}