Nuru_Banmian
Nuru_Banmian
Published on 2025-03-22 / 77 Visits
1
0

C++学习笔记

C++代码标准格式

 #include "iostream"
 #include "windows.h"                                    //用来正常输出中文字符
 using namespace std;
 ​
 int main()
 {
     SetConsoleOutputCP(CP_UTF8);            //和上方引入的库组合使用
     system(Command:"chcp 65001");                       //或者上面两句都不要,直接使用本行的代码
 //前一种方法多一行,后面一种方法运行的时候会多输出一句话
 /*
  *
  *  想要实现的功能代码
  *
  */
     return 0;
 }

一些好用的快捷键

shift+alt+↑/↓ 控制当行上下移动

ctrl+D 复制当前行 // 怎么和blender的复制一样(bushi)

home/end 移动到头/尾

ctrl+←/→ 左右跳单词

ctrl+a 全选


cout打印输出

cout打印输出一般为

 cout << "文字" << endl;
 cout << 1 << endl;
 cout << "文字" << 1 << endl;

观察以上代码可知,文字必须使用 " " 收纳,而纯数字可以直接使用

endl起到换行作用,可以根据需求选择是否填写

避免数字以科学计数法的形式输出的小操作:

 cout << fixed;              // 设置为小数显示
 cout.width(wide:20);        // 设置显示的最大宽度(最大位数)
 /* float只提供前7位的准确输出
  * 如1234567890输出为1234567936.000000
  * 如1.234567890输出为1.234568
  * 第二个例子中,因为小数点也占一位,所以小数后面精确输出了5位
  */

其他浮点数的精确输出位数变量类型

cin数据输入

例子:

 int num;
 cout << "请输入整数:" << endl;
 cin >> num;
 cout << num << endl;

代码注释

单行注释

 // 此为单行注释

多行注释

 /* 此为
  * 多行
  * 注释
  */

标识符

其实就是变量的名字?

标识符命名规则

硬规则:

  1. 只允许字母, 数字和下划线的组合

  2. 数字不可开头

  3. 不能使用关键字(计算机语言已经征用的名字)

软规则:

  1. 符号常量中,如有使用英文字母,应全部大写

  2. 变量中,如有使用英文字母,不应全部大写


常量

字面常量

类型

整形字面常量: 整数

实形字面常量: 小数

字符型字面常量: 单字符,用 ' ' 包围的

字符串字面常量: 字符串,用 " " 包围的 //这都有讲究?

符号常量

定义语法

 #define 标识符(名称) 常量
 //例子
 #define FAT_BMI 28

数字常量知识点

常量类型的确定使用sizeof()函数

常量后面带有后缀可以限定他的类型

后缀

含义

U

表示无符号数

L

整数long类型,浮点数long double类型

UL

unsigned long类型

ULL

unsigned long long类型

F

float类型

D

double类型

一般来说,字面常量会由计算机自动选择,优先度为:

int -> uint -> long -> ulong -> long long -> u long long

浮点数默认为double,不够用时会自动扩充为long double,因此想要让他限定为float形式,需要加后缀来达成目的

字符串常量知识点

char类型

有有符号,无符号类型

无法储存汉字(但是有方法)

因为时使用ASCII的储存方式,所以可以进行一下操作转义字符

 char ch1 = 65;          
 cout << ch1 << endl;        //打印输出为A
 char ch2 = 'a';
 cout << ch2 + 1 << endl;    //打印输出为98
 char ch3 = 'a' + 1;
 cout << ch3 << endl;        //打印输出为c

打印字符非打印控制字符

非打印控制字符

指一些无法打印出来,但是可以用于表示各种控制功能,如换行,制表等的字符

非打印控制字符.png

一般经常使用到的已经使用红色方框框出

字符串
一般格式
// C语言风格字符串
char a[] = "你好呀";	//字符数组形式
char *b = "你好呀";	//指针形式
// C++风格字符串
string c = "你好呀";
字符串的拼接

可以使用" + "进行直接拼接,但是只适用于字符串之间

string name = "andy";
int age = 22;
string major = "计算机";
double height = 179.25;
string all_msg = "我是" + name + "年龄为" + to_string(age) + "专业是" + major + "身高" + to_string(height);

变量

储存数据的载体

先申明再使用

声明

变量类型+ 变量名(标识符)

变量类型

  • short

  • int

  • long

  • long long

  • float (6~7位精度)

  • double (15~16位精度)

  • long double (18~19位精度) //好像不是很必要说实话

  • char

  • string

    如想使用无符号类型的,变量声明时,前面加上' unsigned '或者' u_ '即可,有符号的前面可以加上signed,写了和空着都是有有符号类型的,这段文字的使用说明只能在整数形式的变量类型上面使用

赋值

变量名 = 变量值

同时多次声明和赋值

int a, b, c

int a = 1, b = 2, c = 3;

布尔型

字面量只有两个:

true,false

//先声明,再使用
bool flag0 = true;
bool flag1 = false;

