C/C++基础知识

news2024/11/24 3:52:26

专栏:C/C++
个人主页:

C/C++基础知识

  • 前言
  • C++关键字(C++98)
  • 命名空间
    • 命名空间的定义
      • 正常的命名空间的定义
        • 如何使用命名空间
    • 命名空间可以嵌套
    • 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中(一个工程中的.h文件和test.cpp中的同名也会合并成一个)
  • C++的输入和输出
      • std
  • 缺省参数
    • 缺省参数定义格式
    • 缺省参数分类
  • 函数重载
    • 函数参数个数不同
    • 参数类型顺序不同
  • 引用
    • 引用的特性
    • 常引用
    • 做参数
    • 做返回值
    • 引用和指针的区别
  • auto关键字(C++11)
  • 基于范围的for循环(C++11)
  • 内联函数
  • NULL和nullptr
  • 语法糖简介

前言

C++是在C语言的基础上,添加了面向对象编程,使程序更加模块化,利于维护和扩展,还增加了很多标准库,库中包含了许多实用的数据结构,算法,容器,输入,输出等。

C++关键字(C++98)

C++总计63个关键字,C语言32个关键字

在这里插入图片描述

命名空间

在用C语言编写程序时,要注意命名冲突这一个问题,比如全局变量和局部变量名字相同或者函数名字冲突等。

在这里插入图片描述

C语言并没有给出这种问题的解决方法,那么C++呢?


在C++中,给出了namespace关键字,来解决这一问题。

命名空间的定义

命名空间是一种机制,可以将全局作用域划分为更小的独立作用域,从而利于解决命名冲突的问题。

那么命名空间是如何创建的呢?

namespace namespace_name {
  // 变量、函数、类等定义
}

正常的命名空间的定义

#include <iostream>
#include <stdlib.h>

using namespace std;

namespace test
{
	int rand = 100;
}

int main()
{
	return 0;
}

这样,就不会在出现由于命名冲突造成的警告了。


但是怎么去访问test这块空间呢?

using namespace

这两个单词是什么意思呢?—使用命名空间


如何使用命名空间

在C++中使用命名空间,有两种常见的方式,一种是使用using关键字,另一种是直接使用命名空间限定符。

第一种方式是使用using关键字将命名空间引入当前作用域中,这样就可以在当前作用域中直接使用命名空间中的函数、变量等定义。

也可以这样理解,就是将std中的东西暴漏在全局变量中供使用。

#include <iostream>
using namespace std;  // 引入 std 命名空间

int main() {
    cout << "Hello, world!" << endl;  // 可以直接使用 cout,而不必使用 std::cout
    return 0;
}

需要注意的是,使用using关键字引入命名空间可能会带来命名冲突的问题,因此最好只在函数内部或局部范围内使用,而不要在全局范围内使用。

第二种方式是使用命名空间限定符来访问命名空间中的元素。在访问命名空间中的元素时,需要使用名称前面加上命名空间限定符来表示要访问的元素属于哪个命名空间。例如:

#include <iostream>
#include <stdlib.h>

using namespace std;

namespace test
{
	int rand = 100;
}

int main()
{
	cout << test::rand << endl;
	return 0;
}

使用命名空间限定符的方式可以避免命名冲突问题,但是在代码中会显得比较繁琐。因此,建议在代码中使用合适的方式来使用命名空间。


命名空间可以嵌套

在C++中可以使用命名空间嵌套的方式来实现更加复杂的命名空间划分。

#include <iostream>
#include <stdlib.h>

using namespace std;

namespace test_1
{
	int rand_1 = 100;

	namespace test_2
	{
		int rand_2 = 200;
	}
}

int main()
{
	cout << "namespace test_1:" << test_1::rand_1 << endl;
	cout << "namespace test_2:" << test_1::test_2::rand_2 << endl;
	return 0;
}

需要注意的是,命名空间的嵌套使用并不是局限于两层,可以根据现实需求来设计层数。

同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中(一个工程中的.h文件和test.cpp中的同名也会合并成一个)

同一个工程中可以存在多个相同名称的命名空间。当编译器编译完这些命名空间中的代码后,编译器会将它们合并为同一个命名空间,不同于相同名称的类。这个过程发生在编译期间,因此当程序运行时,只有一个命名空间被使用。

//.h文件
#include <iostream>

using namespace std;

namespace test_1
{
	int  rand_3 = 300;
}

