C 语言指针练手:解 4 嫌疑人谋杀案,从冗余到简洁的优化之路
逻辑推理 C 语言新手指针练习版作为刚接触 C 语言指针的新手我总想找机会练手指针用法 —— 哪怕代码冗余也没关系先把指针用起来这次以 “4 嫌疑人谋杀案3 真 1 假找凶手” 为例我刻意用指针写了初始版本再结合查资料学到的指针知识一步步优化既解了题又吃透了指针的核心用法分享一下新手练习指针的全过程。一、题目背景谋杀案逻辑推理题1.1题目描述某地发生谋杀案警察确定凶手是 4 个嫌疑犯A、B、C、D中的一人。4 人的供词如下A 说不是我。B 说是 C。C 说是 D。D 说C 在胡说。已知条件3 个人说了真话1 个人说的是假话。请编写程序找出凶手。1.2题目逻辑分析写代码前先理逻辑这是新手避免混乱的关键我先给嫌疑人做索引映射方便指针 / 数组操作A0、B1、C2、D3设凶手索引为killer_idx取值 0-3把供词转化为指针 / 数组能操作的逻辑表达式1 真0 假表格嫌疑人供词逻辑表达式A(0)不是我killer_idx ! 0B(1)是 Ckiller_idx 2C(2)是 Dkiller_idx 3D(3)C 在胡说killer_idx ! 3核心条件4 个表达式结果之和 3恰好 3 真 1 假。1.3练指针的初衷我写初始代码时刻意绕了点路 —— 不用简单的数组下标而是用指针*(pi)操作数组就是为了练习指针和数组的等价关系arr[i] *(arri)哪怕代码冗余先把指针用熟再说二、第一版代码为练指针刻意保留冗余初始版本我写得很 “臃肿”但核心目的是练指针所以保留了所有指针变量只通过查资料修正了致命的语法错误确保代码能跑。2.1查资料踩的第一个坑写sofe函数时我误把判断相等的写成了赋值if(arr[i]1)运行后程序完全不对。查 C 语言指针 条件判断的资料才发现是赋值才是判断这是新手用指针 / 数组最容易踩的语法坑2.2第一版代码刻意保留指针仅修正语法#define _CRT_SECURE_NO_WARNINGS #include stdio.h // 打印凶手用指针思路遍历数组练*(arri) void print(int arr[],int n) { // 练习指针用指针遍历数组替代arr[i] int *p arr; for(int i0;in;i) { if(*(pi) 1) // 刻意用*(pi)练指针偏移 { if(i0) printf(凶手是A\n); else if(i1) printf(凶手是B\n); else if(i2) printf(凶手是C\n); else if(i3) printf(凶手是D\n); } } } // 统计真话数量查资料修正赋值→判断 int sofe(int arr[],int n) { int count 0; int *p arr; // 练习指针用指针遍历统计 for(int i0;in;i) { if(*(pi) 1) // 修正把改成 { count; } } return count; } // 核心推理函数全程用指针操作arr1练*(pi) void Jud(int arr1[], int arr2[],int n) { int flag1 0; // 冗余变量先保留后续优化 int flag2 0; int* p2 arr2; // 冗余指针刻意保留先练指针声明/赋值 int killer_idx -1; // 新增存储凶手索引 // 遍历每个嫌疑人假设i是凶手 for(int i0;in;i) { int* p arr1; // 核心用指针操作arr1存储供词真假 // 练指针偏移*(p0)等价于arr1[0] *(p0) (i ! 0); // A不是我 *(p1) (i 2); // B是C *(p2) (i 3); // C是D *(p3) (i ! 3); // DC在胡说 flag2 sofe(p, n); // 指针传参p是arr1的地址 if (flag2 3) // 3真1假找到凶手 { flag1 1; killer_idx i; break; } } // 练指针重置数组用指针把arr1所有元素置0 int *p_reset arr1; for(int i0;in;i) { *(p_reseti) 0; } *(arr1 killer_idx) 1; // 指针标记凶手 print(arr1, n); } int main() { int arr1[4] { 1,1,1,1 }; // 存储供词真假指针操作的载体 int arr2[4] { 0,0,0,0 }; // 冗余数组练指针传参 int n sizeof(arr1) / sizeof(arr1[0]); Jud(arr1, arr2,n); // 指针传参数组名本质是首元素地址 return 0; }2.3第一版思考过程刻意设计全程用*(pi)替代arr[i]就是为了吃透 “指针偏移 数组下标” 这个核心知识点哪怕代码绕弯查资料修正最初写*(pi)1判断时程序统计结果全错查 C 语言指针条件判断的资料才发现把写成了查 “逻辑推理题解法”确认核心条件是 “3 真 1 假”把flag21改成flag23冗余保留p2、flag1、arr2这些没用的指针 / 数组我先保留 —— 新手练指针先 “能用”再 “精简”一步改太多容易忘知识点。运行结果凶手是C指针操作没出错核心逻辑也对第一步练指针的目标达成三、简化步骤 1查资料优化指针使用删冗余保核心第一版能跑但很多指针是 “无效练习”比如p2全程没操作。我查了 “C 语言指针优化技巧” 的资料知道了 “指针要为功能服务不是为了用而用”开始删冗余指针 / 变量保留核心指针用法。3.1简化思路结合指针知识点删冗余指针p2、flag1、p_resetp_reset可以合并到原有循环不用单独声明保留核心指针*(pi)操作数组、指针传参这些练手的核心用法查资料学到arr1[0] arr1[1] arr1[2] arr1[3] 0等价于指针循环置 0更简洁但我仍保留指针写法练手。3.2步骤 1 代码优化指针冗余#define _CRT_SECURE_NO_WARNINGS #include stdio.h // 保留指针遍历打印 void print(int arr[],int n) { int *p arr; for(int i0;in;i) { if(*(pi) 1) { if(i0) printf(凶手是A\n); else if(i1) printf(凶手是B\n); else if(i2) printf(凶手是C\n); else if(i3) printf(凶手是D\n); } } } // 保留指针统计逻辑 int sofe(int arr[],int n) { int count 0; int *p arr; for(int i0;in;i) { if(*(pi) 1) { count; } } return count; } // 删冗余指针p2、flag1保留核心指针p void Jud(int arr1[], int arr2[],int n) { int flag2 0; int killer_idx -1; for(int i0;in;i) { int* p arr1; // 核心指针操作保留 *(p0) (i ! 0); *(p1) (i 2); *(p2) (i 3); *(p3) (i ! 3); flag2 sofe(p, n); if (flag2 3) { killer_idx i; break; } } // 简化指针置0合并循环删p_reset int *p arr1; for(int i0;in;i) *(pi) 0; *(arr1 killer_idx) 1; print(arr1, n); } int main() { int arr1[4] { 1,1,1,1 }; int arr2[4] { 0,0,0,0 }; // 暂留下一步优化 int n sizeof(arr1) / sizeof(arr1[0]); Jud(arr1, arr2,n); return 0; }3.3步骤 1 思考过程指针练习进阶查资料懂了“冗余指针会增加代码复杂度”比如p2只声明没操作完全是无效练习删了不影响指针核心用法保留*(pi)这是我练指针的核心哪怕循环置 0 可以更简洁我还是用指针写法 —— 新手练知识点先熟练再简化指针传参验证sofe(p, n)中p是arr1的首地址传参后函数内操作的还是原数组这一步验证了 “指针传参可以修改原数组” 的知识点查资料确认的。四、简化步骤 2查资料理解 “指针 函数设计”精简参数保留指针我查 “C 语言函数参数设计” 的资料时看到“函数参数越少逻辑越清晰指针传参也要按需设计”。这一步我删无用的arr2重构print函数但仍保留指针核心用法。4.1简化思路指针 函数优化删arr2全程没用到函数参数里留着只是浪费指针传参也要 “按需传递”重构print不用数组直接传凶手索引但我加了一个 “指针版 print” 的备选练手保留Jud函数内的核心指针操作*(pi)赋值、指针传参给sofe。4.2步骤 2 代码指针 函数优化#define _CRT_SECURE_NO_WARNINGS #include stdio.h //简洁版print void print(int killer_idx) { // 练指针用字符数组指针打印替代多个if char suspects[] {A,B,C,D}; char *p suspects; // 指针指向字符数组首地址 printf(凶手是%c\n, *(p killer_idx)); // 指针偏移找凶手 } // 保留指针统计逻辑 int sofe(int arr[],int n) { int count 0; int *p arr; for(int i0;in;i) { if(*(pi) 1) { count; } } return count; } // 精简参数删arr2保留核心指针操作 void Jud(int arr1[],int n) { int flag2 0; int killer_idx -1; for(int i0;in;i) { int* p arr1; *(p0) (i ! 0); *(p1) (i 2); *(p2) (i 3); *(p3) (i ! 3); flag2 sofe(p, n); if (flag2 3) { killer_idx i; break; } } print(killer_idx); // 调用新的指针版print } int main() { int arr1[4] { 1,1,1,1 }; int n sizeof(arr1) / sizeof(arr1[0]); Jud(arr1, n); // 删arr2参数 return 0; }4.3步骤 2 思考过程指针 函数设计查资料学到字符数组也能靠指针偏移访问元素*(p killer_idx)比多个 if 判断更简洁还能练指针函数参数精简Jud函数原本传arr1、arr2、n现在只传arr1和n指针传参的 “目的性” 更强 —— 新手练指针要知道 “指针是工具不是负担”核心收获指针传参的本质是 “传地址”不管是 int 数组还是 char 数组指针偏移的逻辑是通用的这一步把数组指针的用法打通了。五、简化步骤 3指针进阶优化保留指针合并冗余函数最后一步我查 “C 语言指针最佳实践” 的资料知道了 “没必要为短逻辑单独写函数”于是合并sofe函数但全程保留指针核心用法毕竟练指针是核心目的。5.1简化思路指针终极优化不丢练手目标合并sofe函数统计真话的逻辑只有几行合并到Jud中减少指针传参的次数但保留指针统计的逻辑变量名语义化flag2改true_count查资料学到 “变量名要见名知意指针代码更需要清晰命名”保留所有核心指针操作*(pi)赋值、指针遍历、字符数组指针偏移。5.2步骤 3 代码指针版极简化#define _CRT_SECURE_NO_WARNINGS #include stdio.h // 指针版打印函数练手核心 void print(int killer_idx) { char suspects[] {A,B,C,D}; char *p suspects; // 字符数组指针练手 printf(凶手是%c\n, *(p killer_idx)); } // 核心推理函数保留所有指针练手逻辑 void findKiller() { int killer_idx -1; int arr1[4] {0}; // 指针操作的载体 int *p arr1; // 核心指针 // 遍历嫌疑人练指针赋值 for(int i0;i4;i) { // 指针偏移赋值练*(pi) *(p0) (i ! 0); // A的供词 *(p1) (i 2); // B的供词 *(p2) (i 3); // C的供词 *(p3) (i ! 3); // D的供词 // 指针统计真话数合并sofe函数保留指针逻辑 int true_count 0; int *p_count arr1; for(int j0;j4;j) { if(*(p_count j) 1) true_count; } if (true_count 3) { killer_idx i; break; } } print(killer_idx); } int main() { findKiller(); return 0; }5.3步骤 3 思考过程指针练习总结合并函数但不丢指针sofe函数合并后我仍用p_count指针统计没改用数组下标 —— 练指针的目标要守住查资料的关键收获arr[i]等价于*(arri)指针偏移和数组下标是同一逻辑的两种写法指针传参的本质是 “共享地址”所以函数内操作指针能修改原数组指针要 “按需使用”冗余指针只会增加理解成本最终代码既保留了所有练指针的核心用法数组指针、字符指针、指针偏移、指针统计又精简了冗余逻辑解题 练指针的目标都达成了。六、新手练指针的核心收获附避坑指南1. 指针核心知识点查资料 练手总结基础等价关系arr[i] *(arri) *(iarr) i[arr]后两种少用但验证了指针偏移的本质指针传参数组名作为参数传递时本质是传递首元素的地址函数内修改指针指向的内容会影响原数组字符数组指针char *p str中*(pi)可以访问字符串的第 i 个字符和 int 数组指针逻辑一致。2. 新手练指针的避坑点我踩过的坑语法坑把判断写成赋值指针条件判断尤其要注意逻辑坑为了用指针而加冗余指针比如p2忘记 “指针是工具不是目的”命名坑用flag1/flag2这种无意义命名指针代码本身抽象命名不清晰更难理解。3. 练指针的小技巧新手向先 “刻意用”哪怕代码绕弯先把指针的核心用法偏移、传参、遍历用熟再 “查资料优化”写完初始版本后查指针优化的资料区分 “有效指针” 和 “冗余指针”最后 “精简保留”删冗余但保留核心练手逻辑比如我最终版仍保留所有指针操作只合并了冗余函数。七、补充最优写法高效简洁版前面的所有版本核心目的是练指针所以刻意保留了指针操作哪怕有更简洁的写法。但如果单纯追求 “最优解”逻辑最简洁、代码最短、效率最高、可读性最好可以去掉所有冗余不用刻意用指针指针是工具无需为了用而用以下是这道题的最优写法7.1最优写法代码#define _CRT_SECURE_NO_WARNINGS #include stdio.h int main() { // 嫌疑人映射0A,1B,2C,3D char suspects[] {A,B,C,D}; // 遍历每个嫌疑人假设i是凶手 for(int i0;i4;i) { // 直接计算4人供词真假统计真话数核心逻辑一步到位 int true_count (i!0) (i2) (i3) (i!3); if(true_count 3) // 满足3真1假直接打印凶手 { printf(凶手是%c\n, suspects[i]); break; } } return 0; }7.2最优写法解析1.为什么最优效率最高无多余函数调用、无冗余指针 / 数组循环仅执行 4 次每次循环仅 1 行计算时间复杂度 O (1)固定 4 个嫌疑人无额外开销代码最简仅 15 行代码核心逻辑浓缩为 1 行真话数统计可读性最好去掉所有无关语法只保留 “遍历嫌疑人→计算真话数→判断输出” 的核心逻辑新手也能快速理解。2.与练手版的区别练手版核心是 “借解题练指针”刻意用指针操作哪怕冗余重点在知识点练习最优版核心是 “高效解题”按需选择语法不用多余工具重点在逻辑简洁。3.关键逻辑利用 C 语言 “逻辑表达式结果为 1真或 0假” 的特性直接把 4 个供词的逻辑表达式相加得到真话数无需额外数组 / 指针存储供词真假直接计算、直接判断一步到位。八、最终总结这次解题的核心目标不是 “写最简洁的代码”而是 “借解题练指针”—— 从刻意写冗余指针代码到查资料优化冗余、保留核心我不仅找出了凶手C更吃透了数组指针、字符指针、指针传参这些新手必学的知识点。对新手来说练指针不用追求 “一步到位写最优解”先 “能用指针实现功能”再 “查资料优化指针用法”最后 “精简并保留核心练手逻辑”这个过程比直接抄最优解更有收获。而最优写法则告诉我们C 语言中指针、数组都是工具解题的核心是 “逻辑清晰”按需选择工具不堆砌语法才是最优雅、最高效的编程方式。

