IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++Prime Plus(1) -> 正文阅读

[C++知识库]C++Prime Plus(1)

1.C++简介

C++起源:带类的C语言,C++支持3种程序设计方式:过程化程序设计(比如C),面向对象程序设计,泛型程序设计(对变量的数据类型模糊化);

过程化程序设计,类似数学,即算法+数据,用程序语言描述处理数据的过程,为了优化程序的结构,出现了结构化程序设计(自顶向下的设计,程序结构划分为3种:顺序,分支,循环);C语言支持结构化程序设计,C语言可以操作到位,更接近硬件,过去的高级语言通常只能操作到某个变量(在内存中操作)。

面向对象:允许我们设计与问题对应的类。并且提高代码复用性。

泛型程序设计:对于C语言,我们必须规定每个数据的类型,C++可以对数据类型模糊化,统一为T类型。

2.程序生成(创建源码,编译和链接)

源码是程序员写好的程序,用后缀名区分源文件,cpp后缀表示C++源文件,c后缀表示C的源文件。创建源码的方式:在编辑器编辑源文件。现在大家都使用IDE开发,将编辑,编译,链接过程集成到一个软件中。
在VS中,一个软件被称为一个解决方案,解决方案可以包含多个项目(解决方案是项目的容器),每个源文件都是项目的组成部分。
编译:将源文件翻译成机器语言,称为目标文件,目标文件不是可运行的文件;
链接:将目标文件与库的目标文件捆绑,形成可执行文件。
编译链接的方式取决于操作系统和编译器。比如windows+gcc,在命令行输入gcc prog.cpp就能实现编译和链接。在VS中,可以直接”生成解决方案”。

3.进入C++

首先看一个C++的程序示例:
fig1

两种注释: ///*……*/

预处理指令用#开头,编译时先处理预处理指令,再执行编译,比如:#include <iostream>相当于在此处插入iostream的内容,iostream被称为头文件。通常,每个头文件支持一组工具(头文件是库的接口),iostream提供输入输出工具,比如cout输出,传统C++和C风格的头文件后缀为h(stdio.h),新C++风格的头文件不需要后缀。

命名空间:编写大型程序或将多个厂商的代码整合到一起需要的工具,不同厂商的代码中可能有同名的变量和函数,每个厂商的产品封装在自己的命名空间下(ns1::xns2::x)。新C++的标准组件都在命名空间std下(std::cout)。

using编译指令:通知编译器,程序中的标准组件都是某一个命名空间中,不在需要用”命名空间::组件名”的方式,可以直接用”组件名”调用组件。

main函数:C++程序有很多函数组成,但main函数才是执行入口。
函数头:函数的接口,main函数是程序与操作系统之间的接口,函数头由”函数名,返回值,参数”组成,比如int main()
花括号内的是函数体,由一组语句组成,表示函数应该执行哪些计算机指令。
对于cout<<”hello”<<endl<<表示信息流向,hello流向cout,endl流向hello,endl代表重启一行(光标移动到下一行的第一列,也可以用字符’\n’表示)。

4.C++语句

同样看下面示例:
fig2
多了一个变量:程序运行中可以变化的值,变量必须占有存储空间。
变量定义:为变量准备存储空间,为编译器检查变量使用是否正确提供依据。定义格式:”类型 变量列表”,比如int carrots。变量必须先定义再使用。

赋值语句将某个值存放到内存单元,carrots=25,将25存放到carrots对应的内存单元,carrots=carrots-1将carrots对应的内存单元内容减1,再存放到carrots的内存单元。
赋值运算符=:二元运算符(两个运算对象,左右各一个,计算右边表达式的值,存放到左边),右结合的(先执行z=0,再执行y=z,再执行x=y;先执行carrots-1,再执行carrots= carrots-1),比如:

int x, y, x;
x=y=z=0;

