首页 > 代码库 > 《C++primer》v5 第3章 字符串、向量和数组 读书笔记 习题答案
《C++primer》v5 第3章 字符串、向量和数组 读书笔记 习题答案
3.1略
3.2
string str;
//读行
while(getline(cin,str))
cout<<str<<endl;
//读单个词
while(cin>>str)
cout<<str<<endl;
3.3
输入运算符读到空白符结束
getline读到换行符结束,并丢弃换行符
3.4
比较大小。
比较大小是比较的第一个不相同的字符的大小。
int main(){ string a,b; cin>>a>>b; if(a==b) cout<<a<<" "<<b<<endl; else if(a>b) cout<<a<<endl; else cout<<b<<endl; return 0;}
比较长度。
int main(){ string a,b; cin>>a>>b; if(a.size()==b.size()) cout<<a<<" "<<b<<endl; else if(a.size()>b.size()) cout<<a<<endl; else cout<<b<<endl; return 0;}
3.5
注意string类型的加法要求+两侧至少有一个是string类型。
int main(){ string a,str; while(cin>>a) str+=a; cout<<str<<endl; return 0;}
int main(){ string a,str; while(cin>>a) str+=a+‘ ‘; cout<<str<<endl; return 0;}
3.6
修改变量时,范围for循环要用引用
int main(){ string str; cin>>str; for(auto &c:str) c=‘X‘; cout<<str<<endl; return 0;}
3.7
换成char&,结果似乎是一样的。。
int main(){ string str; cin>>str; for(char &c:str) c=‘X‘; cout<<str<<endl; return 0;}
3.8
while
int main(){ string str; cin>>str; int i=0; while(i<str.size()) str[i++]=‘X‘; cout<<str<<endl; return 0;}
传统for循环
int main(){ string str; cin>>str; for(int i=0; i<str.size(); ++i) str[i]=‘X‘; cout<<str<<endl; return 0;}
论方便程度:范围for>传统for>while。其实各有所长吧。
3.9
不合法。如果s为空则s[0]不存在,访问越界!
3.10
需要头文件cctype。第一个c表示从c语言继承而来。
int main(){ string str; cin>>str; for(auto c: str) if(!ispunct(c)) cout<<c; return 0;}
3.11
这是合法的。
auto &c,表示c是指向const char的引用,无法通过修改c来修改字符。
auto c,表示c是char字符的一个拷贝,因为auto不会保留顶层const,所以得到的不是常量。
3.12
(a)末尾的>>可能在旧的编译器中报错。本身定义无错。
(b)错,不同数据类型的vector不能赋值。任何不同的都不行!
(c)这个是对的。调用了vector的一个构造函数。
3.13
(a)空
(b)10个0
(c)10个42
(d)1个10
(e)1个10,1个42
(f)10个空string
(g)10个“hi”
3.14
int main(){ int num; vector<int> vec; while(cin>>num) vec.push_back(num); return 0;}
3.15
int main(){ string str; vector<string> vec; while(cin>>str) vec.push_back(str); return 0;}
3.16
int main(){ vector<int> vec; int val; while(cin>>val) vec.push_back(val); cout<<"size:"<<vec.size()<<endl; for(auto c:vec) cout<<c<<endl; return 0;}
3.17、3.18
多重范围for循环除了最内层,其余都要用&,防止数组转化为指针。这里最内层用引用是因为要修改字符。
int main(){ vector<string> vec; string str; while(cin>>str) vec.push_back(str); for(auto &i:vec) for(auto &j:i) j=toupper(j); for(auto &i:vec) cout<<i<<endl; return 0;}
3.19
int main(){ vector<int> a(10,42.5); vector<int> b={42,42,42,42,42,42,42,42,42,42}; vector<int> c{42,42,42,42,42,42,42,42,42,42}; return 0;}
显然第一种方式最方便。但是第2、3种方式会提示精度损失的情况,但是第1种方式就不会。
3.20
int main(){ vector<int> vec; int val; while(cin>>val) vec.push_back(val); for(int i=1; i<vec.size(); ++i) cout<<vec[i]+vec[i-1]<<endl; for(int i=0; i<=(vec.size()-1)/2; ++i) cout<<vec[i]+vec[vec.size()-1-i]<<endl; return 0;}
3.21
int main(){ vector<int> vec; int val; while(cin>>val) vec.push_back(val); for(vector<int>::iterator it=vec.begin(); it!=vec.end(); ++it) cout<<*it<<endl; return 0;}
3.22
int main(){ string str; cin>>str; for(string::iterator it=str.begin(); it!=str.end(); ++it) *it=toupper(*it); cout<<str<<endl; return 0;}
3.23
int main(){ vector<int> vec(10,66); for(vector<int>::iterator it=vec.begin();it!=vec.end();++it) *it*=2; for(auto i:vec) cout<<i<<endl; return 0;}
3.24
经过测试,++vec.begin()返回第二个迭代器,但是vec.begin()仍然是第一个迭代器。
int main(){ vector<int> vec; int val; while(cin>>val) vec.push_back(val); for(vector<int>::iterator it=++vec.begin(); it!=vec.end(); ++it) cout<<*(it-1)+*it<<endl; for(vector<int>::iterator it=vec.begin(); it<=vec.begin()+(vec.end()-vec.begin()-1)/2; ++it) cout<<*it+*(vec.end()-1-(it-vec.begin()))<<endl; return 0;}
3.25
*的优先级高于+-运算,因此需要先计算迭代器再解引用。而++优先级低于*,所以可以保证++的是解引用以后的值。
int main(){ vector<unsigned> scores(11,0); unsigned grade; while(cin>>grade) if(grade<=100) ++*(scores.begin()+grade/10); for(auto i:scores) cout<<i<<endl; return 0;}
3.26
因为(beg+end)数值可能较大超出范围。
3.27
(a)合法
(b)合法
(c)可能非法。如果该函数返回非正数就会出现问题。
(d)非法,该字符串还有一个‘\0‘字符,所以需要至少12个元素来存放。
数组的下标是unsigned类型?
3.28
sa包含10个空的string,ia包含10个0。
sa2包含10个空的string,ia2包含10个未知数。
3.29
数组不能动态增长和添加删除元素。不能用数组直接赋值。。
3.30
不存在下标为array_size的元素,故访问越界
3.31
数组没有用括号初始化的方式,想想不奇怪,数组是内置数据类型,它不是类,没有构造函数。
int main(){ int a[10]={0,1,2,3,4,5,6,7,8,9}; return 0;}
3.32
int main(){ int a[10]={0,1,2,3,4,5,6,7,8,9}; vector<int> vec(begin(a),end(a)); for(auto i:vec) cout<<i<<endl; return 0;}
3.33
直接用下标访问将越界,因为不存在相应的元素。
3.34
将p1指向p2所在位置。
该式等价于p1=p1+p2-p1
如果p1+p2、p2-p1超出数组范围将非法。
3.35
int main(){ int a[10]= {0,1,2,3,4,5,6,7,8,9}; for(int i=0; i<10; ++i) *(a+i)=0; for(auto i:a) cout<<i<<endl; return 0;}
3.36
如果数组a小于数组b返回1,大于则返回-1,否则返回0。
int compareArray(int *a,int n1,int *b,int n2){ int i=0; while(i<n1&&i<n2) { if(a[i]<b[i]) return 1; else if(a[i]>b[i]) return -1; i++; } if(n1==n2) return 0; else if(n1<n2) return 1; else return -1;}
int compareVector(const vector<int> &a,const vector<int> &b){ if(a==b) return 0; else if(a<b) return -1; else return 1;}
3.37
代码原意是用一个指针指向了该常量字符数组,并遍历输出。
但是这个常量字符数组缺少了结束符,即‘\0‘。
所以遍历不会得到想要结果。
int main(){ const char ca[]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘}; const char *cp=ca; while(*cp) { cout<<*cp<<endl; ++cp; } return 0;}
3.38
两个指针就是两个地址(非空的情况下),请问两个地址相加有何意义?
3.39
int compareString(const string &a,const string &b){ int i=0; while(i<a.size()&&i<b.size()) { if(a[i]>b[i]) return 1; else if(a[i]<b[i]) return -1; i++; } if(a.size()==b.size()) return 0; else if(a.size()>b.size()) return 1; else return -1;}
int compareChar(const char *a,const char *b){ int i=0; while(a[i]&&b[i]) { if(a[i]>b[i]) return 1; else if(a[i]<b[i]) return -1; i++; } if(!a[i]&&!b[i]) return 0; else if(a[i]) return 1; else return -1;}
3.40
int main(){ char x[]="abc",y[]="xyz"; char c[10]; strcpy(c,x); strcat(c,y); puts(c); return 0;}
3.41、3.42
int main(){ int a[5]= {0,1,2,3,4}; vector<int> vec(begin(a),end(a)); int b[5]; for(int i=0; i<vec.size(); ++i) b[i]=vec[i]; return 0;}
3.43
这个题有点难度。值得研究一下。
int main(){ int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11}; for(int (&i)[4]:ia) for(int j:i) cout<<j<<endl; for(int i=0; i<3; ++i) for(int j=0; j<4; ++j) cout<<ia[i][j]<<endl; for(int (*i)[4]=begin(ia); i!=end(ia); ++i) for(int *j=begin(*i); j!=end(*i); ++j) cout<<*j<<endl; return 0;}
如果不用begin和end函数:
int main(){ int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11}; for(int (*i)[4]=ia; i!=ia+3; ++i) for(int *j=*i; j!=*i+4; ++j) cout<<*j<<endl; return 0;}
3.44
int main(){ int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11}; using int_array =int[4]; for(int_array &i:ia) for(int j:i) cout<<j<<endl; for(int_array *i=begin(ia); i!=end(ia); ++i) for(int *j=begin(*i); j!=end(*i); ++j) cout<<*j<<endl; return 0;}
3.45
int main(){ int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11}; for(auto &i:ia) for(auto j:i) cout<<j<<endl; for(auto i=begin(ia); i!=end(ia); ++i) for(auto *j=begin(*i); j!=end(*i); ++j) cout<<*j<<endl; return 0;}