变量就是给一段指定的内存空间起名,方便操作这段内存。
语法:数据类型 变量名 = 初始值;//C++在创建变量时必须给变量一个初始值,否则会报错
//变量的定义
//语法:数据类型 变量名 = 初始值
int a = 0;
常量是用于记录程序中不可更改的数据。
C++定义常量两种方式
#define 宏常量: #define 常量名 常量值
const修饰的变量 const 数据类型 常量名 = 常量值
关键字是C++中预先保留的单词(标识符)。
在定义变量或者常量时候,不要用关键字,否则会产生歧义。
C++关键字:
asm | do | if | return | typedef |
---|---|---|---|---|
auto | double | inline | short | typeid |
bool | dynamic_cast | int | signed | typename |
break | else | long | sizeof | union |
case | enum | mutable | static | unsigned |
catch | explicit | namespace | static_cast | using |
char | export | new | struct | virtual |
class | extern | operator | switch | void |
const | false | private | template | volatile |
const_cast | float | protected | this | wchar_t |
continue | for | public | throw | while |
default | friend | register | true | |
delete | goto | reinterpret_cast | try |
C++规定给标识符(变量、常量)命名时,有一套自己的规则,要见名知意。
C++规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存。
整型变量表示的是整数类型的数据
C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同:
数据类型 | 占用空间 | 取值范围 |
---|---|---|
short(短整型) | 2字节 | (-2^15 ~ 2^15-1) |
int(整型) | 4字节 | (-2^31 ~ 2^31-1) |
long(长整形) | Windows为4字节,Linux为4字节(32位),8字节(64位) | (-2^31 ~ 2^31-1) |
long long(长长整形) | 8字节 | (-2^63 ~ 2^63-1) |
浮点型用于表示小数
浮点型变量分为单精度float 和 双精度double。
两者的区别在于表示的有效数字范围不同。
数据类型 | 占用空间 | 有效数字范围 |
---|---|---|
float | 4字节 | 7位有效数字 |
double | 8字节 | 15~16位有效数字 |
字符型变量用于显示单个字符。
语法:char ch = 'a';
用于表示一些不能显示出来的ASCII字符。
转义字符 | 含义 | ASCII码值(十进制) |
---|---|---|
\a | 警报 | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) (跳到下一个TAB位置) | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表一个反斜线字符"" | 092 |
’ | 代表一个单引号(撇号)字符 | 039 |
" | 代表一个双引号字符 | 034 |
? | 代表一个问号 | 063 |
\0 | 数字0 | 000 |
\ddd | 8进制转义字符,d范围0~7 | 3位8进制 |
\xhh | 16进制转义字符,h范围09,af,A~F | 3位16进制 |
char 变量名[] = "字符串值"
string 变量名 = "字符串值"
布尔数据类型代表真或假的值 。bool类型占1个字节大小。
利用sizeof关键字可以统计数据类型所占内存大小
语法: sizeof( 数据类型 / 变量)
cout << "short 类型所占内存空间为: " << sizeof(short) << endl;
cout << "int 类型所占内存空间为: " << sizeof(int) << endl;
用于从键盘获取数据
语法: cin >> 变量
用于执行代码的运算
运算符类型 | 作用 |
---|---|
算术运算符 | 用于处理四则运算 |
赋值运算符 | 用于将表达式的值赋给变量 |
比较运算符 | 用于表达式的比较,并返回一个真值或假值 |
逻辑运算符 | 用于根据表达式的值返回真值或假值 |
用于处理四则运算
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | a=2; b=++a; | a=3; b=3; |
++ | 后置递增 | a=2; b=a++; | a=3; b=2; |
– | 前置递减 | a=2; b=–a; | a=1; b=1; |
– | 后置递减 | a=2; b=a–; | a=1; b=2; |
将表达式的值赋给变量
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; | a=2; |
-= | 减等于 | a=5; a-=3; | a=2; |
*= | 乘等于 | a=2; a*=2; | a=4; |
/= | 除等于 | a=4; a/=2; | a=2; |
%= | 模等于 | a=3; a%2; | a=1; |
用于表达式的比较,并返回一个真值或假值
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
用于根据表达式的值返回真值或假值
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 |
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。 |
|| | 或 | a || b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
程序按顺序执行,不发生跳转
依据条件是否满足,有选择的执行相应功能
if语句有三种形式
if(条件){ 条件满足执行的语句 }
if(条件){ 条件满足执行的语句 }else{ 条件不满足执行的语句 }
if(条件1){ 条件1满足执行的语句 }else if(条件2){条件2满足执行的语句}... else{ 都不满足执行的语句}
执行多条件分支语句
switch(表达式)
{ case 结果1:执行语句;break;
case 结果2:执行语句;break;
…
default:执行语句;break;
}
通过三目运算符实现简单的判断
语法:表达式1 ? 表达式2 :表达式3
如果表达式1的值为真,执行表达式2,并返回表达式2的结果;
如果表达式1的值为假,执行表达式3,并返回表达式3的结果。
满足循环条件,执行循环语句
语法:for(起始表达式;条件表达式;末尾循环体) { 循环语句; }
满足循环条件,执行循环语句
语法:while(循环条件){ 循环语句 }
只要循环条件的结果为真,就执行循环语句
满足循环条件,执行循环语句
语法: do{ 循环语句 } while(循环条件);
用于跳出选择结构或者循环结构
break使用的时机:
在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
可以无条件跳转语句
语法: goto 标记;
所谓数组,就是一个集合,里面存放了相同类型的数据元素
一维数组定义的三种方式:
数据类型 数组名[ 数组长度 ];
数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
数据类型 数组名[ ] = { 值1,值2 ...};
一维数组名称的用途:
直接打印数组名,可以查看数组所占内存的首地址
对数组名进行sizeof,可以获取整个数组占内存空间的大小
冒泡排序:
作用: 最常用的排序算法,对数组内元素进行排序
二维数组就是在一维数组上,多加一个维度
二维数组定义的四种方式:
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
作用:将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能。
语法 :
返回值类型 函数名 (参数列表)
{
函数体语句
return表达式
}
功能:使用定义好的函数
语法:函数名(参数)
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
**作用:**让代码结构更加清晰
步骤:
可以通过指针间接访问内存
语法: 数据类型 * 变量名;
指针变量和普通变量的区别:
1.可以使用&符号获取变量的地址
2.利用指针可以记录地址
3.对指针变量解引用可以操作指针指向得内存
所有指针类型在32位操作系统下是4个字节
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
int main() {
//指针变量p指向内存地址编号为0的空间
int * p = NULL;
//访问空指针报错
//内存编号0 ~255为系统占用内存,不允许用户访问
cout << *p << endl;
system("pause");
return 0;
}
野指针:指针变量指向非法的内存空间
注:空指针和野指针都不是我们申请的空间,因此不要访问。
const关键字
利用指针访问数组中元素
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int * p = arr; //指向数组的指针
cout << "第一个元素: " << arr[0] << endl;
cout << "指针访问第一个元素: " << *p << endl;
for (int i = 0; i < 10; i++)
{
//利用指针遍历数组
cout << *p << endl;
p++;
}
system("pause");
return 0;
}
利用指针作函数参数,可以修改实参的值
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
语法:struct 结构体名 { 结构体成员列表 };
通过结构体创建变量的方式有三种:
总结1:定义结构体时的关键字是struct,不可省略
总结2:创建结构体变量时,关键字struct可以省略
总结3:结构体变量利用操作符 ‘’.’’ 访问成员
作用: 将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数] = { {} , {} , ... {} }
**作用:**通过指针访问结构体中的成员
->
可以通过结构体指针访问结构体属性作用: 结构体中的成员可以是另一个结构体
作用: 将结构体作为参数向函数中传递
传递方式有两种:
C++内存4区模型
**作用: **给变量起别名
语法: 数据类型 &别名 = 原名
注意:
作用: 函数传参时,可以利用引用的技术让形参修饰实参
优点: 可以简化指针修改实参
作用:引用是可以作为函数的返回值存在的
注意:不要返回局部变量引用
用法:函数调用作为左值
作用: 常量引用主要用来修饰形参,防止误操作
在函数形参列表中,可以加const修饰形参,防止形参改变实参
语法:返回值类型 函数名 (参数= 默认值){}
语法: 返回值类型 函数名 (数据类型){}
//函数占位参数 ,占位参数也可以有默认参数
void func(int a, int) {
//代码
}
int main() {
//填补占位参数
system("pause");
return 0;
}
作用: 函数名可以相同,提高复用性
函数重载满足条件:
注意: 函数的返回值不可以作为函数重载的条件
C++面向对象的三大特性为:封装、继承、多态
封装的意义:
封装意义1:
在设计类的时候,属性和行为写在一起,表现事物
语法: class 类名{ 访问权限: 属性 / 行为 };
封装意义2:
类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有三种:
继承的好处:可以减少重复的代码
class A : public B;
A 类称为子类 或 派生类
B 类称为父类 或 基类
一类是从基类继承过来的,一类是自己增加的成员。
从基类继承过过来的表现其共性,而新增的成员体现了其个性。
继承的语法:class 子类 : 继承方式 父类
继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
- 子类对象可以直接访问到子类中同名成员
- 子类对象加作用域可以访问到父类同名成员
- 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数
语法:class 子类 :继承方式 父类1 , 继承方式 父类2...
多继承可能会引发父类中有同名成员出现,需要加作用域区分
概念:
两个派生类继承同一个基类
又有某个类同时继承者两个派生类
这种继承被称为菱形继承,或者钻石继承
多态分为两类
静态多态和动态多态区别:
总结:
多态满足条件
多态使用条件
重写:函数返回值类型 函数名 参数列表 完全一致称为重写
纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0 ;
当类中有了纯虚函数,这个类也称为抽象类
抽象类特点:
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:
虚析构和纯虚析构区别:
虚析构语法:
virtual ~类名(){}
纯虚析构语法:
virtual ~类名() = 0;
类名::~类名(){}
总结:
1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
2. 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构
3. 拥有纯虚析构函数的类也属于抽象类
c++利用了构造函数和析构函数解决对象的初始化和清理。
构造函数语法:类名(){}
析构函数语法: ~类名(){}
三种调用方式:
1.括号法
2.显示法
3.隐式转换法
C++中拷贝构造函数调用时机通常有三种情况
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
C++中,类内的成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象上
每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。
c++通过提供特殊的对象指针,this指针,解决上述问题。
this指针指向被调用的成员函数所属的对象
this指针的用途:
友元的目的就是让一个函数或者类 访问另一个类中私有成员
友元的三种实现
对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
作用:实现两个自定义数据类型相加的运算
作用:可以输出自定义数据类型
作用: 通过重载递增运算符,实现自己的整型数据
c++编译器至少给一个类添加4个函数
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
作用: 重载关系运算符,可以让两个自定义类型对象进行对比操作
程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
通过文件可以将数据持久化
文件类型分为两种:
操作文件的三大类:
写文件步骤如下:
包含头文件
#include
创建流对象
ofstream ofs;
打开文件
ofs.open(“文件路径”,打开方式);
写数据
ofs << “写入的数据”;
关闭文件
ofs.close();
打开方式 | 解释 |
---|---|
ios::in | 为读文件而打开文件 |
ios::out | 为写文件而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 追加方式写文件 |
ios::trunc | 如果文件存在先删除,再创建 |
ios::binary | 二进制方式 |
读文件步骤如下:
包含头文件
#include
创建流对象
ifstream ifs;
打开文件并判断文件是否打开成功
ifs.open(“文件路径”,打开方式);
读数据
四种方式读取
关闭文件
ifs.close();
以二进制的方式对文件进行读写操作
打开方式要指定为 ios::binary
二进制方式写文件主要利用流对象调用成员函数write
函数原型 :ostream& write(const char * buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
二进制方式读文件主要利用流对象调用成员函数read
函数原型:istream& read(char *buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
模板就是建立通用的模具,大大提高复用性
语法:
template
函数声明或定义
解释:
template — 声明创建模板
typename — 表面其后面的符号是一种数据类型,可以用class代替
T — 通用的数据类型,名称可以替换,通常为大写字母
普通函数与函数模板区别:
调用规则如下:
类模板的作用:
建立一个通用类,类中的成员 数据类型可以不具体制定,用一个虚拟的类型来代表。
语法:
template
类
解释:
template — 声明创建模板
typename — 表面其后面的符号是一种数据类型,可以用class代替
T — 通用的数据类型,名称可以替换,通常为大写字母
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
功能:
vector与普通数组区别: