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

【C++】类和对象1.0

本鼠浅浅介绍一些C++类和对象的知识,希望能得到读者老爷们的垂阅!

目录

1.面向过程和面向对象

2.类的引入

3.类的定义

4.类的访问限定符及封装

4.1.类的访问限定符

4.2.封装

5.C++中struct和class的区别

6.类域

7.类的实例化

8.类对象模型

8.1.类对象大小

8.2.类对象的存储方式

9.this指针 

9.1.this指针的引出

 9.2.this指针的特性

10.Question


1.面向过程和面向对象

作为了解:

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 

C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完 成。

没了,介绍完了。其实对于解决问题,C语言关注的是解决问题的动作,而C++关注的是解决问题的对象呗。

2.类的引入

俺们都知道C语言中有结构体的概念。那么C++兼容C语言的大部分语法,所以C++也可以使用结构体。但是C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数

举个栗子给老爷们瞅瞅:

#include<iostream>
#include<assert.h>
using namespace std;
typedef int SLTDateType;
struct SListNode
{SLTDateType data;struct SListNode* next;//动态申请一个节点SListNode* BuyNode(SLTDateType x){SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));if (newnode == NULL){perror("malloc fail");exit(-1);}newnode->data = x;newnode->next = NULL;return newnode;}//单链表打印void Print(SListNode* plist){SListNode* cur = plist;while (cur != NULL){cout << cur->data << "->";cur = cur->next;}cout << "nullptr" << endl;}//单链表尾插void PushBack(SListNode** pplist, SLTDateType x){assert(pplist);if (*pplist == NULL)//单链表为空{*pplist = BuyNode(x);}else//单链表不为空{SListNode* tail = *pplist;while (tail->next != NULL)//找尾{tail = tail->next;}SListNode* newnode = BuyNode(x);tail->next = newnode;}}//单链表头插void PushFront(SListNode** pplist, SLTDateType x){assert(pplist);SListNode* newnode = BuyNode(x);newnode->next = *pplist;*pplist = newnode;}//销毁单链表void Destroy(SListNode** pphead){assert(pphead);SListNode* cur = *pphead;while (cur){SListNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;}
};
int main()
{SListNode* sl = nullptr;sl->PushBack(&sl, 0);sl->PushFront(&sl, -1);sl->Print(sl);sl->Destroy(&sl);return 0;
}

 是可以运行的,且结果符合预期!!

上面结构体的定义,在C++中更喜欢用class来代替struct。这样C++中结构体就升级成了

3.类的定义


类的定义格式:class为定义类的关键字,ClassName为类的名字(可随意变换),{}中为类的主体,注意类定义结束时后面分号不能省略。

这样子:

class className//className是类的名字
{// 类体:由成员函数和成员变量组成};  // 一定要注意后面的分号

类体中内容称为类的成员:类中的变量称为类的属性成员变量; 类中的函数称为类的方法或者成员函数。 


类的两种定义方式:

1.方式一:声明和定义全部放在类体中。

需注意:成员函数如果在类中定义,编译器可能会将其当成内 联函数处理。

像这样子:

class person
{//成员变量的声明int age;const char* name;const char* sex;//成员函数的定义void showinformation(){cout << name << '-' << sex << '-' << age << endl;}
};

 2.方式二:类声明放在.h文件中,成员函数定义放在.cpp文件中。其实就是成员函数声明和定义分离。

注意:成员函数名前需要加类名::

像这样子:

类的.h文件(假如头文件为Person.h):

class person
{//成员变量的声明int age;const char* name;const char* sex;//成员函数的声明void showinformation();
};

类的.cpp文件:

#include"Person.h"//成员函数的定义void person::showinformation(){cout << name << '-' << sex << '-' << age << endl;}

一般情况下,更期望采用第二种方式。

4.类的访问限定符及封装

4.1.类的访问限定符

C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善(咱们看类可以有成员变量和成员函数,分别对应属性与方法)。通过访问权限选择性的将其接口提供给外部的用户使用。

类的访问限定符有三种:public(公有)、protected(保护)、private(私有)

类的访问限定符体现了访问权限

  • public修饰的成员在类外可以直接被访问。
  • protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)。
  • 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
  • 如果后面没有访问限定符,作用域就到 } 即类结束。
  • class的默认访问权限为private,struct为public(因为struct要兼容C)。

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。


