c++ primer第五版----学习笔记(三)

1.标准库类型string

  • 初始化string对象:直接初始化与拷贝初始化
string s1 = "hiya";         //拷贝初始化(使用 = 初始化变量)
string s2("hiya");          //直接初始化
string s3(10,'c');          //直接初始化,s3的内容是cccccccccc
  • string对象上的部分操作:(1)getline (is, s)     从is中读取一行赋給s,返回is
  •                                          (2)s.empty()          s为空返回true, 否则返回false
  •                                          (3)s.size()             返回s中字符的个数
  •                                          (4)s[n]                   返回s中第n个字符的引用,位置n从0计起
  • string::size_type类型:它是一个无符号类型的值而且能够存放任何string对象的大小
//允许编译器通过auto或者decltype来推断变量的类型
auto len = line.size();   //len的类型是string::size_type

//如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题

 2.多个string对象的操作:

//比较string对象
/************************************************************
1.如果两个string对象的长度不同,而且较短string对象的每个字符都与较长string对象对应位置上的字符相同,就说较短string对象小于较长string对象
2.如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果。
************************************************************/
string str = "Hello";
string phrase = "Hello World";     //判断对象str小于对象phrase
string slang = "Hiya";             //判断对象slang既大于str也大于phrase

//string对象相加、字面值和string对象相加
string s1 = "Hello, ", s2 = "world\n";
string s3 = s1 + s2;               //s3的内容是Hello, world\n

string s1 = "hello", s2 = "world";
string s3 = s1 + "," + s2 +'\n';

3.处理string对象中的字符:

  • 定义在cctype头文件中的一组标准库函数处理单个字符

   

  •  使用范围for语句处理每个字符:
//使用范围for语句不改变字符串中的字符
string str("some string");
for (auto c : str)                 //使用auto得到c的类型,意思是对于str中的每个字符
    cout << c << endl;             //输出每个字符

//使用范围for语句改变字符串中的字符
string s("Hello world!!!");
for (auto &c : s)                  //对于s中的每个字符(c是引用)
    c = toupper(c);                //赋值语句改变s中字符的值,将字符全部改为小写
cout << s << endl;                 //输出字符串s

4.标准库类型vector(容器):

  •  定义和初始化vector对象:
vector<T> vec;             //T可以是内置类型、类类型或vector类型
//列表初始化vector对象
vector<string> v1{"a", "an", "the"};     //列表初始化
//值初始化
vector<int> ivec(10, 1);                 //10个元素,每个都初始化未1

//区分以下两种初始化方式
vector<int> v2(10, 1);
vector<int> v3{10, 1};                  //v3有两个元素,分别为10和1
/****************************************************
1.如果用的是圆括号,可以说提供的值是用来构造vector对象的
2.如果用的是花括号,可以表述成我们想列表初始化该vector对象
****************************************************/
  • vector支持的操作(部分):(1)v.empty()            如果v不含有任何元素,返回真;否则返回假
  •                                               (2)v.size()               返回v中元素的个数
  •                                               (3)v.push_back(t)    向v的尾端添加一个值为t的元素
  •                                               (4)v[n]                      返回v中第n个位置的引用
  • vector对象(及string对象)的下标运算符可用于访问已存在的元素,而不能用于添加元素

5.迭代器(iterator):

  • 使用迭代器可以访问某个元素
  • 迭代器也能从一个元素移动到另外一个元素
  • 标准容器迭代器的运算符:
*iter                    //返回迭代器iter所指元素的引用
iter->mem                //解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem
++iter                   //令iter指示容器中的下一个元素
--iter                   //令iter指示容器中的上一个元素
iter == iter1
iter != iter1            //判断两个迭代器是否相等

//begin和end运算符
vector<int> v;
auto beg = v.begin();
auto last = v.end();

  • 迭代器类型:iteratorconst_iterator两种类型,后者只能读不能写
  • 两个迭代器的距离:右侧的迭代器向前移动多少位置能追上左侧的迭代器,类型是名为difference_type的带符号型整数

