getline<cin,string>;
//带空格的字符串输入
//cin在读到换行符时截止,换行符不写入string
一个有趣的事实是,string.size()返回的对象似乎是一个 unsigned类型的整数。
事实上,该函数返回的类型是string::size_type
的值,这种类型是在string或者是其他标准库中(如vector)内部定义的。
对于size_type,只需要注意两点:①它是一个无符号类型(不要与有符号整数直接混用)②它的大小可以放下任何大小的size
关于string的加法
string s1 = "hello, ", s2 = "world\n";
string s3 = s1 + s2; // s3 is hello, world\n
cout << s1 << s2 << s3 << endl;
s1 += s2; // equivalent to s1 = s1 + s2
cout << s1;
string s4 = "hello", s5 = "world"; // no punctuation in s4 or s2
string s6 = s4 + ", " + s5 + '\n';
cout << s4 << s5 << "\n" << s6 << endl;
string s7="hello"+"world\n";//invalid
//字面值不能直接相加
如何遍历string中所有元素
for (string::const_iterator iter = s4.begin(); iter != s4.end(); ++iter)
{
cout << (*iter);
}
//文艺写法
for (char ch : s4)
{
cout << ch;
}
//普通写法
for (int i = 0; i < s4.size(); i++)
{
cout << s4[i];
}
//更普通写法
第二种写法被称作范围for语句,如果遍历的操作涉及对元素的修改的话,应该是如下写法
for (char &ch : s4)
{
ch=toupper(ch);
}
vector的初始化
vector<string> v1{"a","an","the"};//列表初始化
vector<string>v2(10,"hello");//创建10个string,其内容均为:hello;
vector<int>v3(10);//10个int其数值均为0
//一个有趣的现象:如果初始化是使用了花括号的列表化初始方法但是又没有提供相应的元素,就要考虑用这样的值来构造vector对象了
vector<string> v4{10};//构造出了10个默认构造的string
vector<string> v5{10,“hello"};//构造出10个hello
C++标准要求vector能在运行时高效快速的添加元素。因此vector对象能高效地增长。所以在初始化时直接指定容量可能不是一个最好的选择。
vector的迭代器包含两种分别是
vector<int>::iterator it;//可读可写
vector<int>const_iterator iter;//只能读
//如果vector的对象是const,只能用后者
数组
int a = 1;
int const b = 2;
constexpr int c = 3;
int arr[a];//error:expression must have a constant value
int arr2[b];
int arr3[c];
string strs[get_size()];//get_size()要是一个constexpr
可对数组的元素进行列表初始化,此时允许忽略数组的维度,但是,如果指定了维度,则初始值的总数量不应高于数组的维度
int a[2]={1,2,3};//error
int *ptrs[10];//定义了10个整形指针的数组
int &refs[10];//错误,不存在引用的数组
int (*Parray)[10]=&arr;//Parray指向一个含有10个整数的数组
int (&arrRef)[10]=arr;//arrRef引用一个含有10个整数的数组
//由里向外,由右向左理解类型
int *(&array)[10]=ptrs;//array是数组的引用,这个数组含有10个指针
建议将使用数组元素的下标时使用类型 size_t,这是一个机器相关的足够大的无符号类型,定义在cstddef头文件中
使用数组时,编译器一般会把它转化为指针
auto p1(arr3);//编译器实际执行的是 auto p1(&arr3[0]);
decltype(arr3) p2 = { 1,2 };
p1 = &b;
p2 = &a;//error
p2[1]=0;
//使用auto读取数组的类型,返回的是一个指针
//使用decltype读取数组的类型,返回的是一个同类型同大小的数组
//通过begin和end函数来实现类似于容器的操作
int intarray[]={1,2,3,4,5,6};
int *beg=begin(intarray);
int *last=end(ia);
//两个函数定义在iterator头文件中
同类型指针相减的结果是一种带符号类型ptrdiff_t。定义在cstddef中。
int int_arr[10];
//
//
//
vector<int>ivec(begin(int_arr),end(int_arr));
//使用数组初始化vector
对于多维数组的一些讨论
constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt] = {};
for (auto &row : ia)
{
for (auto col : row)
{
cout << col << ' ';
}
cout << endl;
}
for(auto p=begin(ia),p!=end(ia);++p)
{
for(auto q=begin(*p);q!=end(*p);++q)
{
cout<<*q<<endl;
}
}
//外层的循环变量必须使用引用类型
//参考前面对auto的叙述,外层的auto解出来是一个 int*,遍历对于一个int*是不合适的
typedef char strings[80]//给char[80]起一个strings的别名
using str = char[80];//给char[80]起一个str的别名