当前位置: 首页 > news >正文

2025.1.8(c++对c语言的扩充——堆区空间,引用,函数)

笔记

上一笔记接续(练习2的答案)

练习:要求在堆区连续申请5个int的大小空间用于存储5名学生的成绩,分别完成空间的申请、成绩的录入、升序排序、成绩输出函数以及空间释放函数,并在主程序中完成测试

要求使用new和delete完成

头文件

#ifndef TEST_H
#define TEST_H#include<iostream>
using namespace std;//声明申请空间函数
int * apply(int size);//声明录入成绩的函数
void input_score(int *arr, int size);//声明输出成绩的函数
void output_score(int *arr, int size);//声明排序函数
void sort_score(int *arr, int size);//声明释放空间函数
void free_space(int *arr);#endif // TEST_H

源文件

#include"test.h"
#include<algorithm>//申请空间函数的定义
int *apply(int size)
{//在堆区申请空间int *arr = new int[size];if(NULL==arr){cout<<"空间申请失败"<<endl;return NULL;}cout<<"空间申请成功"<<endl;return arr;
}//录入成绩的函数
void input_score(int *arr, int size)
{for(int i=0; i<size; i++){cout<<"请输入第"<<i+1<<"个学生的成绩:";cin >> arr[i];}cout<<"录入完毕"<<endl;
}//输出成绩的函数
void output_score(int *arr, int size)
{cout<<"学生成绩分别是:";for(int i=0; i<size; i++){cout<<arr[i]<<"\t";}cout<<endl;}//排序函数
void sort_score(int *arr, int size)
{for(int i=1; i<size; i++){for(int j=0; j<size-i; j++){if(arr[j]>arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}cout<<"排序成功"<<endl;
}//释放空间函数的定义
void free_space(int *arr)
{if(NULL!=arr){delete []arr;           //释放堆区内存空间arr = NULL;}
}

主程序(验证代码正确性)

#include <iostream>
#include"test.h"using namespace std;int main()
{//调用申请int *arr = apply(5);//录入学生信息input_score(arr, 5);//输出学生信息output_score(arr, 5);//排序sort_score(arr, 5);//输出排序后的结果output_score(arr, 5);//销毁空间free_space(arr);arr = NULL;cout << "Hello World!" << endl;return 0;
}

7.3 malloc\free与new\delete的区别

共同点:都能够手动完成堆区空间的申请和释放,返回的都是堆区空间的地址

差异点:

1.        malloc\fjree是库函数的调用            new\delete是关键字

2.        malloc申请空间时无法对其进行初始化,new申请空间时可以对其进行初始化

3.        malloc申请空间以字节为单位,new申请空间时以数据类型为单位

4.        malloc申请的空间默认返回结果是void * 类型,使用时需要强制转换,
           new申请空间默认为申请时的数据类型来返回对应的类型指针,(正常使用时)无需强制转换

5.         malloc申请空间时,不区分单个空间和连续空间,而new和delete区分

6.        new申请空间时,会自动调用类的构造函数,而malloc不会

7.        delete释放空间时,会自动调用类的解构函数,而free不会

八、引用(reference)

8.1 引用的引入

1> 在C语言中,向函数中传递数据的方式有两种,分别是值传递和地址传递。当实参传递的是变量的地址时,可能是值传递也可能是地址传递;当实参传递的是普通变量时,一定是值传递。

2> C++中引入的“引用”的概念,不用区分值和地址传递了,可以直接传递该变量本身。当进行引用传递时,无需在被调函数中创建新的变量或者指针作为载体。被调函数无需为实参分配任何空间。

8.2 引用的概念

1> 引用相当于给变量起个“别名”

2> 一个变量的引用和引用的目标使用的是同一个内存空间,就像 宋江和及时雨的关系

3> 引用的分类:左值引用和右值引用

4> 左值引用的定义格式:数据类型 &引用名 = 引用目标;

5> 右值引用的定义格式:数据类型 &&引用名 = 引用目标;

6> 总结 & 的使用方式

        1、两个&作为双目运算符,表示逻辑与

        2、一个&作为双目运算符,表示按位与

        3、一个&作为单目运算符,表示取得某个变量的地址

        4、定义引用时,一个&表示定义的是左值引用

        5、定义引用时,两个&表示定义的是右值引用

8.3 引用的注意事项

1> 引用的使用跟普通变量一样,直接使用即可

2> 引用在定义时,必须用目标对其进行初始化,否则报错

3> 引用与引用的目标是同一个内存空间,系统不会为引用单独分配内存空间

4> 引用和引用的目标一般要求必须是同一数据类型(继承时除外)

5> 引用一旦指定,后期就不能进行更改目标了

6> 一个目标,可以定义多个引用,多个引用和引用目标都是同一个内存空间

#include <iostream>using namespace std;int main()
{int num = 520;          //定义一个普通变量//定义一个引用,目标为num//int &ref_1 ;                     //定义引用时,必须使用目标为其初始化,否则报错int &ref_1 = num;           //从此,num就有了一个别名  ref_1cout<<"ref_1 = "<<ref_1<<endl;           //对数据具有读功能ref_1 = 1314;                     //对数据具有写功能cout<<"ref_1 = "<<ref_1 << "  num = "<< num <<endl;         //两个变量名都更改cout<<"&ref_1 = "<<&ref_1 << "  &num = "<< &num <<endl;       //两个变量名地址相同cout<<"sizeof(ref_1) = "<<sizeof(ref_1) << "  sizeof(num) = "<< sizeof(num) <<endl;    //所占内存地址大小相同cout<<"tipe id of ref_1 = "<<typeid (ref_1).name() << "   tipe id of num =  "<<typeid (num).name()<<endl; //类型相同//double &ref_2 = num;          //不同类型的引用不能进行绑定int value = 999;//将ref_1引用到value上ref_1 = value;               //使用value的值给ref_1(num)重新赋值cout<<"ref_1 = "<<ref_1 << "  num = "<< num << "    value = "<<value<<endl;cout<<"&ref_1 = "<<&ref_1 << "  &num = "<< &num << "    &value = "<<&value<<endl;//一个目标可以定义多个引用int &ref_2 = num;int &ref_3 = ref_1;cout<<"&ref_1 = "<<&ref_1 << "  &num = "<< &num << "    &ref_2 = "<<&ref_2<<"   &ref_3 = "<<&ref_3<<endl;return 0;
}

8.4 引用作为函数的形参(重点)

1> 引用作为函数的形参,就没有了值传递和地址传递的概念了,传递的就是实参本身

2> 案例

#include <iostream>using namespace std;//定义交换函数1
void swap_1(int num, int key)
{int temp = num;num = key;key = temp;cout<<"swap_1::num = "<<num<<"    key = "<<key<<endl;       //1314   520
}//定义交换函数2
void swap_2(int *ptr, int *qtr)
{int *temp = ptr;ptr = qtr;qtr = temp;cout<<"swap_2::*ptr = "<<*ptr<<"    *qtr = "<<*qtr<<endl;     //1314   520
}//定义交换函数3
void swap_3(int *ptr, int *qtr)
{int temp = *ptr;*ptr = *qtr;*qtr = temp;cout<<"swap_3::*ptr = "<<*ptr<<"    *qtr = "<<*qtr<<endl;     //1314   520
}//定义交换函数4
void swap_4(int &n, int &k)
{int temp = n;n = k;k = temp;cout<<"swap_4::num = "<<n<<"    key = "<<k<<endl;       //520   1314
}/***************************主程序********************/
int main()
{int num = 520;int key = 1314;//调用交换函数1swap_1(num, key);cout<<"main::num = "<<num<<"    key = "<<key<<endl;        //520  1314//调用交换函数2swap_2(&num, &key);cout<<"main::num = "<<num<<"    key = "<<key<<endl;        //520   1314//调用交换函数3swap_3(&num, &key);cout<<"main::num = "<<num<<"    key = "<<key<<endl;        //1314   520//调用交换函数4swap_4(num, key);cout<<"main::num = "<<num<<"    key = "<<key<<endl;          //520   1314return 0;
}

8.5 引用作为函数的返回值(重点) ---> 引用函数

1> 引用作为函数的返回值,返回的是一个左值

2> 要求只能是生命周期比较长的变量才能作为返回值结果

3> 生命比较长的成员

        1、全局变量

        2、静态局部变量

        3、堆区空间的内容

        4、主调函数以地址或者引用的形式传过来的变量

#include <iostream>using namespace std;//定义一个引用函数
int &fun()
{static int num = 520;cout<<"fun::&num = "<<&num<<endl;return num;         //不能返回局部变量的空间  可以返回静态局部变量的空间
}//引用函数返回堆区空间的地址
int &hun()
{return *new int(520);      //在堆区空间申请一个int大小的空间并初始化为520,并将该空间返回
}int main()
{int key = fun();            //此时的key和num是不同的变量cout<<"key = "<<key<<"    &key = "<<&key<<endl;             //520int &value = fun();         //此时的value和num是同一个变量cout<<"value = "<<value<<"    &value = "<<&value<<endl;      //520fun() = 1314;                 //引用函数的返回结果是一个左值cout<<"value = "<<value<<"    &value = "<<&value<<endl;      //1314int &ref = hun();              //在主程序中获取被调函数中开辟的堆区空间cout<<"ref = "<<ref<<endl;         //520delete &ref;                  //释放堆区空间return 0;
}

8.6 常引用

1> 对于变量而言,变量的内容既可读又可写

2> 但是,有时函数的形参是引用变量时,在函数体内仅仅只是为了读取数据中的内容,而不

        是为了更改形参

        此时,为了保护新参不被修改,我们可以加常属性 const

3> 引用和目标进行搭配使用

        1、普通引用 普通变量

        2、普通引用 常变量

        3、常引用 普通变量

        4、常引用 常变量

#include <iostream>using namespace std;int main()
{/**************普通引用   普通变量*******************/int num = 520;int &ref_1 = num;cout<<"num = "<<num<< "    ref_1 = "<<ref_1<<endl;       //对空间都有读属性num = 1314;             //普通变量对空间具有写属性ref_1 = 999;             //普通引用对空间也具有写属性/****************普通引用   常变量********************/const  int value = 999;        //定义一个常变量//int &ref_2 = value;            //普通引用不能绑定常变量/***************常引用    普通变量**********************/int temp = 1111;           //定义普通变量const int &ref_3 = temp;         //常引用的目标为普通变量cout<<"temp = "<<temp<< "    ref_3 = "<<ref_3<<endl;       //对空间都有读属性temp = 222;            //普通变量具有写属性//ref_3 = 777;             //常引用没有写属性/******************常引用     常变量******************/const int key = 444;              //定义常变量const int &ref_4 = key;          //定义常引用cout<<"key = "<<key<< "    ref_4 = "<<ref_4<<endl;       //对空间都有读属性//key = 666;            //没有写属性//ref_4 = 777;         //没有写属性return 0;
}

8.7 引用与指针的关系

1> 指针变量也是有8字节的内存空间,既然有内存空间,就可以给该内存空间起个别名

2> 指针引用的定义格式: 数据类型 * & = 引用目标;

3> 指针引用定义后,使用方式跟原指针一致

#include <iostream>using namespace std;int main()
{int num = 520;        //定义普通变量int *ptr = &num;        //定义一个指针变量int * & ptr_ref = ptr;            //定义了一个指针的引用,后期 ptr_ref就可以跟ptr一样被使用cout<<"*ptr = "<<*ptr<<"    *ptr_ref = "<<*ptr_ref<<endl;     //对数据具有读功能cout<<"&ptr = "<<&ptr<<"    &ptr_ref = "<<&ptr_ref<<endl;      //地址一致cout<<"ptr = "<<ptr<<"    ptr_ref = "<<ptr_ref<<"   &num = "<<&num<<endl;      //内容一致int key = 1314;ptr_ref = &key;            //ptr = &key;     //让指针变量重新指向新的空间return 0;
}

8.8 引用与数组的关系

1> C语言中,没有数组的引用,当向一个函数传递数组时,本质上使用的是指针接收的参数

2> C++中支持数组引用,表示给数组起个别名

3> 数组引用定义格式:数据类型 (&引用名)[数组长度] = 其他数组名;

#include <iostream>using namespace std;//定义功能函数
void fun(int arr[], int n)          //arr接受的是主调函数中数组的起始地址,并不是数组本身
{cout<<"fun::sizeof(arr) = "<<sizeof(arr)<<endl;       //?for(int i=1; i<n; i++){for(int j=0; j<n-i; j++){if(arr[j]>arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}//定义功能函数
void hun(int (&arr)[5])              //该函数中的arr接受的就是主调函数中的数组本身
{cout<<"fun::sizeof(arr) = "<<sizeof(arr)<<endl;       //20int n = sizeof(arr)/sizeof (arr[0]);      //求数组长度for(int i=1; i<n; i++){for(int j=0; j<n-i; j++){if(arr[j]>arr[j+1]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}int main()
{int arr[] = {3,8,3,2,4};int len = sizeof(arr)/sizeof (arr[0]);//fun(arr, len);hun(arr);return 0;
}

8.9 右值引用(了解)

1> 右值引用的引入目的:为了解决左值引用的瑕疵问题

2> 左值引用只能引用左值目标,右值引用只能引用右值目标

3> 右值引用定义格式:数据类型 &&引用名 = 右值目标;

#include <iostream>using namespace std;//定义求最值函数
int my_max(int &m, int &n)
{return m>n?m:n;
}int my_max(int &&m, int &&n)
{return m>n?m:n;
}int main()
{int num = 5;int key = 3;int res = my_max(num,key);my_max(100,200);              //不能传递,原因是形参是左值引用,左值引用只能引用左值int &&ref_1 = 520;          //右值引用可以引用常量、临时值、将亡值//int &&ref_2 = num;            //右值引用只能引用右值,不能引用左值int &&ref_3 = move(num);       //使用move函数,将左值移动成右值return 0;
}

8.10 引用与指针的区别(重点)

1> 可以有指针数组,但是没有引用数组

2> 引用必须初始化,但是指针可以不用初始化

3> 指针拥有独立的内存空间,而引用没有,引用与其目标共用同一块内存

4> 指针可以改变指向,但是引用一旦指定目标,后期不能更改

5> 引用不能为空,可以有空指针

6> 指针进行算术运算时,是对地址空间进行偏移,而引用进行算术运算时,就是目标进行的算术运算

7> 指针有二级指针,但是没有二级引用

8> 指针的目标必须是左值的地址,而引用可以有左值引用也可以有右值引用

9> 有万能指针,但是没有万能引用

九、C++对C语言的函数的扩充

9.1 函数重载(overload)

1> 引入目的:程序员在定义函数时,有时仅仅是因为函数的参数不同,导致同一功能的函数

        需要定义多个。例如,求两个整数的和、两个小数的和、两个字符串的和等等,函数内

        部实现逻辑都一样,仅仅只是因为函数参数类型不同,导致需要定义多个函数

2> C++中引入函数重载的概念,表示能够在同一个作用域下定义多个同名的函数

3> 要求:

        1、作用域相同

        2、函数名相同

        3、形参列表必须不同(参数个数、参数类型)

        4、跟返回值没有关系

4> 当调用函数时,系统会根据实参的类型和个数,自动匹配相关函数进行调用

#include <iostream>using namespace std;int sum(int m, int n)      //定义求两个整数的和{return m+n;}//求两个小数的和double sum(double m, double n){return m+n;}float sum(float m, float n){return m+n;}//求两个字符串的和string sum(string m, string n){return m+n;}int main()
{cout << sum(3,5) << endl;          //8cout << sum(3.3,5.5) << endl;      //8.8cout << sum("3","5") << endl;      //35return 0;
}

练习:定义两个整数求最大值、两个小数求最大值、两个字符串求最大值函数,并完成相关的测试

9.2 默认参数

1> 引入背景:

        程序员在定义函数时,有某个参数或者某几个参数,可以由主调函数传递,也可以不需

        要主调函数传递时,此时就可以定义默认参数,对于设置了默认参数的形参变量,如果

        主调函数传递该数据,那么就使用主调函数中传递的数据,如果主调函数不传递数据,

        那么就使用默认提供的参数

2> 设置格式:返回值类型 函数名 (参数1, 参数2=初始值, 参数3=初始值)、

3> 函数形参的默认参数的设置要求:靠右原则,只有某个参数的右侧的所有的形参都设置了

        初始值,当前这个形参才能设置

        因为函数的实参向形参传递的方向是靠左原则

4> 当包含默认参数的函数和函数重载同时出现时,应避免重复性定义

5> 当分文件定义时,默认参数的设置需要写在声明部分,定义部分就不需要写了

#include <iostream>using namespace std;int sum(int  = 100, int = 100, int  = 100);       //函数声明//这个函数与上个函数重载,定义的使用没有问题
/*
int sum(int num, int key)
{return num+key;
}*/int main()
{cout << sum(1,2,3) << endl;      //6cout << sum(1,2) << endl;        //103       //调用时出问题cout << sum(1) << endl;           //201cout << sum() << endl;            //300return 0;
}//定义三个数求和函数
int sum(int m, int n, int k)
{return  m+n+k;
}

9.3 内联函数

1> C++支持内联函数:设置了内联函数的函数,会建议编译器在编译时将函数体展开

        由于是在编译阶段,在被调函数处展开,那么在运行时,就无需再为该函数分配内存空

        间了      能够大大提高运行效率

2> 定义格式:在定义函数前加关键字 inline

3> 要求:

        1、函数体较小,否则会造成主程序膨胀

        2、调用比较频繁

        3、递归函数不允许设置成内联函数

        4> 有时,即使设置了内联函数,也不一定会在编译时展开

#include <iostream>using namespace std;//该函数就是内联函数
inline int sum(int  = 100, int = 100, int  = 100);       //函数声明//这个函数与上个函数重载,定义的使用没有问题
/*
int sum(int num, int key)
{return num+key;
}*/int main()
{cout << sum(1,2,3) << endl;      //6cout << sum(1,2) << endl;        //103       //调用时出问题cout << sum(1) << endl;           //201cout << sum() << endl;            //300return 0;
}//定义三个数求和函数
inline int sum(int m, int n, int k)
{return  m+n+k;
}

9.4 哑元

1> 引入背景:程序员在定义函数时,有时某个形参或者某几个形参,在函数体内没有实质性的作用,但是,也还需要一个参数进行占位,此时就可以定义该参数为哑元。

2> 定义格式:定义形参时,只给类型,不给形参名,函数体内也不用

3> 使用场景:

1、程序优化:原本程序调用某个函数需要5个参数,但是,发布运行一段时间后,由于技术的革新,导致该函数只需要3个参数就能正常运行,但是,由于该函数在整个程序很多地方都已经被调用了,如果直接改变该函数的参数个数,那么需要将每个调用函数处都进行修改,非常不方便,此时,就可以使用哑元,仅仅只是占位作用

2、在进行自增或自减运算符重载时,使用哑元用于区分是前置还是后置(后期讲)

#include <iostream>using namespace std;//此时第二个和第三个参数就是哑元,唯一的作用就是占位作用
int sum(int m, int , int , int g)
{return  m+g;
}int main()
{cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;cout << sum(2,3,4,5) << endl;return 0;
}

 思维导图

相关文章:

2025.1.8(c++对c语言的扩充——堆区空间,引用,函数)

笔记 上一笔记接续&#xff08;练习2的答案&#xff09; 练习&#xff1a;要求在堆区连续申请5个int的大小空间用于存储5名学生的成绩&#xff0c;分别完成空间的申请、成绩的录入、升序排序、成绩输出函数以及空间释放函数&#xff0c;并在主程序中完成测试 要求使用new和d…...

如何将Yum源修改为本地挂载的ISO镜像

要将yum源修改为本地挂载的ISO镜像,您可以按照以下步骤进行操作。假设您使用的是CentOS或类似的基于Red Hat的Linux发行版,且已经将ISO镜像文件挂载到系统中。 步骤一:挂载ISO镜像 创建一个挂载点: 首先,您需要创建一个目录来作为ISO镜像的挂载点。例如: sudo mkdir /mnt…...

salesforce如何在系统里保存密码

在 Salesforce 中&#xff0c;保存密码或类似敏感信息时&#xff0c;不应以明文形式存储&#xff0c;而应采用安全的加密和存储机制。以下是一些最佳实践和实现方法&#xff1a; 1. 使用 Salesforce 提供的加密机制 Salesforce 提供了一些内置的加密工具&#xff0c;可以用来加…...

函数提升+上下文+内存清理及释放

文章目录 函数提升上下文函数释放拓展-垃圾回收机制垃圾回收之触发应用 函数提升上下文 函数提升&#xff08;Hoisting&#xff09; 概念&#xff1a;在JavaScript中&#xff0c;函数声明会被提升到当前作用域的顶部。这意味着可以在函数声明之前调用函数。例如&#xff1a; sa…...

计算机网络之---计算机网络的性能评估

计算机网络的性能评估是指通过各种标准和指标来衡量网络的工作效率和质量&#xff0c;进而对网络进行优化和改进的过程。评估的目标是确保网络能够满足预期的服务质量&#xff08;QoS&#xff09;和性能需求。常见的计算机网络性能评估指标包括带宽、延迟、吞吐量、丢包率等。 …...

Unity学习之UGUI进阶

一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 &#xff08;1&#xff09;常用事件接口 &#xff08;2&#xff09;不常用事件接口 3、使用事件监听接口 &#…...

深度学习领域创新黑马!频域特征融合新突破

最近&#xff0c;FreqFusion引起了广泛关注&#xff0c;这是一种创新的频率感知特征融合方法&#xff0c;可以提升数据处理的准确性和效率&#xff0c;尤其在语义分割、目标检测、实例分割和全景分割等任务中表现卓越。 通过结合频域分析与特征融合技术&#xff0c;FreqFusion…...

路由器的转发表

【4-24】 已知路由器R₁ 的转发表如表T-4-24 所示。 表T-4-24 习题4-24中路由器R₁的转发表 前缀匹配 下一跳地址 路由器接口 140.5.12.64/26 180.15.2.5 m2 130.5.8/24 190.16.6.2 ml 110.71/16 ----- m0 180.15/16 ----- m2 190.16/16 ----- ml 默认 11…...

用Cline打造你的智能搜索助手:Tavily Search MCP集成指南

引言 本文将详细介绍如何在Cline编辑器中集成Tavily Search智能搜索功能。我们将从MCP&#xff08;Model Context Protocol&#xff09;协议基础开始&#xff0c;深入探讨Tavily Search MCP服务器的安装配置、使用方法&#xff0c;以及进阶的二次开发技巧。无论你是AI开发者还…...

HTML+CSS+JS制作中华传统美食主题网站(内附源码,含5个页面)

一、作品介绍 HTMLCSSJS制作一个中华传统文化主题网站&#xff0c;包含首页、菜系页、食材页、名厨页、美食故事页等5个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部横幅导航区 包含网站Logo、搜索栏、主导航菜单&#xff0…...

黄仁勋CES 2025演讲重点内容

黄仁勋CES 2025演讲重点内容 硬件产品发布 GeForce RTX 50系列GPU&#xff1a; 架构与性能提升&#xff1a;正式发布的新一代GeForce RTX 50系列GPU采用英伟达旗舰的Blackwell架构&#xff0c;这是自25年前引入可编程着色技术以来计算机图形领域最重大的创新。该系列显卡在图形…...

TVbox 手机、智能电视节目一网打尽

文章目录 一、简要介绍二、优点三、下载地址 一、简要介绍 TVbox是目前最火爆的多端、多源的电视影音工具&#xff0c;是一款开源的自定义添加站源的影音工具。TVBox&#xff0c;支持电视频道直播。一款TV端影视工具&#xff0c;软件本身不具有任何影视资源&#xff0c;但可以…...

sys.dm_exec_connections:查询与 SQL Server 实例建立的连接有关的信息以及每个连接的详细信息(客户端ip)

文章目录 引言I 基于dm_exec_connections查询客户端ip权限物理联接时间范围dm_exec_connections表see also: 监视SQL Server 内存使用量资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)引言 查询历史数据库客户端ip应用场景: 安全分析缺乏…...

kubesphere前端源码运行

一、下载源码 源码是react&#xff0c;下载地址是 GitHub - kubesphere/console at v3.3.2 然后直接用git下拉就可以了 下拉完成后差不多是这样一个目录结构&#xff0c;记得切分支到3.3.2 二、下载依赖 1、node & yurn 想要运行源码首先需要node&#xff0c;使用刚才…...

分布式主键ID生成方式-snowflake雪花算法

这里写自定义目录标题 一、业务场景二、技术选型1、UUID方案2、Leaf方案-美团&#xff08;基于数据库自增id&#xff09;3、Snowflake雪花算法方案 总结 一、业务场景 大量的业务数据需要保存到数据库中&#xff0c;原来的单库单表的方式扛不住大数据量、高并发&#xff0c;需…...

深入理解感知机(Perceptron)算法

深入理解感知机(Perceptron)算法 1. 引言 感知机是神经网络和深度学习的基石,由Frank Rosenblatt在1957年提出。它模拟了生物神经元的基本特征,是一个简单但重要的二分类线性分类器。本文将从数学原理到实际应用,全面介绍感知机算法。 2. 数学基础 2.1 定义 感知机是一…...

操作系统——死锁与饥饿

死锁的概念 死锁产生的条件 前三种条件可能会产生死锁&#xff0c;第四种条件&#xff08;环路&#xff09;可能会产生死锁 机器检测是否死锁是——检测是否有环路 解决死锁 以上预防死锁的方法不太实用&#xff0c;低效 银行家算法 P2运行完后可用队列就变成了 6 2 3…...

【算法】字符串算法技巧系列

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 引入&#xff1a;字符串相关算法技巧 1&#xff1a;字符串转数组 2&#xff1a;子字符串 3&#xff…...

Vue中el-tree结合vuedraggable实现跨组件元素拖拽

实现效果&#xff1a; 左侧el-tree: <template><el-treeclass"filter-tree":data"treeData":props"defaultProps":filter-node-method"filterNode"node-key"id"draggable:allow-drop"allowDrop"node-dr…...

湘潭大学人机交互复习

老师没给题型也没划重点&#xff0c;随便看看复习了 什么是人机交互 人机交互&#xff08;Human-Computer Interaction&#xff0c;HCI&#xff09;是关于设计、评价和实现供人们使用的交互式计算机系统&#xff0c;并围绕相关的主要现象进行研究的学科。 人机交互研究内容 …...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...