C++基础知识

赋值和运算

进制 | 表达方式 | 例子
二进制 | 0b + 二进制 + 后缀 |
八进制 | 0 + 八进制数 + 后缀 |
十进制 | 十进制数 + 后缀 |
十六进制 | 0x + 十六进制数 + 后缀 |
| |

后缀：

L/l：表示long型

LL/ll：表示long long型

U/u：表示 unsigned型

类型转换

顺序：

long double

double

float

unsigned long long

long long

unsigned long

long

unsigned int

int

字符

字符数据类型

类型 | 内存占用 | 说明 | 示例
char | 1 | Ascii 字符 |
wchart_t | 2/4 | 宽字节字符 | wchar_t wcharA{L'A'};
char16_t | 2 | utf_16 字符 | char16_t wchar16{u'A'};
char32_t | 4 | utf_32 字符 | char32_t wchar32{U'A'};
| | |

类型推断

Copy
// a变量的类型是float
auto a{1.0f}

// 可以使用typeid(a).name()输出来来查看

格式化输出

方法 | 说明
std::fixed | 以小数点模式输出浮点数
std::scientific | 以科学计数法输出小数
std::defaultfloat | 恢复默认小数输出
std::setprecision(int) | 设置小数精度
std::dec | 十进制输出数字
std::hex | 十六进制输出数字
std::oct | 八进制输出数字
std::showbase | 十六进制和八进制显示前缀
std::shownobase | 十六进制和八进制不显示前缀
std::setw(int) | 把输出内容设置成指定宽度输出
std::setfill(char) | 当显示宽度查过字符宽度时，用指定的字符串填充剩余内容
std::left | 设置字符左对齐
std::right | 设置字符右对齐

其中红色方法需要引入头文件iomanip

转义

运算优先级

运算符 | 关联性
() [] -> . 后缀 ++ 后缀 -- typeid const_cast dynamic_cast static_cast reinterpret_cast | 表达式从左往右
! ~ 一元 + 一元 -- 前缀 ++ 前缀 -- & * （类型) sizeof new new [] delete delete [] | 表达式从左往右
.* 0>* | 表达式从右往左
* / % | 表达式从左往右
+ - | 表达式从左往右
<< >> | 表达式从左往右
< <= > >= | 表达式从左往右
== != | 表达式从左往右
& | 表达式从左往右
^ | 表达式从左往右
| | 表达式从左往右
&& | 表达式从左往右
|| | 表达式从左往右
? : op= | 表达式从右往左
throw | 表达式从右往左
. | 表达式从左往右

字符编码

枚举

代码示例：

Copy
// 基本类型只能是整形 int short
enum class 类型名称:基本类型
{
类型1
}

// 基本类型写默认是int
// 不赋值默认是从0开始
enum class EquipLv {
normal,
high,
rare,
epic,
legend,
myth
};

enum class EquipLv {
normal=100,
high,
rare,
epic,
legend,
myth=1000
};

// 使用
EquipLv weaponeCLV{ EquipLv::normal };
EquipLv weaponeDLV{ EquipLv::legend };

枚举类型总结：

枚举类型可以提高代码的可读性和安全性。

枚举类型默认是 int 类型。

枚举类型的成员只能是整数类型。

枚举类型和其他类型转换需要强制转换。

默认情况下，枚举类型的下一个项的初始值是上一项的初始值 + 1。

自定义类型名称

给类型名称改名的方式：(TypeName 被替换为 A)

#define TypeName A

typedef TypeName A

using A = Typename

命名空间

using namespace

变量生命周期

代码块中的变量的生命从声明开始，直到这个代码块结束。

声明在代码开始前的变量叫做全局变量，全局变量的生命是从程序运行开始的，一直到程序结束。

在变量名冲突的分情况下，采用就近原则

要访问名称冲突的全局变量，可以使用限定符：：来访问

自定义数据类型

结构体的本质是按照我们自己的方式定义一块连续的内存结构

声明一个结构体变量的本质是像计算机申请一块内存，而这块内存的大小至少是我们定义的结构成员需要占用的内存之和（内存对齐）

使用结构体则是按照我们定义好的方式从这块内存读取和写入数据。

位运算

输出二进制内容

引入bitset头文件

std::bitset<需要显示的二进制位数>(要显示的变量)

Copy
#include<iostream>
#include<bitset>
int main() {
int a{(int) 0b11111101111111101111111 };
std::cout << std::bitset<32>(a);
return 0;
}

00000000011111101111111101111111
D:\project\cpp\demo1\Debug\demo1.exe (process 75568) exited with code 0.
Press any key to close this window . . .

左移

<<

右移

>>

带符号的数右移的时候，最高位用符号位 补齐

取反

~

与运算

&

或运算

|

异或运算

^

关系运算符

关系运算符 | 说明
> | 大于
< | 小于
== | 等于
>= | 大于等于
<= | 小于等于
!= | 不等于

逻辑运算符号

运算符 | 名称 | 说明

