- 博客(37)
- 收藏
- 关注
原创 C语言经典100题---例003--- 完全平方数
摘要:本文通过数学分析和C语言编程解决了一个整数问题:找出满足"x+100是完全平方数,x+268也是完全平方数"的整数x。通过数学推导将问题转化为求解(n-m)(n+m)=168,并限定a=n-m和b=n+m为偶数因子对。C语言实现中遍历可能的因子组合,计算出x=m²-100并验证。最终输出4个解:1581、261、21和-99,均满足题目条件。
2025-12-08 10:43:11
381
原创 C语言经典100题---例002--- 阶段利润提成
摘要:本文介绍了企业奖金计算问题的两种解决方案。第一种采用if-else条件判断,直观展示各利润区间的分段计算逻辑(10万以下10%,10-20万7.5%等)。第二种通过循环和数组实现,将利润阈值[100,60,40,20,10,0]与对应利率[1%,1.5%,3%,5%,7.5%,10%]配对计算,代码更简洁且易于扩展。两种方法均能正确计算奖金,但第二种方案在可维护性和扩展性上更优,只需修改数组即可调整计算规则。
2025-12-06 21:33:15
366
原创 C语言经典100题---例001---组无重复数字的数
本文通过C语言程序解决排列组合问题:用1、2、3、4四个数字组成互不重复的三位数。首先进行数学分析,得出共有4×3×2=24种可能。程序采用三重循环结构,分别控制百位、十位和个位数字,通过条件判断确保数字不重复。每行输出6个结果以提高可读性,最终输出全部24个符合条件的数字。文章还讨论了时间复杂度(O(n³))和优化方案(如回溯算法),并指出该解法适用于小规模问题,具有代码简洁易懂的特点。
2025-12-04 23:10:03
412
原创 软考高级-系统架构师之存储器
本文介绍了计算机存储系统的层次结构和工作原理。主要内容包括:1)存储器的分类及特性,对比了RAM(含SRAM与DRAM)和各类ROM的特点;2)高速缓存Cache的功能与映射方式(全相联、直接、组相联),重点分析了组相联映射的优越性;3)Cache替换策略,包括随机、FIFO、LFU和LRU算法;4)磁盘存储的基本概念和调度算法(FCFS、SSTF、SCAN、CSCAN)。文章通过比较不同存储技术的特性,阐述了存储系统如何通过分层设计实现大容量、高速度和低成本的目标。
2025-10-22 17:47:21
800
原创 软考高级-系统架构设计师之指令系统
本文介绍了计算机指令系统的核心概念,包括指令格式(操作码+地址码)和两大类寻址方式:指令寻址(顺序/跳跃)与操作数寻址(8种方式)。重点解析了操作数寻址的八种实现机制,从立即寻址到变址寻址,并阐述了指令执行的三阶段流程。最后对比了CISC与RISC指令集的特点,指出CISC指令复杂但编程灵活,RISC指令精简且执行高效,分别采用微程序控制和硬布线技术实现。全文系统梳理了指令系统的关键要素及其技术特性。
2025-09-14 21:53:05
3462
原创 一文快速搞懂CRC校验码原理带案例解析
循环冗余校验码(CRC)是一种基于多项式编码的检错技术,广泛应用于数据传输校验。其核心原理是通过模2运算(二进制异或运算)实现,发送端将数据与生成多项式G(x)进行模2除法,得到余数作为校验码附加到数据末尾;接收端用相同多项式计算,若余数为0则大概率无错。特点包括:只能检错不能纠错,使用约定的生成多项式,通过模2除法运算实现。过程包括发送端添加校验码和接收端验证余数两个阶段,要求收发双方使用相同的生成多项式。CRC提供了一种高效的数据传输错误检测机制。
2025-09-14 00:21:47
9901
原创 奇偶校验与海明码原理详解
本文系统介绍了奇偶校验码和海明码两种重要的校验编码技术。首先详细解析了奇偶校验码的原理,包括校验位计算、错误检测机制及其局限性;然后重点讲解了海明码的核心思想——多重奇偶校验,通过校验位分组的巧妙设计实现单比特错误的定位与纠正;最后介绍了海明距离的概念及其在衡量编码检错纠错能力中的关键作用。全文通过具体示例演示了两种校验码的编解码过程,帮助读者深入理解计算机数据传输中的差错控制机制。
2025-09-06 10:48:01
2354
原创 顺序查找算法详解:原理与实现(带与不带哨兵)
顺序查找是一种基础的线性查找算法,通过逐个比较数组元素来定位目标值。本文介绍了两种实现方式:不带哨兵的标准方法和带哨兵的优化版本。标准方法需要每次循环检查数组边界和目标值,而哨兵方法通过临时修改数组末尾元素来简化循环条件,理论上能提高效率。两种方法的时间复杂度均为O(n),空间复杂度为O(1)。带哨兵实现虽然减少了循环内的判断次数,但需要额外的保存/恢复操作,适用于大规模数据场景。文章通过C语言代码示例、流程图和复杂度分析,全面讲解了顺序查找的实现原理和性能特点。
2025-08-25 13:03:10
1778
原创 折半查找:高效搜索有序数组
摘要:折半查找(二分查找)是一种在有序数组中高效搜索特定元素的算法,通过每次比较中间元素将搜索范围减半。算法步骤包括确定中间位置、比较目标值与中间元素,并相应调整搜索范围。适用于随机访问的有序数组,不适用于链表或动态数据集。C语言实现采用迭代方式,时间复杂度为O(logn),空间复杂度O(1)。性能高效但要求数据有序,适合静态大数据集,不适用于频繁修改的数据结构。
2025-08-25 13:02:15
1717
原创 冒泡排序:可视化讲解与C语言实现
本文详细介绍了冒泡排序算法的工作原理、执行流程及实现方法。该算法通过相邻元素比较和交换,使较大元素逐渐"浮"到数列末端完成排序。文章包含完整的流程图解和分步推演过程,并以数组{29,42,34,28,34,29,16,41}为例演示了排序过程。算法分析显示其最优时间复杂度为O(n),最坏和平均情况为O(n²),空间复杂度为O(1),且具有稳定性。最后提供了C语言实现代码,包含优化后的带交换标志的版本,能有效处理接近有序的数组。
2025-08-11 00:15:42
1238
原创 直接插入排序算法:可视化讲解与C语言实现
直接插入排序是一种简单直观的排序算法,其工作原理类似于整理扑克牌。算法通过将未排序元素逐个插入已排序序列的适当位置实现排序,时间复杂度为O(n²)。该算法是原地排序(空间复杂度O(1)),且具有稳定性(保持相等元素相对顺序)。适用于小规模或部分有序数据,在最好情况下(已排序)时间复杂度可达O(n)。C语言实现展示了核心逻辑:通过后移元素为新元素腾出插入位置,保持了算法的高效性和简洁性。
2025-08-09 23:30:00
9076
原创 选择排序原理与C语言实现详解
选择排序是一种简单直观的排序算法,其核心思想是每次从未排序序列中选出最小(或最大)元素,存放到已排序序列的末尾,直到所有元素排序完毕。算法通过双重循环实现:外层循环控制已排序区位置,内层循环在未排序区查找最小值。时间复杂度为O(n²),空间复杂度O(1),属于原地排序但不稳定(可能改变相等元素的原始顺序)。该算法适合小规模数据排序,大规模数据建议采用更高效的排序算法。示例演示了将数组[64,25,12,22,11]通过四轮比较交换最终排序为[11,12,22,25,64]的过程。
2025-08-03 22:30:24
8583
原创 C/C++中常量放置在比较操作符左侧
摘要:Yoda条件是一种将常量置于比较运算符左侧的编程风格(如if(42==x)),主要用于C/C++等语言中防止误用赋值运算符(=)导致的逻辑错误。当开发者误将==写成=时,例如if(x=42)会通过编译但产生错误;而采用Yoda风格if(42=x)则会触发编译错误。这种写法特别适合大型或安全关键型项目,能在编译阶段捕获潜在错误,提高代码安全性。
2025-07-26 19:13:57
351
原创 单片机启动流程和启动文件详解
单片机启动流程是从上电复位到执行用户main()函数之前的完整过程,这个过程由硬件自动触发并由启动代码(Startup Code / Bootloader)控制。理解启动流程对嵌入式开发至关重要,尤其是涉及底层初始化、内存管理和故障排查时。硬件复位触发复位源上电复位(POR, Power-On Reset):首次通电时电压爬升。外部复位引脚(NRST):用户手动或外部电路触发。看门狗复位(WDT):程序跑飞后超时复位。低功耗模式唤醒复位:某些休眠模式唤醒后复位。
2025-07-20 22:59:27
2428
原创 嵌入式开发必知:volatile关键字的妙用
本文深入解析了C语言中volatile关键字的核心作用和应用场景。volatile告知编译器变量值可能被外部因素(如硬件、中断、多线程)改变,强制每次访问都直接从内存读取/写入。主要应用于:1)硬件寄存器访问(确保实时读取硬件状态);2)中断服务程序共享变量(保证主程序可见中断修改);3)多线程共享变量(需配合同步机制)。关键特性包括禁用优化但不保证原子性,需注意避免常见误区,如误作同步工具或忽略原子性要求。在嵌入式开发中,正确使用volatile是确保硬件交互可靠性的关键。
2025-07-20 19:03:16
889
原创 Keil编译文件格式转换全解析
本文介绍了Keil开发环境中常用的文件格式转换方法和工具使用。主要内容包括:1. Keil自带命令fromelf.exe的功能解析,用于将.axf文件转换为.bin/.hex等格式;2. 三种可烧录文件(.axf/.hex/.bin)的核心差异对比,包括内容、地址信息、调试信息等特性;3. 详细说明了如何获取和生成这些文件,特别是通过User Command设置自动化生成.bin文件;4. 命令参数详解,如路径变量$L和@L的使用方法;5. 补充介绍了生成汇编代码(.asm)的方法及其应用场景。文章为开发者
2025-07-19 22:06:42
1521
原创 C语言strtok函数详解与使用技巧
摘要: strtok是C标准库中的字符串分割函数,通过指定分隔符将字符串拆分为多个标记。其核心特性包括:直接修改原字符串(替换分隔符为\0)、忽略连续分隔符、非线程安全(使用静态变量记录状态)。使用时需首次传入目标字符串,后续调用传入NULL,返回NULL表示结束。线程安全替代方案为strtok_r(POSIX)和strtok_s(C11)。注意事项:空字符串返回NULL、不可嵌套调用、分隔符为字符集合。适用于单线程简单场景,需注意字符串备份和线程安全。
2025-07-17 22:57:28
876
原创 C/C++宏定义中do{}while(0)的妙用
摘要: do{}while(0)是C/C++中一种特殊编程技巧,主要用于宏定义和代码块封装。其核心价值包括: 宏安全性:确保多语句宏在条件语句中展开时语法正确,强制分号结尾,避免if-else断裂问题; 错误处理:替代goto实现结构化资源清理,通过break跳转和集中式回收简化多步骤操作的错误处理; 作用域隔离:创建临时块级作用域,限制变量生命周期,避免命名冲突; 代码一致性:保持与函数调用相同的分号习惯,提升可维护性。该技巧在宏定义、嵌套错误处理及资源管理中具有不可替代的优势。
2025-07-15 23:04:09
1088
原创 C语言字符串与内存比较函数详解:strcmp、strncmp与memcmp对比分析
C语言字符串与内存比较函数对比摘要 本文详细对比了C语言中三种关键比较函数:strcmp、strncmp和memcmp。strcmp用于字典序字符串比较,依赖'\0'终止符;strncmp增加长度限制,提升安全性;memcmp直接比较内存块,无视数据类型和终止符。三者核心区别在于:strcmp/strncmp基于ASCII字符值比较,memcmp比较原始字节值;前两者遇'\0'停止,后者严格比较指定字节数。strncmp适合前缀检查,memcmp处理二进制数据更安全。使用时需注意:返回值仅保证符号意义、跨平
2025-07-06 21:45:16
1514
原创 C语言长度计算函数strlen和运算符sizeof
strlen与sizeof深度对比摘要 strlen是运行时库函数,计算字符串长度(不含\0),必须依赖终止符,时间复杂度O(n)。sizeof是编译时运算符,计算对象内存大小(含\0),无运行时开销。关键区别: 字符串处理:strlen("ABC")=3,sizeof("ABC")=4(含\0) 数组参数:sizeof返回总字节数,strlen返回有效字符数 指针参数:sizeof返回指针大小,strlen计算指向字符串长度 安全性:sizeof无风险,strlen
2025-07-05 14:22:36
958
原创 C语言中snprintf与sprintf函数详解和对比
【摘要】sprintf和snprintf是C语言中常用的格式化输出函数,主要区别在于安全性。sprintf无缓冲区大小检查,存在溢出风险,如写入"2023-12-31"到8字节缓冲区会导致12字节溢出。snprintf通过size参数限制写入量,自动截断并保证结尾\0,更安全。关键差异:1)sprintf返回值是实际写入字符数,snprintf返回完整结果的理论长度;2)snprintf支持预计算缓冲区需求(str=NULL,size=0时);3)所有新代码都应使用snprintf替代s
2025-07-03 22:53:14
596
原创 C语言内存拷贝函数memmove与memcpy详解与对比
本文介绍了C语言中memcpy和memmove两个内存拷贝函数的区别。memcpy速度快但不处理内存重叠,适用于确定无重叠的场景;memmove能安全处理内存重叠,通过自动判断拷贝方向避免数据覆盖,虽然性能稍慢但通用性更强。关键区别在于:memcpy对重叠内存的行为未定义,而memmove会检测重叠并调整拷贝顺序(目标地址在前则从前往后,在后则从后往前)。建议优先使用memmove确保安全,仅在确定无重叠且需要极致性能时选用memcpy。现代编译器优化后两者性能差距已很小。
2025-06-29 17:23:00
1243
原创 深入剖析:C语言字符串拷贝函数对比(strcpy, strncpy, memcpy, snprintf)
本文对比分析了C语言中四种常用的复制函数:strcpy、strncpy、memcpy和snprintf。从安全性角度看,strcpy不检查目标缓冲区大小,极易引发缓冲区溢出;strncpy虽限制长度但不保证自动添加终止符;memcpy高效但不处理字符串特性;而snprintf最为安全,自动处理终止符和截断。性能方面,memcpy最高效,snprintf因格式解析开销较大。根据使用场景推荐:避免strcpy,谨慎使用strncpy(需手动终止),非字符串数据用memcpy,安全字符串操作首选snprintf。
2025-06-26 22:24:03
935
原创 C语言整数除法取整技巧
摘要:本文介绍了C语言中实现正整数除法的三种取整方法:向下取整(Floor)、向上取整(Ceiling)和四舍五入(Round)。向下取整直接利用整数除法特性(a/b);向上取整采用(a+b-1)/b公式实现进位;四舍五入通过(a+b/2)/b公式完成。每种方法都给出了实现原理、公式推导和代码示例,并强调了仅适用于正整数、注意溢出和除数非零等关键点。表格总结了三种取整方式的公式和示例结果(如7/2分别得到3、4、4)。这些方法通过整数运算实现,避免了浮点运算的开销。
2025-06-24 22:56:06
2161
原创 C语言中联合体union使用总结
C语言union联合体是一种共享内存的特殊数据类型,允许在同一内存位置存储不同类型数据。其核心特性包括:所有成员共用内存,大小由最大成员决定;只能初始化首个成员;使用时需注意成员覆盖风险。典型应用包括节省内存、类型转换、硬件寄存器访问和网络字节序处理。安全使用技巧包括添加类型标记和使用匿名联合。与struct相比,union更节省空间但风险更高,需特别注意内存覆盖、未定义行为和对齐问题。最佳实践是结合struct和enum确保安全访问。合理使用union可提高内存效率和灵活性,但需严格管理当前有效成员。
2025-06-24 21:50:33
646
原创 #define宏定义中的#,##,@#,\ 这些符号的用法
C/C++宏定义中的特殊运算符包括:#(字符串化运算符,将参数转为字符串)、##(连接运算符,合并两个标记)和\(续行符)。@#是MSVC的非标准扩展。使用技巧包括双层宏解决连接优先级问题(如CONCAT(var,1+1)需先展开参数)、避免多次求值(如SQUARE(a++)可能导致未定义行为)以及注意变量作用域污染。典型应用场景包括调试宏、函数自动生成和X宏技术。需遵循标准规范,合理使用这些运算符以提升代码灵活性,同时注意避免滥用导致可读性下降。
2025-06-22 22:17:03
4497
原创 const修饰指针用法总结
C语言中const修饰指针的三种用法:1)指向常量数据的指针(内容不可变);2)指针常量(指向不可变);3)指向常量数据的指针常量(两者均不可变)。使用时需注意位置差异,const在*前限制内容,在*后限制指针。合理使用可提高代码安全性,如保护函数参数、访问硬件寄存器等场景。关键区别在于能否修改指针指向和内容,建议默认使用const以防意外修改。
2025-06-16 00:02:41
555
原创 循环缓冲区实现C语言
目录介绍循环缓冲区结构体关键点解析数据类型循环缓冲区实现循环缓冲区满和空的判断满标志的使用写入和读取的前置条件满和空的判断条件初始化循环缓冲区反初始化循环缓冲区判断循环缓冲区是否为空判断循环缓冲区是否已满获取循环缓冲区有效长度(字节为单位)获取循环缓冲区空闲长度(字节为单位)批量写入输出批量读取数据测试测试输出 循环缓冲区是一种数据结构,它使用一个固定大小的缓冲区,当缓冲区满了之后,新的数据会覆盖最旧的数据。它通常用于需要缓冲数据流的场景,比如生产者-消费者问题。在C语言中,循环缓冲区可以通过
2025-06-16 00:02:02
1353
原创 memset函数用法
摘要(147字) memset是C/C++中用于按字节填充内存的函数,原型为void* memset(void* ptr, int value, size_t num)。其核心特性是按字节处理(取value低8位),常用于内存清零、字符数组初始化或结构体清零。使用时需注意: 非字符类型初始化非零值会导致意外结果(如int数组元素变为0x01010101); 越界访问会引发崩溃; 禁用场景:C++含虚函数或指针的类。 正确用法示例包括清零数组(memset(arr, 0, sizeof(arr))),错误用法
2025-06-03 19:55:58
744
原创 C语言结构体赋值总结
C语言结构体赋值方法总结 C语言结构体赋值有多种方式: 声明时初始化:直接赋初值,支持顺序或指定成员初始化(C99+) 直接赋值:同类型结构体变量间可直接赋值(浅拷贝) 逐成员赋值:灵活修改单个成员 memcpy():内存级复制,需包含<string.h> 指针操作:通过结构体指针访问成员 函数返回赋值:结构体可作为函数返回值 嵌套结构体:需分层初始化或赋值 复合字面量(C99+):临时匿名结构体赋值 注意事项: 浅拷贝时,指针成员会共享同一内存,需手动实现深拷贝 动态分配的结构体需注意内存释放
2025-06-02 22:23:07
1209
原创 C语言数组赋值方法总结
C语言数组赋值方法总结 C语言中数组赋值主要分为初始化赋值和后续赋值两种方式。对于基本数据类型数组,可通过完整或部分初始化;字符数组初始化时需注意是否自动添加'\0'。后续赋值可逐个元素赋值、使用循环批量赋值,或利用memset快速填充(注意其字节级操作特性)。数组复制可使用memcpy,字符串数组则用strcpy(需确保以'\0'结尾)。使用时需注意:数组长度固定不可变、严防下标越界、数组名是常量指针不可直接赋值、字符数组作为字符串使用时必须包含结束符。不同赋值方式适用于不同场景,需根据数组类型和需求选择
2025-06-02 11:56:44
4887
原创 KEIL编译工程后输出信息详解(Code、RO-data、RW-data、ZI-data),工程占用FLASH和RAM计算及分配
本文介绍了Keil MDK工程编译后查看信息的方法及存储空间配置要点。1)通过Build Output窗口或.map文件查看工程信息,需确保生成map文件。2)详细解析Flash和RAM的组成:Flash存储代码(Code)、只读数据(RO-data)和初始化变量(RW-data初始值);RAM运行存储RW-data和未初始化变量(ZI-data)。3)存储器分配方法:Flash起始地址通常为0x08000000,RAM为0x20000000,需根据芯片手册设置合理大小。特别指出RW-data需从Flash
2025-06-01 10:53:14
4657
原创 keil中各种编译选项的功能和区别
Keil MDK-ARM编译操作指南:提供Translate(单文件编译)、Build(增量编译)和Rebuild(全量编译)的核心区别,以及BatchBuild、BatchRebuild等批量操作功能说明。Translate用于快速检查单个文件语法错误,Build适合日常开发调试,Rebuild确保完整重新编译。批量操作支持多目标配置管理,其中BatchBuild实现多版本快速生成,BatchRebuild保证全量重新编译,BatchClean清理中间文件,BatchSetup统一配置参数。建议日常使用B
2025-05-27 23:52:20
3133
原创 预处理指令ifndef/define/endif和#ifdef __cplusplus extern “C“ { #endif的作用
本文介绍了C/C++头文件保护机制和跨语言链接处理。头文件保护使用#ifndef、#define、#endif组合防止重复包含,通过检查唯一宏定义来避免编译错误。建议宏名采用大写头文件名形式以确保唯一性。对于C++调用C代码的情况,使用#ifdef __cplusplus配合extern "C"语法,确保C++按C语言规则处理函数声明,解决名称修饰导致的链接问题。文中提供了标准的头文件框架示例,包括适当的位置标记,帮助开发者正确组织头文件内容。这种结构既能防止重复包含,又能保证C/C++
2025-05-27 23:28:49
4564
原创 C语言static关键字作用详解
摘要:static关键字在C语言中用于改变变量和函数的作用域与生命周期。修饰局部变量时,使其变为静态存储,生命周期延长至程序运行期,但作用域仍限于函数内;修饰全局变量或函数时,限制其仅在当前文件可见,避免命名冲突。典型应用包括:1)保持局部变量值不被销毁;2)隐藏模块内部实现细节。通过控制存储位置(静态区)和链接属性(内部链接),static增强了程序的模块化和安全性。
2025-05-25 22:04:49
4603
原创 C语言中双感叹号(!!)作用解析
初识双感叹号(!!),它是一个陌生的事物。但是,我们已经知道单个感叹号!在C语言中是逻辑非运算符,它会把非零的值变成0,把0变成1。比如,!5的结果就是0,而!0的结果就是1。通过查阅资料,双感叹号(!!)并不是C语言中的运算符。因此,我们猜测双感叹号(!!)仅仅是将逻辑非连续运行两次而已。经过验证,事实也是如此。!!通过两次逻辑非操作,将任意整数转换为0或1,确保结果的布尔语义明确。如果仅是简单的了解,着急赶路,那么到此就可以结束了。如果有时间,倒是可以深入剖析下。接下来需要讨论的两点:双感叹号!!
2025-05-25 13:01:01
4571
原创 STM32CubeMx教程---LED闪烁实验
库函数开发:ST官方将寄存器操作封装成库函数,开发者只需调用ST官方封装好的库函数进行编程即可,相对于直接的寄存器开发,大大提升了开发效率,降低了开发难度。只是ST官方这也是过去的一个时代主流开发模式,如博主最早接触的原子和野火教程就是采用库函数开发的。据说是ST全系列的一个大整合,从1种芯片到另1种芯片,解决了移植的老大难问题。明显的缺点是:寄存器数量相对51单片机数量太多太多,编程效率太低,对开发者要求太高;*自行调用HAL开发,通过写代码的方式完成初始化工作(这方面与库函数开发类似)
2023-09-06 11:06:03
5372
C语言经典100题-例003- 完全平方数
2025-12-07
C语言经典100题-例002- 阶段利润提成
2025-12-06
C语言入门经典100题之例001题,组无重复数字的数
2025-12-04
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