举一些栗子来证实访问限定符的作用:

#include<iostream>
using namespace std;
class person
{int _age;const char* _name;const char* _sex;void showinformation(){cout << _name << '-'<<_sex <<'-'<< _age << endl;}
};
int main()
{person HD;HD._age = 20;//error C2248: “person::_age”: 无法访问 private 成员(在“person”类中声明)return 0;
}

主函数第二条语句编译不通过是因为: class的默认访问权限为private,private修饰的成员在类外不能直接被访问。

如果我们改用public修饰该类的所有成员:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation(){cout << _name << '-'<<_sex <<'-'<< _age << endl;}
};
int main()
{person HD;HD._age = 20;HD._name = "HD";HD._sex = "male";HD.showinformation();return 0;
}

 编译通过,运行成功!

又如果:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;
private:void showinformation(){cout << _name << '-'<<_sex <<'-'<< _age << endl;}
};
int main()
{person HD;HD._age = 20;HD._name = "HD";HD._sex = "male";HD.showinformation();//error C2248: “person::showinformation”: 无法访问 private 成员(在“person”类中声明)return 0;
}

 主函数第五条语句编译报错。因为:该类的成员函数被private修饰。第二条到第四条语句编译通过是因为该类的所有成员变量被public修饰。(访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。)

4.2.封装

面向对象的三大特性:封装继承多态

封装:封装本质是一种管控。将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来 隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。

5.C++中struct和class的区别

C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来定义类,和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类 默认访问权限是private。在继承和模板参数列表位置,struct和class也有区别,本鼠以后再介绍,因为本鼠也不清楚捏!

6.类域

类定义了一个新的作用域:类域,类的所有成员都在类的作用域中。与命名空间域一样,类域也只会影响访问,所以在类体外定义成员时,需要使用 :: 作用域限定符指明成员属于哪个类域。

举例请看类的定义方式二。

其实类的定义方式二中的成员函数的声明和定义分离写到同一个.cpp文件下面也行,像这样子:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation();
};
void person::showinformation()
{cout << _name << '-' << _sex << '-' << _age << endl;
}
int main()
{person HD;HD._age = 20;HD._name = "HD";HD._sex = "male";HD.showinformation();return 0;
}

 编译也通过,运行成功。

不过既然都写到同一个文件下了,成员函数的声明和定义分开写好像有种脱裤子放屁的无力感,没必要啊。。。 直接写成类的定义方式一不就好了。。。

7.类的实例化

类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它。所以要让类有使用价值就要将类实例化。

用类类型创建对象的过程,称为类的实例化。说白了类的实例化就是创建类型为该类的对象呗。像这样子:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation();
};
void person::showinformation()
{cout << _name << '-' << _sex << '-' << _age << endl;
}
int main()
{person HD;//HD是person类实例化的对象return 0;
}

 定义出一个类并没有分配实际的内存空间来存储它,如上代码定义出person类,但是没有给person类开空间的。用person类类型创建对象HD,就是person类实例化,对象HD是开了空间来存储的。

一个类可以实例化出多个对象,很简单易懂吧,就像这样:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation();
};
void person::showinformation()
{cout << _name << '-' << _sex << '-' << _age << endl;
}
int main()
{person HD;//HD是person类实例化的对象person LCD;//LCD也是person类实例化的对象return 0;
}

HD和LCD都是person类实例化对象 。

实例化出的对象占用实际的物理空间,存储类成员变量,我们看:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation();
};
void person::showinformation()
{cout << _name << '-' << _sex << '-' << _age << endl;
}
int main()
{person._age = 10;//error C2059: 语法错误:“.”return 0;
}

编译报错是因为:person类是没有空间的,只有person类实例化出的对象才有具体的年龄。person类中的成员变量(如_age)只是声明,没有开空间来存储成员变量,只有person类实例化对象才有空间存储类成员变量(如_age)。

最后提一嘴:类对象实例化的时候代码可以带上class或者struct,也可以不带,一般不会带上。比如这样子写也能编译通过,运行成功:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation(){cout << _name << '-' << _sex << '-' << _age << endl;}
};
int main()
{class person HD;HD._age = 20;HD._name = "HD";HD._sex = "male";HD.showinformation();return 0;
}

 