//.cpp文件

#include "test_2.h"

namespace test_1
{
	int rand_1 = 100;

	namespace test_2
	{
		int rand_2 = 200;
	}
}

int main()
{
	cout << "namespace test_1:" << test_1::rand_1 << endl;
	cout << "namespace test_2:" << test_1::test_2::rand_2 << endl;
	cout << "namespace test_3:" << test_1::rand_3 << endl;
	return 0;
}

在这里插入图片描述

C++的输入和输出

C++的输入和输出与C语言不太一样,C++的输入和输出可以自动识别数据类型,double,char,int等类型的数据都可以直接进行输入和输出。

输入操作为:std::cin

输出操作为:std::cout

在这里插入图片描述

在这里要先介绍一下C++的std

std

在C++中,命名空间std是标准库的命名空间,C++标准库包含一组头文件,类型定义,变量和函数,主要主要用于提供常用的基本功能,如文件输入输出、字符串处理、数学计算、容器、算法等等。这些功能和对象被封装在std命名空间中,以防止名称冲突和命名混乱。

具体而言,命名空间std中包含了大量的常用C++库的定义和声明,它的完整的名称是std::。例如std::cout、std::cin、std::endl等等,这些都是C++标准库中定义的常用对象和函数。

需要注意的是,在使用C++标准库中的功能之前,需要包含对应的头文件。例如,为了使用标准输出流cout,需要在程序中包含头文件iostream。

缺省参数

在C++中,缺省参数是指函数或方法在定义时可以给某些参数指定默认值,当调用该函数或者方法的时候,如果没有为这些参数提供实参时,系统会默认使用默认值。

缺省参数定义格式

return_type function_name(type1 param1 = default_value1, type2 param2 = default_value2, ...);

缺省参数必须位于参数列表的末尾,且每个参数只能有一个缺省值。

下面是一个使用缺省参数的函数定义

#include <iostream>

void add(int a = -1)
{
	std::cout << "add->a:" << a << std::endl;

	return;
}

int main()
{
	add();
	add(10);
	return 0;
}

这个代码中,函数add中的参数a有一个默认值-1,所以在调用add这个函数的时候,如果没有给实参,则a的值默认为-1,如果给了实参,则a的值就是实参的值。

缺省参数分类

全缺省参数

#include <iostream>

void add(int a = -1,int b = 1,int c = 2)
{
	std::cout << a + b + c << std::endl;

	return;
}

int main()
{
	add();
	return 0;
}

在这里插入图片描述

半缺省参数

#include <iostream>

void add(int a = -1,int b = 1,int c = 2)
{
	std::cout << a + b + c << std::endl;

	return;
}

int main()
{
	add(100);
	return 0;
}

在这里插入图片描述

缺省参数不能在函数声明和定义中同时出现。

在这里插入图片描述

函数重载

函数重载指的是在同一作用域中定义多个同名函数的行为,这些同名函数具有不同的参数列表,他们的参数类型,参数个数或者参数类型顺序不同。在调用这些同名函数时,编译器会根据实参的类型和个数匹配最合适的函数。

//函数参数类型不同
#include <iostream>

float max(float a, float b)
{
	return a > b ? a : b;
}

int max(int a, int b)
{
	return a > b ? a : b;
}

int main()
{
	std::cout << "float max " << max(1.2, 1.3) << std::endl;
	std::cout << "int max " << max(1, 2) << std::endl;

	return 0;
}

这里定义了两个同名函数max,一个接受两个int类型的参数,另一个接受两个float类型的参数。这两个函数实现的功能是计算传入的两个数的最大值。在调用这两个函数时,编译器会根据传入的参数类型的不同来匹配最合适的函数。

在这里插入图片描述

需要注意的是,函数的返回值类型并不影响函数重载,也就是说,返回值类型相同的函数也可以重载。但是,如果只有函数的返回值类型不同,则会发生编译错误。


函数重载的底层原理是利用了名字修饰特性,名字修饰指的是将函数名和参数列表的信息编码为一定格式的字符串的过程。

当函数被调用时,编译器会根据函数名和参数列表的类型、数量、顺序等信息生成一个唯一的名字(也就是名字修饰后的字符串)。这个名字被用来表示函数在符号表中的位置,以便于链接器在连接时正确地找到函数的地址。

在这里插入图片描述

在Linux下,采用g++编译完成后,函数名字的修饰发生改变,float max(float a, float b)的名字就变成了 <_Z3maxff>

