自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(26)
  • 收藏
  • 关注

原创 为什么要重写拷贝构造函数实现深拷贝?

也就是说,如果我们不自己定义拷贝构造函数,那么编译器会为我们生成一个默认的拷贝构造函数,它的作用是将原对象的所有数据成员逐个复制到新对象中。但是,这样做有一个问题,就是如果数据成员中有指针类型的变量,那么复制的只是指针的值,也就是内存地址,而不是指针所指向的内容。这样,两个对象的指针就会指向不同的内存空间,互不影响。举个例子,假设我们有一个名为Student的类,它有两个数据成员,一个是int类型的变量id,用来存储学生的编号,另一个是char类型的指针name,用来存储学生的姓名。

2023-09-19 22:20:45 108

原创 C++中类和结构体的空间大小如何分配

• 类和结构体的成员变量在内存中是按照声明的顺序依次存放的,但是可能会有一些空洞(padding)出现,以满足对齐要求。• 对齐要求是指每个成员变量的起始地址要能够被其自身类型所占字节数的整数倍整除,如果不满足则需要在前面补充一些空字节。• 对齐要求的目的是为了提高内存访问效率,不同的编译器和目标平台可能有不同的默认对齐值,一般是4字节或8字节,也可以通过#pragma pack指令来修改。

2023-09-16 22:54:26 221

原创 面向对象编程和面向过程编程有什么区别

从上面的例子可以看出,不同的对象执行相同的方法时,会表现出不同的效果或者结果,这就是多态的一种表现。你可以把它想象成不同的画笔去绘制一幅风景画,他们都要使用draw方法,但是每个画笔都有自己的特性和风格,所以他们会使用不同的颜料和技巧。这样就体现了多态的意义。在上面的代码中,我们使用了虚函数和重写的技术,使得子类可以根据自己的特点修改父类的方法。这样,当我们创建不同的画笔对象,并且调用它们的画画方法时,就会发生多态,也就是说,不同的对象会根据自己的类型执行不同的方法。

2023-09-15 22:42:22 494

原创 Makefile中静态模式规则和普通模式规则的区别

如果你用洗衣机洗,你只需要选择一个通用的模式,比如快速洗或者深度洗,然后把所有的衣服放进去。这里,我们指定了两个目标模式%.jpg和%.png,所以这个规则可以匹配foo.jpg, foo.png, bar.jpg, bar.png等文件。关于第一点:静态模式规则需要在规则的第一行指定目标文件的列表,是为了限制模式规则的作用范围,只对列表中的每个目标使用命令来编译它们。关于第二点:静态模式规则可以指定多个目标模式,而隐含模式规则只能指定一个目标模式。静态模式规则和隐含模式规则的区别有点细微,但是很重要。

2023-09-12 11:22:39 157

原创 HAL_XXX_MspInit 函数的作用

其中第一点与stm32中的HAL_XXX_MspInit函数与HAL_XXX_Init函数类似,把和 MCU 相关的初始化操作(单片机的硬件资源)和和 MCU 无关的初始化操作(单片机的功能)分开来,从而提高代码的可移植性、模块化和灵活性,不同之处在于HAL_XXX_Init函数可以主动调用HAL_XXX_MspInit函数,而uart_init函数里需要我们手动添加调用uart_io_init函数。使用这个函数是为了把和 MCU 相关的初始化操作和和 MCU 无关的初始化操作分开,使代码更清晰和可移植。

2023-09-10 22:41:56 898

原创 linux动态库或者静态库更新后,可执行文件是否需要重新编译

因为在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是在执行文件中记录对动态库的引用。但是,有一情况下可能需要重新编译生成可执行文件,那就是当动态库的接口发生了变化,比如函数的参数或返回值类型改变了,或者函数被删除或重命名了。所以,结论是:如果动态库更新后,只是增加了一些新的功能,而没有改变原有的接口,那么不需要重新编译生成可执行文件;现在假设我们对libmath.so这个动态库做了一些修改,比如增加了一个求立方根的函数cbrt,但是没有改变sqrt函数的接口。

2023-09-10 16:42:39 1055

原创 BSS段、数据段、栈

栈:用来存放局部变量、函数参数、返回地址等,由编译器自动分配和回收,是可读写的。例如,下面例子中在调用函数 func 时,将参数 a 和 b、返回地址和局部变量 c 压入栈中。数据段:用来存放已初始化的全局变量和静态局部变量,是可读写的。

2023-09-09 21:20:03 61 1

原创 Cortex-A7中断系统之start.S文件编写中的汇编指令

当处理器执行 BL(Branch with Link,带链接的分支)指令时,它会将当前的 PC 寄存器的值(也就是 BL 指令的下一条指令的地址)保存到 LR 寄存器中,然后跳转到目标函数去执行。这样就实现了函数调用和返回的功能。第 143 行是在 IRQ 模式下执行的,它操作的是 IRQ 模式下的 LR 寄存器,它保存了中断发生时的地址。第 143 行的 POP {LR} 指令是用来将栈顶的值弹出到 LR 寄存器中的,这里的 LR 寄存器是 IRQ 模式下的 LR 寄存器,它保存了中断发生时的返回地址。