8.类对象模型

8.1.类对象大小

我们也许会有疑问:C语言的结构体成员可不能有函数,计算结构体变量的大小遵循结构体内存对齐呗。但是类定义时可以包含成员变量和成员函数,那么类实例化对象的大小(占多少字节)该如何计算捏?

答案就是一个类实例化对象的大小(或者说类的大小),实际就是该类中”成员变量”之和,当然要注意内存对齐。就是说不用管类成员函数的存在。为什么这样子,本鼠下边再解释。

#include<iostream>
using namespace std;
class rectangle
{
public:double _long;double _wide;double _high;void showinformation(){cout << _long << '-' << _wide << '-' << _high << endl;}
};
int main()
{rectangle n1;cout << sizeof(rectangle) << endl;cout << sizeof(n1);return 0;
}

 

 额,sizeof(类)和sizeof(类实例化对象)是同一个意思,都是计算类实例化对象多大。

附上结构体内存对齐规则:

  • 1. 第一个成员在与结构体偏移量为0的地址处。
  • 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8
  • 3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  • 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。如果空类的大小为0个字节,那么该类实例化对象如何证明存在过捏?

#include<iostream>
using namespace std;
class N
{
};
int main()
{N n1;cout << sizeof(N) << endl;cout << sizeof(n1);return 0;
}

 

 好了,为啥子一个类实例化对象的大小(或者说类的大小),实际就是该类中”成员变量”之和,当然要注意内存对齐。就是说不用管类成员函数的存在。请看类对象的存储方式!!

8.2.类对象的存储方式

拿这个代码来说:

#include<iostream>
using namespace std;
class person
{
public:int _age;const char* _name;const char* _sex;void showinformation(){cout << _name << '-' << _sex << '-' << _age << endl;}
};
int main()
{class person HD;person LCD;return 0;
}

person类实例化对象有两个:HD和LCD。这两个对象个中成员变量是不同的(需要存储不同的属性,所以说是不同的),但是调用同一份函数(类方法是一样的)。当一 个类创建多个对象时,如果每个对象中都会保存一份代码,相同代码保存多次,浪费空间。 

那么计算机的做法是:当一个类创建多个对象时,对象只保存成员变量,成员函数存放在公共代码段(区)。

就是说当类实例化对象时,只会给该对象开遵循结构体内存对齐的“成员变量”之和的内存空间,当该对象需要用到成员函数时去公共代码段调用。

9.this指针 

9.1.this指针的引出

看一个代码:

#include<iostream>
using namespace std;
class Date
{int _year; // 年int _month;// 月int _day;// 日
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
};
int main()
{Date d1, d2;d1.Init(2024, 6, 4);d2.Init(2003, 12, 12);d1.Print();d2.Print();return 0;
}

 

运行没毛病,但是有一个问题: 

 Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分。那当d1调用 Init 函 数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

C++中通过引入this指针解决该问题,其实即:C++编译器给每个“非静态的成员函数“增加了一个隐藏 的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量” 的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。this指针是每个“非静态的成员函数”的第一个参数,而且是隐藏起来的。

this指针是隐藏起来的,拿上面代码来说:当d1调用Init函数时,传递的实参不仅仅有明面上的2024、6和4,还有该对象的地址,即d1的地址,而且第一个传递d1的地址。

Init函数有一个隐藏的this指针用来接收d1的地址,所以Init函数知道该设置d1对象而不是d2对象。

 9.2.this指针的特性

用本代码举例:

#include<iostream>
using namespace std;
class Date
{int _year; // 年int _month;// 月int _day;// 日
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
};
int main()
{Date d1, d2;d1.Init(2024, 6, 4);d2.Init(2003, 12, 12);d1.Print();d2.Print();return 0;
}
  • this指针的类型:类类型* const。即成员函数中,不能给this指针赋值。比如上面代码Init函数隐藏的this指针类型是Data* const。
  • 在实参或者形参的位置上不能将this指针显示写,但是函数内部可以使用。

请看:

