12-19 汇总前面的学习经验(第二章、第三章)

 

10.6中的查询文本方案涉及较多前面章节的细节,需要重新梳理。以下为梳理细节:

1、通过指定 const 变更为 extern,就可以在整个程序中访问 const 对象;

     声明是不分配内存空间的,而定义是分配内存空间的。是否分配内存空间是充要条件。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern。

      extern声明不是定义,也不分配存储空间。事实上它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。

        只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为extern。

        任何在多文件中使用的变量都需要有与定义分离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明(而不是定义)。

       不过有三个例外,一下三中实体的定义也可放到头文件中:

        1.值在编译时就已知的const 变量的定义可以放到头文件中

            如:const int num(10);

         2.类的定义可以放到头文件中

         3.inline 函数

         这三个实体可以定义在多个源文件中,只要在每个源文件中的定义相同。

2、引用作为函数的形参进行沟通,降低运行频率;

3、引用存在就保持关联到初始化指定的对象。引用只是对象的另一个名字。

4、typedef+数据类型+标识符

5、类定义以关键字class开始,+类的名字标识符 +  {  }  + 分号;

      类定义了数据和操作, 即类的成员。public里面包含了操作,

6、struct等效class定义,但是访问符号(private、public)前为public形式,无需增加public,struct里面成员都是public。而class的成员为private。

7、标准库类型bitset,提供抽象方法操作位的集合。string类型支持长度可变的字符串,vector用于保存一组指定类型的对象。

8、需要从标准输入读取数据时,就用 std::cin。这些名字都用了:: 操作符,该操作符是作用域操作符(第 1.2.2 节)。它的含义是右操作数的名字可以在左操作数的作用域中找到。   operater scope作用域

    using std::cin;

9、C++ 标准库将负责管理与存储字符相关的内存,以及提供各种有用的操作。标准库 string 类型的目的就是满足对字符串的一般应用。

#include <string>
#include<iostream>
     using std::string;
     using std::cin;
     using std::cout;
     using std::endl;
以上四句using语句可由using namespace std;代替

以上语句中的using namespace std为using指示,四句分列为using的声明。在新增加的库中最优使用using的声明,避免混乱。

10、字符串字面值和 string 数据类型的使用

        string 类型的输入操作符: 读取并忽略开头所有的空白字符(如空格,换行符,制表符);读取字符直至再次遇到空白字符,读取终止。

11、getline函数接受两个参数:一个输入流对象和一个 string 对象。getline 函数从输入流的下一行读取,并保存读取的内容到不包括换行符。和输入操作符不一样的是,getline 并不忽略行开头的换行符。

12、string的size、empty、比较、赋值、相加、[ ]、cctype头文件;

       size的操作返回值为string::size_type类型的值,size_type为配套类型(companion type)的一种,它定义为unsigned类型,能够存储任意string对象的长度。长度相比int值大两倍。

       任何存储string的size操作结果的变量必须为string::size_type类型。同时,size的返回值赋给一个int变量。

       string区分大小写,同一个字符的大小写形式被认为是两个不同的字符。大写位于小谢之前。任何大写字母都小于小写字母。从第一个字符开始比较;

       赋值操作确实需要做一些工作。它必须先把 st1 占用的相关内存释放掉,然后再分配给 st2 足够存放 st2 副本的内存空间,最后把 st2 中的所有字符复制到新分配的内存空间。

      “hello world”为字符串字面值,s1 = “hello world”为string类型的对象。+的左右操作数至少一个是string类型。

       cctype类型函数:isalnum、isalpha、iscntrl、isdigit、isgraph、islower、isprint、ispunct、isspace、isupper、isxdigit、tolower、toupper;
       可打印的字符是指那些可以表示的字符,空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符中的任意一种;标点符号则是除了数字、字母或(可打印的)空白字符(如空格)以外的其他可打印字符。

13.  C 标准库头文件命名形式为 name 而 C++ 版本则命名为 cname。

       bool值一般作为判断是否存在的标准

       空白字符(如空格,换行符,制表符)。  

       标准库负责管理与存储元素相关的内存。   vector是类模板class template

        getline(cin, s)    

        for(auto i:s)

        ispunct(i)