cout可以输出变量值:cout<<carrots,其实cout很复杂,它可以取出carrots的内容取出,整数25再转换成字符串”25”输出到显示器。cout可以拼接输出流:cout<<”carrots:”<<carrots<<”end”<<endl

我们可以在运行中用键盘赋值变量,使用cin:

cin>>变量; 或者:
cin>>变量1>>变量2; 

键盘输入变量1的值,回车,再输入变量2的值,再回车,执行后面语句。cin示例如下:
fig3

5.函数入门

函数是程序中的一个零件,可以完成一个功能。

返回值类型 函数名(参数列表)
{
	语句组合
}

函数可以没有参数,括号内为空或void,函数可以没有返回值,返回值类型用void表示。

函数原型声明:告诉C++编译器,函数的参数和返回值,使编译器可以检查程序对函数的用法是否正确,比如:double sqrt(double); ,函数原型声明出现在每个源文件的开头。

我们可以从库(我们需要include头文件)中调用函数,头文件中的内容是该库中所有函数的原型声明;因此include就是把原型声明插入源文件中。
fig4
函数定义
设计函数头:根据函数的输入输出设计参数和返回值,并给函数命名;
设计函数体:从参数到返回值的计算过程,使用return返回值并退出函数;

无返回值函数实例:
fig5
有返回值的函数示例:
fig6

6.整型

整型是高级语言处理整数的工具(子集)。
fig7
比如unsigned short,也至少占16位,但是由于视为无符号数,则数值的最大值变得更大了,因为最小值变成了0,同样的占位空间获得了更大的数值范围。
整型变量声音如:short score 或 short int score;int number1, number2;

查看整型占有空间的大小:
方法一是sizeof(一元运算符)输出字节占用数:sizeof(类型名或表达式),即sizeof(int), sizeof(score)
方法二是查看头文件climits,该头文件中定义了各种类型长度的符号常量:
fig8
变量在定义时,初始值是随机的(值是创建变量前,该内存块原有的值)。所以为了避免出错,我们最好在变量定义时赋值:
int score=90
初值可以是常量或一个已经定义的变量:
int scoreAvg=80;
int score=scoreAvg;

整型的字面量通常为:十进制,八进制(以0开头,比如0127),十六进制(以0x开头,比如0x18FD)
fig9
C++在处理数值时,统一转换为二进制处理,输出时统一转换为十进制。

对于整型常量,默认为int,超出范围则视为long,超出long则视为long long。我们也可以用后缀明确指出常量类型,比如100L(长整型);其实,对于int scoreAvg=80; 80就是一个整型常量。

7.char,bool(小整数)

char是用于处理字符的类型:字符在机器内用8位整数编码(编码规则:ASCII,ASCII编码的特点是大写字母编码连续,小写字母编码连续,数字字符编码连续)
编程时,不需要关心字符的编码:字符输入(cin>>字符型变量),字符输出(cout<<字符类型变量或字符常量)

字符类型(char类型)的运算:在早期内存昂贵时候,由于char只占一个字节,程序员常将char作为比short小的整型使用,char也可以执行加减和比较运算,参加运算的是内码值。
fig10
char类型常量:
常规字符:用单引号’A’, ‘s’
转义字符:’\n’换行,’\t’水平制表符

char类型示例:
fig11
bool类型:表示逻辑”真”和”假”,bool类型的值(true和false)
bool类型的机器内表示为一个字节,true是1,false是0,bool可以作为算术运算的运算数。
bool不能直接输入输出,直接输出bool类型的值得到的不是true或flase,而是1或0。

8.const与符号常量

符号常量:为程序中的常量取一个名字,称为符号常量;使用符号常量提高了程序的可读性,并且便于管理常量值。

符号常量的定义
用#define定义:#define 符号常量名 字符串(不建议使用这种C的定义方式);
const限定符:限定一个变量是只读的,(const 类型名 符号常量名 = 初值; ),必须有初值,比如:
const double PI=3.14;
符号常量的命名与变量命名相同,为方便区分,符号常量名采用大写。