#include<iostream>
using namespace std;
class Date
{int _year; // 年int _month;// 月int _day;// 日
public:void Init(Date const* this, int year, int month, int day){_year = year;_month = month;_day = day;}void Print(Data const*this){cout << _year << "-" << _month << "-" << _day << endl;}
};
int main()
{Date d1, d2;d1.Init(&d1, 2024, 6, 4);d2.Init(&d2, 2003, 12, 12);d1.Print(&d1);d2.Print(&d2);return 0;
}

编译报错!因为将形参位置隐藏的this指针显示写出来了,而且实参位置传入d1地址或者d2地址给this指针。这些都是编译器完成的,我们不应该显示写出来。

再看:

#include<iostream>
using namespace std;
class Date
{int _year; // 年int _month;// 月int _day;// 日
public:void Init( int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}void Print(){cout << this->_year << "-" << this->_month << "-" <<this-> _day << endl;}
};
int main()
{Date d1, d2;d1.Init( 2024, 6, 4);d2.Init( 2003, 12, 12);d1.Print();d2.Print();return 0;
}

编译通过,运行成功!函数内部可以使用隐藏的this指针。详情请看Init函数或者Print函数内部。

  • this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。 
  • this指针是“成员函数”第一个隐藏的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。

呃呃呃:this指针存储在栈区(有些编译器用寄存器存储),因为它是一个形参。

10.Question

1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

#include<iostream>
using namespace std;
class A
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

也许你会跟本鼠一样,看到空指针就想选A。但是正确答案是C。因为p虽然是空指针,但是Print函数并不是通过解引用p找到的,因为Print函数存储在公共代码段中,而不是存储在p指向的空间里。

 看看结果如图:

 2.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

