
C/C++语言
文章平均质量分 53
围绕着c/c++语言,记录其方方面面,学习遇到的问题与解决方法,工作当中遇到的问题与解决方法。
程序员如山石
以前从事虚拟化的工作,现在从事嵌入式方面的工作。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
显示当前时间
本文介绍了如何开发一个显示精确到秒的桌面时钟程序。作者因系统自带时钟不显示秒,而选择自己开发一个Qt程序来实现该功能。程序使用QLCDNumber控件显示时间格式字符串(支持"-"、":"等特殊字符),通过QTimer定时器每秒触发一次时间更新。文章提供了核心代码实现,包括界面布局、时间显示和定时器设置,并分享了程序运行效果图和视频演示。最后总结了关键技术点:QTimer的timeout事件机制和QLCDNumber的字符串显示功能,同时提供了程序下载地址。这个案例展原创 2025-08-01 14:51:01 · 365 阅读 · 0 评论 -
神奇的数据跳变
摘要:本文描述了一个奇怪的软件数据跳变问题,数据在158和10之间不断变化。作者通过排查发现:1)问题仅出现在实验室机器上;2)杀毒软件未检测到病毒;3)最终找到了问题根源。文章提供了关键代码片段,包括界面布局、学生成绩初始化和数据显示部分,展示了Qt框架下的实现方式。该问题反映了程序员工作中可能遇到的典型调试场景。原创 2025-07-31 17:35:24 · 356 阅读 · 0 评论 -
一般归一化算法的理解
数据归一化是将原始数据按比例缩放至特定区间的方法,主要目的是消除量纲差异和简化计算。文章介绍了三种常见归一化方式:一般归一化法用百分比表示组分含量,校正面积归一化法引入校正因子处理响应差异,数据标准化处理使数据符合标准正态分布。重点说明了一般归一化法不仅能消除量纲,还能利用比值关系进行数值推导。通过学生思考时间与考试成绩的示例,展示了如何用一般归一化公式计算全校分数分布。文章指出归一化的本质是将有量纲数据转化为无量纲的相对值,使不同属性的对象具有可比性。最后总结归一化方法的核心是利用相对关系进行数值处理和推原创 2025-06-19 11:21:39 · 981 阅读 · 0 评论 -
QMap清空手动分配的内存
摘要:本文探讨了在QMap中使用堆内存时的内存管理问题。当QMap存储手动分配的指针时,直接调用clear()会导致内存泄漏。文章通过示例展示了正确做法:先遍历删除指针对象,再清空QMap。同时推荐使用智能指针(如shared_ptr)进行内存管理,它能自动释放内存,避免手动管理带来的风险。智能指针通过生命周期自动管理内存,在作用域结束时释放资源,有效防止内存泄漏和野指针问题。(150字)原创 2025-06-04 15:06:48 · 953 阅读 · 0 评论 -
错误代码0xc0000005意味着什么
本文分析了C/C++编程中常见的0xC0000005内存访问冲突错误。该错误通常由三种情况引起:解引用空指针、访问野指针(已释放内存)以及数组越界访问。通过示例代码展示了每种错误的具体表现,并指出越界访问有时不会立即报错但仍属于未定义行为。总结认为0xC0000005错误的本质是访问了未分配的内存区域,建议开发者从这三个主要方向排查问题。文章强调即使某些越界访问未直接导致崩溃也属于严重隐患,应采用工具或规范主动预防这类内存错误。原创 2025-05-29 13:56:31 · 656 阅读 · 0 评论 -
不要memset(QString)
摘要:在C++中使用C语言的sizeof和memset处理复杂数据结构存在隐患。文章通过一个使用QString的结构体示例演示了该问题:memset破坏了QString的内部数据结构导致程序崩溃。解释sizeof只能获取编译时确定大小的类型,而memset会覆盖对象内部状态(如引用计数、指针等)。建议对C++复杂类型使用专门的初始化方法(如QString::clear()),避免直接使用memset这类内存操作函数。原创 2025-05-28 15:36:06 · 432 阅读 · 0 评论 -
c++内存栈被损害的问题
1、__stdcall是win32 api默认采用的调用方式,参数采用从右到左的压栈方式,由被调用者(自己)清理栈。2、__cdecl是C语言的调用方式,参数也是采用从右到左的压栈方式,有调用者来清理。为什么需要__cdecl,主要是因为有些函数的参数是不定长参数,被调用者自己都事先无法知道参数的长度,只有调用者才知道,所以函数调用完后只能由调用者来清理。原创 2025-04-16 09:42:57 · 847 阅读 · 0 评论 -
C++的二维数组
在 C++ 中,二维数组是一种常用的数据结构,它可以看作是数组的数组,类似于数学中的矩阵。以下将从定义、初始化、访问元素、内存布局和使用示例等方面详细介绍 C++ 中的二维数组。二维数组的一般定义语法如下:数据类型 数组名[行数][列数];其中,数据类型 可以是任意有效的 C++ 数据类型,如 int、double、char 等;数组名是用户为数组取的名称;行数 和 列数 分别表示数组的行数和列数,它们必须是常量表达式。示例:// 定义一个3行4列的二维整数数组。原创 2025-03-14 15:54:20 · 1689 阅读 · 0 评论 -
c++表达范围勿用数学符号
这种错误,其实就是把数学的表达,带到程序来了。在C++ primer plus书籍中P157,专门提到了这一点:取值范围的测试的每一部分都使用AND操作符将两个完整的关系表达式组合起来。不要使用数学符号将其表示为:编译器不会捕获这种错误,因为它仍然是有效的C++语句。原创 2024-12-30 15:11:51 · 601 阅读 · 0 评论 -
再谈c++线性关系求值
线性关系可以说是最简单的数学关系,在现实当中应用非常的广泛。在编程当中经常使用这种关系。原创 2024-12-27 12:01:50 · 391 阅读 · 0 评论 -
EffectiveC++21条必须返回对象时不要返回引用(通俗讲解)
当然,你会从 getStuScore的返回值中引入构造和析构的开销,但从长远来看,这是为正确的行为付出了一个小的代价。此外,让你恐惧的账单再也不会到来。像许多编程语言一样,C++允许编译器实现者在不改变可视化代码行为的前提下,对代码进行优化,以达到改善生成码性能的目的。在一些情况中,我们发现,getStuScore 返回值的构造和析构可以被安全的消除。当编译器利用了这个事实(编译器经常这么做),你的程序就会以你所期望的方式进行下去,只是比你想要的要快。原创 2024-10-12 13:29:19 · 286 阅读 · 0 评论 -
Qt的互斥量用法
互斥锁,就是只有锁定与解锁,两种状态,可以说,是最简单的锁,也是最实用的锁。原创 2024-09-30 16:55:06 · 974 阅读 · 0 评论 -
Qt多线程操作sqlite数据库
通过锁解决了sqlite数据库多线程操作的写冲突和读写冲突,锁是有消耗的,但很小,我实测6-19ms,这个消耗算是可以了。多线程操作sqlite数据库,关键之处就是在于加锁,保存同时只有一个写的操作;读的操作是可以并发的;有写的操作,读的操作也必须等待,可以说,同时只有一个写操作,无其它操作,通过锁就达到了这一个目的。如果一个线程正在写,另一个线程也要写,怎么办,锁就会让另一个线程等待前一个线程写完,自己再写。锁的本质意义就是保证了,锁的区域,只有一个写线程在访问,而读的线程,可以并发。原创 2024-09-30 13:39:35 · 2015 阅读 · 0 评论 -
winApi与QtApi的共享内存通信
1、是注意QT的封装,其key,在源码内部进行了处理,好在,提供了api接口,可以获取内部的key.2、信号量是进程间协作的常用的协作机制,非常的好用,也非常的简单,就是+1,-1操作,WaitForSingleObject函数实际就是获取成功则-1操作,其条件就是>0则获取了锁,原创 2024-08-15 16:31:14 · 1109 阅读 · 0 评论 -
Qt的64位程序与32位程序的通信
简单的说就是通过共享内存实现了64位程序与32位程序的通信,这样好处挺多。因为这样程序的独立性增强了,共享内存,真得很好用,特别是qt对共享内存的封装特别的好,直接带了锁的功能,lock,unlock非常的好用。其关键如图所示:关键就在于定死长度的数据类型,这样32位程序与64位程序都可以用,这也理解了qint32这种带着长度类型的好处了,一眼就可以看出其长度是多少,在跨进程时,就可以放心的使用,因为其长度是固定的,不同的处理器都可以正确的解析这种类型。原创 2024-07-04 11:36:30 · 1562 阅读 · 0 评论 -
C++中extern “C“的用法
extern "C"是经常用到的东西,面试题目也经常出现,然则,实际用时,还是经常遗忘,因此,深入的了解一下,以增强记忆。extern "C"指令非常有用,因为C和C++的近亲关系。注意:extern "C"指令中的C,表示的一种编译和连接规约,而不是一种语言。C表示符合C语言的编译和连接规约的任何语言,如Fortran、assembler等。另外,extern "C"指令仅指定编译和连接规约,但不影响语义。例如在函数声明中,指定了extern “C”,仍然要遵守C++的类型检测、参数转换规则。综上所原创 2024-06-13 13:44:52 · 634 阅读 · 0 评论 -
c++线性关系求值
两个变量之间存在一次函数关系,就称它们之间存在线性关系。正比例关系是线性关系中的特例,反比例关系不是线性关系。更通俗一点讲,如果把这两个变量分别作为点的横坐标与纵坐标,其图象是平面上的一条直线,则这两个变量之间的关系就是线性关系。在高等数学里,线性函数是一个线性映射,是在两个向量空间之间,维持向量加法与标量乘法的映射。例如,假若,我们用坐标向量(coordinate vector来表示 与。那么,线性函数可以表达为其中, M是矩阵。线性关系,应用非常广泛,我在工作当中,就用过好多次。原创 2024-06-12 16:19:38 · 529 阅读 · 0 评论 -
c++分治法求峰值
分治算法分治算法是将一个规模为N的问题分解为K个规模较小的子问题;这些子问题相互独立且与原问题性质相同;求出子问题的解,就可得到原问题的解;分治法,神奇之处在于,整体与各个部分的分解方法是一样的,可以说体现了事物的普通性与特殊性的原理。这种方法,可以求解很多问题,如果你遇上一个数据量很大,并且,让你头大的问题,一般来说,用分治法,可以很简单的解决。上面的问题,如图所示:整体与部分都可以,进行同样的分解,同样的求频率最高的组,这就是最具特点的地方。原创 2024-06-11 16:33:16 · 949 阅读 · 0 评论 -
Qt设置进程环境变量
这虽然是一个小问题,但也是非常让人头疼,查了不少的资料,问了不少的人。从上图可知,修改系统环境变量,是一个很麻烦的事,因为,有一个单独的进程Explorer管理这一个系统环境变量,还有这么多的进程访问这一个系统环境变量,这就导致了修改和更新很麻烦,虽然通过注册表可以修改系统环境变量,但是想立即生效,却很难。原创 2024-06-07 17:14:26 · 870 阅读 · 0 评论 -
c++容器边遍历边删除
上面图就是结合上面例子的分析,这里最为关键的理解就是,iterator是与容器紧密关联的,如果容器发生了变化,原来的iterator就失效了,因为容器可能重新分配空间,所以必须重新获取iterator.有两种简单的获取方法:1、和原来的一样,再it = myList.begin();2、接着循环往下走:it = myList.erase(it);就是这么简单。原创 2024-06-06 15:41:57 · 982 阅读 · 0 评论 -
c++的队列的用法
队列是操作受限的线性表 限定在只能在表的一端进行插入 在表的另一端进行删除。和日常生活中的排队是类似的道理。原创 2024-03-04 16:45:16 · 1935 阅读 · 0 评论 -
opencv判断二值的情况
先说说理论:什么叫图像的二值化?二值化就是让图像的像素点矩阵中的每个像素点的灰度值为0(黑色)或者255(白色),也就是让整个图像呈现只有黑和白的效果。在灰度化的图像中灰度值的范围为0~255,在二值化后的图像中的灰度值范围是0或者255。黑色:二值化后的R = 0二值化后的G = 0二值化后的B = 0白色:二值化后的R = 255二值化后的G = 255二值化后的B = 255那么一个像素点在灰度化之后的灰度值怎么转化为0或者255呢?比如灰度值为100,那么在二值化后到原创 2024-02-23 13:37:33 · 812 阅读 · 1 评论 -
opencv判断灰化情况
灰化是怎么判断的呢?灰化图在opencv中是单通道图,但保存时,会转化成RGB模式的图。所以,再加载,通过通道数,判断是否是灰度图,这样是不对的。解决方法:首先,一个图片在保存时,其实是以RGB模式保存的,这也是操作系统默认的保存方式。那一个灰化图在保存时,会默认转化为RGB模式,怎么转化,其就是把一个灰化值重复为三份,分别对应RGB,这样就可以了。如图所示:知道这个情况了:就知道如何判断一个图是否灰化了:那就是:R=G=B就可以了。原创 2024-02-22 16:45:38 · 1328 阅读 · 0 评论 -
c++中浮点类型比较的理解
所以,我们还得到另外一个重要的经验:使用浮点数进行相等(==)和不等(!=)比较的操作通常是有问题的。浮点数的相等比较,一般总是使用两者相减的值是否落在0的邻域中来判断的。原创 2024-02-18 17:11:56 · 800 阅读 · 0 评论 -
无法解析的外部符号ShellExecuteExW
SHELLEXECUTEINFO参数说明://结构大小,sizeof(SHELLEXECUTEINFO)//指定结构成员的有效性HWND hwnd;//父窗口句柄或出错时显示错误父窗口的句柄,可以为 NULL//指定该函数的执行动作//操作对象路径//执行参数,可以为 ULL//工作目录,可以为 NULLint nShow;//显示方式//如果设置了 SEE_MASK_NOCLOSEPROCESS ,并且调用成功则该值大于32,调用失败者被设置错误值。原创 2024-01-17 17:45:05 · 744 阅读 · 0 评论 -
C++一个关于delete的幼稚错误
这个错误实在是蠢啊!没有细想,直接写了delete this;这说明基础还是不扎实。##delete 的工作方式delete 运算符将调用函数运算符 delete。对于不是类类型(class、struct 或 union)的对象,将调用全局 delete 运算符。对于类类型的对象,如果 delete 表达式以一元范围解析运算符 (:: ) 开始,则会在全局范围中解析解除分配函数的名称。否则,delete 运算符将在释放内存之前为对象调用析构函数(如果指针不为 null)。原创 2023-11-22 15:23:44 · 279 阅读 · 0 评论 -
字符与代表数据的转化
一开始想时,感觉有些复杂,知道其本质了就简单了了,什么本质,字符在计算机里就是存在数字,这种对应关系就是ASCII表。比如字符 ‘B’ 其对应的数值应该为11,那其:‘B’-‘A’=1,那再加上10,不就是11了吗?再比如’1’,其对应的数据应该为1,那’1’-‘0’=1一切字符都是两个字节的数值,并且是按顺序来的,理解了这个本质,就非常简单了。原创 2023-06-29 15:56:47 · 443 阅读 · 0 评论 -
C++公共变量的定义
C++的公共变量怎么弄呢?在写C++代码时遇上这一个问题,直接放到头文件里,按照通常C的用法,这样有些不妥,因为,面向对象,尽量不要用全局变量。看看高手的讨论吧:其结论就是用命名空间,给全局变量弄命名空间范围,这样就把全局变量限制到一定范围里,比C的那种实现方法强多了关于命名空间的介绍如下:命名空间随标准C++而引入,相当于一个灵活的文件域(全局域),以关键字namespace开头给其起个名字,并用大括号把定义区域括起来(声明块)。在域外使用域内成员时,需要加上命名空间名.原创 2022-02-18 19:32:01 · 1853 阅读 · 0 评论 -
C++静态变量为什么定义在类外
C++ 的静态成员变量为什么一定要在类外定义函数如下,在C++中声明静态成员变量的时候,在类中只是进行了声明,并没有实际的申请出指针的内存,真正的内存是定义初始化的时候才会进行内存的申请为什么这样呢?因为static类型的变量都是随着类的,因此不能随着对象的创建而申请内存,所以需要单独的进行类外定义,在定义的时候C++编译器会申请内存给静态指针。如图所示:其是不属于对象的,所以不能随着对象创建,所以只能在类外进行定义。...原创 2022-08-25 18:36:34 · 920 阅读 · 0 评论 -
c语言的内存对齐
就是内存的对齐方式,为什么要求内存对齐呢,这是cpu的要求,在某些基于RISC(精简指令集计算机)的CPU,如Sparc powerpc等,对内存中的基本数据类型的变量采用高字节在低地址,低字节在高地址的存储 方式 ,在这种自然的存储格式中,要求变量在内存中的位置 必须自然对齐,否则cpu会报告异常。intel的cpu没有这方面的要求,可以根据情况进行设置,arm的应该也可以,实际上我在arm上也是这样用的,对内存对齐进行自己的设置。从上面种种消息可以基本推出:1、字节对齐,可以提高内存查找效率2、字节对齐原创 2022-06-08 17:46:45 · 515 阅读 · 1 评论 -
Linux C 的多文件编译
过程是很简单,就是一个include cal.h头文件不就可以了吗?那程序是如果找到cal.c里面的max函数的实现呢?那是因为gcc会在当前路径找这些函数实现,这里就是在cal.o里面找到max的函数实现,然后,然后把声明的函数max与实现函数的max,链接起来,这就是链接阶段的任务。当然,不仅找当前路径下的,还会去找系统的默认路径/usr/lib/下面找这个,我以前也疑惑,其是怎么找到函数实现,其实,就是这样,一点一点查找的,然后再链接到声明,就这么简单。原创 2022-08-21 18:27:18 · 1161 阅读 · 0 评论 -
反演律在代码中的应用
写代码中,经常用到判断逻辑的处理,处理判断逻辑处理时,经常反向去处理,比如为了把最常用的判断放到前面。反向处理,直接用逻辑代数的反演示律,就非常的简单些,反演律是这样的:也可以非常简单的证明一下,可以用最简单的证明方法,一个个的试,最喜欢这代码逻辑了,因为其非常的简单:列名 A B ¬(A+B) ¬A¬B 逻辑值 0 0 1 1 逻辑值 1 1 0 0 逻辑值 0 1 0 0 .原创 2022-05-30 18:53:00 · 645 阅读 · 0 评论 -
链表反序算法
这三个东西,可以理解为数据结构,其它的步骤就是循环了,就是算法了。面试题 20:怎样把一个单链表反序。前一个节点、当前节点、后一个节点。有这三个东西,就可以进行算法了。(1) 反转一个链表。原创 2023-03-01 17:39:38 · 235 阅读 · 0 评论 -
QString的解析与常用功能
QString存储字符串采用的是Unicode码,每一个字符是一个16位的QChar,而不是8位的char,所以QString处理中文字符没有问题,而且一个汉字算一个字符。count()、size()、length()都返回字符串的个数,这3个函数是相同的,但是要注意,字符串中如果有汉字,一个汉字算一个字符。trimmed()去掉字符串首尾的空格,simplified()不仅去掉首尾的空格,中间连续的空格也用一个空格替换。lastIndexOf()函数则是查的某个字符中最后出现的位置。原创 2023-05-08 11:50:23 · 1046 阅读 · 0 评论 -
removeWidget不起作用的解决方法
今天在写一个界面操作时,如下:objList = ui->widget1->children(); for(int i=0; i<objList.length(); i++) { if(objList.at(i)->inherits("Group")) { Group *tmp = qobject_cast<Group *>(objList.at(i)); ui->原创 2022-01-27 11:46:29 · 2646 阅读 · 2 评论 -
C语言字面常量的内存映像
经常遇到字面常量,比如直接出现的各种进制的数字,字符或字符串等。实际上只存在基本数据类型的字面常量。字面常量在内存当中是如何布局的呢?字面常量存在内存只读区当中由于字面常量只能引用,不能修改,所以语言实现一般,把它保存在程序的符号表里,而不一般的数据区中。符号表是“只读”的,其实它是一种访问保护机制 ,但不能理解为只读存储器。除了字符串外,你无法取一个字面常量的地址。 1 #include <stdio.h> 2 #include <string.h...原创 2022-05-25 11:27:10 · 690 阅读 · 0 评论 -
记sqlite3遇到的unable to open database file
做项目用到sqlite3,在进行测试时遇到了问题。刚开始的读写都没有问题,当继续操作数据库到一定次数时(我大概1000多次)就会报错unable to open database file。错误出在sqlite3_open_v2()函数里面,报错信息就是:unable to open database file; 没有更为详细的错误,也就是提示数据库无法打开。经几番检查后,发现数据库连接打开,却没有关闭数据库(sqlite3_close(mdb)没写这句话)。导致了后面的错误(unable原创 2022-02-22 18:11:45 · 6431 阅读 · 2 评论 -
c语言指针的指针
指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。C 中指向指针的指针一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如,下面声明了一个指向 int 类型指针的指针:int **var;......原创 2022-08-12 18:50:48 · 3241 阅读 · 0 评论 -
c检查给定的值是否为非数字
在一些工作中,经常需要判断数据是否为数值,这一步很关键,如果不检查,直接进行计算,程序就直接报错了。 比如检查float a,检查a是否为数值,这种情况在modbus_rtu获取寄存器的值当中,经常用到,平常应用编程的时候,用的挺少。 总之,解决的问题就是判断一个数值是否为数字,比如float a,a是数值吗? isnan()函数是math标准的库函数,用于检查给定的值是否为NaN(非数字)。 它接受一个值( float , double或long double ),如果给定值为Na原创 2022-07-08 11:19:27 · 1242 阅读 · 0 评论 -
C++的引用类型的掌握
引用类型是C++新增加的一个类型,也是非常体现C++特点的一个类型,一直知道其是别名,但具体含义必须准确掌握,才能准确的应用,其注意点如下:1、定义:引用是已定义的变量的别名(另一个名称)2、用途:引用变量的主要用途是用作函数的形参3、使用注意事项:必须在声明引用时进行初始化(引用更接近const指针,必须在创建时进行初始化,一旦与某个变量关联起来,就将一直效忠于它)这三点记住,就可以说掌握了引用的用法,哪一点不理解到位,使用过程中都报错。比如第一点,定义,引用是已定义的变量的别名,其含原创 2022-03-07 18:39:57 · 728 阅读 · 0 评论