9.浮点数

浮点数即实数R,浮点数名称的来源:小数点可以移动,比如3.14可表示为 314.0 ? 1 0 ? 2 314.0*10^{-2} 314.0?10?2或者 0.314 ? 10 0.314*10 0.314?10

浮点数的表示,浮点数在机器内用二进制表示,我们需要存储两部分,比如 10100 ? 2 1101 10100*2^{1101} 10100?21101,我们分别保存10100和1101,即尾数和指数;
fig12
浮点常量的表示
十进制与日常表示相同,比如127.7。
科学计数法,尾数E指数 或者 尾数e指数,比如34E-8,-1.5e10,科学计数法用于表示很大或很小的实数。

浮点常量默认是double,我们也可以明确指定浮点常量的类型,比如1.5F(float)与 2.3E10L(long double)

浮点类型的精度示例:
fig13
可以看出float确保7位精度,double则确保15位精度。

10.算术表达式

算术运算符:
fig14
优先级
高:乘,除,取模
低:加,减
我们可以用括号自己选择优先级

同一优先级,算术表达式满足左结合性,先计算左边的运算,再计算右边。

除法的结果取决于运算数:两个整数相除结果为整数,只要有一个运算数是浮点数,则会保留小数部分。
fig15
C++在实际执行时,并不能操作不同类型的数据,前面提到的除法只是被做了类型转换才得以实现。C++本身只能操作int和int,double和double,float和float等等。

自动类型转换出现的场合
1.赋值或初始化时,如果右边的表达式计算结果类型与左边的变量类型不同:右边值被转换成左边变量类型;
2.函数参数传递时,实际参数被转换成形式参数的类型;
3.表达式中的运算数类型不一致,需要遵循转换规则:把精度小的运算数向精度大的运算数转换;

自动类型转换的示例:
fig16
我们也可以进行强制类型转换:
C++的风格为:类型 (表达式)
C的风格为:(类型) 表达式
fig17

11.数组

数组用于存储多个同类型的值;
定义格式为:类型 数组名[元素个数] 或者 类型 数组名[元素个数]={初始值表}
比如:
int array[10]; 数组的元素初值为随机值
double darray[3]={1.1,2.1,3.4}
int iarray[]={1,2,3}; []为不指出元素个数情况,该数组有三个元素
short sarray[10]={0,1,1}; 三个初值给了数组的前三个元素,后面的元素初值统一为0

数组元素的索引:数组名[下标],比如array[5]可以访问第6个元素
fig18
编译器不检查下标的合法性,所以要注意数组的范围,不然会无意修改了内存其他区域的值。

数组示例:
fig19

12.C风格字符串

“programming”就是一个字符串常量,看起来是11个字符,但其实是12个字符,因为C语言中规定字符串以’\0’(空字符)结束。
C用char型数组保存字符串,“programming”由12个元素的数组存储。
如:
char str[]={‘s’, ‘t’, ’r’, ‘i’, ‘n’, ‘g’, ‘\0’}
为了使用简单,C也支持char型数组的简便形式赋值:
char str[]=”string” 或 char str[10]=”string”(剩余元素值为0,即在char型下是空字符’\0’)
fig20
注意,字符串是一个字符数组(char型数组),但字符数组不一定是字符串,字符串必须以’\0’结束。
char cArray[]={‘s’, ‘t’, ’r’, ‘i’, ‘n’, ‘g’} 只是一个字符数组,但不是字符串,空字符串“”虽然没有内容,但是也占用一个字节,存放空字符’\0’。
字符串的输出可以使用cout,cout逐个输出字符串中的字符,直到遇到’\0’:
cout<<字符串常量
cout<<字符串变量(字符型数组,并且以’\0’结束)

字符串的cin输入

对于输入一个单词:
cin>>字符数组名,比如cin>>str,cin以回车字符或者空格字符作为输入结束的标记

