- 博客(52)
- 收藏
- 关注
原创 结构体对齐规则与优化
规则核心要点示例说明偏移量规则第一个成员偏移 0,其他成员对齐到对齐数的整数倍char后int跳过 3 字节总大小规则总大小为最大对齐数的整数倍3 成员可能占 8/12/16 字节嵌套规则嵌套结构体对齐到其最大对齐数的整数倍嵌套结构体从 4/8/16 开始修改对齐数改变默认对齐数pack(1)取消对齐offsetof 宏计算成员偏移量(字节)返回 4。
2025-05-21 22:17:54
1047
原创 自定义类型(结构体)
【结构体家族】🎒 普通结构体 → 书包(书+价格)🎁 嵌套结构体 → 套盒(地址+省市区)🚮 匿名结构体 → 塑料袋(临时成绩)🔗 自引用结构体 → 项链(链表钩子)【内存魔法】结构体大小 = 所有成员大小之和(可能有填充,暂时忽略~)
2025-04-21 06:00:00
568
原创 内存操作函数
内存操作四兄弟,各有分工要牢记:cpy快但怕重叠,move全能稍吃力;cmp逐字节较量,set按字节涂漆;断言调试加安检,新手少踩内存坑。🌟 作者碎碎念:刚学 memcpy 时,我把结构体复制写成 strcpy,结果程序崩溃了三天... 后来画内存图才明白,strcpy 遇到 \0 就停,而 memcpy 是真正的「字节复印机」。建议用手机便签存这个对比表,遇到内存问题时,先查表再写代码~ 下期见!
2025-04-20 06:00:00
1064
1
原创 字符分类函数
可打印isprint(含空格),图形isgraph(不含空格)大写isupper,小写islower,十六进制isxdigit空白isspace(空格/制表/换行),控制iscntrl(如退格)
2025-04-19 06:00:00
473
原创 三子棋游戏代码
define GM_H 3 // 棋盘行数(3行)#define GM_W 3 // 棋盘列数(3列)✅作用:通过宏定义统一管理棋盘大小,方便后续扩展为 5x5 等规格。
2025-04-18 04:00:00
1438
原创 进阶指针(二):数组指针
定义:专门指向 “数组” 的指针,存储的是整个数组的地址,而非单个元素地址语法类型 (*指针名)[数组长度](必须加括号!括号决定优先级)// 普通数组(10个int元素)// 正确!parr是数组指针,指向arr数组(存储&arr,整个数组的地址)错误示范// ❌ 错误!int* 只能指向单个int,无法指向整个数组// ❌ 错误!这是“指针数组”(数组存储指针),不是数组指针类型 (*指针名)[数组长度] = &目标数组;(pd 指向包含 5 个 double 的数组 d)
2025-04-15 06:00:00
795
原创 实用调试技巧(一)
Debug 是 “侦探模式”:给自己用,保留所有线索(调试信息)Release 是 “精简版”:给用户用,删掉线索 + 加速运行先切 Debug,再设断点(F9)运行用 F5,单步 F10/F11变量值不对?监视窗口瞧一瞧错误别乱改,步步有依据!通过这套方法,像侦探一样精准定位 Bug,告别 “玄学调试”!😊🚀。
2025-04-13 06:00:00
1108
1
原创 结构体传参:传值 vs 传址
小结构体用传值:简单、安全,不怕数据被改。大结构体用传址:高效、省内存,修改直接生效。指针传参加 const:若不想修改原数据,加const保护:void read_only(const Student* stu) { /* 此时不能修改stu->成员 */ }通过清晰的代码示例和对比,快速掌握结构体传参的核心逻辑。记住:传址调用是 C 语言处理大结构体的 “高效武器”,但要注意指针的合法性检查,避免野指针风险~ 💪。
2025-04-12 06:00:00
1077
原创 结构体(初阶)
结构体是用struct关键字定义的 “复合数据类型”,可以把不同类型的数据(如intcharfloat)打包成一个整体。// 结构体标签:Student(相当于自定义类型名)// 成员变量1:字符数组(姓名)int age;// 成员变量2:整数(年龄)// 成员变量3:浮点数(成绩)// 分号不能少!部分说明struct关键字,声明这是一个结构体定义Student结构体标签(类型名),后续声明变量需用或typedef简化{ }包裹成员列表,每个成员以分号结尾末尾分号;
2025-04-11 06:00:00
1246
原创 指针运算:从数组到二级指针
解引用两次,先得 pa(0x1000),再得 a 的值(10)→ 等价于 a。:解引用 ppa,得到 pa 的地址(0x2000)→ 等价于 pa。✅ 正确步骤:先定义一级指针,再取一级指针的地址给二级指针。📍 一、指针 ± 整数 & 关系运算 —— 数组遍历的核心。📍 一、指针 ± 整数 & 关系运算 —— 数组遍历的核心。四、二级指针 —— 指针的指针(内存地址套娃):二级指针务必先初始化一级指针,再取地址赋值。一级指针存变量地址,二级指针存一级指针地址。二、指针 - 指针 —— 计算元素间隔数。
2025-04-10 06:00:00
639
原创 指针数组 vs 数组指针
语法类型 (*指针名)[长度];()让先与指针名结合,形成指针,指向包含长度个元素的数组)本质:一个指针,指向一个固定长度的数组(数组的地址)。int* p[5];认为是数组指针✅ 正确:无括号时,[]优先级高,这是指针数组(元素是指针)。看括号:有括号(*p)是数组指针,无括号arr[]是指针数组。想本质:指针数组存多个指针,数组指针存整个数组的地址。记用途:指针数组用于 “地址集合”(如字符串数组),数组指针用于 “二维数组行操作”。通过画图和案例,这两个概念会变得清晰!
2025-04-09 23:59:09
772
原创 初级指针(一)
地址 = 指针指针变量 = 存储指针的变量。概念说明指针内存单元的地址(相当于 “门牌号”)指针变量存储地址的变量,大小由平台决定(32 位 4 字节,64 位 8 字节)解引用*指针表示通过地址访问数据,权限由指针类型决定(如int*操作 4 字节)指针步长指针 + 1 的跨度等于指向类型的大小(char*+1 跳 1 字节,int*+1 跳 4 字节)易错点未初始化指针(野指针)、类型不匹配、误解指针大小。
2025-04-09 06:00:00
1207
原创 野指针:C 语言中的隐形炸弹
定义必初始化:局部指针要么指向合法地址,要么置 NULL。越界要小心:指针操作不超过数组边界,用sizeof计算长度。释放必置空free后立即写p = NULL,避免悬空指针。解引用前检查:每次*p前先判断if (p!= NULL)。掌握这四点,就能有效避开野指针的陷阱!编程时养成良好习惯,比 debug 更重要~ 🛡️。
2025-04-09 06:00:00
1179
原创 C 语言操作符
核心原则算术操作符注意整数除法截断和取模规则赋值操作符注意与==的区别逻辑操作符善用短路求值优化代码位操作符直接操作二进制,效率高但易出错代码习惯关系判断用==,赋值用浮点数比较用误差范围(如1e-6复杂表达式加括号明确优先级(如学习建议动手敲代码验证每个操作符的效果遇到错误时,打印中间结果辅助调试用生活例子类比(如分蛋糕理解除法 / 取模)通过以上整理,操作符的知识点更加清晰,配合代码示例和易错点分析,新手能快速掌握核心用法。🚀。
2025-04-08 06:00:00
912
原创 C语言:动态二维数组
最后,在动态内存分配过程中,如果某一步分配失败,需要释放之前已经分配的内存,以确保不会出现内存泄漏。这是编写使用动态内存分配的程序时的一个重要原则,有助于提高程序的健壮性和资源利用率。是一维的指针数组,但通过这种语法糖的形式,我们可以像访问二维数组一样访问它所指向的内存区域。会终止程序的执行,并向操作系统返回一个非零的状态码,表示程序执行过程中出现了错误。尝试为整个二维数组的数据部分分配一块连续的内存,大小为 3 行 4 列的。
2025-04-07 06:00:00
1725
原创 循环排序算法:冒泡、选择、插入、快速排序
通过相邻元素的比较和交换,每次遍历将最大元素 “冒泡” 到末尾。每轮选择未排序部分的最小元素,放到已排序序列末尾。分治策略,选择基准元素,将数组分为小于基准和大于基准的两部分,递归排序。将未排序元素逐个插入到已排序序列的正确位置,类似打扑克牌时整理手牌。:找到剩余最小元素 5,与第 3 个元素 8 交换 →。:找到最小元素 1,与第 1 个元素 5 交换 →。:不要忘记交换操作,否则无法将最小元素放到正确位置。:找到剩余最小元素 3(已在正确位置) →。❌ 忘记交换元素 → 无法正确排序。
2025-04-06 06:00:00
386
1
原创 C 语言函数四(递归)
graph TDA[复杂问题] --> B{能否分解为更小同类问题?B -->|是| C[递归解决]B -->|否| D[直接解决]C --> E[基线条件]C --> F[递归条件]
2025-04-05 06:00:00
2262
原创 C语言函数(三)(嵌套调用 + 链式访问 + 分文件编程)
链式访问就是把一个函数的返回值直接作为另一个函数的参数,就像把几个小链子连接在一起一样。这样可以让代码更简洁,计算过程更清晰。在 C 语言里,要先声明函数,再使用它。这就好比你要邀请别人参加活动,得先告诉别人活动的时间、地点和内容(声明),然后才能让别人来参加(使用)。函数的声明和定义必须保持一致,特别是参数类型和返回值类型。参数名可以不同,但类型一定要一样。// Add.h 声明// Add.c 定义int Add(int a, int b) { // 参数名不同但类型相同 → 允许。
2025-04-04 06:00:00
1218
原创 库函数:字符处理函数与其他函数
⚠️ 注意:如果不使用 设置种子,每次程序运行时 生成的随机数序列是相同的。 🚨 易错:可能会忘记使用 设置种子,导致随机数不随机。📌 重点总结 字符检测:→真,→假转换前先用检查,避免无效转换字符串转数字:→123(部分转换),→0安全第一:要预留足够缓冲区避免执行用户可控命令随机数技巧:生成0到N-1的随机数用确保每次运行种子不同🎯 实战演练:// 生成10个随机大写字母#include <stdio.h>#include <stdlib.h>
2025-04-02 06:15:00
1037
原创 C 语言 scanf 函数输入结束标志及注意事项
存在上述这些停止录入的情况,可能会让输入缓冲区残留一些字符,从而影响后续的输入操作。这里在读取第二个字符前,先清理了缓冲区的换行符,避免它被当作第二个字符读取。为了保证后续输入的准确性,在需要连续进行输入操作时,通常要清理输入缓冲区。在格式控制字符串中可以包含非格式字符,输入时必须按原样输入这些字符。读取字符串后,输入缓冲区可能会残留换行符。在读取字符时,要特别注意输入缓冲区里的换行符等空白字符。读取字符串时,要确保数组有足够的空间,避免缓冲区溢出。限制输入的长度,避免输入的字符串超出数组的大小。
2025-03-28 07:00:00
2507
1
原创 C语言switch语句
switch只认整数,case常量不能变每个case加break,default保安全穿透效果要警惕,合并case更简洁。
2025-03-25 21:34:04
1222
原创 C语言结构体(认识)
struct 结构体名 {数据类型 成员1;// 成员变量1数据类型 成员2;// 成员变量2...// 注意:这里必须有分号!
2025-03-21 07:00:00
684
原创 #define预处理指令
核心作用: 是预处理指令,用于文本替换(不是C语句,不用分号结尾)两大用途:定义常量、定义宏(函数式代码块)格式:特点:预处理阶段直接替换(不分配内存)通常用全大写命名(编程规范)#define MAX 1000 // ✅ 定义常量int arr[MAX]; // 预处理后变成 int arr[1000];二、定义宏 → 小心“替换陷阱”格式:本质:参数直接替换,可能引发运算优先级问题#define ADD(X,Y) X + Y // ❌ 危险写法!int result1
2025-03-19 21:54:06
559
原创 C语言关键字解析(零基础必看)
/ 输出:static变量:1 static变量:2。// 输出:普通变量:1 普通变量:1。printf("static变量:%d ", count);static void privateFunc() { // 私有函数,外部无法调用。void publicFunc() { // 公共函数,外部可访问。// 等价于 int num = 10;i++){ // 外层循环。j++){ // 内层循环。i++){ // 外层循环。j++){ // 内层循环。
2025-03-18 07:00:00
1244
原创 if-else就像“智能开关“
if (条件) { // 如果满足条件// 开灯 // 执行这里的代码} else { // 否则// 关灯 // 执行这里的代码。
2025-03-17 07:00:00
951
原创 操作符说明书(像用家电一样简单!)
操作符名称示例说明++自增i++变量值+1(分前后缀)--自减--j变量值-1按位取反~0b101二进制每位翻转!逻辑非!isOpen真假反转(非0→0,0→1)取地址&num获取变量内存地址(类型)强制转换(int)3.14改变数据类型(可能丢失精度)最终学习建议先掌握基础操作符(+ - * / ==),再学进阶的遇到不理解的运算符,立刻写代码测试复杂表达式多用括号明确优先级配套记忆图操作符类型操作符基础用法例子讲解算术操作符用于两个数相加。
2025-03-17 07:00:00
810
空空如也
汇编语言warning问题
2024-01-03
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