C++复习day2:复合类型与循环(依据C++premier plus)

发散复习了C++ premier plus的四、五章节部分并予以记录。

四:复合类型<因为他们是通过其他类型来派生创建的>,包括类(本章未涉及)、结构体、字符串、指针、数组

五:循环与关系表达式

 

第四章  复合类型


 一、数组

1.声明时需要指出(1)存储在每个元素中的值类型(2)数组名(3)数组中的元素数,形如typeName arrayName【arraySize】

2.数组元素通过下标(或索引)进行寻访,其下标从0开始至n-1,形如a【0】

3.sizeof将返回整个数组的字节数,对元素使用将正常返回其类型字节数

4.局部变量设置的数组未经初始化时,内部值为内存中留存的数值

5.初始化使用数组仅在定义时允许初始化typeName arrayName【arraySize】={value},同时不允许用其他数组为数组赋值,赋值数值个数短于数组声明长度时为剩余值赋0(所以需要数组赋0时,只要int a【n】={0}即可<c++11开始,这里的0也可以省略>)

注:{}初始化不可缩窄(不允许浮点数转换到整数。不允许超出类型容纳范围),arraySize只允许使用整型常量、const int或常量表达式(可通过new 绕过限制)

6.直接初始化时【arraySize】可以省略,表示交给计算机自己计算,c++11开始允许省略数组初始化中的=号,形如float balance[10]{0.25,2.71,0.35}

 

二、字符串(c-风格与基于string类)

1.c-风格字符串:通过char数组缺省空字符且cout输出char数组时采用连续输出直到空字符('\0')的特性呈现的字符串 。形如char dog[3]={'i','c','\0'}或是char dog[3]="ic"或是char dog[]="ic"<这个缺省的长度仍然会是3>(单引号引导字符,双引号引导字符串)

    (1)任何两个由空白(制表符、换行、空格)分割的字符串常量都会自动拼接。形如cout<<"welcome to" " world of c++";

    (2)可使用#include <cstring>中提供的strlen(字符串名)方法得到字符串可见区域的长度也即可见字符个数。计数直到遇到空字符

    (3)cin默认根据空白读入用户输入并分数组得将读入保存,会错误隔断连续的词组,此处对相关问题进行处理,更多cin相关问题将在第11章进行讨论

        <1>cin.getline(数组名,读入长度+1)读取整行并丢弃换行符换成空符号

        <2>cin.get(数组名,读入长度+1)读取整行并保留换行符在输入流中,cin.get()读取流中一个字符<该方法使用比起前者便于调查是否流中读取了完整行>

        <3>上述方法返回的都是流,所以可以进行连续读取的拼接,如cin.get(name1,20).get().get(name2,20);

        <4>读取空行或行长度大于数组长度时将会进行输入阻断,此时需要cin.clear();

        <5>cin的输入读取默认是留下换行符的,这导致了混合输入字符串和数字的跳过输入问题,在数字输入+字串输入中使用如(cin>>year).get()实现对换行符的丢弃

    (4)c风格采用cstring中提供的strcpy等函数实现复制等功能,不如string安全且麻烦。

2.C++ string类

    (1)该类隐藏了字符串的数组性质,使字符串可以像变量一样被处理,string str="i love c++!"即可完成初始化,且对str的cin会动态调整长度(实际上是直接新建了对象)(c++11允许使用c-字符串风格的方式初始化string对象)

    (2)string对象可进行互相赋值,使用+即可实现拼接和附加(即表现为与字符串常量的连接)

    (3)提供了str1.size()的类方法来查看字符串长度

    (4)属于string的行读取为getline(cin,str)表示去cin里找到给str的行,该方法不通过cin调用

    (5)字符串的前缀,u8表示utf8编码,r表示识别原始文字(这里可以自定义定界符),L、u、U表示wchar_t、char16_t、char32_t

    (6)其末尾不使用空字符表示

 

三、结构体  

1.定义结构描述——>按描述创建结构变量(类似没有方法类的使用方式)

2.c++11对结构体的初始化规则的添加等同于数组规则添加(见一.6)

3.同类结构可以进行赋值。可以用函数传递和返回结构。

4.结构声明后跟上结构变量名可以之间完成变量创建。

5.结构的允许声明区间等同于结构声明所在的作用域

6.允许声明结构变量后再进行其成员变量的赋值

7.允许创建结构体变量数组,其使用规则等同于对象数组、类似于一般数组

8.结构中可以声明位字段,且用无名名称的字段提供间距(用于数据结构的硬件匹配)

 

 

四、共用体

1.常用于节省内存,使一块内存可以存多种类型数据,但同一时间其内只有其中一种(如图此时就是用作int,通常会和flag判断或者switch分支判断一起用)

 

五、枚举

1.可用于替代const和将常量意义化(定义相关符号常量),但并没有为枚举常量设置的算术运算符

2.枚举量是整型可以被提升为int进行运算,但不可以用int类型自动转换到枚举量。但如果值大小合法,可以通过强转的方法将之转换。

3.强转枚举的允许范围为其值内存占用长度相关的,即便非枚举值也不一定非法。

 

 

六、指针

1.指针存储值的地址而不是值本身,获取变量的地址可以通过&变量名的形式。(提供灵活的运行阶段决策)

2.注意int* a,b;中a是指针而b是int变量,声明指针的变量都需要加上*标示。