运算符

  • 算术运算符

  • 赋值运算符

  • 比较运算符

  • 逻辑运算符

  • 位运算符

  • ...

算数运算符

算数运算符.png

赋值运算符

赋值运算符.png

比较运算符

进行比较,得到bool型结果

比较运算符.png

逻辑运算符

逻辑运算符.png

三元运算符

语法:num1 > num2? "A" : "B";

如果前面为真,输出"A",假则输出"B"

if逻辑判断

if (chose1)
{
 proccess;
}
else if (chose2)
{
 proccess;
}
else
{
 proccess;
}

switch控制语句

switch(expression){
 case expression_1:
     code;
     break;
 case expression_2:
     code;
     break;
 case expression_3:
     code;
     break;
//...
//...
 default:
     code;				// 没有任何case匹配的时候,执行此语句
}

expression为常量表达式,应当给予一个常量值

类型应当为整形(int, short, char)和枚举类型

此处的case中如果没有break;,代码会直接继续运行下一个case语句中的代码,直到遇到break或者将default中的代码也运行完

枚举类型

例子:

enum Season{
SPRING,		//SPRING = 3
SUMMER,
AUTUMN,
WINTER
};
// 默认情况下,从上到下其数值从0开始递增
// 如果给SPRING赋值了一个初始值,则其他数值的值会按着第一排的初始值开始递增

while循环语句

while (条件) {
    your_code = 1;
}

do
{
    your_code = 1;
}while(条件);

for循环语句

for (int i = 1; i <=5; i++)
{
    your_code = 1;
}
// for后面的几个元素都可以省略,但是不建议,而且不美观

// for循环顺序提取数组内的元素的方法
int sample[] = {1, 2, 3, 4, 5, 6}
for (int element: sample)
{
    cout << element << endl;
}

循环语句中的continue和break

continue和break可以在循环语句中使用

  • continue的作用是跳过本次循环,直接进行下一次

  • break的作用是结束循环,即跳出循环

变量的作用域

{...}是一个代码块,也算是内部变量的作用域

在{...}内部申明的变量,可以在{}内被任何的地方被访问,但是{}之外无法被访问到

int main()
{
 int num1 = 10;

 if (1)
 {
     int num2 = 100;
     num1 += 1;
 }
 else
 {
     num1 +=2;
 }

 num2 +=2;			//<---由于这个元素在创建num2的代码块外面背访问,所以这一段代码有误
}

goto语句

// 创建标志
sample:
code;
code;

// 创建goto跳转
goto sample;
// 执行上段代码会让代码直接跳转到sample继续执行

数组

是由一批相同类型的元素的集合组成的数据结构,分配一块连续的内存来储存

特点:

  • 任意类型都可以创建数组

  • 数组大小固定(一旦定义完成,大小就固定) // 代码中不会做边界检查,超出数组范围编译过程中不会报错,运行时会有位置问题

  • 内存连续且有序

  • 元素可修改

  • 数组的第一个元素是一个指针,所以给指针类型的数赋值一个数组元素的时候不需要在数组名前面加上&来提取地址

//申明
int sample[6];
//sample为int类型,可以储存6个元素,编号从零开始
//赋值方法
sample[0] = 1;

//申明时可以直接赋值
int sample[] = {1, 2, 3, 4, 5, 6}

数组可以使用for循环逐个输出,详细请见for循环

字符数组

char s[] = "hello";
char s[] = {'h', 'e', 'l', 'l', 'o', '\0'}
// 第一个s的创建和第二个的一模一样,虽然第一个的s最后没有\0,但是创建完成的时候会自动加上,\0是一个终止符号
//所以s[6]不会报错

多维数组

//申明
int sample[n][n];
//申明同时赋值
int sample[3][3] = {{11, 22, 33},{44, 55, 66}, {77, 88, 99}}
//多维数组的申明同时赋值需要提供数组长度

//多维数组的遍历可以使用多层for循环或者while循环进行遍历

指针基础

基础

//先声明后赋值
int num = 10;
int * p;
p = &num;
/*----------------------------------------*/
//申明同时赋值
int num = 10;
int * p = &num;
/*----------&代表取变量内存的地址------------*/
/*----------------------------------------*/
cout << p;			//输出num变量的地址
cout << *p;			//输出num的值

动态内存分配

//新建普通变量空间和数组空间
int p1 = new int;
int p2 = new int[5];

*p1 = 10;

//下方两个赋值都是赋值到p2的0号空间中
*p2[0] = 1;
*p2 = 1;
//因为指针的位置在第一个元素上,所以效果一样

//下方同理
p2[1] = 2;
*(p2+1) = 2;

//删除普通变量空间和数组空间
delete p1;
delete[] p2;

//养成一个良好习惯:创建一个动态内存后先写delete函数释放空间,在中间写代码

指针悬挂

int *p1 = new int;
 int *p2 = p1;
 delete p1;
 //因为p2指针直接指向p1,但是p1被释放导致p2指向空,这种情况的p2指针就处于指针悬挂状态,此时使用p2会出问题