相关新闻

手把手教你一步步使用基于HAL库的STM32的蓝牙手机控制以及蓝牙调试器APP的使用

手把手教你一步步使用基于HAL库的STM32的蓝牙手机控制以及蓝牙调试器APP的使用

(一)STM32CubeMX配置 首先需要配置Uart,我们选择UART1配置为异步模式Asynchronous,因为JDY31默认的波特率为9600,所以波特率配置为9600。点击NVIC设置,使能UART1的中断。记录串口1的引脚TX对应PA9&am…

2026/7/14 7:34:18阅读更多 →
C 语言实战:字符串左旋与旋转判断的高效解法

C 语言实战:字符串左旋与旋转判断的高效解法

踩坑实录:从 “越写越乱” 到 “一行核心逻辑”,我搞定了字符串旋转问题 今天刷题时,我接连遇到两道字符串旋转相关的题:一个是实现字符串左旋,另一个是判断一个字符串是否是另一个的旋转结果。本来以为是小问题&…

2026/7/14 7:34:18阅读更多 →
AD7490与PIC18F47Q10构建高性价比数据采集系统

AD7490与PIC18F47Q10构建高性价比数据采集系统

1. 项目背景与核心需求在工业自动化、医疗设备和消费电子等领域,模拟信号到数字信号的转换(ADC)是一个基础但至关重要的环节。AD7490作为一款16位、1MSPS的高性能ADC芯片,配合PIC18F47Q10这款中端8位MCU,能够构建一个高…

