c++
文章平均质量分 77
暮色_年华
这个作者很懒,什么都没留下…
展开
-
嵌入式C语言自我修养:GNU C编译器扩展语法精讲
)(void)是一个类型转换,它将后面的表达式转换为void类型,这意味着表达式的结果被丢弃。而是一个比较两个变量地址是否相同的表达式,这个表达式的结果是一个布尔值,但通过将其转换为void类型,这个结果就被忽略了。void这一行代码的目的是让编译器认为_min1和_min2(或_max1和_max2)这两个变量被使用了,从而避免编译器发出未使用变量的警告。长度为0的数组int a[0];零长度数组有一个特点,就是不占用内存存储空间。原创 2024-09-22 11:57:52 · 585 阅读 · 0 评论 -
嵌入式C语言自我修养:C语言的模块化的编程思想
extern关键字对外部文件的符号进行声明extern声明的变量或函数在别的文件里定义,在本文件使用,告诉编译器不要报错。int age;int num;int num;j<10;定义的本质就是为对象分配存储空间,声明则将一个标识符与某个C语言对象相关联(函数、变量等)。原创 2024-09-19 21:08:43 · 1582 阅读 · 0 评论 -
嵌入式C语言自我修养:C语言的面向对象编程思想
⭐关联知识点:C和C++的区别。原创 2024-09-14 22:08:32 · 1948 阅读 · 0 评论 -
C和指针:函数
函数体就是一个代码块,它在函数被调用时执行。与函数定义相反,函数声明出现在函数被调用的地方。原创 2024-09-14 18:59:16 · 572 阅读 · 0 评论 -
C和指针:指针
只有当两个指针都指向同一个数组中的元素时,才允许从一个指针减去另一个指针,两个指针相减的结果的类型是 ptrdiff_t,它是一种有符号整数类型。减法运算的值是两个指针在内存中的距离(以数组元素的长度为单位,而不是以字节为单位),因为减法运算的结果将除以数组元素类型的长度。要求边界对齐的机器上,整型值存储的起始位置只能是特定的字节,通常是2或4的倍数。c声明为浮点数,但是存放在内存中使用的整数,它们可以被解释为整数,也可以被解释为浮点数,取决于它们被使用的方式。a存放的是一个随机的整数,行为未定义。原创 2024-09-13 15:14:31 · 1445 阅读 · 0 评论 -
C和指针:数组(一维数组,多维数组,指针数组)
char const *string这样的类型声明时,string是一个指向字符的指针,这个字符是指向的内容是不可修改的。上面两个声明等价,数组当作参数传入函数本质是传入指针,但是它传递的只是数组第一个元素的指针,但是这种方法无法让函数知道数组的确切长度,所以需要把数组长度显示传入函数中。d是一个包含3个元素的数组,每个元素都是包含6个元素的数组,6个元素中的每一个又都是包含10个整型元素的数组。c是个一维数组的一维数组。一维数组名的值是一个指针常量,类型是指向元素类型的指针,指向数组的第1个元素。原创 2024-09-13 10:16:23 · 862 阅读 · 0 评论 -
C和指针:标准函数库
longjmp 函数:一旦在程序的其他部分遇到了 longjmp 调用,并且传入了之前 setjmp 初始化的 jmp_buf 数组以及一个非零值作为跳转值,那么程序的控制就会立即跳回到与那个 jmp_buf 关联的 setjmp 处。setjmp 函数:一个函数中调用 setjmp 并传递一个类型为 jmp_buf 的数组作为参数时,setjmp 将会保存当前程序执行环境的一个快照(包括处理器寄存器和程序计数器等状态信息)到这个 jmp_buf 数组中。如果在某个低层的函数中检测到一个错误,你可以立。原创 2024-09-11 09:33:21 · 688 阅读 · 0 评论 -
C和指针:预处理(#include/define/if...)
预处理器把所有name替换成 stuff。在程序中扩展#define定义符号和宏时,需要涉及几个步骤:1.在调用宏时,首先对参数进行检查,看看是否包含了任何由#define 定义的符号。如果是,它们首先被替换。2.替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被它们的值所替代。3.最后,再次对结果文本进行扫描,看看它是否包含了任何由#define 定义的符号。如果是,就重复上述处理过程。这样,宏参数和#define 定义可以包含其他#define定义的符号。但是,宏不可以出现递归。原创 2024-09-10 15:27:18 · 754 阅读 · 0 评论 -
C和指针:高级指针话题
进一步探讨指向指针的指针这些声明在内存中创建了下列变量。如果它们是自动变量,无法猜测它们的初始值。二级指针指向一级指针因为函数传参使用值传递不会修改原值,传递指针可以修改原变量,如只有传入一个链表节点的指针才可以进行链表的插入或删除操作。原创 2024-09-09 21:22:18 · 517 阅读 · 0 评论 -
C和指针:动态内存分配(malloc,calloc,realloc,free)
⭐关联知识点:linux动态内存分配。原创 2024-09-09 11:10:49 · 755 阅读 · 0 评论 -
C和指针:字符串
字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。字符串长度就是字符串中字符数。string为指针常量(const修饰string),指向的string是常量不能修改。size_t是无符号数,定义在stddef.h。C语言遍历字符串: while(*string++!='\0'){}上面两句不等价,第二个恒真,无符合数-无符合数还是无符合数,恒大于0。原创 2024-09-07 11:53:47 · 991 阅读 · 0 评论 -
C++11新特性:lambda表达式(匿名函数)
STL算法的函数有时候需要传递函数,可以传递函数指针,函数对象(函数符)、lambda表达式。功能上,[&变量]可以应用变量,[&]可以引用所有动态变量,[=]可以按值引用所有动态变量。效率上,lambbda函数可以自动优化为内联函数,但是使用函数指针不会优化为内联函数。[ ]替代了函数名,没有声明函数类型,如果函数只有一行,自动推导类型,否则指出类型。函数对象:()操作符重载可以当成一个函数使用,但是不如lambda函数好用。函数位于调用的地方近,便于查看和修改,很方便。原创 2022-10-20 21:55:53 · 704 阅读 · 0 评论 -
C++面向对象:C和C++介绍和发展
使用汇编语言不方便,UNIX操作系统注重可移植性。最初,C语言是为了重新实现UNIX操作系统而设计的,很快,整个UNIX操作系统几乎都用C语言重写,这证明了C语言的强大和实用性。C语言在操作系统、设备驱动、嵌入式应用广泛。(1)过程性语言:C语言作为一种过程性语言,侧重于通过算法描述来指导计算机执行任务,关注的是如何按步骤完成计算任务。过程性强调使用明确且结构良好的控制结构,如for循环、while循环、do-while循环和if-else语句,逻辑清晰、代码的可读性。原创 2021-12-27 23:12:42 · 1496 阅读 · 0 评论 -
C++面向对象:重写、重载、隐藏
如果foo写错的话,就会当成一个新的函数来看,所以这时可以用override来规定这个函数就是要重写父类的一个函数,如果名字打错的话不会通过。如果不希望一个类被继承 或者 一个类被重写,直接在类或函数后面加final关键字。如果重写或继承编译器就会报错。父类定义了虚函数,子类重写父类的虚函数,以下三种方法都可以。原创 2024-04-25 14:27:31 · 377 阅读 · 0 评论 -
C++面向对象:C++的垃圾回收
垃圾收集是编程语言中 使用的内存管理技术之一。它是一种自动内存管理技术,作为许多编程语言的功能添加。垃圾收集器收集或回收分配给变量或对象但不再被程序使用的内存;这也称为垃圾。引用技术算法是唯一一种不用用到根集概念的垃圾回收算法。基本思路是为每个对象加一个计数器,计数器记录的是所有指向该对象的引用数量。每次有一个新的引用指向这个对象时,计数器加一;反之,如果指向该对象的引用被置空或指向其它对象,则计数器减一。当计数器的值为0时,则自动删除这个对象。原创 2024-03-28 19:57:57 · 1127 阅读 · 0 评论 -
C语言: 指针讲解
C语言中,定义变量时,在变量名 前 写一个 * 星号,这个变量就变成了对应变量类型的指针变量。必要时要加( ) 来避免优先级的问题。原创 2024-03-25 16:51:16 · 1028 阅读 · 0 评论 -
C++11新特性:智能指针
C++中动态内存的管理是通过new和delete来完成的,保证new和delete的配对使用。但是有时候会忘记释放内存,甚至有时候我们根本就不知道什么时候释放内存。特别时在多个线程间共享数据时,更难判断内存该何使释放。这种情况下就机器容易产生引用非法内存的指针。由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见。原创 2024-03-24 21:40:34 · 1144 阅读 · 0 评论 -
C语言:volatile关键字讲解
易变”是因为外在因素引起的,像多线程,中断等。中修改的供其它程序检测的变量,需要加volatile:当变量在触发某中断程序中修改,而编译器判断主函数里面没有修改该变量,因此可能只执行一次从内存到某寄存器的读操作,而后每次只会从该寄存器中读取变量副本,使得中断程序的操作被短路。volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问。原创 2024-03-21 11:43:12 · 1149 阅读 · 0 评论 -
C++面向对象:static的使用
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。面向过程程序设计中static的用法主要可以总结:限制作用域,自动初始化为0,具有持久性。static可以修饰全局变量,局部变量,函数。对应的叫静态全局变量、静态局部变量、静态函数初始化:未经初始化的全局静态变量会被自动初始化为0作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。静态变量或静态函数只有本文件内的代码才能访问它,它的名字在其它文件中不可见。原创 2024-03-19 21:55:41 · 615 阅读 · 0 评论 -
C++面向对象:virtual关键字的使用
1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行滞后联编的。2.只有类的成员函数才能说明为虚函数,因为虚函数仅适合用与有继承关系的类对象,所以普通函数不能说明为虚函数。3.静态成员函数不能是虚函数,因为静态成员函数的特点是不受限制于某个对象。4.内联(inline)函数不能是虚函数,因为内联函数不能在运行中动态确定位置。即使虚函数在类的内部定义定义,但是在编译的时候系统仍然将它看做是非内联的。原创 2024-03-19 11:32:36 · 839 阅读 · 0 评论 -
C++ STL:hashtable源码分析
当hashtable中插入的元素个数大于当前vector的容量时,会新建一个vector,新vector的容量是之前vector容量所在质数表里的下一个质数,如53的后一个是97,新vector的容量为97。函数将不同类型的key数据转换成统一的数值格式(如:const char *转换成特定的数值),以便hash函数进行取模处理,取模用的模值就是桶的数量值,也就是vector的容量。m不应该是进制数的幂,比如十进制的时候,m如果是10^n,那么结果总是和原始值的后n位相关的,这样冲突的概率会更大。原创 2024-02-27 15:18:55 · 1085 阅读 · 0 评论 -
C++ STL :红黑树rb_tree源码剖析
STL关联式容器map、set、multimap、multiset,绝大部分操作如插入、修改、删除、搜索,都是由其内含的红黑树来完成的。我下面会总结 STL中rb_tree怎么实现的。首先,rb_tree是红黑树,所以需要定义红色和黑色。然后需要定义 红黑树的节点。_Rb_tree_node_base定义了红黑树的节点类,从类中可以看出一个节点有颜色、父指针、左孩子指针、右孩子指针4个属性。然后定义了几个函数,可以找到以这个节点为根节点的红黑树的最大节点和最小节点。原创 2024-02-25 22:14:15 · 1119 阅读 · 0 评论 -
数据结构与算法:红黑树讲解
1.节点非红即黑。2.根节点是黑色。3.所有NULL结点称为叶子节点,且认为颜色为黑。4.所有红节点的子节点都为黑色。5.从任一节点到其叶子节点的所有路径上都包含相同数目的黑节点。原创 2024-02-25 20:33:17 · 713 阅读 · 0 评论 -
C++ STL:list和vector的比较
由于 vector 使用一段连续的内存空间来存储数据,这意味着当你访问 vector 中的一个元素时,相邻的元素很可能已经被预加载到 CPU 缓存中。当你遍历一个 vector 并访问它的元素时,由于数据连续存储,许多元素访问操作可能直接从缓存中进行,而不是从更慢的主内存中。由于 vector 的连续内存特性,可能会导致更大的内存预留(容量)以减少重新分配的频率,而 list 的内存使用更为紧凑,但每个元素需要额外的空间来存储前后节点的地址。Vector: 底层实现为动态数组,提供了一段连续的内存空间。原创 2024-02-15 20:42:14 · 1438 阅读 · 0 评论 -
C++ STL: list使用及源码剖析
push_front(),push_back(),pop_front(), pop_back()在insert和erase的基础上实现。如果指针node指向置于尾端的一个空白节点,node就能符合stl对于前闭后开区间的要求,这样以下函数便能轻易完成。链表最后使用一个指针指向环形链表的空白节点,空白节点指向头节点,这样就形成了一个环了。可以看出list节点是一个双向链表,next指向下一个节点,prev指向前一个节点。node是指向list节点的一个指针,可以使用这个指针表示整个环状双向链表。原创 2024-02-15 20:08:51 · 1241 阅读 · 0 评论 -
C++面向对象编程:explicit关键字
在C++中, 如果的构造函数只有一个参数时, 那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象。所以explicit只能用于修饰只有一个参数的类构造函数,表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)// 不行, 调用的是CxString(int size), 且size等于'c'的ascii码, explicit关键字取消了隐式转换。原创 2024-02-07 21:37:22 · 811 阅读 · 0 评论 -
C++ STL: vector使用及源码剖析
没有备用空间,就需要扩充空间,它接受两个参数n和value,n指明了要申请的堆空间大小,value指明了要初始化这些堆空间的内容,并把它们传给另外一个函数allocate_and_fill() ,该函数才是真正的申请堆空间和初始化。动态增加大小,并不是在原空间之后接续新空间,(因为无法保证原空间之后上有可供分配的空间),而是以原大小的两倍来另外分配一块较大空间,因此,一旦空间重新分配,指向原vector的所有迭代器就会失。vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新的元素。原创 2024-02-07 13:43:44 · 862 阅读 · 0 评论 -
C++泛型编程:模板偏特化
我们可以指定一部分模板参数的具体类型,或对模板参数施加一些约束条件。类型时,我们希望有一个特殊的实现。这时,可以使用模板偏特化来实现。模板偏特化为模板提供特殊的实现,针对特定的模板参数或参数组合。在模板全特化,所有的模板参数都被指定了具体的类型。我们可以在泛化设计中提供一个特化版本。假设有一个类模板,有两个模板参数。假设当第二个模板参数是。原创 2024-02-06 19:32:38 · 175 阅读 · 0 评论 -
C++11新特性:thread_local
threadSpecificCounter是线程局部存储的变量,每个线程都有自己的拷贝,每个线程都会递增它,并模拟一些计算工作,同时更新共享资源sharedResource。每个线程都有自己独立的变量实例,而不是共享同一个实例,每个线程可以维护自己的状态,而不会相互干扰。通过使用 thread_local , 每个线程都可以独立地操作它们自己的计数器,而不会相互影响。thread_local是C++11 引入的关键字,用于声明线程局部存储变量。例:使用thread_local实现线程特定的计数器。原创 2024-01-25 21:10:09 · 347 阅读 · 0 评论 -
C++并发编程:互斥锁std::mutex和lock_guard的使用
对象离开其作用域时,会自动调用析构函数,该析构函数会释放锁。这确保了在任何情况下(包括由于异常等原因导致的提前退出),锁都会被正确释放,从而避免了忘记手动释放锁而导致的死锁问题。mutex 用于控制多个线程访问共享资源,确保在任意时刻只有一个线程可以访问该资源,避免数据竞争。这确保了同一时刻只有一个线程可以访问被保护的资源,从而防止多线程并发访问导致的数据不一致性。是 C++ 标准库中提供的一个模板类,用于在其构造时自动获取锁,在析构时自动释放锁。是 C++ 标准库中提供的一种用于多线程同步的互斥锁实现。原创 2024-01-25 20:56:27 · 2155 阅读 · 0 评论 -
C++11新特性:模板函数的默认模板参数
函数模板是C++中一种通用的编程机制,允许编写可以处理多种数据类型的通用函数。函数模板使用一个或多个类型参数,允许程序员编写单个函数定义,可以适用于多个数据类型。C++98中引入函数模板与类模板,在模板类声明时可以允许其有默认模板参数,但不支持函数模板的默认模板参数。C++11中模板函数也可以有默认的参数。原创 2024-01-23 20:41:01 · 412 阅读 · 0 评论 -
C++并发编程:线程启动
这声明了一个名为my_thread的函数,这个函数带有一个参数(函数指针指向没有参数并返回 background_task对象的函数),返回一个 std::thread 对象的函数,而非启动了一个线程。启动了线程,需要明确是要等待线程结束(使用join()),还是让其自主运行。在一些情况下,线程运行时,任务中的函数对象需要通过某种通讯机制进行参数的传递,或者执行一系列独立操作;如果传入参数的对象中包含的指针和引用需要谨慎,用一个能访问局部变量的函数去创建线程是危险的(除非十分确定线程会在函数完成前结束)原创 2024-01-22 15:57:54 · 463 阅读 · 0 评论 -
c++vector查找元素所在的索引下标
find函数#include<vector>using namespace std;输出: 1表示3所在下标为1原创 2021-11-15 16:48:51 · 15981 阅读 · 4 评论