Error[8]: Undefined offset: 606, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 114
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

目录

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++的程序示例:

两种注释: [+++]和[+++]

预处理指令用#开头,编译时先处理预处理指令,再执行编译,比如:#include 相当于在此处插入iostream的内容,iostream被称为头文件。

通常,每个头文件支持一组工具(头文件是库的接口),iostream提供输入输出工具,比如cout输出,传统C++和C风格的头文件后缀为h(stdio.h),新C++风格的头文件不需要后缀。

命名空间:编写大型程序或将多个厂商的代码整合到一起需要的工具,不同厂商的代码中可能有同名的变量和函数,每个厂商的产品封装在自己的命名空间下([+++]和[+++])。

新C++的标准组件都在命名空间std下([+++])。

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

main函数:C++程序有很多函数组成,但main函数才是执行入口。


函数头:函数的接口,main函数是程序与 *** 作系统之间的接口,函数头由[+++]组成,比如[+++]
花括号内的是函数体,由一组语句组成,表示函数应该执行哪些计算机指令。


对于[+++],[+++]表示信息流向,hello流向cout,endl流向hello,endl代表重启一行(光标移动到下一行的第一列,也可以用字符[+++]表示)。

4.C++语句

同样看下面示例:

多了一个变量:程序运行中可以变化的值,变量必须占有存储空间。


变量定义:为变量准备存储空间,为编译器检查变量使用是否正确提供依据。

定义格式:[+++],比如[+++]。

变量必须先定义再使用。

赋值语句将某个值存放到内存单元,carrots=25,将25存放到carrots对应的内存单元,carrots=carrots-1将carrots对应的内存单元内容减1,再存放到carrots的内存单元。


赋值运算符[+++]:二元运算符(两个运算对象,左右各一个,计算右边表达式的值,存放到左边),右结合的(先执行z=0,再执行y=z,再执行x=y;先执行carrots-1,再执行carrots= carrots-1),比如:

[+++] x[+++] y[+++] x[+++]
x[+++]y[+++]z[+++][+++][+++]

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

cout可以拼接输出流:[+++];

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

cin>>变量[+++] 或者:
cin>>变量[+++]>>变量[+++][+++] 

键盘输入变量1的值,回车,再输入变量2的值,再回车,执行后面语句。

cin示例如下:

5.函数入门

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

返回值类型 函数名[+++]参数列表[+++]
{
	语句组合
[+++]

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

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

我们可以从库(我们需要include头文件)中调用函数,头文件中的内容是该库中所有函数的原型声明;因此include就是把原型声明插入源文件中。



函数定义
设计函数头:根据函数的输入输出设计参数和返回值,并给函数命名;
设计函数体:从参数到返回值的计算过程,使用return返回值并退出函数;

无返回值函数实例:

有返回值的函数示例:

6.整型

整型是高级语言处理整数的工具(子集)。



比如unsigned short,也至少占16位,但是由于视为无符号数,则数值的最大值变得更大了,因为最小值变成了0,同样的占位空间获得了更大的数值范围。


整型变量声音如:short score 或 short int score;int number1, number2;

查看整型占有空间的大小:
方法一是sizeof(一元运算符)输出字节占用数:sizeof(类型名或表达式),即sizeof(int), sizeof(score)
方法二是查看头文件climits,该头文件中定义了各种类型长度的符号常量:

变量在定义时,初始值是随机的(值是创建变量前,该内存块原有的值)。

所以为了避免出错,我们最好在变量定义时赋值:
int score=90
初值可以是常量或一个已经定义的变量:
int scoreAvg=80;
int score=scoreAvg;

整型的字面量通常为:十进制,八进制(以0开头,比如0127),十六进制(以0x开头,比如0x18FD)

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也可以执行加减和比较运算,参加运算的是内码值。



char类型常量:
常规字符:用单引号[+++]
转义字符:[+++]换行,[+++]水平制表符

char类型示例:

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可表示为[+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++]或者[+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++]

浮点数的表示,浮点数在机器内用二进制表示,我们需要存储两部分,比如[+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++][+++],我们分别保存10100和1101,即尾数和指数;

浮点常量的表示
十进制与日常表示相同,比如127.7。


科学计数法,尾数E指数 或者 尾数e指数,比如34E-8,-1.5e10,科学计数法用于表示很大或很小的实数。

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

浮点类型的精度示例:

可以看出float确保7位精度,double则确保15位精度。

10.算术表达式

算术运算符:

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

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

除法的结果取决于运算数:两个整数相除结果为整数,只要有一个运算数是浮点数,则会保留小数部分。



C++在实际执行时,并不能 *** 作不同类型的数据,前面提到的除法只是被做了类型转换才得以实现。

C++本身只能 *** 作int和int,double和double,float和float等等。

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

自动类型转换的示例:

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

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个元素

编译器不检查下标的合法性,所以要注意数组的范围,不然会无意修改了内存其他区域的值。

数组示例:

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’)