函数参数个数不同

void func()
{
	std::cout << "func()" << std::endl;
}

void func(int a)
{
	std::cout << "func(int a)" << std::endl;
}

int main()
{
	func();
	func(100);

	return 0;
}

在这里插入图片描述

参数类型顺序不同

#include <iostream>

void f(int a, char b)
{
	std::cout << "f int a char b" << std::endl;
}

void f(char a, int b)
{
	std::cout << "f char a int b" << std::endl;
}

int main()
{
	f(1, 'b');
	f('b', 1);

	return 0;
}

在这里插入图片描述

引用

引用并不是定义一个新的变量,而是对一个已经存在的变量,取一个外号(别名),(比如:张三的外号叫大牛,那么我问大牛吃过饭没是不是等价于问张三吃过饭没?),编译器不会为引用变量新开一个空间,他和他引用的变量共用一块空间。

int x = 10;
int &ref = x;
//这里的int 和变量名字都是自己定义的,可以修改

注:引用类型必须和引用实体是同种类型,

引用的特性

  1. 引用必须在定义时初始化,因为引用是已存在的变量的别名,如果没有初始化,就没有引用的对象
#include <iostream>

int main()
{
	int a = 1;
	int& ra;

	return 0;
}

在这里插入图片描述

  1. 引用一旦初始化后,就不能在改变他锁引用的对象(引用一旦绑定,就不能解绑了)
  2. 引用使用时可以像变量一样自然的直接调用
  3. 引用同样需要遵循作用域的规则。在引用的作用域内,它所引用的对象必须处于有效状态
  4. 一个变量可以有多个引用

常引用

void TestConstRef()
{
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量,a只有读的权限,不能提升为不加const的引用之后,权限提升---读和写
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;//,临时空间具有常性
}

做参数

#include <iostream>

void func(int& a)
{
	a--;
}

int main()
{
	int a = 10;
	func(a);
	std::cout << a << std::endl;

	return 0;
}

在这里插入图片描述

当我们想要在函数内部修改某个变量的值,并使这个变化保持在函数外部,可以考虑使用引用作为参数。使用引用作为函数参数的好处在于可以避免函数传递过程中对变量的拷贝,提高程序的效率,同时也可以方便地在函数内部修改变量的值。

做返回值

在用引用做返回值:使用引用作为函数的返回值,使得函数的返回值是某个已经存在的变量,而不是函数内部新创建的一个变量。

#include <iostream>

int& func()
{
	static int n = 0;
	n++;
	return n;
}

int main()
{

	std::cout << func() << std::endl;

	return 0;
}

在这里插入图片描述

n被static修饰了,所以这个代码没什么问题。


#include <iostream>
#include <cstdlib>
int& func()
{
	int n = 0;
	n++;
	return n;
}

int main()
{
	int &ret = func();
	std::cout << ret << std::endl;

	rand();
	std::cout << ret << std::endl;

	return 0;
}

在这里插入图片描述

这个代码输出随机值的原因是因为,在函数func()中,我们返回的是一个局部变量n的引用。当函数返回时,局部变量n会被销毁,它的内存空间被系统回收,所以返回的引用实际上是指向了一个不存在的内存空间。

因此,当我们在主函数中使用返回的引用变量ret时,由于其指向了一个已经被销毁的内存空间,所以输出的结果是不确定的,可能是随机值,也可能是0,也可能是程序崩溃。

解决这个问题的方法是,我们需要将相关变量的生命周期扩展到函数外部。例如,在这个例子中,我们可以将变量n定义为静态变量,使其生命周期和程序的生命周期相同,或者动态分配一个内存空间,并将其地址作为引用返回。

引用和指针的区别

C++中引用和指针都可以用来间接访问变量,在某些情况下它们可以相互替换使用,但是它们仍然有着不同的实现和应用。

  1. 内存占用:指针需要额外使用内存来存放指针变量的地址,而引用本质上并不需要占用额外的内存空间。
  2. 使用限制:指针可以被初始化为空指针或指向任意地址,而引用必须在声明时被初始化,并且不能更改其指向的变量。
  3. 空值:引用永远不会为空,而指针可以为空。
  4. 作为函数参数:引用作为函数参数时,可以避免对象的复制,提高效率。而指针作为函数参数时,可以方便地修改指针指向的变量。
  5. 在sizeof中的含义不同,指针是地址,占用空间为32/64 — 4/8
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