class A
{ 
public:void PrintA() {cout<<_a<<endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->PrintA();return 0;
}

哈哈哈,答案选B。因为PrintA函数会将地址p作为实参传递给PrintA函数隐藏的形参this指针。我们看PrintA函数内部需要用到this指针解引用的哦,this指针接收到的值是空指针,而且成员变量_a是存储在this指向的空间里面的(成员变量存储在类实例化对象里面),当然会崩溃了。

崩溃了!!

感谢阅读!!!!!!! 

相关文章:

【C++】类和对象1.0

本鼠浅浅介绍一些C类和对象的知识&#xff0c;希望能得到读者老爷们的垂阅&#xff01; 目录 1.面向过程和面向对象 2.类的引入 3.类的定义 4.类的访问限定符及封装 4.1.类的访问限定符 4.2.封装 5.C中struct和class的区别 6.类域 7.类的实例化 8.类对象模型 8.1.类…...

Linux下gcc编译32位程序报错

gcc使用-m32选项&#xff0c;编译32位程序时&#xff0c;报错&#xff1a;/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory gcc编译32位程序时&#xff0c;报错&#xff1a;/usr/include/stdio.h:27:10: fatal error: bits/li…...

godot.bk

1.搜索godot国内镜像&#xff0c;直接安装&#xff0c;mono是csharp版本 2.直接解压&#xff0c;50m&#xff0c;无需安装&#xff0c;直接运行 3.godot里分为场景&#xff0c;节点 主场景用control场景&#xff0c;下面挂textureact放背景图片&#xff0c;右键实例化子场景把…...

【C++修行之道】类和对象(三)拷贝构造函数

目录 一、 概念 二、特征 正确的拷贝构造函数写法&#xff1a; 拷贝函数的另一种写法 三、若未显式定义&#xff0c;编译器会生成默认的拷贝构造函数。 四、编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了&#xff0c;还需要自己显式实现吗&#xff1f; 深拷…...

校园外卖系统的技术架构与实现方案

随着校园生活的日益现代化&#xff0c;外卖需求在高校学生群体中迅速增长。为了满足这一需求&#xff0c;校园外卖系统应运而生。本文将详细探讨校园外卖系统的技术架构及其实现方案&#xff0c;帮助读者了解这一系统的核心技术与实现路径。 一、系统概述 校园外卖系统主要包…...

AI的制作思维导图

AI&#xff08;人工智能&#xff09;的实现通常涉及以下几个步骤&#xff1a; 1.问题定义&#xff1a;首先确定你想要解决的问题是什么&#xff0c;这将决定你需要设计什么样的系统。 2.数据收集&#xff1a;根据你的需求&#xff0c;收集相关的数据集来训练你的AI模型。数据的…...

Amazon云计算AWS(四)

目录 八、其他Amazon云计算服务&#xff08;一&#xff09;快速应用部署Elastic Beanstalk和服务模板CloudFormation&#xff08;二&#xff09;DNS服务Router 53&#xff08;三&#xff09;虚拟私有云VPC&#xff08;四&#xff09;简单通知服务和简单邮件服务&#xff08;五&…...

数据库(21)——数值函数

数值函数 函数功能CEIL(x)向上取整FLOOR(x)向下取整MOD(x,y)返回x/y的余数RAND()返回0~1内的随机数ROUND(x,y) 求参数x的四舍五入的值&#xff0c;保留y位小数 演示 select ceil(66.4); select floor(8.9); select mod(3,10); select rand(); select round…...

【PB案例学习笔记】-15怎样限制应用程序运行次数?

写在前面 这是PB案例学习笔记系列文章的第15篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…...

Spring为什么不支持static字段注入

Spring不支持直接依赖注入到静态变量中。在Spring框架中&#xff0c;依赖注入是一个核心概念&#xff0c;它允许开发者将对象间的依赖关系定义转移到容器中&#xff0c;由容器负责管理这些依赖关系。然而&#xff0c;当涉及到静态变量时&#xff0c;情况就变得复杂了。 首先从…...

AI数据分析:用Kimi根据Excel表格数据绘制多条折线图

工作任务&#xff1a;将Excel文件中的学生姓名和他们的语文、数学、英语成绩绘制成三条折线图&#xff0c;以便于比较不同科目的成绩分布情况。 在kimi中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本编写的任务&#xff0c;具体步骤如下&a…...

高级 Go 程序设计:使用 net/http/httputil 包构建高效网络服务

高级 Go 程序设计&#xff1a;使用 net/http/httputil 包构建高效网络服务 介绍ReverseProxy 的使用基本概念实现步骤高级配置实际案例 DumpRequest 的使用功能说明代码示例应用场景NewSingleHostReverseProxy 的特性功能概述 详细教程 注意事项使用 NewChunkedWriter 实现高效…...

Android11 AudioTrack 创建过程

Android 系统播放声音&#xff0c;需要创建AudioTrack来和AudioFlinger通信&#xff0c;其创建过程如下 根据传入的声音属性得到output通过得到的output&#xff0c;找到播放线程AudioFlinger在播放线程内&#xff0c;创建Track&#xff0c;和AudioTrack对应。后续通过它们进…...

数学建模 —— 层次分析法(2)

目录 一、层次分析法&#xff08;AHP&#xff09; 二、构造比较判断矩阵 2.1 两两比较法 三、单准则下的排序及一致检验 3.1 单准则下的排序 3.2 一致性检验 四、层次总排序 4.1 层次总排序的步骤 4.2 总排序一致性检验 一、层次分析法&#xff08;AHP&#xff09; 方…...

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:人工智能消防应用

青鸟消防股份有限公司成立于2001年6月&#xff0c;于2019年8月在深圳证券交易所挂牌上市&#xff0c;成为中国消防报警行业首家登陆A股的企业。公司始终聚焦于消防安全与物联网领域&#xff0c;主营业务为“一站式”消防安全系统产品的研发、生产和销售。公司产品已覆盖了火灾报…...

Flutter 中的 KeepAlive 小部件:全面指南

Flutter 中的 KeepAlive 小部件&#xff1a;全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架&#xff0c;它允许开发者使用 Dart 语言构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的丰富组件库中&#xff0c;KeepAlive 是一个用于维护组件活跃状态的组件&…...

C语言 恼人的结合性和优先级和副作用

结合性和优先级和副作用 1.优先级2.结合性3.副作用4.简单区分i&#xff0c;i&#xff0c;i1&#xff1b;ii1&#xff1b;ii 1.优先级 优先级指的是&#xff0c;如果⼀个表达式包含多个运算符&#xff0c;哪个运算符应该优先执⾏。各种运算符的优先级是 不⼀样的。 在C语言中&a…...

Vue——初识组件

文章目录 前言页面的构成何为组件编写组件组件嵌套注册 效果展示 前言 在官方文档中&#xff0c;对组件的知识点做了一个很全面的说明。本篇博客主要写一个自己的案例讲解。 vue 官方文档 组件基础 页面的构成 说到组件之前&#xff0c;先大致说明下vue中页面的构成要素。 在…...

MQ消息丢失/重复/顺序/挤压

rabbitmq消息丢失解决 rocketMq解决消息丢失 RocketMQ事务消息概要 RocketMQ事务消息是指应用本地事务和发送消息操作可以被定义到全局事务中&#xff0c;要么同时成功&#xff0c;要么同时失败。 采用了2PC&#xff08;两阶段提交&#xff09; 补偿机制&#xff08;事务状态回…...

利用Quarkus构建高效微服务——Java的云原生革新

引言&#xff1a; 在微服务架构和容器技术日益成为企业开发标准的今天&#xff0c;Java开发者面临着如何将传统Java应用转型为高效、轻量级且易于扩展的云原生应用的挑战。Quarkus框架的出现&#xff0c;正是为了解决这一问题&#xff0c;它不仅能够提升Java在Kubernetes环境中…...

python 批量ts合并成一个mp4

首先&#xff0c;确保你已经安装了ffmpeg。 然后再次保证所有ts文件放在同一个文件夹中&#xff0c;并且依次命名为 1.ts 、 2.ts 、 3.ts 、 4.ts 、 4.ts 。。。 Python完整代码如下&#xff1a;(ffmpeg_batch_merge_ts.py文件) #!/usr/bin/python3 # -*- coding: UTF-8 -*…...

Java | Leetcode Java题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; class Solution {public int sumNumbers(TreeNode root) {if (root null) {return 0;}int sum 0;Queue<TreeNode> nodeQueue new LinkedList<TreeNode>();Queue<Integer> numQueue new LinkedList<Integer>();…...

SpringBoot【注解 01】@Scheduled实现定时任务的串行和并行执行

在SpringBoot中&#xff0c;如果使用Scheduled注解来定义多个定时任务&#xff0c;默认情况下这些任务将会被安排在一个单线程的调度器中执行。这意味着&#xff0c;这些任务将会串行执行&#xff0c;而不是并行执行。当一个任务正在执行时&#xff0c;其他被触发的任务将会等待…...

【工具】redis的安装使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Redis简介二、Redis的安装使用三、本文总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 随着开发语言及人工智能工具的普及&am…...

汇编:数据定义数据填充

数组的定义 在32位汇编语言中&#xff0c;定义数组时&#xff0c;通常使用定义数据指令&#xff08;如 DB, DW, DD,DQ &#xff09;和标签来指定数组的名称和内容。DB定义字节数组&#xff08;每个元素占1字节&#xff09;、DW定义字数组&#xff08;每个元素占2字节&#xff…...

Python画图(多图展示在一个平面)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

python-web应用程序-Django数据库-操作表中的数据

python-web应用程序-Django数据库-操作表中的数据 一、新增数据 类.objects.create(字段名 字段值&#xff0c;字段名 字段值&#xff0c;...)导入models包 models.User.objects.create(nameyulin,sex0,info三好学生)即可对数据进行操作 二、删除数据 类.objects.filter(…...

绕过WAF(Web应用程序防火墙)--介绍、主要功能、部署模式、分类及注入绕过方式等

网站WAF是一款集网站内容安全防护、网站资源保护及网站流量保护功能为一体的服务器工具。功能涵盖了网马/木马扫描、防SQL注入、防盗链、防CC攻击、网站流量实时监控、网站CPU监控、下载线程保护、IP黑白名单管理、网页防篡改功能等模块。能够为用户提供实时的网站安全防护&…...

11.7 堆排序

目录 11.7 堆排序 11.7.1 算法流程 11.7.2 算法特性 11.7 堆排序 Tip 阅读本节前&#xff0c;请确保已学完“堆“章节。 堆排序&#xff08;heap sort&#xff09;是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”…...

Patchwork++:基于点云的快速、稳健的地面分割方法

1. 背景 论文发表在2022IROS&#xff0c;是Patchwork的改进版本。算法通过数学方法进行快速而鲁棒性很强的地面分割&#xff0c;在智能机器人上的可操作性非常强。通过微调算法&#xff0c;可以应用于16-beams等多种规格的激光雷达。由于激光雷达点云数据标注的难度非常大&…...