注意,字符串是一个字符数组(char型数组),但字符数组不一定是字符串,字符串必须以’\0’结束。


char cArray[]={‘s’, ‘t’, ’r’, ‘i’, ‘n’, ‘g’} 只是一个字符数组,但不是字符串,空字符串“”虽然没有内容,但是也占用一个字节,存放空字符’\0’。


字符串的输出可以使用cout,cout逐个输出字符串中的字符,直到遇到’\0’:
cout<<字符串常量
cout<<字符串变量(字符型数组,并且以’

’结束)

字符串的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); //此次输入的最开始就不再有换行符存在


字符串示例:

如果把cin.get()注释了:

我们发现不能输入address,这是因为,当我们输入year后,还有一个回车,这个回车被保留在输入队列,cin.getline(address,80)首先读入回车,误认为已经结束输入。



关于cin>>变量1>>变量2; 键盘输入变量1的值,回车(或者空格),再输入变量2的值,再回车(或者空格),才能执行后面语句;对于cin>>的方式,每一次执行>>前,都是变量值与空格放入缓冲区,变量值被赋值给变量,空格在输入队列中,下一次执行>>时,空格从队列中移除,队列中又是新的变量值+空格,然后变量值被赋值到下一个变量。



比如我们cin>>year; 我们输入1990,然后回车,1990与回车就被放到输入缓冲区中(队列),我们必须回车了机器才能将1990赋值给year,队列中剩下空格字符;


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


13.C++风格字符串
C语言没有字符串类型,所以 *** 作起来是不方便的,因此C++出现了string类型;
string类型:专门处理字符串的类型,在头文件string中,在命名空间std下

为了输入带空格的字符串,应该使用std::getline(cin, str),注意不是cin.getline


字符串示例:

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

14.结构

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

建立结构声明:描述结构的组成
 