auto关键字(C++11)

C++11引入了auto关键字,使得程序员可以使用类型推导的方式定义变量,让编译器自动推断变量的类型。它的语法形式为:

auto variable = value;

其中,variable为变量名,value为变量的初始值,编译器会根据value的类型推导出variable的类型。

auto关键字的使用可以使代码更加简洁、易读、易维护,同时也方便定义一些复杂类型的变量,例如迭代器、函数返回值等。以下是auto关键字的一些应用场景:

  1. 推导迭代器类型
map<string, int> m;
for(auto it = m.begin(); it != m.end(); ++it) {
    ...
}
  1. 推导函数返回值类型
auto sum(int a, int b) {
    return a + b;
}
...
auto result = sum(1, 2);
  1. 推导类成员变量类型
class Example {
    auto num = 10;
};

需要注意的是,在使用auto关键字时需要确保变量的类型能够被准确地推导出来,否则会导致编译错误。

基于范围的for循环(C++11)

C++11引入了基于范围的for循环语句,它提供了一种便捷的方式遍历容器(如数组、向量和映射等)及其它支持begin()end()函数的对象。

基于范围的for循环的语法形式如下:

for (declaration : sequence) {
    statement 
}

其中,declaration是用于定义循环的迭代变量的声明(推荐使用auto关键字来进行类型推导),sequence是需要遍历的容器或数据结构,statement是每一次循环要执行的操作。

下面是一个使用基于范围的for循环对数组进行遍历的例子:

int arr[] = {1, 2, 3, 4, 5};
for (auto x : arr) {
    cout << x << " ";
}

输出结果为:1 2 3 4 5

下面是使用基于范围的for循环对向量进行遍历的例子:

vector<int> vec = {1, 2, 3, 4, 5};
for (auto x : vec) {
    cout << x << " ";
}

输出结果为:1 2 3 4 5

基于范围的for循环相比于传统的for循环更加简洁、易读,并且能够避免因数组越界而导致的程序崩溃等问题。此外,它也支持使用const关键字限制迭代变量,使得其值在循环体内不能被修改。


除此之外,也可以修改值

int arr[] = {1, 2, 3, 4, 5};
for (auto& x : arr) {
    x += 1;
}
for (auto x : arr) {
    cout << x << " ";
}

输出结果为:2 3 4 5 6

内联函数

内联函数指的是使用关键字inline定义的函数,表示该函数是一个内联函数。内联函数与普通函数的区别在于,内联函数的调用不是通过函数栈帧的方式,而是直接在调用位置进行代码展开,从而减少了函数调用的开销,提高了程序的执行效率。

具体来说,当我们使用内联函数时,编译器会将函数体的代码直接展开到调用的位置,从而避免了函数调用时压栈和出栈的操作,减少了开销。但是,内联函数也有一些限制,如函数体不能过于复杂,否则可能会导致代码大小明显增加,进而扰动了缓存、提高了指令访问路径(instruction access path)的长度,降低了CPU Pipeline的效率。

一个内联函数的定义通常是放在头文件中,它的定义一般是在函数体前加上inline关键字。例如下面的图片

注:内联函数只是像编译器发出一个请求,编译器可以选择忽略这个请求

在这里插入图片描述

在这里插入图片描述

NULL和nullptr

NULL和nullptr都表示空指针。它们的区别在于,NULL实际上是一个宏定义,通常被定义为0,而nullptr是C++11中引入的关键字,它是一个真正意义上的空指针,可以避免一些因为0被隐式转换为指针而导致的错误。

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

C语言中我们通常使用NULL来表示空指针,例如:

int* ptr = NULL;

而在C++11中,我们可以使用nullptr来表示空指针,例如:

int* ptr = nullptr;

关于这两者的使用,在一些情况下,它们可以互换使用。但是,nullptr减少了一些因为0被隐式转换为指针而导致的错误,例如在函数重载时:

void func(int);
void func(char*);

func(NULL); // 该调用将会调用 func(int);
func(nullptr); // 该调用将会调用 func(char*);

上述代码中,由于NULL是一个宏定义,实际上被展开为0,因此编译器无法通过调用参数来区分是调用func(int)还是func(char*)。而使用nullptr则可以避免这种情况,因为它是一个真正的指针类型,不会被隐式转换为其他类型。

注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

语法糖简介