2026/7/14 7:34:18阅读更多 →
Godot动画状态机:Idle与Walk状态切换的完整实现指南

Godot动画状态机:Idle与Walk状态切换的完整实现指南

这次我们来看Godot引擎中的动画状态机实现,特别是Idle(空闲)和Walk(行走)状态之间的自由切换。对于游戏开发者来说,角色动画的流畅切换是提升游戏体验的关键环节,而Godot的状态机系统提供了直观…

2026/7/14 9:14:29阅读更多 →
遗传算法工程落地:从参数玄学到可调谐优化的实战指南

遗传算法工程落地:从参数玄学到可调谐优化的实战指南

1. 项目概述:为什么“遗传算法第二讲”比第一讲更值得你花时间重读“遗传算法”这四个字,听上去像生物课和计算机课的混血儿——既带着DNA双螺旋的神秘感,又透着代码里for循环的机械味。但真正让我在带三届算法实训班、陪二十多个工业优化项目…

2026/7/14 9:14:29阅读更多 →
Janus-Pro多模态AI模型:架构优化与生成稳定性突破

Janus-Pro多模态AI模型:架构优化与生成稳定性突破

1. Janus-Pro项目概述Janus-Pro是Janus项目的升级版本,专注于统一的多模态理解和生成任务。这个项目在三个关键维度进行了重大改进:训练策略优化、训练数据扩展和模型规模扩大。作为从业者,我认为这种全方位的升级路径在当前多模态AI领域具有…