[+++] [+++]{
	[+++] title[+++]MAXTITL[+++][+++]
	[+++] author[+++]MAXAUTL[+++][+++]
	[+++] value[+++]
[+++]


我们可以定义结构变量,也可以定义结构数组:book book1; book bookarray[10];

结构示例:

结构的成员可以只占若干位,也被称为结构的位字段,位字段的定义为:
类型 变量 : 位数(即bit)

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.指针

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

定义指针变量:[+++],比如[+++];


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

 
[+++] [+++]p[+++] a[+++]
p[+++][+++]a[+++] [+++]

间接访问运算符[+++]:一元运算符,运算对象是指针,运算结果是指针指向的变量,[+++];


指针示例:

指针的注意事项:

16.动态内存分配
程序通过声明变量通知计算机为它准备好内存空间,这些信息是编译时就能确定的。


每个变量对应一块内存空间。


变量名是这块空间的名字,程序通过变量名访问对应的空间。


有时候编程时,我们不必为所有变量进行声明。


我们可以采用动态内存分配节约空间。



动态内存分配:在程序运行时申请内存和释放内存的功能。


动态内存申请:在内存寻找一块大小合适的空间,返回起始地址。


注意,动态分配的内存没有名字,只有地址,只能间接访问。

(这也是C++需要指针的一个原因)

动态内存的申请方法:
 
类型 指针[+++][+++] 类型 [+++]
类型 指针[+++][+++] 类型 [+++]结果值为整数的表达式[+++] [+++]



对于[+++],实现了动态数组。


内存释放:通过变量声明获得的内存会在存储期结束时回收。


但通过动态申请的空间不会被系统自动回收。


释放空间的运算:
 
[+++] 指针 [+++]
[+++] [+++][+++] 指针 [+++]


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


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

动态内存示例2:

17.指针运算
指针变量保存的是整数(所指变量的地址),我们可以对指针执行加减运算:
指针加1是加上一个基类型的长度;
指针减1是减去一个基类型的长度;
也就是说,具体是加减多少取决于基类的类型:

同理,我们写pi=pi+1也是一样的,pi的值增加4;


对于++a和a++:两个表达式的副效应都是令 a 增加 1 。


区别在于表达式 a++ 的值是 a 自增前的值, ++a 的值是 a 自增后的值。


(所以最好用++a形式)



指针与数组:数组名就是指针,因此指针运算应该与数组关联才有意义,因为我们可以利用数组名去访问内存;

但是数组名与指针变量的区别在于,数组名是指针常量,也就是说数组名(指针常量)的地址是不能修改的。


但我们可以将数组名赋给同类型的指针变量:[+++],从而我们将指针变量指向了数组的第一个变量。




通过指针访问数组的示例:

sizeof不同的意义在于:注意明确数组和指针的区别,数组名虽然保存了数组首元素的地址,但数组本身是一个连续的变量组合,指针只是存放地址的变量。

18.指针与字符串

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


由于数组名是一个指针,所以C风格的字符串可以用一个指向字符的指针表示。

通常我们定义指针指向字符串(这个char型数组),并用const限定该指针变量指向的字符串只读(限制我们不能通过指针修改该字符串中的字符);


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



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


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

19.动态结构
运行时通过new申请一个动态的结构变量

注意在访问动态成员时,[+++],由于成员运算符优先级高于[+++]运算符,所以要加括号。

为了避免疏忽括号的情况,我们可以使用指针运算符->
来访问。


动态结构示例:

20.数组的替代品

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


vector是一种动态数组,可以自动调整长度。



用法:包含头文件vector,定义时,需要指出数据类型和规模,规模可以是变量,不指出规模则规模为0;

array是效率高于vector的数组,但规模固定,array是C++11新增的类型。



用法:包含头文件array,定义时需要指出类型和规模,规模是常量。




array和vector相比普通数组的区别在于:array,vector支持整个对象的整体赋值,使用示例如下:

<===>)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 29, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
C++Prime Plus_C_内存溢出

C++Prime Plus

C++Prime Plus,第1张

目录
  • 1.C++简介
  • 2.程序生成(创建源码,编译和链接)
  • 3.进入C++
  • 4.C++语句
  • 5.函数入门
  • 6.整型
  • 7.char,bool(小整数)
  • 8.const与符号常量
  • 9.浮点数
  • 10.算术表达式
  • 11.数组
  • 12.C风格字符串
  • 13.C++风格字符串
  • 14.结构
  • 15.指针
  • 16.动态内存分配
  • 17.指针运算
  • 18.指针与字符串
  • 19.动态结构
  • 20.数组的替代品

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++的程序示例:

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

预处理指令用#开头,编译时先处理预处理指令,再执行编译,比如:#include 相当于在此处插入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”<<<表示信息流向,hello流向cout,endl流向hello,endl代表重启一行(光标移动到下一行的第一列,也可以用字符’\n’表示)。

4.C++语句

同样看下面示例:

多了一个变量:程序运行中可以变化的值,变量必须占有存储空间。


变量定义:为变量准备存储空间,为编译器检查变量使用是否正确提供依据。

定义格式:”类型 变量列表”,比如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<,其实cout很复杂,它可以取出carrots的内容取出,整数25再转换成字符串”25”输出到显示器。