在程序设计中,语法糖(Syntactic sugar)指的是一种让代码更加易读、易写的语法修饰特性,它并不会引入新的功能特性,但却可以减少代码的输入量、提高代码的可读性或可维护性。

常见的语法糖包括但不限于:

  • 运算符重载:使用运算符进行类对象的操作,使得代码更加简洁易懂,如C++中的operator+等。
  • 容器类的简化:通过STL等标准库提供的容器类,简化复杂的数据结构操作,如C++中的vector、list、map等。
  • 面向对象的语言特性:如继承、多态、虚函数等,可以使得代码更具有可扩展性和易维护性。
  • 内置函数和函数库:如C++提供的sort等算法库可以使得编写代码的效率更高,同时代码也更加简洁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/461791.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(数字图像处理MATLAB+Python)第七章图像锐化-第一、二节:图像锐化概述和微分算子

文章目录 一&#xff1a;图像边缘分析二&#xff1a;一阶微分算子&#xff08;1&#xff09;梯度算子A&#xff1a;定义B&#xff1a;边缘检测C&#xff1a;示例D&#xff1a;程序 &#xff08;2&#xff09;Robert算子A&#xff1a;定义B&#xff1a;示例C&#xff1a;程序 &a…

Tailscale: Please Restart the Tailscale Windows Service

之前用的好好的&#xff0c;最近重新升级了一下Tailscale后发现一直连不上。右击win10右下角的Tailscale图标&#xff0c;第一行显示&#xff1a;Please Restart the Tailscale Windows Service。 我查看了一下服务&#xff0c;发现Tailscale是自动的&#xff0c;这里的启动类…

vuex存储数组(新建,增,删,更新),并存入localstorage定时删除

