实验2
task 1-4
1.普通数组、array、vector的相关性,以及,区别
vactor、array都可以定义一个数组,并与普通数组一样,都支持随机访问。
vector是动态数组类模板,数组对象大小是可变的,空间是在堆上按需分配,可以在尾部增加或删除数据项,用于数据项个数无法确定的场合。
array是固定大小数组类模板,创建的数组对象的大小是固定的。在元素个数固定的场合中,使用array比普通数组更安全,比vector效率更高。
2.迭代器与指针相关性,以及,区别
迭代器和指针都可以通过++去访问下一个,亦可+n去访问某个位置的,都可以修改指向对象的值。
但迭代器和指针是完全不同的,指针++只是简单地增加地址大小,但对于内存不连续的来说,就不可行了,而迭代器是可以++访问任意容器的。
这表明迭代器本质上是一个类模板,只不过通过指针的思想去设计它。
3.C风格字符串与string区别
C风格字符串并不是一种类型,它指的是一种编程习惯,指C语言中以'\0'结尾的字符串。
用字符串给字符数组赋值时由于要添加结束符'\0',数组的长度要比字符串的长度大1。
Info.hpp文件源码
#ifndef INFO_HPP #define INFO_HPP #include<iostream> #include<iomanip> #include<string> using namespace std; class Info { public: Info(string a, string b, string c,int d); void print(); ~Info() = default; Info(const Info& p); private: string nickname,contact,city; int n; }; Info::Info(string a = {"nickname"}, string b = {"contact"}, string c = {"city"}, int d=0) :nickname{a}, contact{b}, city{c}, n{d} { } void Info::print() { cout << left << setw(10) << "³Æºô:" << nickname << endl; cout << left << setw(10) << "ÁªÏµ·½Ê½:" << contact << endl; cout << left << setw(10) << "³ÇÊÐ:" << city << endl; cout << left << setw(10) << "ÈËÊý:" << n << endl; } Info::Info(const Info &p) { nickname = p.nickname; contact = p.contact; city = p.city; n = p.n; } #endif
main.cpp源码
#include<iostream> #include"Info.hpp" #include<vector> #include<string> #include<limits> using namespace std; int main() { const int capacity = 100; vector<Info> audience_info_list; int cnt = 0,num = 0; cout << "¼ÈëÐÅÏ¢:" << endl << endl; cout << "³Æºô/êdzÆ,ÁªÏµ·½Ê½(ÓÊÏä/ÊÖ»úºÅ),ËùÔÚ³ÇÊÐ,Ô¤¶¨²Î¼ÓÈËÊý" << endl; string a, b, c; int d; while(cin >> a >> b >> c >> d) { cnt+=d; if(cnt>capacity) { cnt -= d; cout << "¶Ô²»Æð£¬Ö»Ê£" << capacity-cnt << "¸öλÖÃ" << endl; cout << "1.ÊäÈëu£¬¸üÐÂ(update)Ô¤¶¨ÐÅÏ¢" << endl; cout << "2.ÊäÈëq£¬Í˳öÔ¤¶¨" << endl; char choice; cin >> choice; if(choice == 'q') { break; } else if(choice == 'u') { continue; } } else { Info temp(a,b,c,d); audience_info_list.push_back(temp); num++; } } cout << "½ØÖÁÄ¿Ç°£¬Ò»¹²ÓÐ" << cnt << "λÌýÖÚÔ¤¶¨²Î¼Ó¡£Ô¤¶¨ÌýÖÚÐÅÏ¢ÈçÏ£º" << endl; for (int i = 0; i < num; i++) { audience_info_list.at(i).print(); } }
TextCoder.hpp
#ifndef TEXTCODER_HPP #define TEXTCODER_HPP #include<iostream> #include<string> using namespace std; class TextCoder{ public: TextCoder(string s):text{s} { } string encoder(); string decoder(); private: string text; }; string TextCoder::encoder() { for(auto &ch : text) { if(ch>='A'&&ch<='U'||ch>='a'&&ch<='u') { ch += 5; } else if(ch>='V'&&ch<='Z'||ch>='v'&&ch<='z') { ch -= 21; } } return text; } string TextCoder::decoder() { for(auto &sh : text) { if(sh>='F'&&sh<='Z'||sh>='f'&&sh<='z') { sh -= 5; } else if(sh>='A'&&sh<='E'||sh>='a'&&sh<='e') { sh += 21; } } return text; } #endif
main.cpp源码
#include "TextCoder.hpp" #include <iostream> #include <string> using namespace std; int main() { using namespace std; string text, encoded_text, decoded_text; cout << "ÊäÈëÓ¢ÎÄÎı¾: "; while (getline(cin, text)) { encoded_text = TextCoder(text).encoder(); // ÕâÀïʹÓõÄÊÇÁÙʱÎÞÃû¶ÔÏó cout << "¼ÓÃܺóÓ¢ÎÄÎı¾:\t" << encoded_text << endl; decoded_text = TextCoder(encoded_text).decoder(); // ÕâÀïʹÓõÄÊÇÁÙʱÎÞÃû¶ÔÏó cout << "½âÃܺóÓ¢ÎÄÎı¾:\t" << decoded_text << endl; cout << "\nÊäÈëÓ¢ÎÄÎı¾: "; } }
auto
auto即 for(auto x:range) 这样会拷贝一份range元素,而不会改变range中元素;
但是!(重点) 使用for(auto x:vector)时得到一个proxy class,操作时会改变vector本身元素。应用:for(bool x:vector)
auto&
当需要修改range中元素,用for(auto& x:range)
当vector返回临时对象,使用auto&会编译错误,临时对象不能绑在non-const l-value reference (左值引用)需使用auto&&,初始化右值时也可捕获
const auto&
当只想读取range中元素时,使用const auto&,如:for(const auto&x:range),它不会进行拷贝,也不会修改range
const auto
当需要拷贝元素,但不可修改拷贝出来的值时,使用 for(const auto x:range),避免拷贝开销