C++基础

C++基础
M-YoungBWeNC++基础
基本数据类型
C++基本数据类型包括整型、字符型、浮点型、布尔型
基本整型
char 1字节(8位)
short 至少2字节(16位,2^16=65536)
int 至少2字节(16位,[-32768,32767]) unsigned int(16位,[0,65535])
long 至少4字节(32位)
long long (C++11) 至少8字节(64位)
tips:可以通过头文件
char是C++基本整型,字符串string不是基本数据类型,字符串使用std::string类,属于C++的标准库。
char本质是一个整数,由cin/cout处理字符流
char有无符号由C++判定 char/signed char/unsigned char
wchar_t是一种宽字符类型(2字节),原本的char为1字节,此时使用wcin/wcout处理字符流
C++新增char16_t(2字节)/char32_t(4字节)
1 | int a(12); |
1 | char a = 'A'; |
write(字符串地址,显示多少个字符)
1 | const char * a = "hello"; |
浮点型
float 至少4字节(32位) 3.1F/3.1f
double 至少6字节(48位) 通常为8字节64位
long double 至少6字节(48位) 通常为80/96/128位 3.1L/3.1l
tips:可以在头文件cfloat或float.h中查看限制
1 | // C++浮点数默认cout精度为6位,可使用ostream中precision成员函数指定精度 |
转译字符
1 | \n |
常量符号
const 常量限定符(signed/unsigned都是限定符)
1 | int a = 3; |
#define
复合数据类型
数组
C++/C将数组名视为指针(数组第一个元素的地址 &arr[0] ) 如果&arr则返回的是整个数组的地址
数组初始化
1 | int arr[] = {1, 2, 3, 4, 5}; |
在标准 C++ 里,数组的大小必须是一个常量/常量表达式
1 | const int size = 4; |
数组遍历
C++新特性–打印数组的方法
1 | for (declaration : range) { |
1 | int arr[] = {1, 2, 3, 4, 5}; |
获取数组大小
1 | int nums[] = { 1,2,3,4,5 }; |
指针指向数组的例子
1 | int arr1[] { 1,2,3 }; |
sizeof() 获取的是字节数,1字节(byte)等于8位(bit),1KB等于1024字节
字符串
C风格字符串
头文件为
1 | char a[5] = { 'y', 'o', 'u', 'n', 'g' }; |
字符串常量拼接
1 | cout << "mr_""young" << endl; |
C字符串标准库
strlen() 确定字符串长度 只计算可见字符
字符串输入
1 | char a[15]; |
cin使用空白(空格/换行/制表符)确定字符串输入结束
1 | char a[15]; |
面向行的字符串输入方法 get()/getline()
getline()会将换行符Enter转换为空字符\0 get()会读取换行符Enter
1 | char a[15]; |
1 | char a[15]; |
1 | char a[15]; |
一次读多行字符串
1 | char a[15]; |
空行问题 get()/getline()看到前一个队列中留下的换行符会把当前行认为是空行
1 | char a[15]; |
1 | char a[15]; |
strcpy(a,b) 将b赋值给a strncpy()
strcat(a,b) 将b加到a的尾部 strncat()
C++ string类
string包含在std中,可以使用
与char数组的区别:string可以声明为简单变量而不是数组;string可以将一个string赋值给另一个string而不必在意字符串大小;string简化了字符串拼接(不需要使用cstring函数即可快速完成对字符串的操作)
1 | string a = "mryoung"; |
a.size() string确定字符串长度,在这里a是一个string对象size()是一个类方法,而strlen(b)是一个函数b是一个变量 只计算可见字符
1 | string a ="young"; |
C++字符串初始化
1 | char a[] { "young" }; |
C++字符串输入
直接cin输入与C风格字符串基本无异
1 | string b; |
读取一行 getline(cin,a)这个并非istream的类方法,istream没有处理string的类方法
1 | string a; |
原始字符串
通过 “( 和 )” 来界定原始字符串
1 | cout << R"(\0 \ \t)" << endl; |
结构
声明、定义、使用
1 | struct inflatable{ |
结构通常在mian外部声明,在main内部声明只能被main使用而其他函数无法使用(例如main2无法使用在main内部声明的结构) 外部定义的结构的变量是共享的变量,内部则为私有。
1 |
|
结构数组
结构数组与基本类型数组完全相同
1 | inflatable a[10]; |
结构位字段
位字段:以位为单位来指定一个成员所占用的内存空间
1 | unsigned int flag1 : 4; // 4bit |
共用体
union用于节省内存空间
共用体的所有成员共享同一块内存空间,而结构体的每个成员都有独立的内存空间
枚举
枚举有严格的限制
逻辑运算
与 &&
或 ||
非 !
异或 ^
同或 !(a^b)
例题:https://leetcode.cn/problems/xor-operation-in-an-array
内存模型和命名空间
new(运算符) 动态分配内存(自由存储/堆) delete(运算符) 释放
static(关键字) 静态存储
#include
头文件 <head.h>会在标准库中查找 "head.h"会先在当前工作目录或代码目录查找
#ifndef (if not defined) #endif 避免重复定义头文件
1 |
|
自动变量存储在栈中
动态分配内存
new/delete
1 | int* ptr = new int(10); |
智能指针
函数
函数基础
定义、函数原型、调用
函数分为无返回值函数(void)、有返回值函数
函数返回值类型不能是数组
1 | void f1(); // 函数原型 |
函数使用指针处理数组
1 | void f3(int arr[],char a); |
Tips:直接传递数组名时,函数访问的是原本数组;而将数组封装在类或结构体中按值传递时,函数访问的是副本
1 | void show_arr(const int arr[],int n); |
数组区间函数
1 | int sum_arr(const int* begin, int* end); |
函数指针
函数指针,恐怖如斯
1 | int f1(int); // 返回值为int |
标准库函数
strlen() 确定C风格字符串长度
函数探幽
内联函数
用内存换速度 内敛函数使用内敛代码替换函数调用从而节省了函数调用花费的时间但是会占用较多内存
内敛函数为C++新增,原始实现为C的宏#define 但是宏无法按值传递,如果宏执行了类似函数的功能应当将其替换为内联函数
内联函数不能递归
1 | inline double a(double x){return x*x;}; |
引用变量
必须在声明引用变量时初始化,引用更类似于const指针(也可以说是const指针的伪装表示)
1 | int a = 1; |
引用不是原来变量的副本
1 | int a = 1; |
C++允许按引用传递参数,C只能按值传递参数(函数使用值的拷贝),C++按引用传递可以访问调用函数中的变量
1 | void f(int & a,int & b); |
函数重载
允许使用多个同名函数 允许重载的关键是函数的参数列表
函数重载不区分const和非const变量
函数模板
用来创建通用函数 类似蓝图或公式
用于生成可以处理相同逻辑不同数据类型的函数
关键字template、typename,函数名可以随意(AnyType) 模板不创建函数而是告诉编译器如何定义函数
1 | template <typename AnyType> |
并非所以的模板参数都必须是泛型(AnyType)
1 | template <typename AnyType> |
重载的模板
1 | template <class T> |
具体化包括 显式实例化、隐式实例化、显式具体化 相同之处在于,它们表示的是使用具体类型的函数定义而不是通用描述
显示具体化
非模板 > 显示具体化 > 模板化
1 | template<> void f<int>(int,int); |
显式实例化
1 | template void f<int>(int,int); |
模板函数
模板函数是函数模板经过实例化后得到的具体函数
模板函数中的数据类型
1 | template <class T1,class T2> |
模板函数中的返回值类型
使用后置返回类型
1 | template <class T1,class T2> |
C++ 标准库
std::
加上using namespace std;可以直接使用 cout 和 endl,无需写 std::
1 | cout << "Hello, World!" << endl; |
std 指的是标准命名空间(Standard Namespace)。使用 using 声明可以将 std 命名空间中的某个特定标识符引入到当前作用域
ostream(类)
成员函数(方法) put()/write()
成员函数(方法) width() 调整字段宽度 只影响接下来被显示的一个项目
1 | int w = cout.width();//字段宽度默认为0 |
成员函数(方法) fill() 填充字符 cout默认空格填充,cout.fill(‘*’)可指定填充字符 只影响接下来所有项目
1 | cout.fill('*'); |
成员函数(方法) precision() 设置浮点数精度
1 | float a = 0.123456789; |
控制符std::endl 换行、刷新输出缓冲区
控制符std::flush 刷新输出缓冲区(与endl刷新功能类似)
控制符dec/hex/oct
1 | int a = 10; |
istream(类)
对象 cin
方法 getline()/get()
数学
逻辑运算符
C++运算符:https://www.runoob.com/cplusplus/cpp-operators.html
与 全为真则为真 ∧
或 存在真则为真 ∨
同或 输入相同则为真
异或 输入不同则为真
非 取反
与非 与后对结果取非
或非 或后对结果取非
蕴含 https://www.bilibili.com/video/BV1Tf421Z7g3
VS2022基础
创建空项目
生成解决方案文件、项目配置文件
解决方案文件
.sln(Visual Studio Solution):通过为环境提供对项目、项目项和解决方案项在磁盘上位置的引用,可将它们组织到解决方案中。比如生成 Debug 模式还是 Release 模式,是通用 CPU 还是专用的等设置信息也包含其中。该文件可以在开发小组的开发人员之间共享。
.suo(Solution User Operation):解决方案用户选项,记录所有将与解决方案建立关联的选项,以便在每次打开时,它都包含用户所做的自定义设置,如 VS 布局、断点信息以及项目最后编译但未关掉的文件等。.suo 文件是用户特定的文件,不能在开发人员之间共享。
.sdf(SQL Server Compact Edition Database File):工程的信息保存成的数据库文件,用于提供代码自动提示功能和跳转功能。如果没有参加大型团队项目,不涉及高深的调试过程,这个文件用处不大,可以放心删除。若之后又需要,打开工程里的 .sln 文件重新编译链接即可。
项目配置文件
.vcxproj:真正的项目配置文件,以标准 XML 格式记录工程的所有配置,如包含的文件名、定义的宏、包含的头文件地址、包含的库名称和地址、系统的种类等,还可使用过滤条件决定配置是否有效。
.vcxproj.filters:项目下文件的虚拟目录,用于在打开 Visual Studio 时组织显示项目模块的划分。
.vcxproj.user:用户配置文件,用于保存用户个人的数据,如配置 debug 的环境 PATH 等。
.props:属性表文件,用于保存一些配置,可根据需求导入到项目中使用,使用起来很灵活,比如使用开源库时,可将相关配置保存起来,每次新建项目将配置加进来,避免重复配置。
其他文件
源文件(如 .c、.cpp 等):包含项目的源代码,实现项目的具体功能逻辑。
头文件(如 .h):包含函数、类、变量等的声明,用于在多个源文件之间共享声明信息,方便代码的组织和复用。
资源文件(如 .rc):用于存储项目所需的资源,如图标、菜单、对话框等。这些资源可以在程序中通过代码进行加载和使用,以提供更好的用户界面和交互体验。