今天帮学妹选了一天的电脑配件,然后从中领悟:坐看狗东黑我钱,任他涨价我不动!!最后果断的用学妹的钱冲了个Plus,然后领了一堆券,最后学妹还省了30块,另外昨晚找到了一个买酷睿i7 7700k 送主板的,又省了250,然后各种大小活动都去看了个遍,总算是学会了怎么省钱,特此还要多谢我华科电信的一位大佬--“大王”巍的指点,不然我肯定被狗东坑到怀疑人生。看配置的直接翻到正文之后看!
我们自己平时用的时候是:
using namespace std;
老实说我也就会这一句,所以其他的基本漠不关心,但是既然书里讲了我也就写出来了。一般的格式如下:
using std::cin;
有了上面这句,以后写cin就只是cin了。不需要std::cin了。不过也仅限于此,cout还是没法直接用,不过这样的好处就是可以单独的引用,不会造成浪费(Maybe)?
另外头文件不应该包含着using声明,因为头文件的内容会被拷贝到所有引用他的文件中取去,如果头文件内有这个using声明,那么每一个使用了该文件的文件就会有这个声明,对于某些程序来说,由于不经意间包含了一些名字,反而可能会产生始料未及的名字冲突。
首先,要使用string这个标准库就要声明下头文件
#include <string>
using std::string
string s1; //s1:empty
string s2=s1; //s2: empty
string s3="string"; //s3:string\0
string s4(10,'c') //s4:cccccccccc
string s5("string"); //s5:string\0
几种方式的过程和效果我都写出来了,就不多赘述了。
auto len=s.size(); decltype(s.size()) len;
采用基于范围的for循环实现:
for ( auto c:str) //此句的意思是:对于str中的每个字符进行拷贝
cout<<c<<endl;
上述只能实现读而不能实现存,因为是直接拷贝,所以无法对string的单个字符进行操作,但是如果是引用,就可以实现了。
for ( auto &c:str) //此句的意思是:对于str中的每个字符进行引用
{
cout<<c<<endl;
c=toupper(c);
}
利用这些特性,结合一个大家常见的下标运算符(这个点就不讲了,跟数组一样,烂大街了),我自己实现了一个把所有的英文单词的首字母改成大写的程序:
string w="hello boy I don't want to hurt you? baby~~~";
w[0]=toupper(w[0]);
for (decltype(w.size()) index=0; index < w.size(); ++index)
{
if (isspace(w[index]))
{
w[index+1]=toupper(w[index+1]);
}
}
cout<<"================================================\n"<<w<<"\n================================================\n"<<endl;
vector<int> ivec;
vector<string> strvec;
vector<vector<int> > vecivec;
因为vector是容纳对象的,所以不存在包含引用的vector;初始化如下:
vector<T> tvec; // Empty vector
vector<T> tvec(v1); // copy v1 to tvec
vector<T> tvec = v1 ; // 同上
vector<T> tvec(n,val); //tvec包含了n个相同T类型的val元素;
vector<T> tvec(n); //执行n次空的初始化;
vector<T> tvec{a,b,c,d ···}; //具体的初始化
vector<T> tvec={a,b,c,d ···}; //同上
注意如果是拷贝初始化的话,不同类型的vector是不能相互拷贝的!
对于vector这个容器,只能用专用的内置函数来对其增加元素,push_back具体用法如下:
vector<int> ivec;
for(int i=0;i!=100;++i)
{
ivec.push_back(i);
}
从上面我们可以知道,vector具有良好的动态增长的性能,所以一开始如果就限定其大小的话,是一种对特性的浪费,一开始初始化的时候就限定容量是不是一件明智的事情!(注意,其实上面的操作不是很符合规定,因为隐性规定:在循环体中改变了遍历序列的长度的操作不用for 循环,可能造成缓冲区溢出)
我们可以看到,对于vector只有一种添加元素的办法,但是对于元素的读写,可以直接用下标表示法,这个数组,string是完全共同的, 但是请注意,千万不要给定一个不存在的下标,如果超出了vector变量的长度,那么毫无疑问你的,会产生严重错误!甚至可能导致 缓存区溢出!!
vector<int > v;
auto b=v.begin();
此时如果可以查看b的类型,你会发现其实就是个指针对象。只是其类型由编译器给定。我们只管auto 或者 decltype就好了!,另外还有一个end()函数返回尾后迭代器,没有什么实际意义,正如名字,是在最后一个元素的下一个位置,用于判断是否为空的容器(begin end指向一个位置的时候)
vector<int>::iterator iter;
语句定义了一个名为 iter 的变量,它的数据类型是 vector定义的 iterator 类型。每个标准库容器类型都定义了一个名为 iterator 的成员,这里的 iterator 与迭代器实际类型的含义相同。
for (vector<string>::const_iteratoriter = text.begin();iter != text.end(); ++iter)
cout << *iter << endl; // printeach element in text
使用 const_iterator 类型时,我们可以得到一个迭代器,它自身的值可以改变,但不能用来改变其所指向的元素的值。可以对迭代器进行自增以及使用解引用操作符来读取值,但不能对该元素赋值。
记住一点:但凡是使用了迭代器的循环体,此时就不要像迭代器所属的容器进行添加元素的操作了!!!千万不要!!
iter + n
iter - n
iter1 - iter2
vector<int>::iterator mid = vi.begin() +vi.size() / 2;
任何改变 vector 长度的操作都会使已存在的迭代器失效。例如,在调用 push_back 之后,就不能再信赖指向 vector 的迭代器的值了!!!!!!!~
我只能看着这个配置流口水啊!!具体的购买详细和指导请看我另一篇文:万元台式机组装养成记
后来又加了三件配个套: