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

【C++基础知识学习笔记】精华版(复习专用)

常用语法

函数重载(Overload)

规则:

  • 函数名相同

  • 参数个数不同、参数类型不同、参数顺序不同

注意:

  • 返回值类型与函数重载无关

  • 调用函数时,实参的隐式类型转换可能会产生二义性

默认参数

C++ 允许函数设置默认参数,在调用时可以根据情况省略实参。规则如下:

  • 默认参数只能按照从右到左的顺序
  • 如果函数同时有声明、实现,默认参数只能放在函数声明中
  • 默认参数的值可以是常量、全局符号(全局变量、函数名)

如果函数的实参经常是同一个值,可以考虑使用默认参数。

int age = 33;void test() {cout << "test()" << endl;
}void display(int a = 11, int b = 22, int c = age, void (*func)() = test) {cout << "a is " << a << endl;cout << "b is "<< b << endl;cout << "c is " << c << endl;func();
}int main() {display();
}

函数重载、默认参数可能会产生冲突、二义性(建议优先选择使用默认参数)

void display(int a, int b = 20) {cout << "a is " << a << endl;
}void display(int a) {     cout << "a is " << a << endl; 
}int main() {display(10); // 编译失败,存在二义性
}

extern "C"

extern "C" 修饰的代码会按照 C 语言的方式去编译

extern "C" void func() { cout << "func()" << endl; 
}extern "C" void func1(int age) {cout << "func(int age) " << age << endl; 
}

如果函数同时有声明和实现,要让函数声明被 extern “C” 修饰,函数实现可以不修饰

extern "C" void func();
extern "C" void func1(int age);void func() {cout << "func()" << endl;
}void func1(int age) {cout << "func(int age) " << age << endl;
}
extern "C" {void func();void func1(int age);
}void func() {cout << "func()" << endl;
}void func1(int age) {cout << "func(int age) " << age << endl;
}

由于C、C++ 编译规则的不同,在C、C++ 混合开发时,可能会经常出现以下操作:

  • C++ 在调用 C 语言 API 时,需要使用 extern "C" 修饰 C 语言的函数声明
    在这里插入图片描述

  • 有时也会在编写 C 语言代码中直接使用 extern "C" ,这样就可以直接被 C++ 调用了
    在这里插入图片描述

#pragma once

我们经常使用#ifndef、#define、#endif来防止头文件的内容被重复包含

#pragma once可以防止整个文件的内容被重复包含

区别:

  • #ifndef、#define、#endif受 C/C++ 标准的支持,不受编译器的任何限制

  • 有些编译器不支持#pragna once (较老编译器不支持,如GCC 3.4版本之前),兼容性不够好

  • #ifndef、#define、#endif可以针对一个文件中的部分代码,而#pragma once只能针对整个文件

内联函数(inline function)

使用inline修饰函数的声明或者实现,可以使其变成内联函数。建议声明和实现都增加inline修饰。

特点:

  • 编译器会将函数调用直接展开为函数体代码
  • 可以减少函数调用的开销
  • 会增大代码体积

注意:

  • 尽量不要内联超过10行代码的函数

  • 有些函数即使声明为inline,也不一定会被编译器内联,比如递归函数

VS中可通过如下配置选择禁用或启用内联扩展:

在这里插入图片描述

内联函数与宏

  • 内联函数和宏,都可以减少函数调用的开销

  • 对比宏,内联函数多了语法检测和函数特性

思考以下代码的区别

#define sum(x) (x + x)int a = 10;int main() {std::cout << sum(a++) << std::endl; // 21std::cout << a << std::endl; // 12
}
  • 上面代码中 sum(a++) 等价于 (a++) + (a++)sum的计算结果会先取a的值(10)再取a++之后a的值(11)所以之和是21,而a本身由于自增了两次所以结果是12
inline int sum(int x) { return x + x; }int a = 10;int main() {std::cout << sum(a++) << std::endl; // 20std::cout << a << std::endl; // 11
}
  • 上面代码中 sum(a++) 属于函数调用,因此会捕获 a 的副本(10)传入函数中,在函数体中执行 10 + 10 得到结果是 20,在这之后由于 a 本身执行自增操作变成了 11

表达式

C++ 的有些表达式是可以被赋值的

int a = 1;
int b = 2;
(a = b) = 3; // 赋值给了 a
(a < b ? a : b) = 4; // 赋值给了 b

const

  • const是常量的意思,被其修饰的变量不可修改

  • 如果修饰的是类、结构体(的指针),其成员也不可以更改

struct Student { int age; }; int main() {Student stu1 = {10};Student stu2 = {20};const Student *pStu1 = &stu1;*pStu1 = stu2;     // 编译报错,*pStu1不能修改(*pStu1).age = 30; // 编译报错,*pStu1的成员不能修改pStu1->age = 30;   // 编译报错,*pStu1的成员不能修改pStu1 = &stu2;     // 编译成功,pStu1指向可以修改Student * const pStu2 = &stu2;*pStu2 = stu1;     // 编译成功,*pStu2 可以修改(*pStu2).age = 30; // 编译成功,*pStu2 的成员可以修改pStu2->age = 30;   // 编译成功,*pStu2 的成员可以修改pStu2 = &stu1;     // 编译报错,pStu2不能修改指向
}

思考:以下5个指针分别是什么含义?

int age = 10;
const int *p0 = &age;
int const *p1 = &age;
int * const p2 = &age;
const int * const p3 = &age;
int const * const p4 = &age;

上面的指针问题可以用以下结论来解决:const修饰的是其右边的内容

验证代码:

int main() {int a = 2;int age = 10;const int *p0 = &age;p0 = &a; // p0 可以修改*p0 = 3; // *p0 不能修改, 编译报错int const *p1 = &age;p1 = &a; // p1 可以修改*p1 = 3; // *p1 不能修改, 编译报错int * const p2 = &age;p2 = &a; // p2 不能修改, 编译报错*p2 = 3; // *p2 可以修改const int * const p3 = &age;p3 = &a; // p3 不能修改, 编译报错*p3 = 3; // *p3 不能修改, 编译报错int const * const p4 = &age;p4 = &a; // p4 不能修改, 编译报错*p4 = 3; // *p4 不能修改, 编译报错
}

引用(Reference)

  • 在C语言中,使用指针(Pointer)可以间接获取、修改某个变量的值
  • 在C++中,使用引用(Reference)可以起到跟指针类似的功能
int age = 20;
// rage 就是一个引用
int &rage = age;

注意点:

  • 引用相当于是变量的别名(基本数据类型、枚举、结构体、类、指针、数组等,都可以有引用)
  • 对引用做计算,就是对引用所指向的变量做计算
  • 在定义的时候就必须初始化,一旦指向了某个变量,就不可以再改变,“从一而终
  • 可以利用引用初始化另一个引用,相当于某个变量的多个别名
  • 不存在【引用的引用、指向引用的指针、引用数组】

引用存在的价值之一:比指针更安全、函数返回值可以被赋值

引用的本质

  • 引用的本质就是指针,只是编译器削弱了它的功能,所以引用就是弱化了的指针

  • 一个引用占用一个指针的大小

常引用(Const Reference)

引用可以被const修饰,这样就无法通过引用修改数据了,可以称为常引用

  • const必须写在符号的左边,才能算是常引用

const引用的特点:

  • 可以指向临时数据(常量、表达式、函数返回值等)
  • 可以指向不同类型的数据
  • 作为函数参数时(此规则也适用于const 指针):
    可以接受const和非const实参(但非const引用只能接受非const实参)
    可以跟非const引用构成重载

注意:当常引用指向了不同类型的数据时,会产生临时变量,即引用指向的并不是初始化时的那个变量。

数组的引用

常见的2种写法:

int array[] = { 10,20,30 }; 
int (&ref1)[3] = array;
int * const &ref2 = array; ref1[0] = 8;
int a = ref1[2];
ref2[1] = 4;
int b = ref2[2]

变量地址总结

一个变量的地址值,是它所有字节地址中的最小值

面向对象

  • C++ 中可以使用structclass来定义一个类

structclass 的区别:

  • struct 的默认成员权限是 public
  • class 的默认成员权限是 private

在这里插入图片描述
在这里插入图片描述

  • 上面代码中person对象、p指针的内存都是在函数的栈空间,自动分配和回收的
  • 可以尝试反汇编structclass,看看是否有其他区别
  • 实际开发中,用class表示类比较多

C++编程规范

每个人都可以有自己的编程规范,没有统一的标准,没有标准答案,没有最好的编程规范

变量名规范参考:

  • 全局变量:g_
  • 成员变量:m_
  • 静态变量:S_
  • 常量:C_
  • 使用驼峰标识

对象的内存布局

思考:如果类中有多个成员变量,对象的内存又是如何布局的?

struct Person {int m_id; int m_age; int m_height;void display() {cout << "m id is " << m_id << endl;cout << "m_age is " << m_age << endl;cout << "m_height is " << m_height << endl;}
};

在这里插入图片描述

this

  • this是指向当前对象的指针

  • 对象在调用成员函数的时候,会自动传入当前对象的内存地址

struct Person {int m_id;int m_age;int m_height;void display() {cout << "m id is " << this->m_id << endl;cout << "m_age is " << this->m_age << endl;cout << "m_height is " << this->m_height << endl;}
};

思考:可以利用 this.m_age 来访问成员变量么?

  • 不可以,因为this是指针,必须用this->m_age

指针访问对象成员的本质

思考:以下代码最后打印出来的每个成员变量值是多少?

struct Person {int m_id;int m_age;int m_height;void display() {cout << "m id is " << this->m_id << endl;cout << "m_age is " << this->m_age << endl;cout << "m_height is " << this->m_height << endl;}
};int main() {Person person;person.m_id = 10;person.m_age = 20;person.m_height = 30;Person *p = (Person *) &person.m_age;p->m_id = 40;p->m_age = 50;person.display();
}

答案输出是:

m id is 10
m_age is 40
m_height is 50

在这里插入图片描述

思考:如果将 person.display() 换成 p->display() 呢?

输出如下:

m id is 40
m_age is 50
m_height is -1063256544

此时 p->m_height 指向了一块未知的内存。、

封装

成员变量私有化,提供公共的gettersetter给外界去访问成员变量

struct Person{
private:int m_age;
public:void setAge(int age) {this->m_age = age;}int getAge() {return this->m_age;}
};Person person;
person.setAge(20);
cout << person.getAge() << endl;

内存空间的布局

每个应用都有自己独立的内存空间,其内存空间一般都有以下几大区域

在这里插入图片描述

  • 代码段(代码区):用于存放代码

  • 数据段(全局区):用于存放全局变量等

  • 栈空间

    • 每调用一个函数就会给它分配一段连续的栈空间,等函数调用完毕后会自动回收这段栈空间
    • 自动分配和回收
  • 堆空间:需要主动去申请和释放

在这里插入图片描述

在这里插入图片描述

堆空间

在程序运行过程,为了能够自由控制内存的生命周期、大小,会经常使用堆空间的内存

堆空间的申请\释放

  • malloc \ free

  • new \ delete

  • new[] \ delete[]

注意:

  • 申请堆空间成功后,会返回那一段内存空间的地址

  • 申请和释放必须是1对1的关系,不然可能会存在内存泄露

现在的很多高级编程语言不需要开发人员去管理内存(比如Java),屏蔽了很多内存细节,利弊同时存在

  • 利:提高开发效率,避免内存使用不当或泄露

  • 弊:不利于开发人员了解本质,永远停留在API调用和表层语法糖,对性能优化无从下手

下图是x86环境(32bit):

在这里插入图片描述

堆空间的初始化

在这里插入图片描述

memset

memset函数是将较大的数据结构(比如对象、数组等)内存清零的比较快的方法

Person person;
person.m_id = 1;
person.m_age = 20;
person.m_height = 180;
memset(&person, 0, sizeof(person));Person persons[] ={ { 1,20,180 }, { 2,25,165,},{ 3,27,170 } }; 
memset(persons, 0, sizeof(persons));

对象的内存

对象的内存可以存在于3种地方:

  • 全局区(数据段):全局变量
  • 栈空间:函数里面的局部变量
  • 堆空间:动态申请内存(mallocnew等)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

构造函数(Constructor)

构造函数(也叫构造器),在对象创建的时候自动调用,一般用于完成对象的初始化工作

特点:

  • 函数名与类同名,无返回值(void都不能写),可以有参数,可以重载,可以有多个构造函数
  • 一旦自定义了构造函数,必须用其中一个自定义的构造函数来初始化对象

注意:

  • 通过malloc分配的对象不会调用构造函数

一个广为流传的、很多教程/书籍都推崇的错误结论:

  • 默认情况下,编译器会为每一个类生成空的无参的构造函数

  • 正确理解:在某些特定的情况下,编译器才会为类生成空的无参的构造函数(哪些特定的情况?以后再提)

构造函数的调用

struct Person {int m_age;Person() {cout << "Person()" << endl;}Person(int age) {cout << "Person(int age)" << endl;}
}

在这里插入图片描述

默认情况下,成员变量的初始化

在这里插入图片描述

  • 如果自定义了构造函数,除了全局区,其他内存空间的成员变量默认都不会被初始化,需要开发人员手动初始化。

成员变量的初始化

对象初始化

Person() {memset(this, 0, sizeof(Person)); 
}

析构函数(Destructor)

析构函数(也叫析构器),在对象销毁的时候自动调用,一般用于完成对象的清理工作

特点:

  • 函数名以~开头,与类同名,无返回值(void都不能写),无参,不可以重载,有且只有一个析构函数

注意:

  • 通过malloc分配的对象free的时候不会调用析构函数
  • 构造函数、析构函数要声明为public,才能被外界正常使用。

声明和实现分离

在这里插入图片描述

命名空间

命名空间可以用来避免命名冲突

在这里插入图片描述

思考:如下代码能通过编译吗?

namespace MJ {int g_age;
}
namespace FX {int g_age;
}using namespace MJ;
using namespace FX;// 这句代码能编译通过么?
g_age = 20;
  • 不能,必须指明命名空间前缀,否则具有二义性,编译器无法做出判断

命名空间的嵌套

有个默认的全局命名空间,我们创建的命名空间默认都嵌套在它里面

namespace MJ {namespace SS {int g_age;}
}int main() {MJ::SS::g_age = 10;using namespace MJ::SS;g_age = 20;using MJ::SS::g_age;g_age = 30;
}
int g_no = 20;namespace MJ {namespace SS {int g_age;}
}int main() {::g_no = 20;::MJ:SS::g_age = 30;
}

命名空间的合并

以下2种写法是等价的:

namespace MJ {int g_age;
}
namespace MJ {int g_no;
}
namespace MJ {int g_age;int g_no; 
}

在这里插入图片描述

其他编程语言的命名空间

Java:

  • Package

Objective-C:

  • 类前缀

继承

继承,可以让子类拥有父类的所有成员(变量\函数)

struct Person {int m_age;void run() {cout << "Person::run()" << endl;}
};
struct Student : Person {int m_no;void study() {cout << "Student::study()" << endl;}
};int main() {Student student; student.m_age = 20; student.m_no = 1; student.run(); student.study();
}

关系描述

  • Student 是子类(subclass,派生类)
  • Person 是父类(superclass,超类)

C++中没有像Java, Objective-C的基类:

  • Java: java.lang.Object
  • Objective-C: NSObject

继承关系中的对象内存布局

在这里插入图片描述

构造函数的初始化列表

  • 一种便捷的初始化成员变量的方式
  • 只能用在构造函数中
  • 初始化顺序只跟成员变量的声明顺序有关

下面两种代码写法是等价的:

struct Person {int m_age;int m_height;Person(int age, int hei

相关文章:

【C++基础知识学习笔记】精华版(复习专用)

常用语法 函数重载(Overload) 规则: 函数名相同 参数个数不同、参数类型不同、参数顺序不同 注意: 返回值类型与函数重载无关 调用函数时,实参的隐式类型转换可能会产生二义性 默认参数 C++ 允许函数设置默认参数,在调用时可以根据情况省略实参。规则如下: 默认参数只能…...

探索ChatGPT在学术写作中的应用与心得

随着人工智能的迅猛发展&#xff0c;ChatGPT作为一种强大的自然语言处理模型&#xff0c;逐渐在学术界引起了广泛的关注。本文将探讨ChatGPT在学术写作中的应用&#xff0c;并分享使用ChatGPT进行学术写作时的一些经验和心得。 01 — ChatGPT在学术写作中的应用 1.文献综述和…...

Android:怎么学习才能更好的进大厂呢?

怎么学习才能更好的进大厂呢&#xff1f; 很多朋友都在问这个问题。 其实没有什么特别的技巧&#xff0c;就是依靠自己的毅力和决心。一天做不到&#xff0c;就一个月&#xff1b;一个月做不到&#xff0c;就一年。只要有决心&#xff0c;无论学历或资历如何&#xff0c;都不是…...

CSS标点符号换行问题

最近遇到一个奇怪的现象,元素中中文文本正常显示,但是加了一堆符号后中文文本居然换行了. div{width: 200px;border: 1px solid blue;word-break: break-all;} <div>文本</div>经过研究发现&#xff0c;因为标点符号不允许出现在行首和行尾&#xff0c;连带着符号…...

jdbc Preparestatement防止SQL注入的原理

2023-10-28T03:37:11.264132Z 2 Execute select * from users where username liulemon and password \ or \1\ 1\ 可以看到这一行&#xff0c;预编译时&#xff1f;变成了转义字符 useServerPrepStmtstrue加上这句才能预编译...

如何控制 LLM 的输出格式和解析其输出结果?

现在很多人对于如何使用像 ChatGPT 这样的 LLM 已经比较有经验了&#xff0c;可以使用各种不同的 Prompt 得到自己想要的结果。但有时候我们的使用场景不局限于手动操作&#xff0c;而是需要结合程序去调用 API&#xff0c;并且解析 API 的返回结果&#xff0c;从而实现一些自动…...

【Linux】 ps 命令使用

ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器。 语法 ps [选项] ps命令 -Linux手册页 著者 ps最初由布兰科兰克斯特撰写<lankestefwi.uva.nl>。迈克尔K约翰逊<johnsonmred…...

C++二分查找算法的应用:长度递增组的最大数目

本文涉及的基础知识点 二分查找 题目 给你一个下标从 0 开始、长度为 n 的数组 usageLimits 。 你的任务是使用从 0 到 n - 1 的数字创建若干组&#xff0c;并确保每个数字 i 在 所有组 中使用的次数总共不超过 usageLimits[i] 次。此外&#xff0c;还必须满足以下条件&…...

提示3D标题编辑器仍在运行怎么解决,以及3D标题编辑器怎么使用

在进行视频剪辑时&#xff0c;尤其是剪辑一些带有文字的开场视频&#xff0c;一般都会使用具有立体效果的3D标题&#xff0c;这样制作出来的视频效果不仅好看&#xff0c;还非常的炫酷&#xff0c;但是对于一些刚刚开始接触视频剪辑的小伙伴来说&#xff0c;可能对3D标题还不是…...

1. PPT高效初始化设置

1. PPT高效初始化设置 软件安装&#xff1a;Office 2019 主题和颜色 颜色可以在白天与黑夜切换&#xff0c;护眼 切换成了黑色 撤回次数 撤回次数太少&#xff0c;只有20次怎么办 自动保存 有时忘记保存就突然关闭&#xff0c;很需要一个自动保存功能 图片压缩 图…...

el-cascader级联选择器选中一个全选中问题

问题 只选中一个却把同级全选中 解决 :props中添加label、value、children属性 label、value、children属性值需要和后端返回的集合中的字段名保持一致 后端返回数据&#xff1a;...

Opencascad(C++)-创建自定义坐标系

文章目录 1、前言2、在Opencascad中显示小的坐标系3、在Opencascad中创建自定义的坐标系 1、前言 在Opencascad开发时&#xff0c;在view中可以显示小的坐标系&#xff0c;但是有时我们需要在建模时创建基准坐标系&#xff0c;当然可以作为工件坐标系也可以作为基准坐标系。本…...

MySQL数据库入门到大牛_01_数据库概述

文章目录 1. 为什么要使用数据库2. 数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库与数据库管理系统的关系2.3 常见的数据库管理系统排名(DBMS)2.4 常见的数据库介绍 3. MySQL介绍3.1 概述3.2 MySQL发展史重大事件3.3 关于MySQL 8.03.4 Why choose MySQL?3.5 Oracle v…...

Web - Servlet详解

目录 前言 一 . Servlet简介 1.1 动态资源和静态资源 1.2 Servlet简介 二 . Servlet开发流程 2.1 目标 2.2 开发过程 三 . Servlet注解方式配置 ​编辑 四 . servlet生命周期 4.1 生命周期简介 4.2 生命周期测试 4.3 生命周期总结 五 . servlet继承结构 5.1 ser…...

postgresql 触发器如何生成递增序列号,从1开始,并且每天重置

大家好&#xff0c;我是三叔&#xff0c;许久不见&#xff0c;这期给大家介绍一下笔者在开发中遇到的业务处理&#xff1a;pgsql 创建触发器生成每日递增序列&#xff0c;并且第二天重置&#xff0c;根据不同的用户进行不同的控制。 1.创建生成递增序列的 table 表 -- 创建us…...

“第五十九天”

这是昨天那道题&#xff0c;这个后面自己的处理思路还是差了点&#xff0c;这道题关键感觉就是对进位的处理的&#xff0c;由于进位的存在&#xff0c;所以处理数据的时候只能从最低位开始&#xff0c;我一开始是从高位处理的&#xff0c;而且后面越来越迷&#xff0c;这个点一…...

IDEA集成Docker插件打包服务镜像与运行【附Docker命令汇总】

Docker官网 Docker官网&#xff1a;https://www.docker.com/ Docker Hub官网&#xff1a;http://hub.docker.com/ 什么是Docker Docker 是一个开源的容器引擎&#xff0c;可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者和系统管理员在笔记本上编…...

【Linux网络编程_TCP/UDP_字节序_套接字 实现: FTP 项目_局域网聊天项目 (已开源) 】.md updata:23/11/03

文章目录 TCP/UDP对比端口号作用字节序字节序转换api套接字 socket实现网络通讯服务端 逻辑思路demo&#xff1a; 满血版双方通讯/残血版多方通讯服务端 demo客户端 demo FTP 项目实现sever demo:client demo: 局域网多方通讯 配合线程实现sever demo:client demo: TCP/UDP对比…...

Leetcode刷题详解——全排列

1. 题目链接&#xff1a;46. 全排列 2. 题目描述&#xff1a; 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],…...

JSONP 跨域访问(1), 简介, 原理, 实验, 缺点

JSONP 跨域访问(1), 简介, 原理, 实验, 缺点 一, JSONP 简介 JSONP&#xff08;JSON with Padding&#xff09;是一种非官方跨域数据交互协议。它允许web页面从不同的域名下加载数据。 由于同源策略&#xff0c;web页面通过XMLHttpRequest调用通常只允许访问与其自身相同域名…...

velero备份k8s集群

流程图 velero备份原理 本地 Velero 客户端发送备份指令。Kubernetes 集群内就会创建一个 Backup 对象。BackupController 监测 Backup 对象并开始备份过程。BackupController 会向 API Server 查询相关数据。BackupController 将查询到的数据备份到远端的对象存储。 velero的…...

描述低轨星座的特点和通信挑战,以及它们在5G和B5G中的作用。

文章目录 2章4 章5章&#xff08;没看&#xff09;6章&#xff08;没看&#xff09; 2章 将卫星星座中每个物理链路中可实现的数据速率、传播延迟和多普勒频移与3GPP技术报告中的参数进行分析和比较[3]。 相关配置 面向连接的网络&#xff0c;预先简历链路 卫星和地面终端有…...

Spring Boot实践 --windows环境下 K8s 部署 Docker

第一步&#xff1a;搭建项目并制作合适的jar包 这里我们准备好前面项目 用户管理系统 项目里的jar包。测试功能&#xff0c;定时任务会每过10s打印一次日志&#xff1a; E:\test>java -jar demospringboot-0.0.1-SNAPSHOT.jar2023-11-01 20:24:21.059 INFO 11848 --- [ …...

Linux 将Qt程序打包为AppImage包

前言 在 Linux 环境下&#xff0c;开发完 Qt 程序后&#xff0c;也需要制作为一个安装包或者可执行文件进行分发。这里介绍使用 linuxdeployqt 将 Qt 程序打包为 .AppImage 应用程序&#xff08;类似于 Windows 的绿色免安装软件&#xff09; 环境配置 配置 Qt 环境变量 这…...

修复国产电脑麒麟系统开机出现initramfs 问题

目录预览 一、问题描述二、原因分析三、解决方案四、知识点呀initramfsBusyBox 五、参考链接 一、问题描述 国产麒麟系统出现 initramfs 模式 二、原因分析 一般在拷贝卡顿过程【强制关机】或者电【脑异常断电】的情况下概率性导致系统分区损坏&#xff0c;重启后大概率就会进…...

机器人控制算法—如何使用C++读取pgm格式的栅格地图并转化为ROS地图格式的data?

1.Introduction 近期正在做全局规划局部动态规划的项目&#xff0c;目前遇到的问题是&#xff0c;我们如何利用C处理pgm地图文件。即将地图信息要与像素点结合起来。所以我们需要知道地图读取和处理的底层原理&#xff0c;这样更好地在非ROS平台下移植。 2.Main 如下几条信息…...

牛客项目(五)-使用kafka实现发送系统通知

kafka入门以及与spring整合 Message.java import java.util.Date;public class Message {private int id;private int fromId;private int toId;private String conversationId;private String content;private int status;private Date createTime;public int getId() {retur…...

计算机网络——第一章时延部分深入学习、相关习题及详细解析

目录 时延相关 习题1 习题1-改 习题2 时延相关 之前我们学习过&#xff0c;时延由发送时延、传播时延和处理时延三部分构成。 发送时延的计算公式为“分组长度除以发送速率”&#xff0c; 发送速率应该从网卡速率、信道带宽、以及对端的接口速率中取最小。 传播时延的计…...

CSS3媒体查询与页面自适应

2017年9月&#xff0c;W3C发布媒体查询(Media Query Level 4)候选推荐标准规范&#xff0c;它扩展了已经发布的媒体查询的功能。该规范用于CSS的media规则&#xff0c;可以为文档设定特定条件的样式&#xff0c;也可以用于HTML、JavaScript等语言。 1、媒体查询基础 媒体查询…...

UG\NX二次开发 超长的对象属性值,怎么设置

文章作者:里海 来源网站:里海NX二次开发3000例专栏 感谢粉丝订阅 感谢 Dr. Lin 订阅本专栏,非常感谢。 简介 使用UF_ATTR_assign设置对象属性,如果属性值超过UF_ATTR_MAX_STRING_LEN则会报错。 #define UF_ATTR_MAX_STRING_LEN 132 怎么办呢?下面这种方法可以解决: 效果 …...