6.数组(部分重点特性):

  • 不允许拷贝和赋值:
int a[] = {0, 1, 2};        //含有3个整数的数组
int a2[] = a;               //错误:不允许使用一个数组初始化另一个数组
a2 = a;                     //错误:不能把一个数组直接赋值给另一个数组
  • 要想理解数组声明的含义,最好的方法是从数组的名字开始按照由内到外的顺序阅读
  • 在使用数组下标时,通常将其定义为size_t类型,它是一种机器相关的无符号类型,在cstddef文件中定义
  • 指针和数组:
//对数组的元素使用取地址符就能得到指向该元素的指针
string numbers[] = {"one", "two", "three"};
string *p = &numbers[0];       //p指向numbers的第一个元素

//标准库函数begin()和end(),定义在iterator头文件中
int ia[] = {0, 1, 2, 3, 4, 5};
int *beg = begin(ia);           //指向ia首元素的指针
int *last = end(ia);            //指向ia尾元素的指针
  • 使用数组初始化vector对象:只需指明要拷贝区域的首元素地址和尾后地址
int int_arr[] = {0, 1, 2, 3, 4, 5};
vector<int> vec(begin(int_arr), end(int_arr));

7.多维数组(数组的数组):

  • 多维数组的初始化:
//使用花括号初始化多维数组
int ia[3][4] = {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11}
};

//显示的初始化每行的首元素
int ia[3][4] = {{0}, {4}, {8}}; 
//显示的初始化第一行,其他的元素默认初始化
int ia[3][4] = {0, 3, 6, 9};
  • 使用for语句处理多维数组:
//使用普通for语句处理多维数组
constexpr size_t rowcnt = 3, colcnt = 4;
int ia[rowcnt, colcnt];   //12个未初始化的元素
//对于每一行
for (size_t i = 0;i != rowcnt;++i)
{
    //对于行内每一列
    for (size_t j = 0;j != colcnt;++j)
    {
        //将元素的位置索引作为它的值
        ia[i][j] = i * colcnt + j;
    }
}

//使用范围for语句处理多维数组
size_t cnt = 0;
for (auto &row : ia)              //对于外层数组的每个元素
{ 
    for (auto &col : row)     //对于内层数组的每个元素
    {
        col = cnt;        //将下个值赋給该元素
        ++cnt;            //将cnt加1
    }
}

//使用指针处理多维数组
int ia[3][4];
for (auto p = ia;p != *p + 4; ++p)           //p指向含有4个整数的数组
{
    for (auto q = *p;q != *p + 4; ++q)       //q指向4个整数数组的首元素,q指向一个整数
    {
        cout << *q << " ";
    }
    cout << endl;
}

//使用begin()和end()函数处理
for (auto p = begin(ia);p != end(ia); ++p)           //p指向含有4个整数的数组
{
    for (auto q = begin(*p);q != end(*p); ++q)     //q指向4个整数数组的首元素,q指向一个整数
    {
        cout << *q << " ";
    }
    cout << endl;
}


  • 使用类型别名简化多维数组的指针
using int_array = int[4];
typedef int int_array[4];     //int_array表示4个整数的数组

8.部分习题解答:

扫描二维码关注公众号,回复: 3427884 查看本文章

3.3:

对于string类的输入函数,它会自动忽略开头的空白(空格、制表符、换行等等),从第一个真正的字符开始直到下一个空白。 对于getline()函数,它会保存字符串中的空白符,它读入数据,直到遇到换行符位置。

3.5:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string str, sumstr;
    while (cin >> str)
    {
        sumstr += str;
    }
    cout << sumstr << endl;
    system("pause");
    return 0;
}

3.6:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string str = "fanhaihua";
    for (auto &c : str)
    {
        c = 'x';
    }
    cout << str<< endl;
    system("pause");
    return 0;
}

3.7:

单使用char类型改变不了字符的值,必须使用char &

3.10:

;