2026/7/14 9:14:29阅读更多 →
揭秘AI图像鉴伪黑科技:一键识别PS、生成式与OCR攻击

揭秘AI图像鉴伪黑科技:一键识别PS、生成式与OCR攻击

1. AI图像鉴伪技术为何成为刚需? 十年前修图还需要专业软件,现在手机App一键就能把照片改得面目全非。更可怕的是,生成式AI能让完全不存在的脸孔、场景以假乱真。去年某银行就遇到过客户用AI生成的房产证骗贷,损失高达数百万。这种…

2026/7/14 9:14:29阅读更多 →
TB67H480FNG与PIC18F45K22电机控制方案详解

TB67H480FNG与PIC18F45K22电机控制方案详解

1. 为什么选择TB67H480FNG与PIC18F45K22组合 在电机控制领域,TB67H480FNG驱动芯片与PIC18F45K22微控制器的组合堪称经典搭配。这套方案特别适合需要高性价比、中等复杂度的运动控制场景。TB67H480FNG是东芝推出的双通道H桥驱动器,最大输出电流可达4.5A&a…

2026/7/14 9:14:29阅读更多 →
二、PyTorch气温预测:从数据探索到模型部署全流程解析

二、PyTorch气温预测:从数据探索到模型部署全流程解析

1. 气温预测项目概述 气温预测是机器学习中一个典型的回归问题,通过历史气象数据来预测未来某天的最高温度。这个项目非常适合初学者练手,因为它涵盖了数据科学项目的完整流程:从数据探索、预处理到模型构建、训练和评估。使用PyTorch框架可以…