const指针

const int * p1;
 int const * p2;
 //这种const指针不能改 指针的数据 但是可以更改 指针的指向 ,const写到*前面即可创建

 int num = 10;

 int * const p3 = &num;
 //这种const指针不能改 指针的指向 但是可以更改 指针的数据 ,const写到*后面即可创建

 const int * const p4 = &num;
 //这种const指针的 指针的指向 和 指针的数据 都不能更改

 //后两个const指针创建的时候都需要同时赋值,因为创建完就不能更改指向

结构体

	//创建结构体基本结构
 struct Student
 {
     string name = "你好:)";
     int age = 18;
     string gender = "无";
 };
 //像这样提前赋值就相当于设定了一个默认值,不赋值的时候即为这个值
 //声明结构体变量,声明的前面可以不用带struct,但是带struck可以让代码易读
 //结构体变量赋值,里面赋值的顺序就是创建的结构体里面元素的顺序

 /*    基本结构体    */
 //方法一
 struct Student stu1;
 stu1 = {"絆面", 22, "男"};

 //方法二
 struct Student stu2 = {"你好", 19, "女"};

 /*    结构体数组    */
 //方法一
 struct Student stu_line1[3];
 stu_line1[0] = {"絆面", 18, "男"};
 stu_line1[1] = {"X", 19, "女"};

 //方法二
 struct Student stu_line2[2] = {
     {"絆面", 18, "男"},
     {"你好", 1, "女"}
 };

 //访问
 cout << stu1.name << endl;
 cout << stu2.name << endl;
 cout << stu_line1[0].name << endl;
 cout << stu_line2[1].name << endl;
	//创建结构体基本结构
 struct Student
 {
     string name = "你好:)";
     int age = 18;
     string gender = "无";
 };

 /*  结构体指针的创建  */
 //方法一
 struct Student stu = {"絆面", 18, "男"};
 struct Student *p1 = &stu;

 //方法二
 struct Student *p2 = new Student{"絆面", 18, "男"};


 /*  结构体数组指针的创建  */
 //方法一
 struct Student stu1[2] = {{"絆面", 18, "男"},{}};
 struct Student *p3 = stu1;

 //方法二
 struct Student *p4 = new Student[2]{
     {"絆面", 18, "男"},
     {}
 };

 //访问
 cout << p1->name << endl;
 cout << p2->name << endl;
 cout << p3[1].name << endl;
 cout << p4[1].name << endl;

 //释放指针空间
 delete p1;
 delete p2;
 delete[] p3;
 delete[] p4;

函数

//基本结构
int sample(int a,int b,int c){
	int result = 0;
    result += a+b+c;
    return result;
}

void out_put(string target){
    cout << target << endl;
}

void zako_mode(){
    cout << "雑魚雑魚" << endl;
}

//函数的调用
int main(){
    int sum = sample(1,2,3);
    out_put(sum);
    return 0;
}
//函数可以直接传入数组
void func1(int arr[]){}
void func2(int arr[1]){}
void func3(int * arr){}
//三种效果一样,因为上中下实际上都是创建一个指针形参,导入数组其实是导入数组的指针

引用

  1. 引用创建之后,不可更改(更改指向到其他的内存区域)

  2. 因不可更改,所以引用创建时必须初始化

  3. 因必须初始化,所以引用不可为空(不可修改)

//基本格式
int a = 10;
int& b = a;
//上面就是b引用了a的数值,b的值会随着a的变化而变化

引用传参和指针传参

两种可以使用函数改变实参的方法

void func1(int* a){
    a = 10;
}

void func2(int& a){
    a = 10;
}

int main(){
    m = 5;
    n = 5;
    func(&m);
    func(n);
    cout << m << n << endl;
}
//输出都是10

使用函数返回指针/数组

//数组的第一个数据是一个指针,所以操作和指针一样
int * sum1(int a, int b){
    int sum1 = a + b;
    return &sum1;
}

int * sum2(int a, int b){
    int * sum2 = new int;
    *sum = a + b;
    return sum2;
}

int * sum3(int a, int b){
    static int sum3;
    sum3 = a + b;
    return &sum3;
}

int main(){
    result1 = sum1(1,2);
    result2 = sum2(1,2);
    cout << result1 << endl;
    cout << result2 << endl;
    delete sum2;
  	return 0;
}
/*
使用第一个函数会导致代码出错,因为函数代码在执行结束的时候会释放内存,
函数的指针对应地址里面的数据也会被释放掉,导致得到的东西不是想要的
所以函数返回指针一般使用new函数创建一个动态内存,
动态内存只能使用delete进行内存的释放,
因此他不会被函数的自动释放内存释放掉
或者使用只有在程序结束时才会释放内存的static关键字元素
*/

static关键字

一个只有在程序运行结束才会被清理内存的变量修饰词

还可以修饰函数

声明:static int a;



Comment