#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
    string str("hello!world!");
    for (auto c : str)
    {
	if (!ispunct(c))
	{
		cout << c;
	}
    }
    system("pause");
    return 0;
}

3.17:

#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
int main()
{
    vector<string> text;
    string s;
    while (cin >> s)
    {
	text.push_back(s);
    }
    for (auto it = text.begin();
	it != text.end()&& !it->empty(); ++it)        //it指向容器内元素的首地址
    {
	for (int j = 0; j < (*it).length(); ++j)      //j在每个元素内循环
	{
		(*it)[j] = toupper((*it)[j]);
	}
    }
    for (auto c : text)
    {
	cout << c << endl;
    }
    system("pause");
    return 0;
}

3.20:

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<int> v2;
    int n, sum;
    while (cin >> n)
    {
	v2.push_back(n);
    }
    for (int i = 0,j = v2.size()-1; i <j; ++i,--j)
    {
	cout << v2[i] + v2[j] << endl;
    }
    system("pause");
    return 0;
}

3.22:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s("Hello world!!!");
    for (auto it = s.begin();
	    it != s.end() && !isspace(*it); ++it
    {
	    *it = toupper(*it);
    }
    cout << s << endl;
    system("pause");
    return 0;
}

3.23:

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
    vector<int> vec(10,5);
    for (auto it = vec.begin();it != vec.end();++it)
    {
        *it = *it * 2;
        cout << *it <<endl;
    }
}

3.24:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v2;
    int n, sum;
    while (cin >> n)
    {
	v2.push_back(n);
    }
    for (auto beg = v2.begin(), last = v2.end() - 1;beg < last;++beg,--last)
    {
	cout << *beg + (*last) << endl;
    }
    system("pause");
    return 0;
}

3.25:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> grade(11, 0);
    int number;
    while (cin >> number)
    {
	if (number > 100)
	{
		cout << "The input number is wrong" << endl;
	}
	auto it = grade.begin();
	int n = number / 10;
	it += n;
	++(*it);
    }
    for (int i = 0; i < 10; ++i)
    {
	cout << i * 10 << "~" << i * 10 + 10 << "\t";
	cout << grade[i] << endl;
    }
    system("pause");
    return 0;
}

3.36:

//容器版本比较
#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v1 = { 1,2,3,4,5 };
    vector<int> v2 = { 2,3,4,5 };
    int num = 0;
    if (v1.size() == v2.size())
    {
	for (auto i = v1.begin(), j = v2.begin();
		i < v1.end(); ++i, ++j)
	{
		if (*i != *j)
		{
			cout << "not equal" << endl;
		}
		else
		{
			num++;
		}
	}
    }
    else
    {
	cout << "not equal" << endl;
    }
    if (num == 5)
    {
	cout << "equal" << endl;
    }
    system("pause");
    return 0;
}

3.41:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int a[10] = {0,1,2,3,4,5,6,7,8,9};
    vector<int> vec(a, a+10);
    for (int i = 0;i < 10;++i)
    {
        cout << "vec[" << i << "]" << vec[i] << endl;
    }
    system("pause");
    return 0;
}

3.42:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int a[10];
    vector<int> vec(10, 1);
    for (int i = 0;i < 10;++i)
    {
        a[i] = vec[i];
        cout << "a[" << i << "]" << a[i] << endl;
    }
    system("pause");
    return 0;
}

3.43、3.44、3.45:


//初始化二维数组

//版本1:
for (int(&p)[4] : ia)
{
	for (const int(&q) : p)
		cout << q << "\t";
	cout << endl;
}

//版本2:
for (size_t i = 0; i < 3; ++i)
{
	for (size_t j = 0; j < 4; ++j)
		cout << ia[i][j] << "\t";
	cout << endl;
}

//版本3:
for (int(*p)[4] = ia; p != end(ia); ++p)
{	
	for (int *q = *p; q != end(*p); ++q)
		cout << *q <<"\t";
	cout << endl;
}*/


//3.34即用类型别名替代上述出现的类型
//3.35即用auto代替上述出现的类型

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/81673772