对于输入一行:
cin.getline(字符数组名,数组规模)
cin.get(字符数组名,数组规模)
以回车字符或达到数组规模结束输入,区别:getline将回车的换行符丢弃,get会将换行符留在缓冲区放在下一次输入的最开始位置。

在早期C语言没有getline时候,只能使用get,但是get对于读入回车的处理会让人们对字符文本的逻辑容易出错,为了让get每次都只输入一行,并让回车不放在下一次输入的行中,我们使用无参数的cin.get(),cin.get()读入任意一个字符,包含回车。于是常见的输入格式为:
cin.get(str1,80);
cin.get(); //读入cin.get(str1,80);中的回车换行符
cin.get(str2,80); //此次输入的最开始就不再有换行符存在

字符串示例:
fig21
如果把cin.get()注释了:
fig22
我们发现不能输入address,这是因为,当我们输入year后,还有一个回车,这个回车被保留在输入队列,cin.getline(address,80)首先读入回车,误认为已经结束输入。


关于cin>>变量1>>变量2; 键盘输入变量1的值,回车(或者空格),再输入变量2的值,再回车(或者空格),才能执行后面语句;对于cin>>的方式,每一次执行>>前,都是变量值与空格放入缓冲区,变量值被赋值给变量,空格在输入队列中,下一次执行>>时,空格从队列中移除,队列中又是新的变量值+空格,然后变量值被赋值到下一个变量。
fig23
比如我们cin>>year; 我们输入1990,然后回车,1990与回车就被放到输入缓冲区中(队列),我们必须回车了机器才能将1990赋值给year,队列中剩下空格字符;

cin.get和cin.getline都是从缓冲区(输入队列)中读入,键盘的输入也是先进入队列,才被get和getline读到。


13.C++风格字符串

C语言没有字符串类型,所以操作起来是不方便的,因此C++出现了string类型;
string类型:专门处理字符串的类型,在头文件string中,在命名空间std下
fig24
为了输入带空格的字符串,应该使用std::getline(cin, str),注意不是cin.getline

字符串示例:
fig25
可以看到,std::getline(cin, str)也是从缓冲区读,也是先读入了cin>>处引入的空格字符,如果我们在cin>>s1时,最后采用换行,那么getline将读到换行,误认为结束。

14.结构

结构类型:将描述一个复杂对象的多个部分组成一个整体

建立结构声明:描述结构的组成

struct book{
	char title[MAXTITL];
	char author[MAXAUTL];
	float value;
}

我们可以定义结构变量,也可以定义结构数组:book book1; book bookarray[10];
fig26
结构示例:
fig27
结构的成员可以只占若干位,也被称为结构的位字段,位字段的定义为:
类型 变量 : 位数(即bit)
fig28
z指定的位数决定了结构体变量d的大小,当z:29时,占用4个字节,共32位;此时,x,y,z相当于共用一个int变量(1个int刚好32位);
当z:32时,需要使用8个字节,因为结构此时占用35位,需要根据成员类型自动补齐,35位超出1个int的空间,所以要两个int,一个用于存储z,另一个用于x,y的共享;
从int的视角看,成员存在共享,但从bit角度看,每个成员占用的位是不同的。

15.指针

指针:值为内存地址的变量,指针提供了间接访问的方式;

定义指针变量:类型名 *指针变量名,比如int *p;

运算符&:一元运算符,运算对象是变量,运算结果是变量的地址。

int *p, a;
p=&a; //将a的地址赋值给指针变量p

间接访问运算符*:一元运算符,运算对象是指针,运算结果是指针指向的变量,*p=*p * 2;

指针示例:
fig29
指针的注意事项:
fig30

16.动态内存分配

程序通过声明变量通知计算机为它准备好内存空间,这些信息是编译时就能确定的。每个变量对应一块内存空间。变量名是这块空间的名字,程序通过变量名访问对应的空间。

有时候编程时,我们不必为所有变量进行声明。我们可以采用动态内存分配节约空间。
动态内存分配:在程序运行时申请内存和释放内存的功能。