14. vector<T> v1数据类型定义

       vector保存的为含有构造函数的类类型 string元素

       vector的操作:v.empty()、v.size()、v.push_back(t)、v[n]、等同于string的操作

 15.定义size_type类型时,vector<int>::size_type的使用,必须指出该类型是在何处定义。vector类型需要包括vector的元素类型。下标为左值运算过程,并不能添加元素。必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时,不会添加任何元素。

        优先选用 != 作为循环判断条件

        for (int i; std::cin >> i; vec.push_back(i));

#include<iostream>
#include<vector>

//案例3.13 c++4rd
using namespace std;
using std::vector;

int main()
{
	vector<int> num;
	int ival;

	//读入数据到vector对象
	cout << "please input some numbers:" << endl;
	while (cin >> ival) {
		num.push_back(ival);
	}

	//计算相邻元素的和并输出
	if(num.size() == 0) {
		cout << "No elements?" << endl;
	return -1;
	}
	cout << "Sum of each pair of adjacent elements in the vector:" << endl;
	for (vector<int>::size_type m = 0; m < num.size() - 1; m = m + 2) {
		cout << num[m] + num [m+1] << "\t";
		if ((m + 1) % 6 == 0)  //每行输出6个和
			cout << endl;
	}
	if (num.size() % 2 != 0) {
		cout << endl
			<< "The last elment is not been sumbed"
			<< "and its value is"
			<< num[num.size() - 1] << endl;
		return 0;
	}
}
#include<iostream>
#include<string>
#include<vector>
#include<cctype>

using namespace std;


int main()
{
	//输入文本中的一串字符
	string str;
	vector<string>  line;
	while (cin >> str)
		line.push_back(str);

	//检验line中每一个字符是否为大小写
	for (vector<string>::size_type n = 0; n <= line.size(); ++n) {
		for (string::size_type index = 0; index != line[n].size(); ++index)
			//以上语句中的string声明,以及line[n][index],两个的联系
			if (islower(line[n][index]))
				line[n][index] = toupper(line[n][index]);
		cout << line[n] << " ";
		if ((n + 1) % 8 != 0)
			cout << endl;
	}
/*   采用迭代器iterator来遍历string中的单词,使用下标来表示每个单词中的单个字母
for (vector<string>::iterator n = line.begin(); n != line.end(); ++n) {
		for (string::size_type index = 0; index != (*n).size(); ++index)
			//以上语句中的string声明,以及line[n][index],两个的联系
			if (islower((*n)[index]))
				(*n)[index] = toupper((*n)[index]);   //toupper属于cctype的内容
		cout << *n << " ";
        ++accout;
		if ((n + 1) % 8 != 0)
			cout << endl;
	}

*/





	return 0;
		//划分8个不同的字符情况
}
//列出三种定义vector对象的方法

//方法1

vector<int> ivec(10,42);

//方法2

vector<int> ivec(10);
for(vector<int>::interator iter = ivec.begin();
                           iter != ivec.end(); ++iter)
   *iter = 42;

//方法3

vector<int> ivec(10);
for(ix = 0; ix < 10; ++ix)
     ivec[ix] = 42;

//方法4

vector<int> ivec;
for (cnt =1; cnt <= 10; ++cnt)
     ivec.push_back(42);

//方法5

vector<int> ivec;
vector<int>::iterator iter =ivec.end();   //由 end 操作返回的迭代器指向 vector 的“末端元素的下一个”。“超出末端迭代器”(off-the-end iterator)。表明它指向了一个不存在的元素。如果 vector 为空,begin 返回的迭代器与 end 返回的迭代器相同。


for( int i =0; i != 10; ++i){
    ivec.insert(iter,42);
    iter =ivec.end();
}

运行过程中的错误:

15、迭代器interator,是检查容器内元素并遍历元素的数据类型。可以小标访问vector对象的元素;

       所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持小标操作。迭代器对所有容器都适用

       vector<int>::iterator iter; 其中,iter的数据类型为vector<int>定义的iterator。

       若一种类型支持一组确定的操作(这些操作可用来遍历容器内的元素,并访问这些元素的值),我们就称这种类型为迭代器。

       由 end 操作返回的迭代器指向 vector 的“末端元素的下一个”。“超出末端迭代器”(off-the-end iterator)。表明它指向了一个不存在的元素。如果 vector 为空,begin 返回的迭代器与 end 返回的迭代器相同。

        由 end 操作返回的迭代器并不指向 vector 中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完 vector 中所有元素。由于 end 操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作

        迭代器类型使用解引用操作符(dereference  operator)访问迭代器所指向的元素

        解引用操作符的返回值是一个左值,因此可以对它进行赋值来改变它的值;

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

int main()
{
	cout << "please input some numbers into the nums:" << endl;
	//读入数据到nums
	vector<int> nums;
	int n, num, sum;
	vector<int> ::size_type cnt = 0;
	while (cin >> num)
		nums.push_back(num);   //cin为单个数字进行输入
	if (nums.size() == 0) {
		cout << "no elemnts?! " << endl;
		return -1;
	} 
	for (vector<int> ::iterator iter = nums.begin(); iter != nums.end(); iter = iter + 2) {
		cout << *iter * *(iter + 1) << "\t";
		++cnt;
		if (cnt % 6 == 0)
			cout << endl;
     }
/*

	for (vector<int> ::iterator first = nums.begin(), last = nums.end(); first < last; ++first, --lastiter ) {
		cout << *first * *last << "\t";
		++cnt;
		if (cnt % 6 == 0)
			cout << endl;
     }
//定了两个不同的变量,两个变量进行不断地迭代更新
*/

	//提示最后一个元素没有求和
	if (nums.size() % 2 != 0)
		cout << endl
		<< "the last element is not been summed"
		<< " and its value is"
		<< "*(nums.end()-1)" << endl;
	return 0;
}

        

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

int main() 
{
	cout << "please input ten numbers : " << endl;
	vector<int> vect;
	int vec, a =0;
	while (cin >> vec)
		vect.push_back(vec);
	for (vector<int> ::iterator num = vect.begin(); num != vect.end(); ++num) {
		++a;
		cout << *num * 2 << " ";  //如果输入是一行输入,但是cin是单个读入系统内,pushback也是单个写入。输出的时候也就是一行。
		// if (a % 3 == 0)
	    //    cout << endl;
	}
}

 

迭代器的算术操作:iterator arithmetic。iter + n 、 iter - n {n的类型应该是vector的size_type类型或difference_type类型}、iter1 - iter2{距离为difference_type的signed类型size_type的值,保证足够大}

vector<int>::iterator mid = vi.begin() + vi.size() /2 ;

16、标准库bitset(3.5节)

         要使用 bitset 类就必须包含相关的头文件。在本书提供的例子中,假设都使用 std::bitset 的 using 声明:    

          #include <bitset>

            using std::bitset;

         在定义 bitset 时,要明确 bitset 含有多少位,须在尖括号内给出它的长度值。类型对象的区别仅在长度而不在于类型。

         bitset<n>   b(s, pos, n)    b是s中从位置pos开始的n个位的副本

         bitset<n>  bitvec    以0位开始的位串是低阶位(low-order),以31位结束的位串是高阶位(high-order)

          unsigned long值作为bitset对象的初始值,该值将转化为二进制的位模式。总共为32位。

          string对象和bitsets对象之间是反向转化的。 bitset是从右向左进行添加

          把b中的位集输出到os流中

         count操作返回类型是标准库中命名为size_t类型。size_t定义在cstddef头文件中。

          vector和string中的size操作,返回bitset对象中的二进制位个数,返回值类型为size_t。

          为了测试某个二进制位是否为1,可以用test操作或者测试下标操作符的返回值:为1是true,否则返回false

           bitvec.test(i) 等价于bitvec[i]

          test、reset、flip的操作

          to_ulong 操作主要用于把 bitset 对象转到 C 风格或标准 C++ 之前风格的程序上。如果 bitset 对象包含的二进制位数超过 unsigned long 长度,将会产生运行时异常

           bitset<32>  bv(0x2012e)   对象的初始化

 

           

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章