cout可以拼接输出流:cout<<”carrots:”<

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

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

键盘输入变量1的值,回车,再输入变量2的值,再回车,执行后面语句。

cin示例如下:

5.函数入门

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

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

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

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

我们可以从库(我们需要include头文件)中调用函数,头文件中的内容是该库中所有函数的原型声明;因此include就是把原型声明插入源文件中。



函数定义
设计函数头:根据函数的输入输出设计参数和返回值,并给函数命名;
设计函数体:从参数到返回值的计算过程,使用return返回值并退出函数;

无返回值函数实例:

有返回值的函数示例:

6.整型

整型是高级语言处理整数的工具(子集)。



比如unsigned short,也至少占16位,但是由于视为无符号数,则数值的最大值变得更大了,因为最小值变成了0,同样的占位空间获得了更大的数值范围。


整型变量声音如:short score 或 short int score;int number1, number2;

查看整型占有空间的大小:
方法一是sizeof(一元运算符)输出字节占用数:sizeof(类型名或表达式),即sizeof(int), sizeof(score)
方法二是查看头文件climits,该头文件中定义了各种类型长度的符号常量:

变量在定义时,初始值是随机的(值是创建变量前,该内存块原有的值)。

所以为了避免出错,我们最好在变量定义时赋值:
int score=90
初值可以是常量或一个已经定义的变量:
int scoreAvg=80;
int score=scoreAvg;

整型的字面量通常为:十进制,八进制(以0开头,比如0127),十六进制(以0x开头,比如0x18FD)

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也可以执行加减和比较运算,参加运算的是内码值。



char类型常量:
常规字符:用单引号’A’, ‘s’
转义字符:’\n’换行,’\t’水平制表符

char类型示例:

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.0102或者 0.314 ∗ 10 0.314*10 0.31410

浮点数的表示,浮点数在机器内用二进制表示,我们需要存储两部分,比如 10100 ∗ 2 1101 10100*2^{1101} 1010021101,我们分别保存10100和1101,即尾数和指数;

浮点常量的表示
十进制与日常表示相同,比如127.7。


科学计数法,尾数E指数 或者 尾数e指数,比如34E-8,-1.5e10,科学计数法用于表示很大或很小的实数。

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

浮点类型的精度示例:

可以看出float确保7位精度,double则确保15位精度。

10.算术表达式

算术运算符:

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

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

除法的结果取决于运算数:两个整数相除结果为整数,只要有一个运算数是浮点数,则会保留小数部分。



C++在实际执行时,并不能 *** 作不同类型的数据,前面提到的除法只是被做了类型转换才得以实现。

C++本身只能 *** 作int和int,double和double,float和float等等。

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

自动类型转换的示例:

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

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个元素

编译器不检查下标的合法性,所以要注意数组的范围,不然会无意修改了内存其他区域的值。

数组示例:

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’)

注意,字符串是一个字符数组(char型数组),但字符数组不一定是字符串,字符串必须以’\0’结束。


char cArray[]={‘s’, ‘t’, ’r’, ‘i’, ‘n’, ‘g’} 只是一个字符数组,但不是字符串,空字符串“”虽然没有内容,但是也占用一个字节,存放空字符’\0’。


字符串的输出可以使用cout,cout逐个输出字符串中的字符,直到遇到’\0’:
cout<<字符串常量
cout<<字符串变量(字符型数组,并且以’

’结束)

字符串的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); //此次输入的最开始就不再有换行符存在


字符串示例:

如果把cin.get()注释了:

我们发现不能输入address,这是因为,当我们输入year后,还有一个回车,这个回车被保留在输入队列,cin.getline(address,80)首先读入回车,误认为已经结束输入。



关于cin>>变量1>>变量2; 键盘输入变量1的值,回车(或者空格),再输入变量2的值,再回车(或者空格),才能执行后面语句;对于cin>>的方式,每一次执行>>前,都是变量值与空格放入缓冲区,变量值被赋值给变量,空格在输入队列中,下一次执行>>时,空格从队列中移除,队列中又是新的变量值+空格,然后变量值被赋值到下一个变量。



比如我们cin>>year; 我们输入1990,然后回车,1990与回车就被放到输入缓冲区中(队列),我们必须回车了机器才能将1990赋值给year,队列中剩下空格字符;


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


13.C++风格字符串
C语言没有字符串类型,所以 *** 作起来是不方便的,因此C++出现了string类型;
string类型:专门处理字符串的类型,在头文件string中,在命名空间std下

为了输入带空格的字符串,应该使用std::getline(cin, str),注意不是cin.getline


字符串示例:

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

14.结构

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

建立结构声明:描述结构的组成
 
struct book{
	char title[MAXTITL];
	char author[MAXAUTL];
	float value;
}


我们可以定义结构变量,也可以定义结构数组:book book1; book bookarray[10];

结构示例:

结构的成员可以只占若干位,也被称为结构的位字段,位字段的定义为:
类型 变量 : 位数(即bit)

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;


指针示例:

指针的注意事项:

16.动态内存分配
程序通过声明变量通知计算机为它准备好内存空间,这些信息是编译时就能确定的。


每个变量对应一块内存空间。


变量名是这块空间的名字,程序通过变量名访问对应的空间。


有时候编程时,我们不必为所有变量进行声明。


我们可以采用动态内存分配节约空间。



动态内存分配:在程序运行时申请内存和释放内存的功能。


动态内存申请:在内存寻找一块大小合适的空间,返回起始地址。


注意,动态分配的内存没有名字,只有地址,只能间接访问。

(这也是C++需要指针的一个原因)

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



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


内存释放:通过变量声明获得的内存会在存储期结束时回收。


但通过动态申请的空间不会被系统自动回收。


释放空间的运算:
 
delete 指针 //释放动态变量
delete [] 指针 //释放动态数组


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


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

动态内存示例2:

17.指针运算
指针变量保存的是整数(所指变量的地址),我们可以对指针执行加减运算:
指针加1是加上一个基类型的长度;
指针减1是减去一个基类型的长度;
也就是说,具体是加减多少取决于基类的类型:

同理,我们写pi=pi+1也是一样的,pi的值增加4;


对于++a和a++:两个表达式的副效应都是令 a 增加 1 。


区别在于表达式 a++ 的值是 a 自增前的值, ++a 的值是 a 自增后的值。


(所以最好用++a形式)



指针与数组:数组名就是指针,因此指针运算应该与数组关联才有意义,因为我们可以利用数组名去访问内存;

但是数组名与指针变量的区别在于,数组名是指针常量,也就是说数组名(指针常量)的地址是不能修改的。


但我们可以将数组名赋给同类型的指针变量:int *ap=a,从而我们将指针变量指向了数组的第一个变量。




通过指针访问数组的示例:

sizeof不同的意义在于:注意明确数组和指针的区别,数组名虽然保存了数组首元素的地址,但数组本身是一个连续的变量组合,指针只是存放地址的变量。

18.指针与字符串

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


由于数组名是一个指针,所以C风格的字符串可以用一个指向字符的指针表示。

通常我们定义指针指向字符串(这个char型数组),并用const限定该指针变量指向的字符串只读(限制我们不能通过指针修改该字符串中的字符);


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



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


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

19.动态结构
运行时通过new申请一个动态的结构变量

注意在访问动态成员时,(*指针).成员,由于成员运算符优先级高于*运算符,所以要加括号。

为了避免疏忽括号的情况,我们可以使用指针运算符->
来访问。


动态结构示例:

20.数组的替代品

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


vector是一种动态数组,可以自动调整长度。



用法:包含头文件vector,定义时,需要指出数据类型和规模,规模可以是变量,不指出规模则规模为0;

array是效率高于vector的数组,但规模固定,array是C++11新增的类型。



用法:包含头文件array,定义时需要指出类型和规模,规模是常量。




array和vector相比普通数组的区别在于:array,vector支持整个对象的整体赋值,使用示例如下:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/674874.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)