&&

逻辑与

1. 注意和位运算符 & 的区别
2. 操作数都为 true 的时候，表达式为 true

||

逻辑与

1. 注意和位运算符 | 的区别
2. 操作数中有一个为 true，表达式为 true

!

逻辑非

1. 注意和位运算符～的区别
2. 操作数为 false 时 表达式为 true

注意：

一元运算符的优先级高于二元运算符

位运算的优先级高于逻辑运算

~! > & > |

数值在逻辑运算中的本质是吧数值转换成 boolean 值，再进行逻辑运算

字符串处理

字符串处理函数（cctype 头文件）

函数 | 说明
int isupper(char) | 判断字符是否是大写字母
int islower(char) | 判断字符是否为小写字母
int isalpha(char) | 判断字符是否为字母
int isdigit(char) | 判断字符是否是数字
int isalnum(char) | 判断字符是否是字母或者数字
int isspace(char) | 判断字符是否是空白
int isblank(char) | 判断字符是否是空格
int ispunct(char) | 判断字符是否是标点符号
int isprint(char) | 判断字符是否是可打印字符
int iscntrl(char) | 判断字符是否是控制字符
int isgraph(char) | 判断字符是否是图形个字符
int tolower(char) | 将字符转换为小写
int toupper(char) | 将字符转换为大写

语句块的中变量

C++17 新语法

Copy
if(变量生命; 条件)
{

}
else
{

}

格式化流输出以及转义

printf

参数 | 说明
d | 十进制数
o | 八进制数
u | 无符号十进制数
x/X | 十六进制整数
f | float 小数
lf | double 小数
s | 字符串
0 | 用 0 来补齐
+ | 替数字输出

无显示的输入

控制台不会显示输入的内容。

头文件需要引入 <conio.h>

int _getch();

Copy
#include<iostream>
#include<conio.h>
int main() {
int a = _getch();
printf("输入的字符是： %d", a);
return 0;
}

goto

Copy
#include<iostream>
int main() {
char a;
rep:
printf("请输入一个大写字母： ");
std::cin >> a;
if (a > 64 && a < 91 )
{
a += 32;
}
else
{
goto rep;
}
return 0;
}

数组本质

一维数组的本质是按照所申请的数据类型，想操作系统申请了一段连续的内存空间

多维数组的本质也是想操作系统申请一块连续的内存，一般来讲是按照低维度有线排序的方式来排序（可能因为操作系统和编译器的不同而不同）而索引只是为了方便访问对应的额你村区域

一维数组

定义方式：

数据类型名 数组名[常量表达式];

初始化方式：

Copy
int a[10] = {0,1,2,3,4,5,6,7,8,9};

二维数组

定义方式：

数据类型名 数组名[常量表达式1][常量表达式2];

初始化方式：

Copy
// 全部定义在大括号内
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
// 可以省略一维长度
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

// 对部分元素赋值
int a[3][4] = {{1},{5},{9}};

基于数组的循环

Copy
#include<iostream>
int main() {
int a[4] = { 3, 4, 2, 7 };
// 第一种方式
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
std::cout << a[i] << std::endl;
}

// 第二种方式
// 数据类型可以写成auto
for(int value :a)
{
std::cout << value << std::endl;
}

return 0;
}

std::array

原生数组 + 额外功能

语法：

std::array<变量类型, 元素数量> 变量名

如：std::array<int, 5> studentId;

常见用法：

Copy
// 返回studentId的元素个数
studentId.size();
// 设置studentId中所有的元素为250
studentId.fill(250);
// 返回studentId[1]的内容，越界会报错
studentId.at(1);

std::vector

语法：

std::vector<数据类型> 变量名

如：

std::vector<int> studentId

常用方法：

Copy
// 初始化一个vector元素为1,2,3
std::vector<int> studentId{1,2,3};

// 设置这个vector拥有5个元素
std::vector<int> studentId(5);

// 设置这个额vector拥有5个元素，并且初始化为100
std::vector<int> studentId(5, 100);

常用方法：

std::array中的方法 std::vector基本都可以使用

Copy
// 将值添加到vector中
studentId.push_back(值);

// 将studentId重新初始化拥有10个元素，每个元素为100
studentId.assign(10, 100);

// 将studentId清空
studentId.clear();

// 判断studentId是否是空的
studentId.emtpty();

输入

C 语言

Copy
char str[0xff];
scanf("%s", str);

wchar_t wstr[0xff];
wscanf(L"%s", wstr);

Copy

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
int main()
{
const char* username[10];
printf("请输入您的名字：");
scanf("%s", &username);

printf("\n您的名字是: %s\n", username);

// 宽字符
setlocale(LC_ALL, "chs");
wchar_t* w_username = new wchar_t[5];
printf("【宽字符】请输入您的名字：");
wscanf(L"%s", &username);
wprintf(L"\n【宽字符】您的名字是: %s\n", username);

return 0;
}

字符长度

strlen()

宽字符求长度：

wslen()