一、名词定义- Vector:是一种类型的对象的集合,每个对象都有一个对应的整数索引值。它又称为容器,因为他可以包含其他对象。而在一个容器中对象的类型必须是一致的。在使用Vector之前必须包含相关头文件。#include using std::vector;vector是一个类模板。
- 迭代器:除了根据下标访问对容器中的对象进行访问之外,还可以通过迭代器进行访问。标准库为每一种标准容器(eg:Vector)定义了一种迭代器类型。
- 数组:C++语言提供了类似与Vector的低级复合类型--------数组;它也是一种存储单一数据类型对象的容器,其中每一个对象都没有单独的名字,而是通过它在数组中的位置通过下标进行访问。
- 指针:C++语言提供了类似与迭代器的低级复合类型---------指针;指针用于指向对象,与迭代器一样,指针提供对其所指对象的间接访问,只是指针更加通用一些。与迭代器不同的是,指针指向单个对象,而迭代器只能用于访问容器内部的元素。
二、定义及初始化
- 定义一个Vector 需要指定类型和一个变量的列表。是可以动态增长的。
- vector v1 ; vector保存类型为T的对象,构造函数默认为空;
- vector v2(v1) ; v2是v1的副本
- vector v3(n,i) ;v3包含n个值为i的元素
- vector v4(n) ;v4含有值初始化的元素的n个副本
如果没有指定元素的初始化,那么标准库将自行提供一个元素的初值进行值的初始化。这个由库生成的初始之将用来初始化容器中的每一个元素。例如vetcorok(10) ------------10 elements.each initialized to 0;如果vetcor含有的是构造函数的类型元素,标准库将用该类型的默认构造函数创建元素的初始化。 - 每种容器类型都定了他自己的迭代器类型,如vector:vector :: iterator iter;每个标准库容器类型都定义了一个名为iterator的成员,这里的iterator与迭代器实际类型的含义相同;每个容器都定义了命名为begin和end的函数,用于返回迭代器。如果使用的是begin()则返回的迭代器指向第一个元素,反之指向最后一个;迭代器类型定义一些操作来获取迭代器所指向的元素,并且允许迭代器从一个元素到另一个元素(自增自减操作符)。在迭代器中可以使用解引用操作符(*操作符)来访问迭代器所指向的元素。
- 数组的位数必须用值大于等于1的常量表达式定义。此常量表达式只能包含三整型面值、枚举常量或者常量表达式初始化的整型const对象。数组的维数必须要在一对[]进行指定。
- 1、显示初始化数组元素
- 在定义数组时,可为其元素提供一组逗号分隔的初值,这些初值用花括号{}扩起来,称为初始化列表
- const unsigned array_size=3
- int array[array_size]={0,1,2};
- 如果没有显示提供元素的初值,则数组会象普通变量一样初始化
- :在函数体外定义的内置数组,其元素初值为0;
- :在函数体内定义的内置数组,其元素无初始化;
- :不关数组定义在哪里,如果类型为类类型,则自动调用该类的默认构造函数进行初始化;如果没有默认构造函数,则必须为该数组的元素提供显示初始化。
- 2、特殊的字符数组
- 字符数组可以用一组花括号扩起来、逗号隔开的字符字面值进行初始化;也可以用一个字符串字面值进行初始化。但是对于后者来讲惠自动添加一个null作为结束符号,因此要对于数组大小多申请一个元素。
- 3、不允许数组直接复制和赋值
- eg:
- int ia[]={1,2,3};
- int ia2[](ia) ;/*error*/
- int main()
- {
- const usigned array_size = 3;
- int array[array_size];
- ia3=ia;/*error*/
- return 0;
- }
- 声明/定义格式: 类型 *变量名 / 类型* 变量名。 指针可能取到的值:保存一个特定对象的地址;指向某一个对象后面的另一对象;或者是0值;批注:void * 类型的指针可以保存任何类型对象的地址。
三、操作及代码
- vector :vector标准库提供了许多类似string对象的操作。
- v.empty() ;如果v为空则返回true,否则返回false
- v.size() ;返回v中元素的个数
- v.push_back(t) ;在v的末尾添加一个值为t的元素
- v[n] ;返回v中位置为n的元素
- v1=v2 ;把v1的元素替换为v2的中元素的副本
- v1==v2;如果v1与v2相等,则返回true
- !=,<,<=,>=,> 保持这些操作符惯有的含义
批注:对于C++中遍历元素的循环语句中的判断条件是:i!=v.size() 原因是对于容器而言是随时并且动态的增长的,因此不会用一个变量unsigned int n=v.size(),i!=n来取代上面的代码。对于容器而言,通过索引只能访问元素不能添加值。并且只能对于确知已存在的元素进行下标操作。对于下标的类型是vectot::size_type index
- #include<iostream>
- #include<vector>
- #include<string>
- using std::string;
- using std::cin;
- using std::cout;
- using std::endl;
- using std::vector;
- int main()
- {
- string word;
- unsigned int n=0;
- vector<string> text;
- vector<string> text1(3,"jkjk ");
- vector<string> text2(text1);
- if(text.empty())
- cout <<"empty" << endl;
- else
- cout <<"not empty "<<endl;
- if(text1==text)
- cout<<"text1 equal to text "<<endl;
- cout<<"text1 " <<<endl;
- else
- cout<<"text1 equal to text "<<endl;
- if(text1==text2)
- cout<<"text1 equal to text2 " <<endl;
- else
- cout<<"text1 not equal to text2 " <<endl;
- cout<<"the text2 : "<<endl;
- for(int i=0;i!=text2.size();i++)
- cout<<text2[i]<<" ";
- cout<<endl;
- while(n++<5)
- {
- cin>>word;
- text.push_back(word);
- }
- cout<<endl;
- for(int i=0;i!=text.size();i++)
- cout<<text[i]<<" ";
- cout<<endl;
- return 0;
- }
开始时,编程使用的是26行的加粗形式进行的编码,但是出现编译错误。----得出:对于容器是无法用cout进行输出的只能对其中某一个对象进行操作。如图: 运行结果如图: - 迭代器:用==或者!= 对两个迭代器进行比较,如果两个迭代器指向同一个元素,则相同。类型为vectot::iterator
- #include<iostream>
- #include<string>
- #include<vector>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::string;
- using std::vector;
- int main()
- {
- vector<int> num(5,3);
- cout<<"index show :"<<endl;
- for(vector<int>::size_type i=0;i<num.size();i++)
- cout<<" " << num[i];
- cout<<endl;
- int i=0;
- for(vector<int>::iterator iter=num.begin();iter!=num.end();iter++ )
- *iter=i++;
- for(vector<int>::iterator iter=num.end()-1;iter>=num.begin();iter-- )
- cout<<" "<<*iter;
- cout<<endl;
- return 0;
- }
批注:对于迭代器的类型还可以是const_iterator;类型的,则vector元素中的值将无法改变。对于const vector iterator 是不同的,对于后者定义时是需要初始化的,初始化后就无法修改。运行结果: - 对于数组的操作主要是经过下标来实现的,其类型为size_t。
- #include<iostream>
- int main()
- {
- char st[11]="fundamenal";
- char st[11]="fundamenaly";/*出现越界错误*/
- for(size_t i=0;i<11;i++)
- std::cout<<st[i] << " ";
- std::cout<<std::endl;
-
- for(size_t i=0;i<11;i++)
- std::cin>>st[i];
- std::cout<<std::endl;
- return 0;
- }
- 指针:提供了间接操作其所指对象的功能。指针是数组的迭代器。
- 1、生成左值的解引用操作
- *sp = "goodbye"
- 或
- string s1="some value"
- sp = &s1;
- 2、指针和引用的比较
- 引用总是指向某个对象,定义时未初始化的引用是错误的;赋值行为的差异,给引用赋值修改的是 该引用锁关联的对象的值,而不是使引用与另一个对象的关联。引用一经初始化就始终指向同一个特定对象。
- int val1=1024,ival=2048;
- int *p1 = &val1,*pi2=&ival;
- p1 = p2;
- p1所指的对象值不变,但是赋值操作将p1的指向修改了。
- int &r1=ival,&r2=ival2;
- r1=r2;
- 赋值语句将r1引用ival的值而不是r1的值。赋值后,这两个引用还是指向原来关联的对象,此时两个对象的值相等。
- 3、指向指针的指针:int *p=&val1;int **p1 = &p;
四、指针和const限定符
1、指向const对象的指针: 不允许用指针来修改其值;const 类型 * 变量名,const 限定的是该指针指向对象而不是指针本身,因此该指针变量不是必须初始化,如果需要的化可以修改他的值。
eg : const int * ptr ; *ptr = 54; /*error ,*ptr must be const/
const int ok=8; const int * ptr = &ok;
批注: :把一个const对象的地址赋值给一个普通的、非const对象的指针会导致编辑错误
:不能使用void *指针保存const对象的地址,而必须使用const void *指针保存。
:允许将非const对象的地址赋值给指向const对象的指针。不能使用指向const对象的指着修改基础需对象,然额如果该指针指向一个非const对象,可用其他方法修改其所指对象的值。
2、const 指针--------本身不能修改;const指针在定义时必须初始化;类型 const * 变量名。
3、指向const对象的const指针----------本身和指向的对象都无法修改。const 类型 const * 变量名
4、指针和typedef
typedef stringp *string ;
const stringp cstr;
其中stringp虽然是一个string 类型的指针,但是对于const的修饰来讲并不等价于
const string * cstr ;因为在typedf后stringp已经是一个整体,所以cstr定义为指向string类型对象的const指针,这个定义等价于string * const cstr;
阅读(6808) | 评论(0) | 转发(0) |