C++ primer 详解(第三章)
3.1 命名空间的using声明
1.在初学C++的时候,写的第一条代码便是在控制台输出一个Hello Word,而在#include后面的第一句话便是using namespace std;,那时候只知道不写这句代码就会报错,但是不知为什么。这句话的含义是:这个文件会使用到std标准库中的名字。
2.using声明有两种方式:
using namespace std; //这种是最方便的,但是可能会包含太多
using std::cout; //这种是指定需要使用std中哪个名字
3.注意头文件中不应该包含using声明,因为头文件被包含的时候,会将里面的内容拷贝到引用它的文件里面去,如果头文件中有using声明,那么每个使用了该头文件的文件都会有这个声明,在一些程序中,可能会引起一些名字冲突。
3.2标准库类型string
3.2.1定义和初始化string对象
默认初始化:string s1; //使用string类默认初始化,s1被初始化为空
拷贝初始化:string s2=“value”;
直接初始化:string s3(“value”);
每个值都相同的直接初始化:string s4(10,’c’);
每个值都想同的拷贝初始化:string s5=string(10,’c’);
2.拷贝初始化和直接初始化的区别:在转载的一篇博客上有详解,这里大概说一下:拷贝初始化会首先生成一个临时对象,然后调用拷贝构造函数,将临时对象拷贝到需要复制的那个对象中。而直接初始化是直接调用与实参所匹配的构造函数。
3.2.2sting对象上的操作
1.可读写:string对象重载了<<操作符,可以使用cout<<在控制台打印string对象,(在这里说明一下使用cout,cin一个string对象和一个char数组的区别,string对象在创建的时候就已经保存了长度,而且在输出的时候也是根据string对象所保存的长度进行输出,这和char数组的输出不一样。)
2.string对象在使用cin>>string赋值的时候,会忽略掉开头的空格,结束于下一个空格。
3.可以使用getline获取一行string对象,直到遇到回车符(回车符最后会被去掉)
4..empty()(判断是否为空)操作和.size()(获取string字符的个数)。size返回的是string::type_size类型,只知道它是一个无符号类型,不要和int类型混用。
5.string对象可以相互比较,比较规则:首先如果长度和对应的1字母都相同,那么这两个string对象就是完全相同的,然后如果字母有不相同的那么就按字典序比较第一对不同的字母(字典排序越靠后越大),如果字母完全相同就比较长度。
6.string对象可以用“+”拼接。
7.对string对象中的元素进行处理:
1.遍历使用for(auto c :str) cout<<c<<endl;
(这里的for应该把它当成一个函数来使用,因此若想在循环里面改变c的值,则使用(for(auto &c:str)))
2.如果不想使用遍历,而是只处理一部分字符,可以使用下标运算符:[];
3.3Vector
Vector的英文翻译为向量,在这里作为容器。
Vector是应用的模版实现,因此每次在使用的时候需要具体类型实例化后使用。
3.3.1定义和初始化vector对象
默认初始化:vector<T> v1;
拷贝初始化:vector<T> v2=v1;
直接初始化:vector<T> v3(v2);
指定含有多个不相同初始值的初始化:vector <T> v4{a,b,c,d};
指定含有多个相同初始值的初始化:vector<T> v5(10,-1);
- 在vector中,圆括号只用于:
- 以一个vector对象直接初始化另外一个对象。
- 指定元素的个数
而列表初始化用于:
- 若花括号里面是该vector是被实例化的类型,则用来初始化。
- 若花括号里面不是该vector对象类型,编译器会尝试以圆括号的方式解析。
3.3.3对Vector的一些操作
1..push_back()向尾端添加一个元素
2.vector也能使用for循环遍历
3.vector的大小类型:vector<int>::size_type.
4.vector也可以比较大小,规则和string一样。
5.只能用下表操作符访问已经存在的元素,需要添加元素等则使用push_back();
3.4迭代器Iterator
迭代器性质和指针差不多,因此可以按照指针的性质来理解
3.4.1使用迭代器
1.V.begin()和V.end(),其中V.begin()返回一个指向容器第一个元素的迭代器,V.end()返回指向最后一个元素的下一个位置。
2.如果容器为空,则begin()=end().=。
3.如果不明白begin()和end()的返回值,可以用auto。
4.迭代器也可以使用*操作符解引用,也可以使用++运算符。
5.在条件运算中,对于容器来说尽量使用!=代替大于或小于,因为有些容器并没有定义大于小于,但是定义等于和不等于确很简单。
6.理解const_iterator与const iterator与typedef定义的类型一样,const iterator const修饰的时iterator这个指针,因此说明的这个指针是常量。而单独定义的const_iterator是指所指对象是const的。
7.begin()和end()若对象是普通对象返回的也是一个普通迭代器,若对象是常量,返回const_iterator。若想一直得到一个指向这个对象,但是不修改这个对象的值的指针,用cbegin();
8.使用指针访问成员函数操作符“->”的由来:使用指针,需要解引用:*it,再使用点操作符,但是由于优先级的原因,需要打上括号:(*it).begin();为了简便,把括号加*操作符符加点操作符简化为“->”;it->begin();
9.指针可以使用++运算符来移动一个类型的位子。比如一个int类型,++一次,移动4字节(在int占32位的情况下。)
10.谨记:但凡使用了迭代器的循环体,都不能改变这个容器中元素的个数。
3.4.2迭代器的运算
1.迭代器之间可以相减,得到的结果两个元素之间的距离(可以为负数)
2.迭代器也可以和指针一样,使用++操作符移动一个元素之间的距离。
3.5数组
1.数组和Vector有差不多的性质,可以使用下标随机访问,与Vector不同的是,数组的大小是确定的,也不能随意改变它的大小,性能高但是不灵活。
2.对于Vector和数组的选择,如果不清楚元素的确切个数,选择使用vector,如果能够确定元素个数的话,使用数组。
3.5.1 定义和初始化内置数组
int arr[42] //含有42个整形元素的数组;
int *arr[10] //含有10个整型指针的数组
- 数组里面的元素个数[]也可以用常量代替,但是必须是编译时常量,也就是常量表达式。
例如:const int sz=5;
int arr[sz];
是可以的。
- 数组和内置类型一样,如果在函数内部定义了一个数组,那么这个数组会被默认初始化为未定义的值。
- 显式初始化数组:可以对数组使用列表初始化{},在带有显示初始化数组定义中,可以不指定数组的大小,编译器会根据初始值的数量自己计算并推测出来。
- 字符数组也可以使用花括号初始化,但是一定注意后面需要留一个位置给‘\0’
char a1[]={‘C’,’+’,’+‘,‘\0’};
char a2[]=”C++”; //a2的维度为4;
char a3[3]=”C++”;//错误:”C++”,这个字符串是4个元素。
char a4[]={‘C’,’+’,’+’}; //这种定义是允许的,但是后面会有一系列的问题。
- 不允许将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值:
int a[]={0,1,2};
int a2[]=a; //错误,不允许将一个数组作为初始值给另外一个数组
a2=a; //错误,不能把一个数组直接赋值给另外一个数组
- 理解复杂的数组声明
int *ptrs[10]; //这个数组有10个元素,每个元素都是int指针。
int &refs[10]; //错误,数组里面应该是对象,不能是引用。(引用不占空间)
int (*Parray)[10]=&arr; //Parray指向一个含有10个int类型的元素的数组。
int (&arrRef)[10]=arr; //arrRef引用一个含有10个整型元素的数组。
int *(&arry)[10]=ptrs;//arry引用一个含有10个指向int类型的指针的数组
//在编译器上试了一下把括号去掉的效果
int *&array[10]=ptrs;编译器会报错了,报错内容是不允许定义引用的数组。
继续测试: int **array[10];这样的数组初始化必须是{ptr1,ptr2,ptr3…};
因此如果对于定义数组,不打括号的话,数组里面的元素应该是数组名字左边的所有声明符加起来。
书上说,对于数组的理解应该按照由内到外理解。但是按照之前对指针类型的分析,这里可以这样分析。首先看这个数组里面的元素类型是什么:int *ref[10];
可以这样看(int *)ref[10];也就是说这个数组里面的元素都是指针。而
int (*Parray)[10]=&arr;这种类型,首先数组里面的元素是int型的,再看parray它就是一个指针了。指向这个数组。
3.5.2访问数组元素
1.和其他数组元素一样,数组也有自己独有的下标类型:size_t类型,这是一种和机器相关的无符号类型。
2.与vector相比,数组的下标类型可以是有符号类型,也可以是无符号类型,但是vector的下标必须是无符号类型。
3.5.3指针和数组
在C++中,指针和数组有很多紧密的联系。在很多时候,使用数组的时候,编译器会将它转换为指向数组首元素的指针。
- 使用数组名初始化auto和decltype关键字的不同:
int ia[]={0,1,2,3,4,5,6,7,8,9};
auto ia2(ia); //ia是一个整型指针,指向ia的第一个元素
decltype(ia) ia3={0,1,2,3,4,5,6,7,8,9}; //ia是一个数组。
//思考为什么:因为ia2是用数组初始化的,前面提到不能用数组初始化一个数组,因此auto会将其转化为指针。
- 与其他容器一样,数组也有迭代器,数组的迭代器是指针。
- C++11标准中可以使用begin和end函数得到指向数组的头指针和尾元素的下一个指针。
- 指向数组元素的指针的运算和其他容器有一样的性质。可以加一个整数,可以想减,想减结果是一个有符号类型。
- 一个指针指向的数组类型,也可以使用下标运算符。
3.5.4C风格字符串
1.C风格字符串:以‘\0‘结尾的字符串。
2.C风格字符串的函数:strlen(p),strcmp(p1,p2);strcat(p1,p2);strcpy(p1,p2);
3.在很多编译器中,使用以上函数会出现waring或者报错,这是因为以上函数都不会去验证这个字符串是否是标准的C风格字符串。也就是如果这个字符串不是以‘\0’结尾,它会沿着这个字符串所在的内存一直向后找,直到找到‘\0’;
4.对于大多数情况,字符串使用string会更加的安全。
3.5.5与旧代码的接口
1.版本总是会兼容以前的内容,因此string可以很容易转换为C风格字符串。使用.c_str();就可以,但是这个函数只是返回一个C风格字符串,而没有改变它本身,因此想一直使用它返回的字符串,最好拷贝下来。
2.想将C风格字符串转换为string类型,可以直接用C风格字符串初始化string类型。
3.数组也可以用来初始化vector。传入头指针和尾指针即可:
int int_arr[]={0,1,2,3,4};
vector<int> ivec(begin(int_arr),end(int_arr));
3.6多位数组
对于多维数组,没什么好说的,只要记得,多位数组仅仅是数组里面的元素是数组,其他就都很好理解了。
可以使用类型别名简化多位数组的指针
using int_array=int[4];
typedef int int_attay[4];
int_array *p;//p是一个二维数组的指针。
转载于:https://www.cnblogs.com/citron/p/6145291.html
C++ primer 详解(第三章)相关推荐
- 孙鑫VC++深入详解第三章学习笔记
第三章 3.1创建MFC AppWizard 如何利用vs2019创建MFC应用见参考文献[1] 需要注意的地方有 [1] 创建MFC单文档应用程序 [2]开启类视图窗口 3.2基于MFC的程序框架剖 ...
- TCP/IP详解--第三章
第3章 IP:网际协议 3.1 引言 IP是TCP/IP协议族中最为核心的协议.所有的 TCP.UDP.ICMP及IGMP数据都以 IP数据 报格式传输(见图 1-4).许多刚开始接触 TCP/ ...
- Tensorflow 2.x(keras)源码详解之第九章:模型训练和预测的三种方法(fittf.GradientTapetrain_steptf.data)
大家好,我是爱编程的喵喵.双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中.从事机器学习以及相关的前后端开发工作.曾在阿里云.科大讯飞.CCF等比赛获得多次Top名次.现 ...
- 【java8新特性】——Optional详解(三)
一.简介 Optional类是Java8为了解决null值判断问题,借鉴google guava类库的Optional类而引入的一个同名Optional类,使用Optional类可以避免显式的null ...
- Miracast技术详解(三):RTP MPEG2-TS
Miracast音视频流概述 在上一篇文章中,我们已经成功完成RTSP能力协商与会话的建立,并准备开始音视频流的传输阶段.那么下一步,就是对音视频流进行解析,并将音视频展示给用户的过程.这样整个Mir ...
- 【FFmpeg】ffmpeg命令详解(三)高级选项
ffmpeg命令详解(三)高级选项 1.-map 2.-ignore_unknown 3.-copy_unknown 4.-map_channel 5.-map_metadata 6.-map_cha ...
- IIS负载均衡-Application Request Route详解第三篇:使用ARR进行Http请求的负载均衡(上)...
IIS负载均衡-Application Request Route详解第三篇:使用ARR进行Http请求的负载均衡(上) 在前两篇文章中,我们已经讲述如何配置与安装ARR,从本篇文章开始,我们将重点的 ...
- ViewPager 详解(三)---PagerTabStrip与PagerTitleStrip添加标题栏的异同
相关文章: 1.<ViewPager 详解(一)---基本入门> 2.<ViewPager 详解(二)---详解四大函数> 3.<ViewPager 详解(三)-- ...
- 大型企业网络配置系列课程详解(三)--OSPF高级配置与相关概念的理解
大型企业网络配置系列课程详解(三)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&qu ...
- java同步异步调用_详解java 三种调用机制(同步、回调、异步)
1:同步调用:一种阻塞式调用,调用方要等待对方执行完毕才返回,jsPwwCe它是一种单向调用 2:回调:一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口: 3:异步调用:一种类似消 ...
最新文章
- pycharm 常用代码签名
- Java集合中HashSet的实现原理
- file命令及Linux重要关键路径介绍
- AWS CEO Andy Jassy 专访:我们一直思考的是未来 2-5 年的事 | 人物志
- 多个canvas画布合并_canvas的基础入门
- ibm中文语音识别输入系统
- 基于opencv,C++实现中值滤波器
- JavaWeb 注解
- 解决uniapp分享到微信跳转两次app>打开微信>打开APP>打开微信 的问题
- qq空间显示手机型号android,手机QQ空间说说怎么显示手机型号
- 极米和当贝投影仪应该怎样抉择?一文告诉你答案
- win10如何设置pdf默认打开方式
- 【网站备案】2018年以后的阿里云备案以及公安备案流程最佳实践
- 谷歌colab运行自己的项目的一些细节
- 新西兰奥克兰发生三车追尾事故 造成一死一伤
- BW Upgrade Authorization Solution(转帖)
- 基于jQuery上传文件插件
- Fluke SimpliFiber Pro FTK1475做光纤损耗测试
- 铂链第1课 如何在WINDOWS操作系统下搭建BOTTOS开发环境
- 常用的sql知识点总结