3.通过&或数组名、对象名获得指针,通过对指针变量的*表示解除引用获取指针内部的数据。

4.在对指针进行解除引用的值操作之前一定要为其分配一个确定的存放地址,否则可能破坏程序(修改未知位置的值是危险的)<变量是在编译是分配的有名称的内存,指针是可以通过名称直接访问的内存别名>

5.指针更常通过new 类型的方式来进行赋值,实现动态的内存分配

6.使用delete释放new开辟出来的内存,作用于内存而非指针变量,注意不要对同一块内存进行两次释放(但对空指针进行释放是允许的),对非new的内存进行释放是不允许的

7.如上图可见指针并没有被删除,但内存被释放了

8.用new []为数组分配空间的情况需要用delete []进行释放

9.通过int* intarray=new int[10]创造的动态数组可以完全按照一般数组名的方式进行下标索引,也可以通过如intarray+3的方式进行指定位置的移动(*(intarray+3)效力等同intarray【3】)

 

七、指针/数组/指针算数

1.实质上c++将数组名解释为地址(第一个元素的地址)

2.使用sizeof(指向数组的指针)不会返回数组大小,只会得到指针内容地址的大小

3.指向数组的指针 int (*p)[n];<这个p就等同于数组名的效力了>和指针的数组 int *p[n];(这个则表示一组指针)

4.数组名创建数组称为静态联编,指针创建数组称为动态联编

5.变量存储于栈,而new的内存来源于自由存储区或堆

6.下图验证了动态长度数组的实现

7.类与结构都可以动态指向,使用方法如pointer->member或(*pointer).member两种方式

8.对于长数据活用new与delete能节约大量内存

9.c++的四种管理数据内存方式(线程存储为c++11新增)

    (1)自动存储:函数内部常规变量所使用的,调用时自动产生,离开函数时消亡释放,称为局部或自动变量存储在栈中

    (2)静态存储:存在于程序整个生命周期(第九章详述)

    (3)动态存储:通过new与delete由程序员来控制内存的释放与占用

    (4)光new不delete可能造成内存泄漏(占用的内存持续不被释放导致内存耗尽),最好成对使用他们

 

 

八、类型组合

1.在定义框架下复合类型可以进行组合(如指针数组、指向数组的指针等等)

2. int const* p;  const int* p; 常量指针可以指向任何地址但不能通过指针改变该地址内容(const靠近int,突出常量)

3. int* const p; 指针常量可以改变地址内容值但不能改变指向(const靠近p,突出指针)

 

九、数组的替代品vector和array(array是c++11新增模板)

1.vector(相当于自动完成new和delete实现动态的数组)<需要引入vector头文件>效率较差,可用变量构造

    使用vector<typeName> vt(n_elem)的方式创建,其长度可以在后面改动但需要使用方法

2.array实现方式类似数组,安全高效,但不能动态长度

    使用array<typeName,n_elem> arr;的方式创建

3.vector与array对象具备方法.at(索引)可对问题索引进行捕获。

 


第五章 循环和关系表达式


一、循环

1.for循环:初始化部分声明的新变量作用于仅限在循环中。for(初始化;判断条件;标识变化)其中判断条件会在初次循环前进行判断

主要会用于计数循环

2.while循环:while(判断条件)在循环体中进行条件的修改,其中判断条件会在初次循环前进行判断

可用于不知道次数的条件循环

3.do while循环:出口条件循环,第一次执行前无判断

4.c++11基于范围的for循环,遍历循环

 

 

二、循环和文本输入

1.原始cin输入(哨兵字符方法)<其中第八行可以改为cin.get(name)由于name是数组名是引用,所以保留方法的作用>

2.基于模仿文件尾判断方式的EOF方法

用cin.fail()或cin.eof()作为判别条件。文件读入中可以直接用,键盘录入中将ctrl+z作为判断结束的依据

此外,(ch=cin.get())!=EOF也是一种借用文件尾的判断方法

 

 

三、概念补充(关系表达式等)

1.每个c+表达式都有它的表达式值

2.cout.setf()方法可对输出的格式进行控制

3.自增、自减前缀即处理后使用(先付钱再使用),反之就是使用后处理(在同一条语句对同一变量自增自减多次会导致不确定结果<顺序点问题>)

4.用户自定义类的自增自减中前缀的效率可能会更高(内置类别没差别)<后缀的算术优先级更高>

5.循环体也是一种语句块(复合语句)其中的新定义变量,作用域仅限该语句块

6.当语句块新建与外界同名变量,将出现新变量隐藏旧变量的屏蔽现象

7.','逗号运算符常用于将两个或更多表达式融合成一条表达式,还具备从左往右依次运算并以最末结果为整条表达式值的特性

8.算术运算符优先于关系运算符

9.c-风格字符串(即字符数组)使用==只能比较地址,其内容的比较要通过<cstring>的strcmp实现(相等反0,否则反±1<符号由差异位字典顺序差决定>)

10.string字符串和string字符串或c-风格字符串的比较直接用运算符就行(因为实现了运算符的重载)

11.typedef typeName aliasName用于为类型创建别名,#define预处理也可以但有时不适用。(#define aliasName typeName)主要用在移植当中

12.二维数组与指向数组指针的指针见练习2.

 


简单练习:

1.<ctime>库配合循环创建延迟循环(延迟0.01秒)

 

2.二维数组

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值