动态内存申请:在内存寻找一块大小合适的空间,返回起始地址。注意,动态分配的内存没有名字,只有地址,只能间接访问。(这也是C++需要指针的一个原因)

动态内存的申请方法:

类型 指针=new 类型 //申请一块保存某种类型数据的内存空间,返回申请到的内存地址
类型 指针=new 类型 [结果值为整数的表达式] //申请一块保存某种类型数组的内存空间,返回申请到的内存地址

fig31
对于int *array = new int [n],实现了动态数组。

内存释放:通过变量声明获得的内存会在存储期结束时回收。但通过动态申请的空间不会被系统自动回收。
释放空间的运算:

delete 指针 //释放动态变量
delete [] 指针 //释放动态数组

delete的重要性:没有delete的动态内存一直被程序占用,特别是,当程序执行结束,这块空间依然被标识为被使用,这被称为内存泄漏。

动态内存示例1,可以看出,指针只是一个用于保存地址的变量,不管指向什么类型的变量,该指针都占用8字节(与操作系统64位有关),由于指针是变量,我们也能够对指针变量取其地址:
fig32
动态内存示例2:
fig33

17.指针运算

指针变量保存的是整数(所指变量的地址),我们可以对指针执行加减运算:
指针加1是加上一个基类型的长度;
指针减1是减去一个基类型的长度;
也就是说,具体是加减多少取决于基类的类型:
fig34
同理,我们写pi=pi+1也是一样的,pi的值增加4;


对于++a和a++:两个表达式的副效应都是令 a 增加 1 。区别在于表达式 a++ 的值是 a 自增前的值, ++a 的值是 a 自增后的值。(所以最好用++a形式)
fig35


指针与数组:数组名就是指针,因此指针运算应该与数组关联才有意义,因为我们可以利用数组名去访问内存;
fig36
但是数组名与指针变量的区别在于,数组名是指针常量,也就是说数组名(指针常量)的地址是不能修改的。

但我们可以将数组名赋给同类型的指针变量:int *ap=a,从而我们将指针变量指向了数组的第一个变量。
fig37
通过指针访问数组的示例:
fig38
sizeof不同的意义在于:注意明确数组和指针的区别,数组名虽然保存了数组首元素的地址,但数组本身是一个连续的变量组合,指针只是存放地址的变量。

18.指针与字符串

C风格的字符串使用一个char型数组存储,并以’\0’作为结束符;

由于数组名是一个指针,所以C风格的字符串可以用一个指向字符的指针表示。通常我们定义指针指向字符串(这个char型数组),并用const限定该指针变量指向的字符串只读(限制我们不能通过指针修改该字符串中的字符);


const 与指针,分为三类:pointer to const,const pointer与const pointer to const
fig39
fig40
fig41


cstring库中的函数以及用cout输出时,都是从数组名对应的地址或从指针指向的地址开始处理到’\0’结束。

字符串示例如下,注意当指针指向char时,与指向其他类型不同,所以我们需要额外留意指针与字符串的读写问题:
fig42
fig43

19.动态结构

运行时通过new申请一个动态的结构变量
fig44
注意在访问动态成员时,(*指针).成员,由于成员运算符优先级高于*运算符,所以要加括号。为了避免疏忽括号的情况,我们可以使用指针运算符->来访问。

动态结构示例:
fig45

20.数组的替代品

C++中有两种数组的替代:vector和array

vector是一种动态数组,可以自动调整长度。
用法:包含头文件vector,定义时,需要指出数据类型和规模,规模可以是变量,不指出规模则规模为0;
fig46
array是效率高于vector的数组,但规模固定,array是C++11新增的类型。
用法:包含头文件array,定义时需要指出类型和规模,规模是常量。
fig47
array和vector相比普通数组的区别在于:array,vector支持整个对象的整体赋值,使用示例如下:
fig48

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:22:53  更:2022-04-18 17:23:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:21:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码