3.1命名空间的using声明
在c++语言中,需要使用“::”作用域操作符,以在命名空间(namespace)中寻找所需要的名字,例如std::cin就是在std命名空间中寻找cin,为了简化操作,就出现了using操作,using声明格式如下:
#include<iostream"
using std::cin;
int main()
{int i;
cin>>i;//正确
cout<<i;//错误,没有定义cout
std::cout<<i;//正确。**因为每个名字都需要独立的声明
return 0;}
3.2标准类型库string
#include
using std::string;
3.2.1定义和初始化string对象
string s1//s1是一个空字符串
string s2(s1)//s2是s1的副本;直接初始化;
string s2=s1//等价于上一条;拷贝初始化;
string s3(“vallue”)//把vallue赋予s3;
string s3=“vallue”//同;
string s4=(10,‘c’)//s4=“cccccccccc”;
这里注意区分拷贝初始化和直接初始化,初始化时带"="时是拷贝初始化,而使用其他方法是直接初始化,我并不认为这有多么重要,但需要了解。
3.2.2string对象上的操作(**对比c语言,简化不少)
os<<s and is>>s;//最为简单的输入和输出,不做他述。
getline(is,s);//将输入字符赋予s,直到换行符的出现(换行符丢弃),弥补inc不能出现空格;
s.empty();//判断s是否为空,为空则返回ture;
s.size();//判断s的大小;
s[n];//返回s字符串中第n个字符,n从0开始计;
s1+s2;//将s2中内容复制粘贴在s1末尾;
s1=s2;//将s2中的字符赋予s1;
s1==s2;//判断s1是否和s2相等,区分大小写
s1!=s2;
<,>,<=,>=;//判断 大小,对大小写敏感 依据是ASCII码号数大小,
//相同时比较字符长短,不同时比较第一个不同处
字面值与string对象相加 s1+”,”+”world”; 这个表达式满足左结合律,字面值之间是不能相加的。
string::size_type 类型 它是无符号类型的值,可以存放任何string 的大小
3.2.3处理string对象中的字符(cctype库函数)
isalnum©//判断c是否是数字或者字母
isalpha©//判断c是否是字母
iscntrl©//判断c是否是控制字符
isdigit©//判断c是否是数字
isgraph©//c不是空格且c可打印时为真
islower©//c不是小写字母时为真
isprint©//c时可打印字符时为真
ispunct©//c是标点符号时为真
isspace©//c时空白时为真(即c是空格,制表符,回车,换行符的一种)
isupper©//c是大写字母时为真
isxdigigit©//c是16进制时为真
tolower©//将字母全部变为小写字母
toupper©//将字母全部变为大写字母
使用范围for 语句改变字符串中的字符时,要注意变量实际上是被依次绑定在序列的每个元素上,所以要使用引用,才能进行修改。
eg.使用下标来处理部分字符
string 对象的下标从0计算,s[0]是第一个字符
for(decltype(s.size()) index=0;index!=s.size()&&!isspace(s[index]);++index)
s.[index]=toupper(s.[index]);//这个程序使句子的开头的一个单词完全大写。
3.3标准库类型vector
标准库vector是对象的集合,其中所有的对象类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。因为“vector”用于存放对象(引用不是对象,所以vector不包含引用),所以又称为容器。
vector包含以下类型
vector,vector,vector<sales_item>
定义和初始化vector对象
vector v1//v1一个空vector
vector v2(v1)//v2是v1的副本
vector v3(n,va1)//v3包含了n个va1
vector v4(n)//v4包含n个初始化对象
vector v5{a,b,c…}//v5包含括号里的元素
vectorv6{10,”hi”} // v6有10个为“hi”的元素
vectorv7{10,1} // v7有2个元素,分别是10和1
vectorv8{10} //v8有1个元素,这个元素的值时10
***vector是一个类模板,以后会学习自己定义类模板。
***圆括号可以理解为创建对象,花括号可以理解为列表初始化
vector中的其他操作
v.empty()//v如果为空,返回ture
v.size()//返回v的元素个数
v[n]//返回v中第n个元素,n从0开始计数
v1=v2//将v2赋予v1
v1={a,b,c…}//用列表中的元素拷贝替换v1中的元素
v1==v2//判断v1与v2是否相等
v1!=v2
<,<=,>,>=
***向vector中添加元素
这里需要利用push_back()函数。***注意,绝对不能使用下标来进行赋值或者进行添加元素!
eg
vector<int> v2;
for(int i=0;i<100;i++)
v2.push_back(i);//将.0到100依此赋予v2;
也可以这样
vector<string> text;
while(cin>>word){
text.push_back(word);}//将输入的单词插入,比c语言结构体简便了不少。
3.4迭代器介绍
3.4.1使用迭代器
和指针不一样的是,迭代器并不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。
比如,这些类型都有名为begin和end的成员,其中,begin指向第一个元素,end则指向最后
一个元素的后面,尾后(off the end)元素.
auto b=v.begin(),e=v.end();//其中e指向尾后元素,并无实际意义,仅仅是一个标记而已,又称
尾后迭代器。
迭代器类型
iterator 和 const_iterator
iterator :可读可写,如果vector 或string对象是一个常量,只能使用const_iterator 反之都行
const_iterator : 和常量指针差不多,能够读取但不能修改它所指的元素
vector<int>::iterator it;//It能读写vector<int>的元素
string::iterator it2;//it2 能读写string对象的字符
vector<int>::const_iterator it3;//it3只能读元素,不能写元素
string::const_iterator it4;//it4只能读字符,不能写字符
***迭代器运算符
*iter//返回迭代器iter所指元素的引用
iter->mem//解引用iter并获取该元素名为mem的成员 等价(*iter).men
++iter//指向下一个
--iter//指向上一个
iter1==iter2//判断是否相等
iter1 !=iter2//判断是否相等 指示的是同一个元素或者它们是同一个容器的尾后迭代器,则相等
eg string s("some string")
if(s.begin()!=s.end()){
auto it=s.begin();
*it=toupper(*it);}//将字符改为大写形式。
迭代器运算
iter+n//迭代器加上一个整数仍是一个迭代器,移动若干元素(向前移动)
iter-n
iter+=n//将iter加n的结果赋给iter
iter-=n
iter1-iter2//得出俩个元素的距离,将运算符右侧的迭代器向前移动差值个元素后
将得到左侧的迭代器。
,>=,<,<=;//比较俩个元素位置
eg使用迭代器的一个经典算法是二分搜索。
//text必须有序
//beg和end是搜索范围
auto beg=text.begin(),end=text.end(),mid=beg+(beg-end)/2;//创建三个迭代器
while(mid!=end&&*mid!=sought){//检查是否为空或者是否找到
if(sought<*mid)
end=mid;
else
beg=mid+1;
mid=beg+(end-beg)/2;}
***注意二分法的前提条件,text必须有序排列。
***3.5数组
3.5.1定义和初始化内置数组
数组的大小确定不变,不能随意向数组中添加元素,数组的维度必须是一个常量表达式
int arr[10]//含有10个整数的数组
int *arr[10]//含有42个整形指针的数组
int (*parray)[10]=&arr; //parray指向一个含有10个整数的数组
int (&parray)[10]=arr // parray引用一个含有十个整数的数组
int *(&arry)[10]=ptrs; // arry是数组的引用,该数组含有10个指针(由内向外阅读)
*****不存在引用的数组
数组同其他内置类型一样需要初始化,否则会默认初始化为一个不确定的值。
显式初始化数组:
const unsigned sz=3;
int ial[sz]={0,1,2};
int ial[]={0,1,2};
string a4[3]={“hi”,“bye”}//维度比提供的初始值大,则剩下元素执行默认初始化
int a5[2]={0,1,2}//报错,超出范围
***字符数组的特殊性:注意数组后面一定有一个空字符,若空间不足以放置空字符会报错。
const char a4[6]=”daniel”;// 错误,没有空间可存放字符,需要的维度是7
***数组不允许拷贝和赋值
int a[]={1,2,3};
int a2[]=a;//不允许这样初始化
a2=a;//报错,不允许赋值
3.5.2访问数组元素
访问数组元素的时候我们把下标设为size_t类型,这是一个足够大的,无符
号以便表示计算机内部任意对象的大小,这个类型在头文件cstddef中定义。
***数组对于vector的缺点:
***1.数组大小固定,需要时刻提防数组越界(超级烦这个!)
2.数组不支持直接赋值
3.5.2指针和数组
通常情况下对指针初始化需要使用取地址符’&‘,但数组有一个特性:很多
情况下,数组的名字会被编译器自动的将其替换为一个指向数组首元素的指针:
string *p=nums;//等价于p2=&nums[0];
由上可知,对于数组的操作实际上是对指针的操作。(和c语言相通)
我们看完迭代器再涉及指针会发现指针也是迭代器的一种。
****begin()和end()函数
int ia[]={0,1,2,3};
int *beg=begin(ia);
int end=end(ia);//作用与之前相同,begin返回一个指向首元素的指针,end则
返回尾后指针,这俩个函数包 含在iterator头文件中。这里也可以发现指针和迭
代器的相同。我们已经得出指针是迭代器的结论,所以迭代器的运算自然指针
也可以使用,比如加减,自加,自减。但要注意一点俩个指针相减是一种ptrdiff_t
的类型,当然,我们可以使用auto类型。
int ia{}={0,2,4,6,8};
int last=(ia+4);//就是is[4]的值
last = *ia +4; // 等价于 ia[0]+4
int i=ia[2];// 等价于 (ia+2)
3.6多维数组
***严格来说c++没有多维数组,所谓的多维数组可以理解为数组的数组,或者
嵌套数组(征服c指针中也如此形容过c语言)。
多维数组的初始化:
int a[2][3][4]={0};//将所有元素初始化为0;
int a[3][4]={
{0,1,2,3},
{4,5,6,7},
{8,9,10,11}
};//其中内层嵌套的花括号并非必须,也可以转化成下列的形式
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11};
Int a[3][4]={{0},{4},{8}};//显示地初始化每行的首元素
int a[3][4]={1,2,3,4};//显示地初始化第一行,其他元素被初始化为0
数组下标的引用:
int (&row)[4]=ia[1];//把row绑定到ia的第二个4元素数组上
***指针和多维数组
int a[3][4];
int (*p)[4]=a;//p指向含有4个整数的数组(注意理解多维数组是数组的嵌套)。
p=&ia[2]//p指向ia的尾元素
for(auto p=ia;p!=ia+3;++p)
{
for (auto q=*p;q!=*p+4;++q) // *p是含有四个整数数组的首元素
cout << *q<< ‘ ’;
cout << endl;
}