chapter 3
1、
string a4(n, 'c'); //把s4初始化为由连续n个字符c组成的串。
string s5 =string(10,'c'); //拷贝初始化
while(getline(cin, line)) //每次读入一整行,知道达到文件末尾
cout<< line <<endl;
触发getline函数返回的按个换行符实际上被丢弃了,得到的string对象不包含换行符。
string.empty(); //函数返回一个对应的布尔值
string.size(); //返回一个string::size_type类型的值,这是一个unsigned int型
//所以,一条表达式中已经有size()函数就不要再使用int了,避免混用带来问题。
string s3 = s1 + s2; //两个string对象相加
string s4 = "hello" + ","; //包含字面值相加的情况,必须保证+两侧中有一个是string型
2、
为兼容C语言的标准库,C++将这些文件命名为cname。在名为cname的头文件中定义的名字从属于命名空间std,而定义在.h中的头文件则不然。
decltype(s.size()) punct_cnt =0; //punct_cnt的类型和s.size的返回值类型一样。
ispunct(c); //判断标点符号的个数
for(auto &c : s) //对于s中的每个字符(c是引用)
c = toupper(c); //c是一个引用,因此赋值语句将改变c中字符的值。
cout<< s <<endl;
3、
vector是模板而非类型,由vector生成的类型必须包括vector中元素的类型,例如vector<int>
vector<vector<int>>vector对象的又尖括号和其他元素类型之间要添加一个空格。
vector<int>v1{"a", "an", "the"}; //列表初始化
vector<int> vi =10; //错误,必须使用直接初始化的形式执行想来那个大小。
vector<string> v7{10};vector<string> v8{10, "hi"}; //都不是列表初始化,有10个元素的初始化
vector对象(包括string对象)的下标可用于访问已存在的元素,而不能用于添加元素。
string s("string");
if(s.begin() != s.end()){
auto it = s.begin();
*it = toupper(*it); //通过解引用迭代器来获取它所指示的元素。
}
将指向同一容器中元素的两个迭代器相减,结果是两个迭代器的距离。其类型是difference_type,可正可负,是带符号类型的。
4、
char a3[] = "c++";
const char s4[6] ="Daniel"; //错误,没有空间可存放空字符
指针和数组
string nums ={"one","two","three"};
string *p = &nums[0]; //p指向nums的第一个元素
string *p2 = nums; //等价于p2 = &nums[0];
int arr[] ={0,1,2,3,4,5,6,7,8,9};
int *e = &arr[10]; //指向尾元素的下一个元素
for(int *b = arr; b != e; ++b)
cou<<*b <<endl; //输出arr的元素
5、
两个指针相减的结果类型是一种名为ptrdiff_t的标准库类型,和size_t一样,其也是定义在cstddef头文件中的机器相关的类型。ptrdiff_t是带符号的类型。
int ia[] = {0,2,4,5,8};
int *p = &ia[2];
int k = p[-2]; //p[-2]是is[0]表示的那个元素
内置的下标运算符所用索引值不是无符号类型,这与string和vector不同。
6、
char ca[] = {'c', '*', '1'};
cout << strlen(ca)<<endl; //严重错误,C语言风格的字符串函数,ca没有以空字符结尾
string s("hello");
char *str = s; //错误,不能用string对象初始化char*
const char *str =s.c_str(); //正确。如果想一直使用c_str()返回的数组,最好将其拷贝一份
多维数组
int ia[3][4];
int (*p)[4] = ia;
int *ip[4]; //整形指针的数组
int (*ip)[4]; //指向含有4个整数的数组
#include <iostream> #include <vector> #include <cstring> #define NUM343 using namespace std; string sa[10]; int ia[10]; int main(){ /*3.1*/ #ifdef NUM31 cout<<"参见:http://blog.csdn.net/refuil/article/details/51226530 " "http://blog.csdn.net/refuil/article/details/51236735"<<endl; #endif /*3.2*/ #ifdef NUM32 string line; string word; while(getline(cin, line)//一次读入一行,直至遇见文件结束符 cout << line <<endl; while(cin >> word) //一次读入一个单词,直至遇见文件结束符 cout << word <<endl; #endif /*3.3*/ #ifdef NUM33 cout<<"string类型读取并忽略有效字符之前所有的空白字符,然后读取字符直至再次遇到空白字符,读取终止(空白字符仍留在输入流中)" "getline()函数不忽略开头的空白字符,读取字符直至遇到换行符,读取终止并丢弃换行符。"<<endl; #endif /*3.4*/ #ifdef NUM34 string str1, str2; cout << "Enter two strings: " <<endl; cin >> str1 >> str2; if(str1 == str2) cout << "They are the same."<<endl; else if(str1 > str2) cout << "The bigger one is: " << str1 <<endl; else cout << "The bigger one is: " << str2 <<endl; /* 比较size */ string::size_type len1, len2; len1 = str1.size(); len2 = str2.size(); if(len1 == len2) cout << "They are the same length."<<endl; else if(len1 > len2) cout << "The longer one is: "<<str1<<endl; else cout << "The longer one is: "<<str2<<endl; #endif /*3.5*/ #ifdef NUM35 string str, sum; cout << "Enter two strings: " <<endl; while(cin >> str) sum += str; cout<< "The concatenation of string is: "<< sum <<endl; /* Add the blank*/ cout << "Enter two strings: " <<endl; while(cin >> str) sum += " " + str; cout<< "The concatenation of string is: "<< sum <<endl; #endif /*3.6*/ #ifdef NUM36 string str("abcddefg"); for(auto &c : str){ if(!isspace(c)) c = 'X'; } cout<< str << endl; #endif /*3.7*/ #ifdef NUM37 string str("abcddefg"); for(char &c : str){ if(!isspace(c)) c = 'X'; } cout << str << endl; #endif /*3.8*/ #ifdef NUM38 string str("abcddefg"); int index = 0; while(index !=str.size()){ if(!isspace(str[index])) str[index] = 'X'; ++index; } cout<< "while语句: "<< str<<endl; /* for语句*/ for(decltype(str.size()) index =0; index != str.size();++index){ if(!isspace(str[index])) str[index] = 'X'; } cout<< "for语句: " <<str <<endl; #endif /*3.9*/ #ifdef NUM39 string s; cout << s[0] << endl; cout<<"输出s字符的第一个字符,不合法,因为s没有初始化是空字符串,是s[0]是无效的."<<endl; #endif /*3.10*/ #ifdef NUM310 string str, result; bool has_punct; cout<<"Enter the string with punctuation: "<<endl; getline(cin, str); for(auto &c : str){ if(ispunct(c)) has_punct = true; else result += c; } if(has_punct) cout<<"After the remove: "<< result <<endl; else{ cout<<"No punctuation character in the string" <<endl; return -1; } #endif /*3.11*/ #ifdef NUM311 cout<<"当且仅当不去改变 c 值时才是合法的,c的类型是const char&; 如果试图改变就是不合法的。"<<endl; #endif /*3.12*/ #ifdef NUM312 cout<<"(b)不合法,赋值左右类型不同,svec是string对象的vector对象,ivec是保存vector<int>对象的vector对象. "<<endl; #endif /*3.13*/ #ifdef NUM313 cout<<"(a)0个int元素;(b)10个int元素,值都是0;(c)10个int元素,值都是42;(d)1个int型元素,值是10;(e)两个int元素,10和42;(f)10个string元素,值为0;(g)10个hi元素。"<<endl; #endif /*3.14*/ #ifdef NUM314 vector<int> vec; int i; cout<<"Enter number: "<<endl; while(cin >> i){ vec.push_back(i); } for(auto &c : vec) cout<< c; cout<<endl; #endif /*3.15*/ #ifdef NUM315 vector<string> vec; string i; cout<<"Enter string : "<<endl; while(cin >> i){ vec.push_back(i); } for(auto &c : vec) cout<< c; cout<<endl; #endif /*3.16*/ #ifdef NUM316 vector<int> v1; // size:0, no values. cout<<"v1: size is "<<v1.size()<<" "; for(auto &c : v1) cout<< c; cout<<endl; vector<int> v2(10); // size:10, value:0 cout<<"v2: size is "<<v2.size()<<" "; for(auto &c : v2) cout<< c <<" "; cout<<endl; vector<int> v3(10, 42); // size:10, value:42 cout<<"v3: size is "<<v3.size()<<" "; for(auto &c : v3) cout<< c <<" "; cout<<endl; vector<int> v4{10}; // size:1, value:10 cout<<"v4: size is "<<v4.size()<<" "; for(auto &c : v4) cout<< c <<" "; cout<<endl; vector<int> v5{10, 42}; // size:2, value:10, 42 cout<<"v5: size is "<<v5.size()<<" "; for(auto &c : v5) cout<< c <<" "; cout<<endl; vector<string> v6{10}; // size:10, value:"" cout<<"v6: size is "<<v6.size()<<" "; for(auto &c : v6) cout<< c <<" "; cout<<endl; vector<string> v7{10, "hi"}; // size:10, value:"hi" cout<<"v7: size is "<<v7.size()<<" "; for(auto &c : v7) cout<< c <<" "; cout<<endl; #endif /*3.17*/ #ifdef NUM317 string str; vector<string> vec; while(cin >> str) vec.push_back(str); for(decltype(vec.size()) index = 0; index != vec.size(); ++index){ for(auto &c : vec[index]){ toupper(c); } cout<< vec[index] <<endl; } #endif /*3.18*/ #ifdef NUM318 vector<int> ivec; ivec[0] = 42; cout<<"不合法,ivec是空的vector,不允许通过下标形式访问任何元素,只能用push_back添加元素."<<endl; #endif /*3.19*/ #ifdef NUM319 vector<int> vec1(10,42); vector<int> vec2{42,42,....}; vector<int> vec3(10); for(vector<int>::iterator iter = vec.begin(); iter != vec.end(); ++iter) *iter = 42; #endif /*3.20*/ #ifdef NUM320 int val; vector<int> vec; cout<< "Enter numbers: " <<endl; while(cin >> val) vec.push_back(val); if(!vec.size()){ cout<<"No elements! " <<endl; return -1; } cout<<"The result has been sumed: "<<endl; for(vector<int>::size_type index =0; index < vec.size()-1; index = index +2)//这里不能用index != vec.size();因为index是逢2加,可能直接略过size()大小 cout << vec[index] + vec[index+1] <<" "; cout<< endl; //program changed cout<<"头尾元素相加: "<<endl; vector<int>::size_type first, last; for(first = 0, last = vec.size()-1; first < last; ++first, --last) cout<< vec[first] + vec[last] << " "; cout<<endl; #endif /*3.21*/ #ifdef NUM321 /*原理都在3.20中体现*/ int val; vector<int> vec; cout<< "Enter the numbers: "<<endl; while(cin >> val) vec.push_back(val); if(!vec.size()){ cout<<"No element! "<<endl; return -1; } cout <<"相邻两个元素相加: "<<endl; for(vector<int>::iterator iter = vec.begin(); iter < vec.end()-1; ++iter) cout<< *iter + *(iter+1) <<" "; cout<<endl; //program changed cout<<"头尾元素相加: "<<endl; vector<int>::iterator first, last; for(first = vec.begin(), last = vec.end()-1; first < last; ++first, --last) cout<< *first + *last << " "; cout<<endl; if(first == last) cout<<"The mid element isn't been sumed: "<< *first<<endl; #endif /*3.22*/ #ifdef NUM322 string word; vector<string> text; while(cin >> word) text.push_back(word); vector<string>::iterator it = text.begin(); for(string::iterator iter = (*it).begin(); iter != (*it).end(); ++iter) *iter = toupper(*iter); for(;it != text.end(); ++it) cout<< *it <<endl; #endif /*3.23*/ #ifdef NUM323 vector<int> vec(10,1); for(vector<int>::iterator iter = vec.begin(); iter !=vec.end(); ++iter){ *iter = (*iter) * 2; cout<< *iter <<" "; if(iter == vec.end()-1) cout<<endl; } #endif /*3.24*/ #ifdef NUM324 cout<<"见3.21"<<endl; #endif /*3.25*/ #ifdef NUM325 vector<unsigned> scores(11,0); vector<unsigned>::iterator iter = scores.begin(); unsigned grade; while(cin >> grade){ if(grade <= 100){ iter = iter + (grade/10); (*iter)++; iter = scores.begin(); //The iterator must be returned } } for(iter = scores.begin(); iter != scores.end(); ++iter) cout<< *iter <<" "; cout<<endl; #endif /*3.26*/ #ifdef NUM326 cout<<"begin + end是非法的,因为vector的迭代器并没有定义+运算符,编译器会报错."<<endl; #endif /*3.27*/ #ifdef NUM327 cout<<"(a)非法,buf_size是一个变量,不能用于下标取值。" "(c)非法,txt_size()是函数调用,不是常量表达式。" "(d)非法,存放这个字符串的数组必须要有12个元素. "<<endl; #endif /*3.28*/ #ifdef NUM328 string sa2[10]; int ia2[10]; cout<< sa[0]<<" "<<sa2[0]<< " "<<ia[0]<<" "<<ia2[0]<<endl; cout<<"sa, sa2默认构造函数将各元素初始化为空字符串;" "ia在函数体外初始化,默认初始化0; ia2在函数体内初始化,默认初始化不确定."<<endl; #endif /*3.29*/ #ifdef NUM329 cout<<"数组长度固定,要扩大容量,只能重新定义更大的数组再讲之前的拷贝进去;" "数组也没有vector的size/push_back操作,程序相对较复杂。"<<endl; #endif /*3.30*/ #ifdef NUM330 cout<<"ix = array_size时数组越界了."<<endl; #endif /*3.31*/ #ifdef NUM331 constexpr size_t array_size = 10; int ia[array_size]; for(size_t ix =0; ix < array_size; ++ix){ ia[ix] = ix; cout<< ia[ix]<<" "; } #endif /*3.32*/ #ifdef NUM332 constexpr size_t array_size = 10; int ia1[array_size]; int ia2[array_size]; cout<<"ia1: "; for(size_t ix =0; ix < array_size; ++ix){ ia1[ix] = ix; cout<< ia1[ix]<<" "; } cout<<endl; cout<<"ia2: "; for(size_t ix =0; ix < array_size; ++ix){ ia2[ix] = ia1[ix]; cout<< ia2[ix]<<" "; } cout<<endl; vector<int> vec1(10); vector<int> vec2(10); int i = 0; cout<<"vec1: "; for(auto &c : vec1){ c = i; ++i; cout<< c<<" "; } cout<<endl; i = 0; cout<<"vec2: "; for(auto &c : vec2){ c = vec1[i]; ++i; cout<<c<<" "; } cout<<endl; #endif /*3.33*/ #ifdef NUM333 cout<<"如果不初始化,scores就是未定义的,它的元素取值是不确定的."<<endl; #endif /*3.34*/ #ifdef NUM334 p1 += p2 - p1; cout<<"该语句使得p1也指向p2原来所指向的元素,只要p1和p2都是指向同一个数组的元素,该语句总是合法的。"<<endl; #endif /*3.35*/ #ifdef NUM335 int arr[] = {1,2,3,4,5}; int *p = arr; for(int i= 0; i <= 4; ++i){ *(p + i) = 0; cout<< *p << " "; } cout << endl; #endif /*3.36*/ #ifdef NUM336 /*For arrays*/ int arr_size = 5; int arr1[arr_size], arr2[arr_size]; cout << "Enter 5 numbers for array1: " <<endl; for(size_t i = 0; i < 5; i++) cin >> arr1[i]; cout << "Enter 5 numbers for array2: " <<endl; for(size_t i = 0; i < 5; i++) cin >> arr2[i]; for(size_t i = 0; i !=arr_size; ++i) if(arr1[i] != arr2[i]){ cout<< "array1 is not same with array2."<<endl; return 0;//只要存在一个元素不相同直接退出 } cout<< "array1 is same with array2."<<endl; /*For vectors*/ vector<int> vec1(5), vec2(5); cout<< "Enter 5 numbers for vector1: "<<endl; for(auto &c : vec1) cin >> c; cout<< "Enter 5 numbers for vector2: "<<endl; for(auto &c : vec2) cin >> c; for(vector<int>::size_type ivec =0; ivec != vec1.size(); ++ivec) if(vec1[ivec] != vec2[ivec]){ cout<< "vector1 is not same with vector2."<<endl; return 0; } cout<< "vector1 is same with vector2."<<endl; #endif /*3.37*/ #ifdef NUM337 const char ca[] = {'h','e', 'l', 'l', 'o'}; const char *cp = ca; while(*cp){ cout << *cp <<endl; ++cp; } cout<<"混合C风格的字符串类型,在数组末尾往汪有'/0'结束,所以输出的一般会多于5个字符."<<endl; #endif /*3.38*/ #ifdef NUM338 cout<<"当两个指针指向头一个数组,相减表示两者之间的距离;相加却很难解释,也是没有定义的,所以没有意义." #endif /*3.39*/ #ifdef NUM339 /*For string*/ string str1 = "linuxc++a"; string str2 = "linuxc++b"; if(str1 > str2) cout<< str1 <<endl; else cout<< str2 << endl; /*For C style char**/ const char* s1 = "linuxc++c"; const char* s2 = "linuxc++d"; if(strcmp(s1, s2) > 0) cout<< s1 <<endl; else cout<< s2 << endl; #endif /*3.40*/ #ifdef NUM340 const char* str1 = "linux"; const char* str2 = "c++"; size_t len = strlen(str1) + strlen(str2); char* str3 = new char[len+1];; strcpy(str3, str1); strcat(str3, str2); cout << "str3: " <<str3<<endl; #endif /*3.41*/ #ifdef NUM341 const size_t arr_size = 5; int arr[arr_size]; cout<< "Enter 5 numbers for array. "<<endl; for(size_t i =0; i!= arr_size; ++i) cin >> arr[i]; vector<int> vec(begin(arr), end(arr));//另一种写法vector<int> vec(arr, arr+arr_size) for(auto &c : arr) cout << c << " "; #endif /*3.42*/ #ifdef NUM342 int val; vector<int> vec; cout<< "Enter numbers for vector: " <<endl; while(cin >> val) vec.push_back(val); if(!vec.size()){ cout<<"No elements! " <<endl; return -1; } size_t ix = 0; //C风格数组的类型与vector的元素不一样,ix需要初始化 int *pstr = new int[vec.size()]; for(vector<int>::iterator i = vec.begin(); i != vec.end(); ++i, ++ix) pstr[ix] = *i; for(ix =0; ix < vec.size(); ++ix) cout<< *(pstr+ix) <<" "; delete []pstr; #endif /*3.43*/ #ifdef NUM343 int arr[3][4] ={0,1,2,3,4,5,6,7,8,9,10,11}; /*版本一*/ for(auto *p = begin(arr); p != end(arr); ++p) for(auto q = begin(*p); q != end(*p); ++q) cout<< *q <<" "; cout<<endl; /*版本一*/ for(int i =0; i < 3; ++i) for(int j =0; j < 4; ++j) cout<< arr[i][j]<<" "; cout<<endl; /*版本三*/ using int_array = int[4]; for(int_array *p = arr; p != arr+3; ++p) for(int *q = *p; q != *p+4; ++q) cout<< *q <<" "; cout<<endl; #endif /*3.44*/ #ifdef NUM344 int arr[3][4] ={0,1,2,3,4,5,6,7,8,9,10,11}; typedef int int_array[4]; for(int_array *p = arr; p != arr+3; ++p) for(int *q = *p; q != *p+4; ++q) cout<< *q <<" "; cout<<endl; #endif /*3.45*/ #ifdef NUM345 int arr[3][4] ={0,1,2,3,4,5,6,7,8,9,10,11}; for(auto (&row)[4] : arr) for(auto (&col) : row) cout<< col <<" "; cout<<endl; #endif return 0; }