//2 - 10
//头文件 #include<iostream>
//把这个头文件的内容全部拷贝在出现的位置上来。。。。
//< > " " 的区别
//< > 是从编译器指定的路径寻找这个文件
//" " 在当前的目录下找这个文件
//如果找不到再从是从编译器指定的路径寻找这个文件
//2 - 11
//main 函数 函数执行的开始....
//一个程序有且只有一个 main 函数
//int main() {
//}
//int main(int argc, char* argv) {
//
//}
//2 - 12
//字符串常量
//"这个就是字符串常量"
//内容不会发生变化的字符串.用 " " 括起来
//常量 : 在程序运行期间值不会发生任何变化
//变量 : 在程序运行期间值可以发生变化的量
// 2 - 13
// cout << "输出" << endl; endl 是换行
// cout << "输出\n"; \n 是换行符
// printf("你好,%d\n”,300);
// %d 整数 %f 浮点数(带小数的数据) %s 字符串
// 占位符 %d,%f,%s
// 2 - 14
//命名空间 避免名字的冲突
//using namespace lizhi;
//namespace lizhi {
// string haha = "无法";
//}
//namespace zhansan {
// string haha = "唉 唉";
//}
//int main() {
// cout << zhansan::haha << endl;
// cout << lizhi::haha << endl;
// return 0;
//}
//3 - 16
//注释 // /* */ 不参与程序的运行
//4 - 29
//控制台语句:
//cout 输出
//cin 输入
// 5 - 30
// 数据类型
// 1 表示意义不同
// 2 占用内存不同
// 3 表示的范围不同
// 4 使用方法不同
// 5 - 31
// 变量 在程序运行中值不断发生变化的量
// 存储在内存里面
// 数据类型就是变量的类型
// 定义变量 int a;
// 变量在内存的中存放是从低字节到高字节存放
//5 - 33
//整数类型
//int 4 字节 一个字节 8个二进制位
//long / long int 等效
//64位 8 字节 32位 占4 字节
//long long 不管32 64 占8字节
//short 2字节
//unsigned int
//unsigned long
//unsigned long long
//unsigned short 无符号 全部正整数
//从0 开始计算
//5 - 34
//char 占一个字节(8个二进制位) 字符型
//用 ' '单引号括起来
//char name = 'a' char name = 97
//int a = 'a' + 1 ==98
//5 - 35
//float a = 3.14 单精度浮点型 占4个字节
//小数点后面 7位 第7位四舍五入
//double a = 3.142132 双精度浮点型
//最长小数点后面16位
//5 - 36
//默认情况下 cout输出float 型只输出6 位有效数字
//cout.precision(4); 控制输出有效位数
//cout.flags(cout.fixed);
//控制 cout.precision(4)里面的参数为小数点后面的参数
//cout.unsetf(cout.fixed);
//取消cout.flags的设置
//5 - 37
//cin 是在标准输入设备中读取数据
//string a;
//while (!cin.eof()) {
//cin.eof() 读取文件结束符 读取到返回true
//否则返回false ctrl+z 是文件结束符
// cout << "进入了" << endl;
// cin >> a; //阻塞程序
//}
//5 - 38
//两种不同的常量
//字面常量
//200L 在Windows 下都是4个字节
//100L L表示 字面常量 long
//100LL LL 表示字面常量 long long
//"a' 字符型 字面常量
//1 整数字面常量
//"LIZHI" LIZHI 字符串型字面常量
//3.14f 单精度的浮点字面常量
//3.14 双精度的浮点字面常量
//2 符号常量 :
//# define 宏定义的符号常量
//# define cao 100; 出现cao 的地方用 100代替.
//const int a = 100; 此时 a 是常量;
//6 - 40
//int a;
//cin >> a; //假如输入了字母
//if (cin.fail()) {
// 如果输入错误 将会返回true
// 这里的错误是cin >> a a是整数,输入了个字符
// cin.clear();// 清楚cin 的错误标字
// cin.sync(); // 清空输入缓冲区
// cout << 输入错误了 << endl;
//}
//7 - 49
//字符串 由0个或多个"字符"组成的"有序"的序列
//string a = "" 长度是0
//string a = " " 长度是1
//string a = ""; string b; a == b true;
//字符串结束符 c 语音中使用
// ''lz'' == > ' l ' ' z ' ' \0 ';
//7 - 50
//赋值
//string a = "lizhi"
//把字符串常量拷贝到 a 里面去;
//string b = a;
//把字符串a里面的值拷贝到b里面去;
//string c("lizhi");
//string d(a);
//string e(10, 'A'); 里面是10个A
//7 - 51
//string 的输入输出
//cin >> 输入
//从第一个非空白字符
//(空白字符: 回车符, 制表符, 空格) 开始,
//直到遇到空白字符为止
//空格 abc 空格 efg
//cin 读取的是 abc efg 不读取
//efg下一次 cin 读取
//处理方法 : 读取一行
// string a;
// getline(cin, a);
//从标准输入设备(cin),
//读取一行字符串,保存到字符串变量 a 里面
// 读一行,直到遇到回车符(换行符),
//不包括回车符 这行读取结束.
//cin >>a ctrl + z + inter == > 0
//while (cin >> a) {
//}
//7 - 52
//string a;
//a.empty() //判断字符串是不是空
//a.size() //计算长度
//a.length() //计算长度
//7 - 53
//比较预算符有:
// > >= < <= ==
//字符串的比较
//从字符串的第一个字符开始, 对应的字符啄个比较,
//直到遇到不相等的字符为止
//比较的结果为 : 真 / 假
// 7 - 54
// 字符串的加法
// string a = "lizhi";
// string b = "草";
// string c = a + b
// cout << c == = > lizhi草
//7 - 55
//c 语言的字符串 用字符串数组来表示;
//char name[32]
//scanf("%s", name)
//scanf相当于c++的cin
//7 - 56
//数组 : 相同大小的内存块组成, 即相同类型的数据
//编号从0 开始递增
//数组的"容量"是不能改变的
//int a[8]; //定义了一个数组
//7 - 57
//数组的初始化
//int a[8] = { 1,2,3,4,5,6,7,8 };
//int b[8] = { 100 };
// 第一个值是100 后面的全是 0
//int c[100] = { 1,2,3,4 }// 没有指定的 用0 来填充
//int d[] = { 1,2,3 }; //数组的个数是 3
//int m[50] = {
// [15] = 90,[20] = 95,[25] = 85,
//}; c 语言编译器支持 c++ 不支持
//8 - 58
//数组元素的访问 通过下标来访问
//string name = "LIZHI";
//name[0] = 'w'; // 字符型号
//for (int i = 0; i < name.length(); i++) {
//}
//8 - 59
//c 语音字符串的初始化
//char name[32] = "lizhi";
//等效于
//char name[32] = { 'l','i','z','h','i','\0' };
//8 - 60
//c语音的字符串的输入输出
//char name[10];
//scanf("%s", name); cin >> name;
//fflush(stdin); // c 清空输入缓冲区
//gets(name) //读一行,直到遇见回车符
//c++11 取消换成 gets_s
//strlen(name) 计算字符串的长度
//8 - 62
//cin.sync() 在c++ vs 中无效 清空输入缓存区
//cin.clear() //清楚错误标志 使流重新处于有效状态
//getchar() 函数读一个字符
// \n 表示换行
// 8 - 64
// 断点调试
// 断点的前一行 程序执行到那里
// f11 逐语句
// f10 逐过程
// shift + f11 跳出函数
// 8 - 66
// scanf("%s", char a[10]);
//遇见文件结束符合(ctrl+z) 返回 -1 cin 返回0
// 8 - 67
//getline(cin, string a) //读一行
//gets(char a[128]) //读一行
//9 - 69
//字符串的比较
//比较运算符 == > < >= <= !=
//结果 bool true / false
// 9 - 70
// bool 类型
// 使用 0 表示假
// 非0的任何值表示真 :
//9 - 71
//c 语言的字符串的比较
//strcmp c语言字符串的比较
//char a[10];
//char b[10];
//int c = strcmp(a, b);
//a<b 返回值 <0 有些编译器返回 - 1
//a>b 返回值 >0 有些编译器返回 1
//a=b 返回值 为 0
//9 - 72
//其他数据类型的比较 比较结果为 bool 类型;
//9 - 73
//逻辑运算
//&& 与(且) a&&b a为真b为真 才为真
//(当a为假的时候 b不进行判断)
//|| 或 a || b 只要 一个为真 都为真
//!非 !条件 真的变成假的 假的变成真的
//9 - 74
//位运算
//内存的基本单位是字节, 一个字节 8 个二进制位
//& 位与
//0 & 0 0
//0 & 1 0
//1 & 0 0
//1 & 1 1 相当于 0 的乘法
//| 位 或
//0 | 0 0
//0 | 1 1
//1 | 0 1
//1 | 1 1 有一位是1,对应的才是 1
//~位 非
//~1 0
//~0 1 1变成0.。。。。0变成1.。
//^ 位 异或
//0 ^ 0 0
//1 ^ 1 0
//0 ^ 1 1
//1 ^ 0 1 对应位不同, 结果才是 1
//<< 左移 只适用于整数类型
//8 << 1 8 的二进制位 全部像左移动一位
//右边空出一位 补充 0 左边多出的一位不要
//左移一位相当乘以2
//x << n = > x * 2的n 次方
//>> 右移
//8 >> 1 8 的二进制位 全部像右边移动一位
//左边空出一位 补充 0 / 1
//(正数补0,负数补1 )
//右边多出的一位不要
//x >> n = > x / 2 的n次方
//9 - 76
// / 取整 % 取余数
// x += 10 x = x + 10
// x -= 10 x = x - 10
// 后缀自增 x = i++ x = i i = i + 1
// x = i-- x = i i = i - 1
// cout << i++ << endl;
//第一次打印i的值,第二次打印i++...
//前缀自增 x = ++i i = i + 1 x = i
//x = --i i = i - 1 x = i
//cout << ++i << endl;
//直接打印++i的值
//三目运算符
//条件 ? 表达式 1 : 表达式 2
//真选 : 表达式 1 假选 : 表达式2
//cout << (300 > 200 ? "哎呀" : "gogo") << endl;
//输出: "哎呀"
//3.14 浮点型常量 是double 类型
//3.14f 强制指定为 float 类型
//cout << typeid(3.14).name() << endl;
//typeid ().name() 查询类型的信息
//cout << typeid(3.14f).name() << endl;
//cout << sizeof(3.14) << endl;
//cout << sizeof(int) << endl;
//=====> 4 sizeof 查询对象或类型的大小。
//10 - 77
//运算符的优先级 :
//最高优先级:()[]
//最低优先级 : 逗号表达式
//倒数第二低优先级 : 赋值和复合赋值(=, +=, -=);
// !> 算术运算符 > 关系运算符 > && > || > 赋值运算符
//10 - 78
// 数据类型的转换
//1 隐式类型转换(自动完成转换)
//1 算术转换 char int long long long float double
// 15 + 3.14 == = 》15.0 + 3.14
//2 赋值转换 int x = 3.14 * 10 x = 31
//3 输出转换 print('%c' \n'', 255 + 50) -> 1 %c 是char 类型
//2 强制类型转换
// int x = (char)257 + 100; char 257 == 1 x = 101
//高级强制类型转换: 后面学
//10 - 79
//if (a < 100)........... 1 只执行这个行语句
// ...........2 不执行这行语句
// if 语句的三种形态
// if (.......) {}
// if (....) {
// }else {....};
// if (...) {
// }
// else if (...) {
// }
// else if{
// }
// else {
// else 可以不 +
// }
//10 - 81
//switch 的 用法
//english 开关 当有多个条件只满足一个条件的时候用 Switch
// int a;
// Switch(a) {
// case 1: 当a = 1 时 执行下面的语句
// ...........;
// break;
// case 2:
// default: 当全部不匹配的时候执行这条语句
// ...........;
// break;
// }
//10 - 82
// switch 的特殊用法
// switch (a) {
// case 6:
// case 7:
// 满足6 7 其中一个执行这条语句
// .....................
// break;
// }
//11 - 93
// while 循环
// while (条件) {
// 语句
// break; 跳出
//}
//11 - 94
//for 循环 使用到已经知道循环次数的语句中
// for (表达式 1; 表达式 2; 表达式3) {
// 1->2->4 ->3 -> 2->4->3 当2是假的时候 跳出循环
// 循环语句 4
// }
//表达式1
// for (; 表达式 2; 表达式3) {
// }
//for (; 表达式 2; ) {
// 表达式3
//}
//for (; ; ) {
//和 while (1) 一样
// 循环语句 4
//}
// 12 - 95
// do while 循环
// do {
// 至少执行一次循环体 然后再判断条件
// 循环体
// } while (条件)
// 12 - 96
// 循环中的控制
// continue (结束这次循环进入下一次循环)
// break 跳出循环
// 12 - 97
// goto 语句 很少用 可以用定义函数替代
//int main() {
//for (int i = 0; i < 10; i++) {
// if (i == 5) {
// goto happy;
// }
//}
//return 0;
//happy:
//cout << "跳出来了哦" << endl;
//return 0;
//}
// 15 - 126
//函数的定义
//1 先确定函数的功能
//2 确定函数的参数 s
//3 确定函数的返回值
//15 - 127
//函数的声明
//int lz(int a); 函数声明
//int lz(int); 写法二
//int main() {
// lz(100) 100是实参
//}
//int lz(int a) {
// a 是形参
//}
//15 - 128
//函数声明在多模块开发中的使用
//int lz(int a);.h 文件
//int lz(int a) {
//.cpp 文件
//每个cpp 文件至少有一个头文件.cpp
//最好包含字节的头文件 函数比较多要存在先后关系
//}
//1.
//#pragma once 这个头文件 只能被包含 一次 不能夸平台
//2
//#ifndef _TOOLS_H_ if no def 如果没有定义
//#define _TOOLS_H_ 定义
// 内容..........
//#endif end if 跨平台 这个头文件只能包含一次
//15 - 129
//函数的调用以及传递的方式
//函数的实参 带到函数的形参后
//实参与形参没有任何关系 相当于 形参 = 实参 实参赋值给形参
//15 - 130
// 只要是指针64 位占 8字节 32位 4 字节;
//
// 数组作为函数的参数
/*void xx(int a[3]) {
传递的 a是一个数组的地址
}
void yy(int b[]) {
传递的 b是一个数组的地址
}
*/
//16 - 131
// 默认参数
// void xx(int a = 10, int b = 20) {
// 默认参数 不能放在形参之前 void mm(int a = 10, int b ) 会报错
// }
//c语言不支持默认参数;
// 16 - 132
// 函数重载
// 函数的名字相同时 参数不同可以进行函数重载
// c 语言不支持函数重载
//16 - 133
//函数的栈空间
//每个函数都会在栈空间里面分配一块内存;
//递归函数 调用时 注意栈溢出 .....
// 16 - 134
// 内联函数 inline
// inline int add(int a, int b) {
// return a + b;
// }
// int main(void) {
// cout << add(3, 5) << endl;
//相当于把 add 函数里面的代码替换到 add(3, 5)的位置上来
// }
// 缺点 会消耗执行函数中的栈空间.....
// 16 - 135
// 递归函数 自己调用自己
//int xx(int a) {
// if (a > 5) {
// return a;
// }
// xx(a + 1);
// cout << a << endl;
// return a; // 最开始执行的函数的返回值
//}
//int main() {
// cout << xx(0) << endl;
// return 0;
//}
//16 - 138
//制作自己的库文件 不点运行就行
//需要在vs里面配置
//17 - 141
//二维数组
//int a[x][y]; x 表示行 y 表示列
//数组的初始化:
//int a[2][5] = {
//{1,2,3,4,5},
//{6,7,8,9,10}
//};
//int a[2][5] = {
//{1, }, // 省略掉的部分是 0
//{6,7,8,9,10}
//};
//int a[2][5] = { 1,2,3,4,5,7,8,9,10,11 };
//int a[2][5] = { 1 }; 省略掉的部分是 0
//17 - 142
//int a[][4] = { //等效于 int a[3][4]
//{1,2,3,4},
//{5,6,7,8},
//{9,10,11,12}
//};
//17 - 143
//二维数组的访问
//for (int i; i < 3; i++) {
// for (int j = 0; j < 4; j++) {
// a[i][j] = i * 4 + j + 1;
// }
//}
//17 - 144
//二维数组的存储方式
//数组在内存中存储的方式是连续的............
//17 - 145
//多维数组 不经常用到!!!!
//17 - 146
//二维数组作为函数的参数:传递的是数组本身 也就是传递的是地址
//void xx(int a[3][4]);
//void xx(int a[][4]);
//void xx(int a[][4], int b);
//18 - 147
//int a[][4]; 错
//int b[3][]; 错
//18 - 151
//#include<assert.h>
//int xx(int x, int y) {
// assert(0 < x && 0 < y); //不满足这个条件程序直接停止
//}
//19 - 155
//为什么要使用指针
//1 函数的值传递, 无法通过调用函数, 来修改函数的实参
//2 被调用函数需要提供更多的"返回值"给调用函数
//3 减少值传递时带来的额外开销, 提高代码执行效率
//19 - 156
//指针是保存地址的一个变量
//数据类型可以指定指针的类型
//指针的值是一个地址
//int *p;
//19 - 157
//指针的初始化
//int a = 100;
//int *p = &a;
//19 - 158
//指针的访问
//int a = 100;
//int *p = &a;
//cout << p; 地址
//cout << *p 地址的值
//char* p = "laozicaonima";
//cout << strlen(p) //字符串的个数
//cout << p; // 字符串的值也就是它的地址
//cout << *p; // 字符串的第一个字母
//19 - 159
//空指针和坏指针
//int *p;
//cout << p; 程序会终止 没有赋值 坏指针
//int* p = NULL / 0; 空指针 *p 会出错不能访问
//19 - 160
//指针的自增操作:
//int a[5] = { 1,2,3,4,5 };
//int *p = a;
//p = p + 1 / p++ 数组第二个元素的地址
//p++ 在p当前地址的基础上, 增加p 对应类型的大小
//19 - 161
//指针的自减操作
//p-- *p-- 先执行*p 再执行p--;
//19 - 162
//int a[6] = { 1,2,3,4,5,6 }
//int *p = a;
//指针与整数的加减 p + 2 p - 4
//指针与指针的加减 : 指针与指针相加没有意义,
//指针与指针相减得相差的个数
//指针与指针的相加在同一个数组中操作
//20 - 162
//const 修饰的指针 靠近谁,修饰谁。。。。。
//const int *p; 修饰int *p值不能修改
//int const *p; 修饰 *p *p值不能修改
//int* const p; 修饰 p,此时指针是常量只能赋予一个值
//const int * const p; p是常量指针,
//只能指向一个地址且不能修改它的值。
//20 - 164
//二级指针
//int a;
//int *p;
//int **q;
//p = &a; 存变量a的地址
//q = &p; 存指针的地址
//20 - 165
//二级指针的用途
//二级指针可以将变量通过参数带入函数内部,
//也可以将函数内部变量带出函数的外部.
//解决办法 二级指针
//void xx(int **p) {
// static int boy = 20; 全局变量
// *p = &boy;
//}
//int main() {
// int *q = NULL;
// xx(&q); //这里带入的是*q的地址。。
// cout << *q << endl;
//}
//20 - 166
//多级指针 不常用
//int *q;
//int **q;
//int ***q;
//21 - 167
//数组和指针的纠缠
//int main() {
// int a[6] = { 1,2,3,4,5,6 };
// for (int i = 0; i < 6; i++) {
// cout << a[i] << endl;
// cout << *(a + i) << endl;
// }
//}
//21 - 168
//指针数组
//int *p[n];
//21 - 169
//数组的地址等于数组第一个元素的地址也等于数组的值
//指向二维数组的指针
//int b[4][3] = {
//{1,2,3},
//{4,5,6},
//{7,8,9},
//{10,11,12}
//};
//int(*p)[3];// 指向三个成员的数组的指针
//p = &b[0]; //p 指向 b的第一列
//p++; //指向第二列
//cout << (*p)[1] << endl;
// 通过下标访问 (*p)相当于b[0]
//cout << *(*p + 1) << endl;
// 通过指针访问 *p/*p + 1 相当于地址
//21 - 169
//数组和指针的差别
//函数形参接受指针数组的时候 用二级指针
//22
//void 类型的指针
//void* p;
//int a[] = { 1,2,3 };
//p = a;
//cout << *p << endl; // 访问会出错
//int* m = (int*)p; // 强制类型转换..
//cout << *m << endl;
//22 - 170
//函数的指针
//void xx(int a,int b) {
//}
//cout << &xx << endl; //打印函数的地址
//void(*p)(int, int); // 定义了一个指向函数的指针
//p = &xx; // 给指针赋值
//(*p) (10, 20); // 调用时 使用指针的解引来进行访问...
//p(10, 20); // 直接调用 原因是有历史原因.........
//cout << *p << endl; // 函数的地址 函数的地址在栈区
//cout << p << endl; // 函数的地址
//引用
//引用可以看作一个已经定义变量的别名;
//引用的语法: int & name = 已知变量
// int a = 666; int &b = a; b 就是a 的别名
// cout << a << endl;
// cout << b << endl; 值一样
// cout << &a << endl;
// cout << &b << endl; 地址一样
// 引用的本质
// 引用有自己空间的.....
// 引用只能指向一个变量, , , 不能指向别的变量........
// int &b = a; 本质是 int *const b = &a;
//指针的引用
// int *p = NULL;
// int* &q = p; 定义了一个指针的引用
// cout << q << endl;
// cout << p << endl; //地址一样
// cout << *q << endl;
// cout << *p << endl; //值也一样
// 二级指针用引用简化
// void xx(int**q) { //二级指针
// }
// void xx(int* &q) { //这里相当于传递了一个指针的引用
//也就是直接带入这个指针本身
// }
//常引用
//int a = 10;
//const int& b = a; 不能修改值
// 24 - 174
// c++ 内存分布
// 代码区 存放函数体包括类的成员函数,
// 全局函数(全部函数)的二进制代码
// 常量区 字符串常量 const修饰的变量
// 全局(静态区) 存放 全局变量 / 静态变量
//int a = 100; 全局变量 声明extern 其他cpp 文件可以使用
//static void xx() { 静态函数 作用域(当前文件)避免命名冲突
//static int yy = 200; 静态变量 只能在这个函数内部使用
// 且只能被赋值一次
//}
//堆区: 程序员分配释放 new创建 delete删除
//栈区 : 临时变量,函数形参,函数内部局部变量,返回值
//24 - 175
//位什么要使用动态内存;
//1 不管在哪个位置产生 不delete 一直都在
//2 按需分配, 不浪费资源....
//3 堆区比较大
// void* memcpy(void* dest, const void* src, std::size_t count);
// 拷贝内存的函数
// dest 指向要复制的对象的指针
// src 指向复制来源对象的指针
// count 复制的字节数
//int *p = (int*)malloc(数量);
//free(p);
//24 - 176
//动态内存的分配, 使用, 释放
//new delete
//malloc free
//24 - 177
//内存泄漏
//24 - 178
//变量的4种储存类型
//auto 自动变量 int a ;
//register 寄存器变量 register int a;
//static 静态变量 全局存在
//extern 外部变量 全局存在
//24 - 179
//变量的作用域和生存周期
//存储类别 存储期 作用域 声明方式
//auto 自动 块{ } 块内 auto it = 100;auto自动推导 int
//register 自动 块{ } 块内, 使用关键字 register
//static(局部)全局静态 块 { } 块内, 使用关键字static只能初始化一次
//static(全局)全局静态 文件内部 所有函数外, 使用关键字static
//extern 全局 文件外部 所有函数外
//25 - 180
//函数的返回值使用指针
//注意函数的作用域
//还有new 分配 delete
//25 - 181
//申请的内存不能多次释放
//内存泄漏。一次都没有释放
//释放的内存不是申请时的地址
//释放空指针
//释放一个内存块,但继续用其中的内容
//越界访问
//25 - 187
//内存泄露工具
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>
// 第二步: 接管 new 操作符
//#ifdef _DEBUG
//#ifndef DBG_NEW
//#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ ,__LINE__)
//#define new DBG_NEW
//#endif
//#endif
// 代码段。。。。。。。
// 第三步: 在代码结束出输出内存泄漏信息
//_CrtDumpMemoryLeaks();
//26
//宏定义:
//#define xxx xxxxxxxx\
// xxxxxxx 替代的数据太长可以用 \ 换行
//#define xxx(s) s*s
// 出现xxx(s) 的地方全部替换成后面的数据
//结构体 :
//struct 结构名 {
// string name = "xxxxxxx";
//}h2; // 这里的h2是struct结构名的对象 (还是全局变量)
//struct 结构名 h1; //h1 是结构体的对象
//struct {
// int a;
//}h2;
//枚举类型
//enum 变量名 {
// spring, //0
// summer, //1
// autumn, //2
// winter //3
//} h2; // h2 是枚举的对象
//enum 变量名 h1;// h1是 枚举的对象
//h1 = spring;// 给枚举赋值
//enum {
//} ss,h3; //没有变量名 只有对象 无法定义其它变量
//类型定义
//typedef int yyy; 此时 yyy 是变量 int 的别名
//typedef int(*p)(char); // 定义了一个函数指针 p 类型
//p a = &函数名
//p a = 函数名 // 因为函数名的值等于它的地址。。所以这两种写法都正确
//然后可以通过 a(‘c’)调用这个函数
//#include<iostream>
//using namespace std;
//class b {
//public:
// b(int a) {
// this->a = a;
// };
// int a;
//};
//
//class a{
//public:
// a() :age(age),h1(20){
// this->h2 = new b(30);
// };
// a(int age):age(age), h1(20) {};
// a(a &h1) :age(10), h1(20) {}; // a h2=h1; a h3(h1); a h4[2]={h1,h2}
// a operator=(a h1) { return *this;}; //a h1;a h2; h1=h2
// ~a() {};
//
// static void xx() {};
// static int aa;
//
// void yy()const {};
// const int age=20;
// b h1;// 组合
// b* h2;//聚合
//
//private:
//};
//int a::aa = 100;
//除了“构造函数”和“析构函数”,
//父类的所有成员函数,以及数据成员,都会被子类继承!
//public 继承全不变
//private 继承全变私
//protected继承只把public降级为protected
/*
子类型
Son yangGuo;
Father* f = &yangGuo;
Father& f2 = yangGuo;
Father f1 = yangGuo;
*/
//#include <string>
//#include <sstream>
//#include <iostream>
//using namespace std;
//
//class Father //虚基类
//{
//public:
// Father(int age) {
// this->age = age;
// };
// void xx() { cout << "aaaaaaa" << endl; };
// ~Father() {};
//private:
// int age;
//};
//
//class Son : virtual public Father { //虚继承 相同的数据只保存一份
//public:
// Son(int age, const char* game) : Father(age) {
// this->game = game;
// };
// void xx() { cout << "bbbbbbb" << endl; };
// ~Son() {};
//private:
// string game;
//};
//void text(Father a) {
// a.xx();
//}
//
//int main(void) {
// Father h1(10);
// Son h2(10,"xx");
// text(h1);
// text(h2);
// system("pause");
// return 0;
//}
/*
ifstream 读文件
ofstream 写文件
fstream 对文件读写
"\t" 空格
ofstream f1; //写文件
f1.open("xxx.txt");
f1.is_open();
f1 << name << "\t";
stringstream s;
s << "name:" << name << endl;
f1 << s.str();
f1.close();
ifstream f2; //读文件
f2.beg 相对于开始位置
f2.cur 相对于当前位置
f2.end 相对于结束位置
f2.seekg(-50, f1.end);//指定位置
f2.tellg();//距离文件的起始位置的偏移量
f2.seekp(4, f2.beg);//指定位置写入
f2.open("xx.txt");
getline(f2, line);
sscanf_s(line.c_str(), "姓名:%s 年龄:%d",
name,sizeof(name), &age);
f2.eof();
f2>> age;
f2.close();
*/
//友元
//#include <iostream>
//using namespace std;
//class A;
//class B {
//public:
// void func(A& a);
//};
//class A {
//public:
// friend void B::func(A& a);//类的成员函数作为友元
// friend void upgrade(A* c);//全局函数作为友元函数
// friend class C; //友元类
//private:
// int value = 10;
//};
//void B::func(A& a) {
// cout << a.value << endl;
//}
//void upgrade(A* c) {
// c->value = 100;
//}
//运算符重载
//#include <sstream>
//#include <iostream>
//using namespace std;
//class A;
//class B;
//
//class C
//{
//public:
// C(int weight) { //C c3 = 100;
// this->weight = weight;
// };
// operator const char* () const;//const char *a =C c3;
// A operator+(const C& cow);
// A operator=(const C& cow);
// bool operator>(const C& boy);
// int operator[](std::string index);
// ostream& operator<<(ostream& os) const;
// friend ostream& operator<<(ostream& os, const C& boy);
// friend A operator+(const C& cow1, const C& cow2);
//private:
// int weight = 0;
//};
//class A
//{
//public:
// A(int weight) {
// this->weight = weight;
// };
//private:
// int weight = 0;
//};
//ostream& operator<<(ostream& os, const C& boy)
//{
// os << "xxxxxxxxxx" << endl;
// return os;
//}
//A operator+(const C& cow1, const C& cow2)
//{
// int tmp = (cow1.weight + cow2.weight) * 2;
// return A(tmp);
//}
//A C::operator+(const C& cow)
//{
// int tmp = (this->weight + cow.weight) * 2;
// return A(tmp);
//}
//A C::operator=(const C& cow) {
// int tmp = (this->weight + cow.weight) * 2;
// return A(tmp);
//};
//bool C::operator>(const C& boy) {
// if (this->weight > boy.weight) {
// true;
// }
// else { return false; }
//};
//int C::operator[](std::string index) {
// if (index == "weight") {
// return weight;
// }
//};
//ostream& C::operator<<(ostream& os) const
//{
// os << "ID: aaaaaaaa:" << endl;
// return os;
//}
//
//C::operator const char* () const
//{
// return "xxx";
//}
//int main(void) {
// C c1(100);
// C c2(200);
// A p = c1 + c2;
// C c3 = 100;
// const char* a = c3;
// system("pause");
// return 0;
//}
//多态
//多态的本质:
//形式上,使用统一的父类指针做一般性处理,
//但是实际执行时,这个指针可能指向子类对象,
//形式上,原本调用父类的方法,但是实际上会调用子类的同名方法。
//#include <iostream>
//using namespace std;
//
//class A {
//public:
// virtual void play() { //
// cout << "到KTV唱歌..." << endl;
// }
// virtual void xxx() final { //不能从写xxx 只修饰虚函数
// }
// virtual float area() = 0;//纯虚函数不能创建对象
// virtual ~A() {};
//};
//
//class B final :public A {//final 下面的类不能继承B
//public:
// virtual void play()override {
// cout << "一起打王者吧!" << endl;
// }
// virtual float area()override {};
//};
//int main(void) {
//
// return 0;
//}