QT_C++
C 与 C++ 区别: 面向过程:吃(狗,屎)
面向对象:狗. 吃(屎)
^ . ^
博客:https://www.runoob.com/cplusplus/cpp-tutorial.html
插入符:<<
控制符:endl
换行符:
cout:打印屏幕输出( cout.put )
cin :读取键盘输入(cin>> cin.get() )
数据类型: 类
类: 描述一种数据类型全部属性
对象: 根据描述创建的实体
类库
英雄 雷锋 (类 对象)
iostream cout (cout 是 iostream 的类对象)
数据: 常量 变量
类型: 基本类型: 整型(无符号和有符号 * char, short, int, long, long long = 10 种)
short 至少16位
int 至少与short一样长 (自然长度,计算机处理效率最高)
long至少32位,至少与int一样长 (大于16位使用)
long long 64位
实型(float, double, long double)
float 至少32位(32位)
double 至少48位,不少于float(64位)
long double 至少和double一样多
表示方法:小数 指数(E法:E+n小数点右移n位;E-n小数点左移n位)
字符(char)''
#include<climits>
这些其实就是宏 !
字符串:" "
bool: true 1 false 0
const 限定符
类型转换:
表达式转换:整型提升(bool, char, unsigned char, short 提升为 int )int 为计算机的自然类型
运算涉及两种类型,小类型转换为大类型
传参的转换:整型提升 float 提升为 double
强制的转换: (int)val C int(val) c++ 很危险
static_cast<long><val> 将一种类型转换为另一种类型;
整型常量:十进制 八进制 十六进制
浮点
使用变量
复合类型:
变量名:两个下划线或下划线和大写字母开头的名称被保留给实现使用,以一个下划线开头的名称被保留给实现,用作全局标识符。
运算符
+ - * / %
复合类型(构造类型)
数组
数组的
动态联编:int arr [5] ;
静态联编:int * arr = new int [10];
数组表示法;arr [1];
指针表示法:*(arr + 1);
字符串
字符数组 指针(常用) string类库
字符数组:
char arr[5] = {'a', 'b', 'c', ' ' };
char arr[ ] = {"abc"};
字符串的比较:strncmp
拼接字符串常量:
将两个引号中的字符串合并为一个
面向行输入:
cin.getline: cin.getline(arr, 20);
cin.get: cin.get(arr,20) / cin.get()
cin.get.get cingetline.getline (拼接)
get() 读取空行后将设置失效位,可以通过cin.clear() 恢复;
字符数字混合:
string 类: 提供了字符串作为数据类型的表示方法
string str ; str 创建一个长度为0的string对象,并自动调整str的长度(所以更加方便!)
char 数组用于存储一个字符串的char存储单元;string类表示字符串的实体;
特点: 1. 可以像整型一样,直接赋值;(字符数组不行)
2. 字符合并相加,arr1 += arr2 (arr2插入arr1尾部)
字符数组:strncpy(string1, string2,n);string类的字符串拷贝:直接赋值
字符数组:strncat (string1,string2,n) ;string类的字符串尾插:直接 +=
字符数组存在溢出危险,string类不担心
所以字符串处理:string类比字符数组更加简单;
string类的IO:
结构体
struct
C++结构体定义可以省略struct
由于C++使用string类作为字符串的数据类型,则可以添加到结构体中;
结构体可以作为函数参数和返回值,同类型结构体变量可以相互赋值(即使是数组);
C++结构体除了成员变量,还可以有成员函数;
结构体数组:
struct arr [5] arr 为数组,并非结构体; arr[0] 为结构体;
初始化:struct arr[5] = {
{ },
{ },
{ },
};
结构体位字段:指定占用特定位数的结构体成员
struct info {
u8 : 4;
boo: 1 ;
}
联合体
union
可以存储不同数据类型,只能同时存储其中一种类型
由于共用体每次只能存储一个值,则它必须有足够的空间来存储最大的值,所以共用体长度为最大成员的长度;
匿名联合体:没有名称,成员位于相同地址处的变量
用途:数据使用多种格式,可节省空间;
枚举
enum
enum tem (a,b,c,d);
abcd 符号常量,代表0~3;常量叫做枚举量
tem 只能被abcd赋值;枚举变量只能被枚举量赋值
枚举量是整型,可被提升为int,但int不能自动转换为枚举类型
枚举量之间不能运算符,要不然为int型;
用处:常用来定义相关的符号常量,如switch语句中使用的符号常量
枚举量赋值:enum tem (a=2,b,c=3,d) 没有赋值的值默认比前一个大1,b=c=3
枚举的范围:
指针
(地址 + 步长)
c int *point c++ int* point
计算器分配存储地址的内存,不会分配存储指针指向数据的内存;
int *p; p=(int *)0x00000001;
指针:运行阶段分配没命名的内存以存储值;
malloc 分配内存
new 操作符(运行阶段为int分配未命名内存) 堆空间
new特点:运行时创建,优于编译时创建!
new创建动态指针:
设置数据类型,new找到正确的内存块,返回内存块的地址;
typename point = new typename ;
int *p = new int ;
内存被耗尽,new返回0!
内存的释放:delete操作符,将内存归还内存池;
int *p = new int ; delete p ;
一定成对使用,否则发生内存泄漏!(被分配的内存再无法使用,如泄漏严重程序由于不断寻找更多内存而终止)
(不能释放两次,结果不确定,delete不能释放声明过的内存!)
new创建动态数组:
int *p = new int [10] ;(返回第一个元素的地址)
delete [ ] p ; (new带[],delete带[],new不带[],delete不带[])
new和delete:delete只释放new分配的内存;
delete不能对同一内存释放两次;
new[]为数组分配内存,用delete[]释放;
new[]为实体分配内存,用delete释放;
空值指针,delete是安全的
不能用sizeof来确定动态分配数组的字节数!
动态数组成员使用:
int *p = new int [3];
p[0] = 1;
p[1] = 2;
指针 + 1 = 指针 + 步长
new创建动态结构:
创建动态结构:
struct info {
char * name ;
int age ;
}
info* tony = new info;
tony->name;
*(tony).age;
数据管理内存方式:
自动存储:
函数内部定义的常规变量(函数调用自动产生,函数结束自动消失)
局部变量
静态存储:
整个程序执行期间一直存在
方式:函数外定义;关键词static修饰
动态存储:
new / delete 管理一个内存池,允许一个函数分配另一个函数释放;数据生命周期不受程序或函数的生存时间控制
指针是被设计用来存储地址的变量
控制流
顺序 选择(if;if...else...;if..else if...else...; switch) 循环(for; while; do...while)
C++:for允许for(int i=0;i<num;i++) 程序离开循环,变量消失
i++:当前值计算表达式,然后值加1
++i:当前值加1,然后计算表达式
*++p 指针加1再取值 ++*p 指针取值再加1
*p++ ++优于*
组合赋值操作符:+= -= *= /= %=
逗号表达式的值为第二个值;优先级最低
关系表达式:>, <, = =, >=, <=, != 六种 优先级比算数表达式低
for for 与二维数组
if:
逻辑表达式
逻辑操作符 ,用于表达式:&& || !三种
&& 与 关系操作符,构成取值范围
字符函数库 cctype:
isspace 检测字符是否为空白 isalpha()检测字符是否为字母
ispunct 检测字符是否为标点 isdigits()检测字符是否为数字
三目运算符:?: int c = a>b ? a:b 常用来替代if...else 语句
枚举做标签与switch结合
switch与if..else..区别:
switch不能处理小数与取值范围
对于整数,switch比if...else...效率更高
项数不小于三项用switch
break : 跳出循环(结束循环)只在循环中使用
continue :跳回循环 (重新循环)
文件IO
C++编程模块
函数不能返回数组,可以将数组作为结构或者对象组成部分来返回
可以返回,整型 实型 结构 对象
函数原型自动将被传递的参数强转为期待的类型
数组作为函数的形参:void fun(int arr[], int n) == void fun(int *arr, int n) // arr为数组名,n为size
void fun(const int arr[], int n) 不能修改实参数组的数据
1.传统第一个参数提供数组的起始位置,第二个参数提供数组的长度
2.数组区间函数,通过两个指针,第一个参数为数组起始位置,第二个参数为数组的终点位置
void fun(const int *arr, const int *end);
数组作为函参意义:
const 变量的地址可以赋给const指针,但const变量地址不能赋给常规指针
函数与二维数组:
int fun( int(*arr)[ 4 ], int size) == int fun( int arr[ ][ 4 ], int size)
arr 为数组指针
函数与字符串:
int fun(const char* arr, char ch)
返回字符串:
函数与结构体:
结构体作为函参:
结构体作为返值:
struct info{
char name[20];
int name ;
}
info fun( info t1, info t2 );
info fun(info* t1, info* t2);
函数与string对象:
string arr [size]; 数组的每个元素都为string对象
函数与递归:
自己调自己,容易出现死循环;
函数与指针:
函数指针:void (*fun)(void)
指针函数:void *fun(void)
函数探幽
内联函数:
——————————————————————————————————————————————
《inline 内敛函数》
函数:不断的压栈出栈,再压栈出栈,开销比较大。
宏:预处理阶段展开;不需要压栈出栈,弊端数据不处理。
内联函数:编译器阶段展开;不需要压栈出栈,
本质:牺牲代码段空间为代价,提高运行的时间效率;
特点:定义声明加inline
c++编译器将函数体直接插入到被调用的地方;
没有普通函数调用时的开销(压栈,跳转,返回)
弊端:函数不能庞大,循环,判断,取址
计算机速度:cpu(寄存器)>缓存>内存>硬盘>网线
运行速度比常规函数快,但占用更多的内存;
内联函数不能递归;
——————————————————————————————————————————————
引用变量:
——————————————————————————————————————————————
是一种复合类型;
主要用于函数的形参:函数将使用原始数据,而不是拷贝;
1. 声明时必须初始化;
2. &前有数据类型为引用,其他皆为取址
3. 可对引用再次引用,多次引用只是取别名
4. 引用与变量地址相同
int a ;
int & b = a;
引用作函参:
值传递导致函数调用使用拷贝;
引用允许被调函数访问调用函数的变量;
引用与结构:
struct info{
char name[10];
int name ;
};
const info & fun(info & a);
const返回引用最佳:意味着不能使用返回的引用直接修改他指向的结构!
返回引用不能使用临时值,要不然不存在!!
遇到一个strcpy的C++问题:
将strcpy_s代替strcpy插入include<cstring>,可以编过
引用与类对象:
类对象作为函参,常使用引用 !(如string)
对象继承与引用:
默认占位参数:
——————————————————————————————————————————————
《函数的默认参数与占位参数》
默认参数:定义函数参数直接赋值,默认起始从右至左 !
占位参数:没什么意义!
——————————————————————————————————————————————
函数重载:
——————————————————————————————————————————————
《函数重载》
函数重载:函名相同,函参不同,缺一不可!
注意:函数重载,不要写默认参数,避免函数冲突!
类型严格匹配,不匹配隐式转换,字符串不行!
编译器:void fun(char a,int b) --> fun_ci
——————————————————————————————————————————————
函数模板:
——————————————————————————————————————————————
template<class any> (typename any)
void fun(any &a, any& b){
any temp ;
temp = a;
a = b ;
}
函数重载模板
——————————————————————————————————————————————
template<class any> (typename any)
void fun(any &a, any& b);
void fun(any &a, any& b, int c)
内存模型与名称空间
数据存储:自动: (局部)
静态:static (定义的位置至结束)
外部,内部,无链接性
动态:new / delete ()
作用域: 局部变量:局部函数
全局变量:定义位置至结束;
- 友元函数
- 友元类
- 友元成员函数
main 返回值并不是返回给程序,而是返回给操作系统,0代表成功,非0为异常;