第三者:字符串,向量和数组

本章主要介绍string, vector,迭代器等标准库类型和内置类型数组。

一:命名空间的using声明

        例如using std::cin,以后使用cin不必说明std了。还可以用using namespace std;

二:string类型的初始化

        第三个和第五个是拷贝初始化,其他几个是直接初始化。

三:字符串的输入

 

        定义string s; 可以使用cin>>s;输入字符串,读取方式是遇到空白符跳过,直到遇到第一个真正的字符,然后开始读入s,当遇到空白符结束。也可以使用getline(cin, s); 此时从缓冲区读取字符到s,直到遇到换行符,换行符被丢弃。

四:string的相加

 

	string s = "hello";
	string s1 = s + "," + "world";
	string s2 = "ximing" + "," + s;

        在上面的代码中,s1定义合法,s2定义错误。s2定义中,先执行"ximing"+",",而编译器无法执行该语句。因为在c++中,字符串字面值不是string类型啊,而是字符数组类型鸭。”+“的运算符重载是在string中定义的鸭。

 

五:头文件cctype

 

六:cctype是ctype.h,有.h后缀到c前缀说明是继承于c语言的类库。但是c前缀的头文件的名字都是包含于std的命名空间,所以建议使用c前缀鸭。

七:for循环新形式

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main()
{
	string s = "hello, world";
	for (auto &c : s)
	{
		if (isalpha(c))
			c = 'x';
	}
	cout << s << endl;
	return 0;
}

上面这段代码将字符串中的字母转换为‘x'。变量c是引用类型。这种范围for循环的循环体内不能有改编遍历对象大小的语句

八:vetor容器

vector<string> s = {"hello", "hi", "nihaoa"};
vector<string> s1(10, "hi");

        对s使用的是列表初始化,对s2使用的是构造vector对象。前者是花括号,后者是圆括号。

s1.push_back("i am coming");

        运用push_back函数向容器添加元素

        vector容器也可以比较大小,根据字典序方式比较。但是如果元素本身不可以比较大小,那么vector容器不能比较大小

九:迭代器

        所有的标准库容器都可以使用迭代器,但是只有少数几种能同时支持下标索引。容器可以返回迭代器成员,例如begin()返回第一个元素迭代器,end()返回的是最后一个元素的下一个位置的迭代器,常被称为“尾后迭代器”。若容器为空,则begin()和end()返回同一个迭代器。还有一对函数,cbegin()和cend(),返回的是begin()和end()的const版本,即只能通过迭代器读元素而不能写元素。 

        在上面的代码中,注意以下几点。第一:若要访问元素,则和指针的用法类似,通过解引用符号。第二,迭代器访问下一个元素用自增运算符 。 比较迭代器和尾后迭代器用“!=”而不是"<"。

        但凡使用了迭代器的循环体,都不要向迭代器指向的容器添加元素。

        vector迭代器的特殊功能如下图

十:数组

        

int *a[10];
int *(&array)[10] = a;

        在上面的代码中,a是一个含有十个元素的数组,数组元素是int指针。array是一个引用,引用了一个含有十个元素的数组,数组元素是int指针。

#include <iostream>
#include<vector>
#include <string>
#include <cctype>
using namespace std;

int main()
{
	int a[10] = { 1,2,3,4,5 };
	for (auto i: a)
	{
		cout << i << " ";
	}
	cout << endl;
	while (1) {}
	return 0;
}

        在上面的代码中,会输出十个元素,分别是1,2,3,4,5,0,0,0,0,0.因为定义时候规定了数组维度是十,所以使用范围for循环会输出十个元素。

 

int i = 9;
int *p = &i;
int ai[] = { 1,2,3,4,5 };
auto ai2(ai);
decltype(ai) ai3 = { 3,4,5,6,7 };
ai2 = p;
ai3 = p;

        在上面的代码中,ai2的类型是int*类型,所以ai2 = p是正确的,而ai3是int [5]类型,是不能赋值的,所以ai3 = p是错误的。

 

#include <iostream>
#include<iterator>
using namespace std;

int main()
{
	int a[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
	auto abegin = begin(a);
	auto aend = end(a);
	int sum = 0;
	for (auto p = abegin; p != aend; p++)
	{
		sum += *p;
	}
	cout << sum << endl;
	return 0;
}

        在上面的代码中,输出是120。用到了c++11标准中新加的两个函数begin()和end(),在头文件iterator中定义,可以返回数组的首元素和最后一个元素的下一个元素。

        在上图中,指针p也可以用下标访问数组元素。其实下标访问和解引用访问是一样的。p[1]就是*(p+1)。还可以看出,可以用负号作为数组的访问下标索引值,但是vector和string的下标索引只能是正数。

 

十一:c风格字符串

        c语言风格的字符串就是字符数组,以‘'\0'结束那种。上面的变量p,p1,p2都是c风格的字符串。

     

char s1[] = "hello,";
char s2[] = "my dear";
char s3[20];
strcat_s(s1, s2);
strcpy_s(s3, s1);
cout << s3 << endl; 

        上面这段代码运行时侯会出错,因为s1的大小不能存放s1和s2连接后的字符串。所以使用c风格的字符串不如使用string安全高效。

        

	string s = "hello, my dear";
	const char *ch = s.c_str();
	s = "hello, my another dear";
	cout << ch << endl; 

        上面这段代码将string类型的字符串转化为c风格的字符串。注意最后的输出是不确定的字符串,s更改,ch也就变成了无效字符串了。现在的c++应该尽量使用vector和迭代器代替数组和指针,使用string代替c风格的字符串。

十二:多维数组

	int a[2][3];
	int cnt = 0;
	for(auto &row:a)
		for (auto &col : row)
		{
			col = cnt++;
		}
	for (auto &row : a)
	{
		for (auto &col : row)
		{
			cout << col << " ";
		}
		cout << endl;
	}

        在上面的代码中,通过范围for循环访问二维数组。这里要注意除了最内层循环之外,其余都要用引用类型,因为不用引用编译器会把数组a转换为整数指针赋值给row,这样row就是int*类型的,那么内层循环就不合法了。对于这段代码的输出循环,还可以用指针的方式输出,如下代码所示

	for (auto row = a; row < a + 2; row++)
	{
		for (auto col = *row; col < *row + 3; col++)
		{
			cout << *col << " ";
		}
		cout << endl;
	}

        注意内层循环的解引用符号。row的类型是 int (*row)[3], col的类型是int* col,可以看出auto的使用非常方便啊。还记得iterator头文件中定义的begin()和end()函数吗?用这两个函数循环输出也很简洁。代码如下所示

	for (auto row = begin(a); row != end(a); row++)
	{
		for (auto col = begin(*row); col < end(*row); col++)
		{
			cout << *col << " ";
		}
		cout << endl;
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值