vuex存储数组(新建&#xff0c;增&#xff0c;删&#xff0c;更新)&#xff0c;并存入localstorage定时删除 本文目录 vuex存储数组(新建&#xff0c;增&#xff0c;删&#xff0c;更新)&#xff0c;并存入localstorage定时删除使用背景store中实现增删改组件中维护数组&#x…

缩小数据文件

今天又出现12.2c 环境的问题&#xff0c;1T的数据空间还剩下2G&#xff0c;吓了一身冷汗&#xff0c;赶紧查看原因&#xff0c;不知道哪路业务大神作妖了。 发现sysaux和system增加N多数据文件&#xff0c;而且目前使用不多&#xff0c; 缩小表空间的数据文件 可以使用下面的语…

直升机空气动力学基础---002 桨叶的主要参数

源于 1.桨叶的平面形状和主要参数 由于其设计制造比较简单&#xff0c;早期直升机大多采用矩形桨叶&#xff0c;缺点是在高速气流中&#xff0c;无法抑制桨尖涡&#xff0c;会消耗向下的诱导速度&#xff0c;降低旋翼的拉力。现代多采用梯形桨叶。 桨尖后掠能够降低桨尖涡 …

【Linux】Linux基本指令(2)

一.你如何看待指令 指令说白了就是可执行程序&#xff0c;且指令一定是在系统的某一个位置存在的&#xff0c;在执行指令前&#xff0c;我们需要先找到它。 二.man指令 众所周知&#xff0c;Linux的指令有很多&#xff0c;指令的选项也有很多&#xff0c;我们不可能全记住&…

android注解注入AspectJ面向切面AOP插桩技术改变android原生类对象行为记录View点击事件,Java(3)

droid注解注入AspectJ面向切面AOP插桩技术改变android原生类对象行为记录View点击事件&#xff0c;Java&#xff08;3&#xff09; 动态改变Toast提示的内容&#xff0c;弹之前修改。Button在每次点击后记录。 import android.util.Log; import android.widget.Toast;import o…

基于天牛须(BAS)与NSGA-Ⅱ混合算法的交直流混合微电网多场景多目标优化调度(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …

论Shell编程规范与变量

目录 一&#xff1a;shell脚本 1.shell概述 2.linux中包含的常用shell 3.shell脚本概述 4.shell脚本应用场景 5.shell脚本的作用 6.用户的登录shell 二&#xff1a; 编写脚本 1.脚本的基本格式 2.shell脚本的执行 3. 交互式硬件设备 4.重定向操作 5.管道操作符号 “…

信号完整性分析基础知识之传输线和反射(一):阻抗变化引起反射

阻抗不连续引起的反射和失真可能会导致信号的误触发和误码&#xff0c;这是导致信号失真和质量下降的主要原因。 在某些情况下&#xff0c;这看起来像振铃。当信号电平下降时&#xff0c;下冲会影响噪声预算并导致误触发。或者&#xff0c;在下降信号上&#xff0c;峰值可能会上…

阅读笔记 First Order Motion Model for Image Animation

文章解决的是图片动画的问题。假设有源图片和驱动视频&#xff0c;并且其中的物体是同一类的&#xff0c;文章的方法让源图片中的物体按照驱动视频中物体的动作而动。 文章的方法只需要一个同类物体的视频集&#xff0c;不需要而外的标注。 方法 该方法基于self-supervised策…

Qt信号槽原理

Qt之信号槽原理 一.概述 所谓信号槽&#xff0c;实际就是观察者模式。当某个事件发生之后&#xff0c;比如&#xff0c;按钮检测到自己被点击了一下&#xff0c;它就会发出一个信号&#xff08;signal&#xff09;。这种发出是没有目的的&#xff0c;类似广播。如果有对象对这…

idea无效的目标版本和类文件具有错误的版本 61.0, 应为 52.0错误(测试有用,一次性解决问题)

SpringBoot己更新到3后&#xff0c;使用的JAVA版本最低要求JAVA17&#xff0c;如果低于这个版本就是报错&#xff1a; 问题一&#xff1a;类文件具有错误的版本 61.0, 应为 52.0。 解决就只有升级JAVA-sdk&#xff1a; 官方下载地址&#xff1a;JAVA20-17 官方推荐更好的sd…

MySQL 视图、函数和存储过程

MySQL 是一种流行的关系型数据库管理系统&#xff0c;其具有强大的功能和灵活性&#xff0c;使其成为了许多企业和个人喜爱的数据库选择。在 MySQL 中&#xff0c;视图、函数和存储过程是常见的数据库对象&#xff0c;它们都有助于提高数据的处理效率和可重用性。 一、视图 视…

UE5实现Runtime环境下绘制点功能

文章目录 1.实现目标2.实现过程2.1 C++实现2.2 蓝图调用3.参考资料1.实现目标 UE5在Runtime环境下基于PDI绘制点,GIF动态如下: 2.实现过程 UE常用的在运行时环境下绘制点方法主要有两种。一种是基于Mesh,即添加Sphere等StaticMesh来模拟显示绘制点;另一种是基于Primitive的…

用代码实现标签打印的三种方式

最近项目中要实现标签打印的功能&#xff0c;有几个条件 标签模板可以事先生成&#xff0c;用的是CodeSoft软件标签模板里面有二维码标签模板里面有一些变量&#xff0c;要求打印的时候自动填充产线电脑上没有安装CodeSoft&#xff0c;即便安装也不能使用&#xff0c;因为没有…

Java线程池及拒绝策略详解

前文提到线程的使用以及线程间通信方式&#xff0c;通常情况下我们通过new Thread或者new Runnable创建线程&#xff0c;这种情况下&#xff0c;需要开发者手动管理线程的创建和回收&#xff0c;线程对象没有复用&#xff0c;大量的线程对象创建与销毁会引起频繁GC&#xff0c;…

Unity入门(一)

Unity Unity是一套完善体系与编辑器的跨平台游戏开发工具&#xff0c;也可以称之为游戏引擎。游戏引擎是指一些编写好的可以重复利用的代码与开发游戏所用的各功能编辑器。 基于C#编程&#xff0c;易上手&#xff0c;高安全性独特的面向组件游戏开发思想让游戏开发更加简单易…

Maven 如何下载依赖包的源码包

使用Maven下载依赖包的时候&#xff0c; 默认是不会下载源码包的&#xff0c;但是有时候&#xff0c; 需要Debug代码&#xff0c;或是看看依赖项的源码的写法&#xff0c; 就需要下载源码包了。 这里以 Apache 的 commons-text 为例&#xff0c; 在Maven中添加如下依赖配置&am…

pwlink用作USB转TTL,进入HC-05的AT模式

不说废话的文章概括&#xff1a; 直接连接PWLINK与HC-05&#xff0c;无法进入AT模式&#xff0c;因为蓝牙模块的VCC只能接5V&#xff0c;不能接3.3V&#xff0c;而且PWLINK有两个VDD引脚&#xff0c;且两个VDD引脚初始默认输出电压都是3.3V&#xff0c;所以需要将3.3V改为5V的…