2026/7/14 9:09:27阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/14 4:56:14阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/14 2:55:05阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/14 6:17:41阅读更多 →
【Cursor数据库安全红线】:自动执行SQL前必须校验的6项权限策略,金融级项目已强制落地

【Cursor数据库安全红线】:自动执行SQL前必须校验的6项权限策略,金融级项目已强制落地

更多请点击: https://intelliparadigm.com 第一章:Cursor数据库安全红线概览 Cursor 作为一款基于 AI 的智能编程助手,其本地数据库(SQLite 存储)承载着用户代码片段、会话历史、自定义规则及敏感上下文信息。理解其安…

2026/7/14 0:03:18阅读更多 →
【Notion AI写作避坑白皮书】:基于127份真实用户失败案例,总结6大致命误用陷阱

【Notion AI写作避坑白皮书】:基于127份真实用户失败案例,总结6大致命误用陷阱

更多请点击: https://codechina.net 第一章:Notion AI写作辅助的底层能力边界认知 Notion AI 并非通用大语言模型的直接封装,而是基于 Llama 系列与自研微调模型构建的轻量化推理服务,其输入上下文窗口严格限制在 8192 token&…

2026/7/14 0:03:18阅读更多 →
AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

更多请点击: https://kaifayun.com 第一章:AI Agent数据越界行为的合规性挑战与溯源必要性 AI Agent在自主执行任务过程中,可能因提示注入、上下文污染或权限配置缺陷,无意或有意访问、缓存、传输受保护数据(如PII、G…

2026/7/14 0:03:18阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/13 4:21:17阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/14 4:45:36阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/14 2:42:17阅读更多 →