本篇目录
一、通用设置
1.1 基本概念
-
内存概念
名称 意义 位(bit) 计算机物理存储基本单位,可以看做电子开关,关(0),开(1) 字节(Byte) 计算机内存使用的最小单位,1 Byte = 8 bit,1字节可表示256个数(2的8次方),对应ASCII码 常规存储 1GB = 1024MB = 1024x1024 KB = 1024X1024X1024 B = 1024^3 * 8bit -
变量命名规则
关键字 规则 变量前缀 s(字符串)、c(单个字符)、p(指针)、b(布尔值)、无(整形、浮点型);例: pmy_num
大小写 类名 MyClass()
、函数myFunction
、普通变量名:my_num
常量 大写 MY_NUM
-
强制类形转换
关键字 说明 static_cast 常规:编译期间转换,一般不会导致意外发生,风险很低 const_cast 常规:用于 const 与非 const、volatile 与非 volatile之间的转换 reinterpret_cast 高危:这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换 dynamic_cast 进阶:程序运行期间借助 RTTI 进行类型转换,用于类型安全的向下转型(Downcasting)
1.2 强制类型转换
- 常用初级转换(其他的进阶了再学)
// C 风格的强制类型转换,C++ 中编译器渐渐不支持了 double scores = 95.5; int n = (int)scores; // C++ 风格写法,功能同上 double scores = 95.5; int n = static_cast<int>(scores);
超界:默认超界会产生不可预知错误
二、数字
2.1 整型、浮点型、const限定符
-
整形
名称 范围 unsigned short型 2字节,(-215) ~ (215 -1),3万级别 16比特,第一比特是符号位,unsigned short:没有负数,范围扩大一倍,无符号位 int型 4字节,(-231) ~ (231 -1),,21亿级别 unsigned:没有负数,范围扩大一倍 long型 同上 同上 long long型 8字节,(-263) ~ (263 -1),,9百万兆级别 unsigned long long:没有负数,范围扩大一倍 -
浮点型
名称 范围 写法 float型 上限极值:3.40282e38
下限极值:1.17549e-38标准用法: float num = 3.1415926f
科学计数法:3.14159e10f
double型 上限极值:1.79769e308
下限极值:2.22507e-308标准小数型: double num = 3.1415926
科学计数法型:3.14159e10
-
以上两者写法
// 定义:type 变量名; int n; double dn; // 赋值 n = 3; dn = 3.14; // 定义、初始化:type 变量名 = 值; int n = 3; double dn = 3.14;
-
const限定符
// 常量必须定义同时初始化,且相应生命周期内不可改变 // 限定符只在仅在执行改变常量的操作时才会发挥作用 // 写法:const type 常量名 = 值; const int n = 3; const double dn = 3.14;
2.2 C++内置函数声明
- 列表
写法 参数解释 double cos(double)
形参是弧度值,返回值为余弦值(浮点型),sin、tan同样 double log(double)
返回参数的自然对数(浮点型) double pow(double, double)
假设首参数为x,次参数为y,返回x的y次方(浮点型) double sqrt(double)
返回参数的平方根(浮点型) int abs(int)
返回整数的绝对值(整型) double round(double)
四舍五入,返回浮点型,3.5=>4.0 double floor(double)
向下取整,3.5=>3.0 double ceil(double)
向上取整,3.5=>4.0
2.3 生成随机数
- 代码示例
#include <iostream> // time()函数显示现在到1970年1月1日午夜的秒数(int) #include <ctime> // 随机函数的头文件 #include <cstdlib> using namespace std; int main() { /* strand()为种子函数,相同的种子,生成的随机数相同, 每次运行用time()函数初始化种子函数,放入内存中 */ srand(time(NULL)); for (int i = 0; i <= 7; i++) { /* 1、rand()产生一个随机整数:若种子相同,序列顺序及值也相同, 在0~(int)RAND_MAX之间 2、自定义随机数区间:6是随机集合整数的个数,-3是起始整数, 代表-3~2,注意包含0 */ int y = rand() % 6 - 3; cout << y << endl; } }
四、数组及枚举
4.1 数组
- 定义
// 定义、初始化:大括号只可在此初始化情况下用 // 二选一:不可重复定义 int num_arr[3] = {10, 30, 40}; int num_arr[3] = {}; // 定义 int num_arr[3]; // 赋值:为单个元素赋值,序号为0、1、2 num_arr[2] = 40;
- 长度计算(sizeof 函数)
// 显示数组占用的内存总长:12字节 int size_of_array = sizeof(num_arr); // 显示其中一个元素占用的长度(每个占用的都一样):4字节 int size_of_element = sizeof(num_arr[1]); // 相除,得有几个元素:3个 int num = size_of_array / size_of_element ;
- 指针前导(具体看指针篇)
int arr[3] = {1,3,5}; int * pt, * pt_1; // pt指向数组的第一个元素的首地址 pt = arr; // pt_1指向数组第二个元素的地址 pt_1 = &arr[1]; // 打印数组第一个元素的值:1 cout << *arr << endl;
4.2 枚举(类似批量const功能)
- 初始化
// 以下二选一,不可重复定义 // enum叫枚举型,elist 叫枚举,red为符号常量,0为枚举值 enum elist {red, yellow, blue, orange}; // 其值为 0 1 2 3 enum elist {red = 2, yellow = 0, blue, orange}; // 其值为 2 0 1 2
- 赋值
// 以下二选一,不可重复定义 // 枚举变量的定义、初始化,不可用 band = 2,也不可加减 elist band = blue; // 枚举变量定义 elist band_2; // 赋值方法一: band_2 = band; // 赋值方法二: // 此方法是选择值为2的符号常量,即blue赋给band_2 band_2 = elist(2); // 输出枚举值:整型,结果为2 cout << band_2 << endl;
五、字符类
5.1 C风格字符串
-
字符(相当于下面一个格子)
名称 范围 char型 1字节存储一个字符,单字节字符,局限性最大,能表示256个字符 wchar_t型 2字节存储一个字符,宽字节字符,老版本 char_16型 2字节存储一个字符,unicode字符 char_32型 4字节存储一个字符,unicode字符 编码:字节里存整型,每个数字对应一个字符,其映射表刻在cpu中。
局限:char只能应用于英语国家,宽字节及unicode编码用于世界各国。 -
以下是 C/C++ 中定义的字符串的内存表示:
-
本质:C风格字符串本质为字符数组,变量名为数组首元素的地址(指针篇详解)
5.1.1 初始化
- 写法
// 内存存储:'1'、'2'、'3'、'\0'、'\0',内存浪费 char charr_1[5] = "123"; // 内存存储:'1'、'2'、'3'、'\0',刚刚好 char charr_2[4] = "123"; // 内存存储:'1'、'2'、'\t'、'3'、'\0',刚刚好 char charr_3[5] = "12\t3"; // 报错:数组界限溢出 char charr_4[3] = "123"; // 编译器自动选择合适数组位数,同charr_2 char charr_5[] = "123"; // 在Unicode中常会被用到,使用方法相同 wchar_t title[] = L"宽字符串";
- 末尾隐式追加:’\0’会自动隐式的添加到字符数组尾,显示定义数组位数时需注意
- wchar_t:宽字符类型(老版本)
- 初始化字符变量:
wchar_t words = L'a';
- 输入输出字符串:
wcout << L"abcd" << endl;
,同理wcin
- 初始化字符变量:
- C++新增类型:
- 写法一:
char16_t ch1 = u'a';
- 写法二:
char32_t ch2 =U'a';
- 写法一:
5.1.2 常用方法
- 头文件:
#include <cstring>
,针对后缀有_s
方法 - 字符串赋值
char charr_0[3] = {}; char charr_1[5] = "abcd"; // 字符串指针初始化(看完指针篇回看) // "abcd"为字符串字面量,存储在只读内存区的字面量池中,因为只读 // 所以可以用const指针指向此字符串字面量值 const char * charr_n = "cdefg"; // 常规方法:直接赋值字符串,注意跟初始化区别,这是深拷贝 strcpy(charr_0, "ef"); // 方法1:将charr_1复制给charr_0,控制2个字符(自动追加\0),若超则报错 strcpy_s(charr_0,2,charr_1); //方法2:起始复制--将charr_1取出2个字符复制给charr_0,若超出则报错 strncpy_s(charr_0, 3, charr_1, 2); // 手动尾部追加\0 charr_0[2] = '\0'; // 方法2:非起始复制--从charr_1第2个字符起复制3个字符给charr_0,即"bcd" // sizeof为C++关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小 strncpy_s(charr_0, sizeof(charr_0), charr_1+1, 3);
此处涉及到数组指针相关,建议看完指针回看
strcpy_s:是strcpy的安全版本,新的C++编译器强制使用这个,strcat同
strncpy的原型为:char * strncpy(char * str2, char * str1, int size); - 拼接、长度、比较
// 将charr_1追加到charr_0尾部,且总长不超过10,程序员控制charr_0的长度 strncat(charr_0, charr_1, 3); // 字符数组长度,不包含'\0',但字符数组尾部至少有一个格子存\0 int num = strlen(charr_1); // 比较两个字符串,实参为字符串指针: // 若返回负数,a,b为正序 // 若返回正数,a,b为逆序 if (strcmp(a, b) == 0) cout << "两字符串相同" << endl;
5.2 string类库
5.2.1 基础操作
- 调用文件
- 头文件:
#include<string>
- 名称空间:
using namespace std;
- 头文件:
- 初始化、赋值
// 常规初始化 string str_1 = "123"; // 默认为空 string str_2; // 拷贝赋值:str_3为str_1的副本,两个值隔离 string str_3(str_1); // 缩写法:“***” string str_4(3,'*'); // 赋值:区别于定义(初始化) str_4 = "123";
- 转换为char*
string str_3 = "help"; // 方法1:c_str函数返回的字符串字面量,即const char*类型 const char *c_1 = str_3.c_str(); // 方法2:const_cast:强制类型转换,去掉const属性,返回char*变量 char *c_2 = const_cast<char *>(str_3.c_str()); // 方法3:使用堆内存动态存储 char * c_3; c_3 = new char [str_3.size()+1]; strcpy (c_3, str_3.c_str()); // 下面错误赋值原因:因为c_str函数创建一个副本并赋值 // 随后副本被析构,temp指向垃圾内存,编译错误 char* temp; string s="1234"; // 错误:temp = s.c_str(); strcpy(temp, s.c_str());
函数字符串传递:形参定义为:const string & ,可以接收实参为: string,char * ,const char *,字符串字面值
- 字符串转string:可以直接赋值
const char * charr_n = "cdefg"; string str = charr_n;
- 计算
// 拼接,输出:123123 string str_3 = str_1 + str_2; // 拼接2:尾部附加 str_3 += "end"; // 字符串长度,不包含'\0' int num = str_3.size();
5.2.2 进阶操作
- 列表释义
写法 意义 cout << s; 直接在屏幕打印字符串 cin>>s1>>s2; 键盘连续赋值,可空格或enter区隔 getline(cin,s); 将一行输入string变量s中 s.empty(); 若s为空,返回true s.size(); 返回字符串字符个数 s[n]; 第n个字符,0开始 s1 + s2; 字符串拼接 s1 = s2; 赋值操作 s1 == s2 判断两字符串是否值相同
六、自定义组合类型
6.1 结构
- 定义:结构是用户定义的类型(模板),通过将一组简单的数据类型组合成一个新的数据类型
- 声明
// goods为特定的结构类型 struct goods { // 用于存储商品名称 char name[20]; // 用于存储商品个数 int store; // 用于存储产品单价 double price_per; }; // 分号很重要,别落了 struct goods { char name[20]; int store_num; double price_per; // 声明同时定义两个变量 } fruit_0,fruit_1;
注:可以放在函数外,全局可用,也可以在内部,仅当前函数内可用
- 赋值
// 定义、初始化 goods fruit_0 = {}; // fruit_1数据类型是goods结构,定义、初始化 goods fruit_1 = {"apple", 135, 4.5}; // 结构化数组,定义、初始化 goods food[3] = { {"rice", 123, 23.5}, {"bread", 503, 10.0}, {"egg", 1350, 13.5} }; // 注意结尾分号
- 调用
// 普通结构 cout << fruit_1.store << endl; // 结构列表 cout << food[2].price_per << endl;
6.2 共用体
- 定义:一种数据格式,能同时存储int,long或double,当数据项使用两种或多种格式(但不会同时使用),可节省空间
- 声明
// 方法1: // 可以用此语句块替换结构声明中的 int store; 行 union store { int int_store; double double_store; }; // 分号很重要 // 方法2:声明定义共用体,同时定义共用体变量 union store // 可以用此语句块替换结构声明中的 int store; 行 { int int_store; double double_store; } store_egg; // 分号很重要
- 赋值及调用
// 定义共用体变量store_egg store store_egg; // 变量赋值 store_egg.int_store = 1590;