2023-09-07 16:36:41 110 1

原创 CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7F);

【代码】CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7F);

2023-09-05 11:18:07 81 1

原创 在Makefile中,?= 和 := 的区别?

如果在Makefile中已经存在对 NAME`的赋值,那么这行代码不会改变 NAME 的值。= 进行赋值时,会进行延迟赋值,也就是说,只有在变量之前没有被赋值的情况下,才会将右侧的值赋给变量。而 := 用于立即赋值,并且不受后续重新赋值的影响。当使用 := 进行赋值时,会立即将右侧的值赋给变量,并且该赋值操作会忽略之后对变量的重新赋值操作。不管之后是否有其他对 OBJS 的赋值,它的值都会保持为 "start.o main.o"。= 和 := 是两种不同的变量赋值操作符,它们有不同的用途和行为。

2023-08-24 23:03:48 854 1

原创 #define SW_MUX_GPIO1_IO03 *((volatile unsigned int *)0X020E0068)

而且一般来说,帧缓冲区中存储像素是从左到右、从上到下的方向的,也就是说左上角的点对应第一个字节,右上角的点对应第tftlcd_dev.width * 4个字节(因为一行有tftlcd_dev.width个像素),左下角的点对应第(tftlcd_dev.height - 1) * tftlcd_dev.width * 4 + 1个字节(因为一共有tftlcd_dev.height行),右下角的点对应最后一个字节。现在,如果你想知道某个点的颜色是什么,你就需要找到这个点在画布上的位置,然后读取它的颜色值。

2023-08-19 20:34:36 75

原创 为什么外部时钟频率减半,需要两个上升沿或下降沿才能使计数值加一?

从图中可以看出,当外部时钟信号不分频时,每个上升沿或下降沿都会使计数值加一;当外部时钟信号 2 分频时,需要两个上升沿或下降沿才会使计数值加一。也就是说,需要两个周期的外部时钟信号才能使计数值加一。

2023-08-03 15:59:59 121

原创 stm32通用定时器实现高电平脉宽的测量

进入这个函数表示捕获到了上升沿或者下降沿。

2023-08-02 22:24:20 298

原创 将文件描述符号为 0、1、2 定位到/dev/null

dev/null 是一个特殊的设备文件,它丢弃一切写入其中的数据,也不提供任何数据给读取它的进程。打开 /dev/null 文件,以读写模式(O_RDWR),并返回一个文件描述符(默认是最小的可用值)。再次复制文件描述符 0,并返回一个新的文件描述符(默认是最小的可用值)。复制文件描述符 0,并返回一个新的文件描述符(默认是最小的可用值)。这样,程序就将标准输入、标准输出和标准错误输出都重定向到了 /dev/null 文件,相当于关闭了这些输入和输出。

2023-07-04 21:32:00 126

原创 如何理解int (*(*(*pfunc)(int *))[5])(int *);

它表示pfunc是一个指向函数的指针,这个函数接受一个int *类型的参数,并返回一个指向数组的指针,这个数组有5个元素,每个元素都是一个指向函数的指针,这些函数都接受一个int *类型的参数,并返回一个int类型的值。// 定义一个新的类型pfunc_type,它是一个指向函数的指针,这个函数接受一个int *类型的参数,并返回一个array_ptr类型的值。// 定义一个新的类型func_ptr,它是一个指向函数的指针,这个函数接受一个int *类型的参数,并返回一个int类型的值。

2023-06-25 17:17:45 185

原创 C语言头文件中什么时候要使用extern关键字?

如果想要修改或初始化extern修饰的变量或函数,需要在它们的定义处进行。2.当你想在一个源文件中引用另一个源文件中定义的全局变量或函数,但是不想包含另一个源文件的头文件,那么你就需要在当前源文件中使用extern关键字,表示这些变量或函数是在其他地方定义的,需要编译器去寻找。1.当你想在头文件中声明一个全局变量,但是不想在头文件中定义它,而是在其他的源文件中定义它,那么你就需要在头文件中使用extern关键字,表示这个变量是在其他地方定义的,需要编译器去寻找。

2023-06-16 16:16:32 1258

原创 如何在Ubuntu 20 中通过设置代码模板来实现所需要的注释格式

如何在Ubuntu 20 中通过设置代码模板来实现所需要的注释格式

2023-02-24 16:35:33 257

原创 学习类和继承part1

学习类和继承part1

2022-11-16 20:46:23 27

原创 学习泛型part2

学习泛型part2

2022-11-11 15:52:53 21

原创 学习泛型part1

学习泛型part1

2022-11-09 13:15:25 20

原创 学习-转换

学习转换

2022-11-08 17:11:50 28

原创 学习接口part2

接口part2

2022-11-07 15:50:29 16

原创 为什么要使用设计模式以及什么是高内聚低耦合

高内聚低耦合

2022-11-07 13:31:29 53

原创 学习接口part1

接口part1

2022-11-07 13:30:46 22

原创 学习委托part2

学习委托part2

2022-11-06 14:49:07 18

原创 学习委托part1

委托part1

2022-11-04 13:39:05 14

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除