实验5-3 使用函数求Fibonacci数看到 []脑子里要浮现出“数组、格子、存数据”它是可以放在等号左边被赋值的。看到 ()脑子里要浮现出“动作、函数、加工厂”它只能放在等号右边当成计算结果来用绝对不能放在等号左边被赋值实验5-4 输出每个月的天数int m[12]{31,28,31,30,31,30,31,31,30,31,30,31};初始化数组的格式记得写顿号实验5-5 使用函数求最大公约数两个数的最大公约数等于其中较小数和两数相除余数的最大公约数。步骤如下用较大数 a 除以较小数 b得到余数 rr a % b如果余数 r 0则 b 就是最大公约数如果余数 r ≠ 0则把 b 赋值给 a把 r 赋值给 b重复步骤 1直到余数为 0。实验5-8 使用函数求圆台体积圆台体积 大圆锥 − 小圆锥V πh(R ^2Rrr ^2)/3实验6-7 使用函数输出一个整数的逆序数负数取余 % 还是负数要真正返回一个反转后的数字我们不能只打印必须把它重新组装起来。新数字 老数字 * 10 拆下来的个位数实验6-8 使用函数输出指定范围内的完数使用函数要注意职责分离实验6-11 使用函数输出水仙花数在拆解数字之前必须先拿一个变量把原数备份下来最后用备份去比较。实验8-1-2 利用指针找最大值1. 核心本质什么是指针在 C 语言中普通变量如int、double是用来存放**“具体数据”的房间。 而指针Pointer是一个极其特殊的变量它不存具体数据它只存“物理内存地址门牌号/GPS坐标”**。 黄金比喻房间与万能房卡变量a一个真实的房间里面装着数字100。指针p一张写着变量a房间号的“万能房卡”。拿着这张卡你就能随时随地找到并进出这个房间。2. 必备的两把钥匙和*要玩转指针必须把这两个符号刻进肌肉记忆取地址符获取门牌号作用放在普通变量前面用于查出这个变量在内存中的真实物理地址。大白话“告诉我这个房间的 GPS 坐标是多少”*解引用符魔法传送门作用放在指针变量前面代表顺着地址找过去直接操作那个房间里的真实数据。大白话“按下房卡上的传送按钮让我进去改写里面的东西”经典代码演示int a 100; // 1. 开一间叫 a 的房间里面放 100 int *p; // 2. 向上帝申请一张只能写整型地址的房卡 p p a; // 3. 把 a 的门牌号比如 0x1122抄写在房卡 p 上 *p 0; // 4. 【魔法生效】顺着 p 上的门牌号传送过去把里面的 100 强行改成了 0 // 此时如果 printf(%d, a); 打印出来的结果将是 03. 为什么必须用指针三大超能力⚡️ 超能力一隔空打牛跨函数修改真实变量痛点C 语言的函数传参是“复印件模式”。如果你把x传给函数函数里怎么修改都不会影响外面的真实的x。指针解法引用传递不要传复印件直接把房间钥匙地址传给函数函数拿着钥匙开门进去改外面的真实数据就会瞬间同步改变。这就是经典的swap交换两个变量位置的原理。⚡️ 超能力二极致的性能拒绝搬砖痛点如果你有一个包含几百人信息的struct结构体把它传给另一个函数时系统会极其吃力地把成千上万个字节全部复制一遍内存瞬间爆炸。指针解法不管别墅有多大你只需要把这栋别墅的“钥匙只占 4 或 8 个字节的地址”**递过去。函数拿着钥匙自己上门去看效率提升成千上万倍⚡️ 超能力三打破定局动态内存分配痛点普通数组必须提前写死大小如char name[100];不够用或者用不完都会很僵硬。指针解法配合malloc函数可以在程序运行到一半时向系统申请任意大小的内存系统会把这块新大陆的**起始坐标地址**交到你的指针手里。这是后续学习“链表、树、图”等高级数据结构的绝对基石。4. 指针与scanf的前世今生防坑指南现在你就能彻底懂scanf的逻辑了因为scanf本质上就是一个需要你提供“物理地址”的快递员遇到普通变量int,double,char普通变量是路痴必须加上主动把门牌号交给scanf例如scanf(%d, age);。遇到数组名字符数组char str[100];绝不能加因为在 C 语言中数组的名字str天生自带 GPS 属性它本身就是一个指针代表公寓的0号房地址。直接写scanf(%s, str);即可。5. 新手致命死穴野指针Wild Pointer铁律绝对不要操作一个还没有明确指向没有写上合法房间号的指针int *p; // 制造了一张房卡但还没给它赋值任何门牌号里面是随机的乱码 *p 10; // ❌ 致命错误试图传送到一个随机的未知宇宙可能是系统核心禁区程序直接崩溃段错误防御方法定义指针时如果暂时不知道指向哪一定要立刻给它赋值为NULL空指针表示“这张卡现在是作废的哪也去不了”。实验8-1-7 数组循环右移要想在不借用另外一个巨大数组的情况下完成完美移位企业面试和算法竞赛中最经典的神级操作叫做**“三次翻转法三步反转”**。就像切扑克牌一样把它分成两截各自翻面再整体翻面实战演示数组[1, 2, 3, 4, 5]右移2位。第一步将整个数组全部翻转。变成[5, 4, 3, 2, 1]第二步翻转前 m 个元素。前 2 个元素5, 4翻转 变成[4, 5, 3, 2, 1]第三步翻转剩下的 n-m 个元素。后 3 个元素3, 2, 1翻转 变成[4, 5, 1, 2, 3]——完美达成目标void Reverse(int a[], int left, int right) { while (left right) { // 首尾交换的经典指针/下标操作 int temp a[left]; a[left] a[right]; a[right] temp; left; right--; } }实验8-1-8 报数 C语言经典算法笔记约瑟夫环报数问题1. 核心痛点与破局思路痛点 1直线变圆圈。人在现实中围成的是圆圈但 C 语言的数组是一条直线数到尽头会越界。痛点 2出局者的“幽灵占位”。数组里的元素不能直接“凭空消失”后面的人报数时必须跳过已经出局的人。 破局核心让out数组“身兼两职”不要去借新的数组直接利用题目要求保存退出顺序的out[]数组当裁判存活状态活人格子里存0。遇到活人嘴巴才出声报数。出局状态幽灵格子里存非0的数字即出局的名次。遇到幽灵嘴巴闭上直接跳过但他依然占据一个物理空间。2. 模拟现场的三大“记录员”核心变量要完美还原游戏现场必须定义三个各司其职的计数器count发牌官 / 死亡总数记录当前已经死了几个人。当count n时游戏结束。同时它也就是当前倒霉蛋的“退出编号名次”。call_num大喇叭 / 报数器模拟嘴巴里喊出的声音从1喊到m。只要喊到m就清零重新开始。index扫描手指 / 数组下标从0一直走到n-1。不管是指着活人还是幽灵手指永远在往前走。3. 核心代码骨架肌肉记忆区void CountOff( int n, int m, int out[] ) { // 1. 初始化全员存活标记为 0 for (int i 0; i n; i) out[i] 0; int count 0; // 已出局人数兼名次 int call_num 0; // 当前报的数 int index 0; // 当前数组下标 // 2. 只要存活人数还没死光就一直循环 while (count n) { // 【核心判定】只有指到活人0才开口报数 if (out[index] 0) { call_num; // 如果刚好报到了致命数字 m if (call_num m) { count; // 死亡人数1也就是生成了最新的名次 out[index] count; // 把名次发给他他瞬间变成了非0的“幽灵” call_num 0; // 喇叭清零下一个人重新从1喊 } } // 手指无脑往下走一格 index; // 【空间魔法】把直线掰弯成圆圈 // 如果手指走出了数组边界瞬间拉回起点 if (index n) { index 0; } } }4. 避坑指南 易错点总结千万别忘了call_num 0;每次有人出局后下一个活着的人必须重新从1开始报数。如果喇叭不清零逻辑直接全盘崩溃。index的位置手指的移动index必须放在if (out[index] 0)的外面因为不管是活人还是幽灵手指都必须跨过去不能停滞不前。圆圈魔法index n这里是 n而不是 n-1。因为当index为n-1时它是合法的最后一个元素当它加完一变成n时才真正越界需要重置为0也可以用取余技巧index index % n;替代。实验8-2-3 删除字符双指针思想一前一后void delchar(char *str, char c) { int fast 0; // 探路员 int slow 0; // 记录员 // 只要探路员还没碰到字符串结尾的 \0 while (str[fast] ! \0) { // 如果这个字符不是要删除的垃圾需要保留 if (str[fast] ! c) { str[slow] str[fast]; // 记录员把它抄下来 slow; // 记录员走向下一个空白格子 } fast; // 探路员无脑往前走不管是不是垃圾 } // 极其致命的最后一步补上终结符 // 删完之后字符串变短了必须在记录员停下的位置强行打上 \0 str[slow] \0; }实验8-2-4 使用函数实现字符串部分复制若m超过输入字符串的长度则结果字符串应为空串。if(mlen){ s[0]\0; }分清楚什么时候用strcpy将一整串字符串复制到另一个字符串里面如果仅仅是修改一串字符串里面的一个字符那么直接用等号赋值即可。// 2. 终极大招指针偏移空降兵 // t[m-1] 代表获取第 m 个字符的物理地址。 // strcpy 会直接从这个地址开始把后面所有的字符连同 \0 一次性全部搬进 s 里 strcpy(s, t[m-1]);实验8-2-7 字符串的连接char *str_cat( char *s, char *t ){ int lenstrlen(s); strcpy(s[len],t[0]); //必须在前面加上取地址符 变成 s[len]。 //意思是“请从 s 数组下标为 len 的那个房间的门口开始卸货” return s; }实验9-4 计算两个复数之积在 C 语言里只要函数规定了返回值是struct xxx不管你中间的计算过程用了多少个结构体在return之前你必须、一定、绝对要自己亲手定义一个struct xxx的变量造个空盒子把数据塞进去然后把它return出去struct complex multiply(struct complex x, struct complex y){ struct complex result;//造一个空盒子 result.real(x.real*y.real)-(x.imag*y.imag); result.imagx.real*y.imagx.imag*y.real; return result; }实验10-4 递归实现顺序输出整数void printdigits(int n) { if (n 10) { printf(%d\n, n); // 出口只剩一位数了直接打印 } else { printdigits(n / 10); // 动作A先派分身去处理前面的数字 printf(%d\n, n % 10); // 动作B分身回来了我再打印我自己的尾巴 } } 慢动作逐帧拆解当传入123时发生了什么⬇️ 第一阶段入梦疯狂召唤分身按下暂停键1. 第一层梦境你是大老板拿到了123电脑问123 10吗不是进入else。遇到动作Aprintdigits(123 / 10)也就是要召唤一个分身去处理12。⚠️【极其致命的底层机制】电脑是一个单线程的死脑筋。此时它绝对不会往下执行动作B去打印3它会在这里按下一个死死的暂停键把打印3的任务暂存在大脑深处然后纵身一跃跟着分身进入第二层梦境。2. 第二层梦境一号分身拿到了12电脑问12 10吗不是进入else。遇到动作Aprintdigits(12 / 10)召唤二号分身去处理1。⚠️ 再次按下暂停键把打印尾巴2的任务暂存起来纵身一跃进入第三层梦境。3. 第三层梦境二号分身拿↩️ 第二阶段触底反弹找到出口到了1电脑问1 10吗是的终于不再召唤分身了触发了出口条件直接执行printf(%d\n, 1)。【屏幕第一次亮起打印出第一个数字】1第三层梦境的任务圆满完成梦境坍塌电脑的控制权退回到上一层。⬆️ 第三阶段苏醒解除暂停清算旧账4. 回到第二层梦境此时 n 还是12刚刚这层梦境卡在了哪里卡在了召唤分身的动作A。现在二号分身回来了暂停键解除电脑终于可以往下走执行这层梦境遗留的动作Bprintf(%d\n, 12 % 10)。【屏幕第二次亮起打印出第二个数字】2第二层梦境任务彻底清空坍塌消失退回到最外层。5. 回到第一层梦境此时 n 还是123大老板也终于等回了一号分身解除暂停执行大老板遗留的动作Bprintf(%d\n, 123 % 10)。【屏幕第三次亮起打印出第三个数字】3第一层梦境彻底结束。函数圆满下班实验10-10 十进制转换二进制十进制转二进制采用除二取余法十进制转二进制的本质是除 2 取余倒序排列基础版用数组存储余数后倒序输出递归版利用递归天然实现倒序。实验11-1-2 输出月份英文名函数生命周期与指针if (n 1) { char str[] January; return str; // ❌ 致命错误 }str是一个在这个函数内部临时开辟的“小房间局部变量”。当函数执行完return准备下班时系统会瞬间把这个房间拆除回收内存 虽然你把房间的门牌号地址交给了外面的主函数但当主函数顺着门牌号找过去时那里已经是一片废墟乱码了。这叫做“悬空指针”。要让函数下班后数据依然存活最好的办法就是使用双引号括起来的“字符串常量”。 在 C 语言中双引号里的字符串是“永生”的它们被强制保存在系统的“只读数据区”直到整个程序彻底结束才会销毁。所以我们只需要建一个“指针数组查表”把这 12 个“永生”字符串的地址存起来用户要几月我们就直接把对应的地址飞镖一样扔给他// 2. 核心武器建立“永生”的字符串地址查找表 // 这是一个指针数组里面装了 13 个地址。 char *months[] { Padding, // 下标 0纯粹用来占位永远用不到 January, // 下标 1 February, // 下标 2 March, // 下标 3 April, // 下标 4 May, // 下标 5 June, // 下标 6 July, // 下标 7 August, // 下标 8 September, // 下标 9 October, // 下标 10 November, // 下标 11 December // 下标 12 };实验11-1-3 查找星期遇到“给数字求字符串”比如上题的月份直接用return 数组名[n]。遇到“给字符串求数字”比如这题的星期直接写个for循环搭配strcmp去数组里搜搜到了就return i。
计算机复试C语言上机笔记(浙大第四版函数部分)
实验5-3 使用函数求Fibonacci数看到 []脑子里要浮现出“数组、格子、存数据”它是可以放在等号左边被赋值的。看到 ()脑子里要浮现出“动作、函数、加工厂”它只能放在等号右边当成计算结果来用绝对不能放在等号左边被赋值实验5-4 输出每个月的天数int m[12]{31,28,31,30,31,30,31,31,30,31,30,31};初始化数组的格式记得写顿号实验5-5 使用函数求最大公约数两个数的最大公约数等于其中较小数和两数相除余数的最大公约数。步骤如下用较大数 a 除以较小数 b得到余数 rr a % b如果余数 r 0则 b 就是最大公约数如果余数 r ≠ 0则把 b 赋值给 a把 r 赋值给 b重复步骤 1直到余数为 0。实验5-8 使用函数求圆台体积圆台体积 大圆锥 − 小圆锥V πh(R ^2Rrr ^2)/3实验6-7 使用函数输出一个整数的逆序数负数取余 % 还是负数要真正返回一个反转后的数字我们不能只打印必须把它重新组装起来。新数字 老数字 * 10 拆下来的个位数实验6-8 使用函数输出指定范围内的完数使用函数要注意职责分离实验6-11 使用函数输出水仙花数在拆解数字之前必须先拿一个变量把原数备份下来最后用备份去比较。实验8-1-2 利用指针找最大值1. 核心本质什么是指针在 C 语言中普通变量如int、double是用来存放**“具体数据”的房间。 而指针Pointer是一个极其特殊的变量它不存具体数据它只存“物理内存地址门牌号/GPS坐标”**。 黄金比喻房间与万能房卡变量a一个真实的房间里面装着数字100。指针p一张写着变量a房间号的“万能房卡”。拿着这张卡你就能随时随地找到并进出这个房间。2. 必备的两把钥匙和*要玩转指针必须把这两个符号刻进肌肉记忆取地址符获取门牌号作用放在普通变量前面用于查出这个变量在内存中的真实物理地址。大白话“告诉我这个房间的 GPS 坐标是多少”*解引用符魔法传送门作用放在指针变量前面代表顺着地址找过去直接操作那个房间里的真实数据。大白话“按下房卡上的传送按钮让我进去改写里面的东西”经典代码演示int a 100; // 1. 开一间叫 a 的房间里面放 100 int *p; // 2. 向上帝申请一张只能写整型地址的房卡 p p a; // 3. 把 a 的门牌号比如 0x1122抄写在房卡 p 上 *p 0; // 4. 【魔法生效】顺着 p 上的门牌号传送过去把里面的 100 强行改成了 0 // 此时如果 printf(%d, a); 打印出来的结果将是 03. 为什么必须用指针三大超能力⚡️ 超能力一隔空打牛跨函数修改真实变量痛点C 语言的函数传参是“复印件模式”。如果你把x传给函数函数里怎么修改都不会影响外面的真实的x。指针解法引用传递不要传复印件直接把房间钥匙地址传给函数函数拿着钥匙开门进去改外面的真实数据就会瞬间同步改变。这就是经典的swap交换两个变量位置的原理。⚡️ 超能力二极致的性能拒绝搬砖痛点如果你有一个包含几百人信息的struct结构体把它传给另一个函数时系统会极其吃力地把成千上万个字节全部复制一遍内存瞬间爆炸。指针解法不管别墅有多大你只需要把这栋别墅的“钥匙只占 4 或 8 个字节的地址”**递过去。函数拿着钥匙自己上门去看效率提升成千上万倍⚡️ 超能力三打破定局动态内存分配痛点普通数组必须提前写死大小如char name[100];不够用或者用不完都会很僵硬。指针解法配合malloc函数可以在程序运行到一半时向系统申请任意大小的内存系统会把这块新大陆的**起始坐标地址**交到你的指针手里。这是后续学习“链表、树、图”等高级数据结构的绝对基石。4. 指针与scanf的前世今生防坑指南现在你就能彻底懂scanf的逻辑了因为scanf本质上就是一个需要你提供“物理地址”的快递员遇到普通变量int,double,char普通变量是路痴必须加上主动把门牌号交给scanf例如scanf(%d, age);。遇到数组名字符数组char str[100];绝不能加因为在 C 语言中数组的名字str天生自带 GPS 属性它本身就是一个指针代表公寓的0号房地址。直接写scanf(%s, str);即可。5. 新手致命死穴野指针Wild Pointer铁律绝对不要操作一个还没有明确指向没有写上合法房间号的指针int *p; // 制造了一张房卡但还没给它赋值任何门牌号里面是随机的乱码 *p 10; // ❌ 致命错误试图传送到一个随机的未知宇宙可能是系统核心禁区程序直接崩溃段错误防御方法定义指针时如果暂时不知道指向哪一定要立刻给它赋值为NULL空指针表示“这张卡现在是作废的哪也去不了”。实验8-1-7 数组循环右移要想在不借用另外一个巨大数组的情况下完成完美移位企业面试和算法竞赛中最经典的神级操作叫做**“三次翻转法三步反转”**。就像切扑克牌一样把它分成两截各自翻面再整体翻面实战演示数组[1, 2, 3, 4, 5]右移2位。第一步将整个数组全部翻转。变成[5, 4, 3, 2, 1]第二步翻转前 m 个元素。前 2 个元素5, 4翻转 变成[4, 5, 3, 2, 1]第三步翻转剩下的 n-m 个元素。后 3 个元素3, 2, 1翻转 变成[4, 5, 1, 2, 3]——完美达成目标void Reverse(int a[], int left, int right) { while (left right) { // 首尾交换的经典指针/下标操作 int temp a[left]; a[left] a[right]; a[right] temp; left; right--; } }实验8-1-8 报数 C语言经典算法笔记约瑟夫环报数问题1. 核心痛点与破局思路痛点 1直线变圆圈。人在现实中围成的是圆圈但 C 语言的数组是一条直线数到尽头会越界。痛点 2出局者的“幽灵占位”。数组里的元素不能直接“凭空消失”后面的人报数时必须跳过已经出局的人。 破局核心让out数组“身兼两职”不要去借新的数组直接利用题目要求保存退出顺序的out[]数组当裁判存活状态活人格子里存0。遇到活人嘴巴才出声报数。出局状态幽灵格子里存非0的数字即出局的名次。遇到幽灵嘴巴闭上直接跳过但他依然占据一个物理空间。2. 模拟现场的三大“记录员”核心变量要完美还原游戏现场必须定义三个各司其职的计数器count发牌官 / 死亡总数记录当前已经死了几个人。当count n时游戏结束。同时它也就是当前倒霉蛋的“退出编号名次”。call_num大喇叭 / 报数器模拟嘴巴里喊出的声音从1喊到m。只要喊到m就清零重新开始。index扫描手指 / 数组下标从0一直走到n-1。不管是指着活人还是幽灵手指永远在往前走。3. 核心代码骨架肌肉记忆区void CountOff( int n, int m, int out[] ) { // 1. 初始化全员存活标记为 0 for (int i 0; i n; i) out[i] 0; int count 0; // 已出局人数兼名次 int call_num 0; // 当前报的数 int index 0; // 当前数组下标 // 2. 只要存活人数还没死光就一直循环 while (count n) { // 【核心判定】只有指到活人0才开口报数 if (out[index] 0) { call_num; // 如果刚好报到了致命数字 m if (call_num m) { count; // 死亡人数1也就是生成了最新的名次 out[index] count; // 把名次发给他他瞬间变成了非0的“幽灵” call_num 0; // 喇叭清零下一个人重新从1喊 } } // 手指无脑往下走一格 index; // 【空间魔法】把直线掰弯成圆圈 // 如果手指走出了数组边界瞬间拉回起点 if (index n) { index 0; } } }4. 避坑指南 易错点总结千万别忘了call_num 0;每次有人出局后下一个活着的人必须重新从1开始报数。如果喇叭不清零逻辑直接全盘崩溃。index的位置手指的移动index必须放在if (out[index] 0)的外面因为不管是活人还是幽灵手指都必须跨过去不能停滞不前。圆圈魔法index n这里是 n而不是 n-1。因为当index为n-1时它是合法的最后一个元素当它加完一变成n时才真正越界需要重置为0也可以用取余技巧index index % n;替代。实验8-2-3 删除字符双指针思想一前一后void delchar(char *str, char c) { int fast 0; // 探路员 int slow 0; // 记录员 // 只要探路员还没碰到字符串结尾的 \0 while (str[fast] ! \0) { // 如果这个字符不是要删除的垃圾需要保留 if (str[fast] ! c) { str[slow] str[fast]; // 记录员把它抄下来 slow; // 记录员走向下一个空白格子 } fast; // 探路员无脑往前走不管是不是垃圾 } // 极其致命的最后一步补上终结符 // 删完之后字符串变短了必须在记录员停下的位置强行打上 \0 str[slow] \0; }实验8-2-4 使用函数实现字符串部分复制若m超过输入字符串的长度则结果字符串应为空串。if(mlen){ s[0]\0; }分清楚什么时候用strcpy将一整串字符串复制到另一个字符串里面如果仅仅是修改一串字符串里面的一个字符那么直接用等号赋值即可。// 2. 终极大招指针偏移空降兵 // t[m-1] 代表获取第 m 个字符的物理地址。 // strcpy 会直接从这个地址开始把后面所有的字符连同 \0 一次性全部搬进 s 里 strcpy(s, t[m-1]);实验8-2-7 字符串的连接char *str_cat( char *s, char *t ){ int lenstrlen(s); strcpy(s[len],t[0]); //必须在前面加上取地址符 变成 s[len]。 //意思是“请从 s 数组下标为 len 的那个房间的门口开始卸货” return s; }实验9-4 计算两个复数之积在 C 语言里只要函数规定了返回值是struct xxx不管你中间的计算过程用了多少个结构体在return之前你必须、一定、绝对要自己亲手定义一个struct xxx的变量造个空盒子把数据塞进去然后把它return出去struct complex multiply(struct complex x, struct complex y){ struct complex result;//造一个空盒子 result.real(x.real*y.real)-(x.imag*y.imag); result.imagx.real*y.imagx.imag*y.real; return result; }实验10-4 递归实现顺序输出整数void printdigits(int n) { if (n 10) { printf(%d\n, n); // 出口只剩一位数了直接打印 } else { printdigits(n / 10); // 动作A先派分身去处理前面的数字 printf(%d\n, n % 10); // 动作B分身回来了我再打印我自己的尾巴 } } 慢动作逐帧拆解当传入123时发生了什么⬇️ 第一阶段入梦疯狂召唤分身按下暂停键1. 第一层梦境你是大老板拿到了123电脑问123 10吗不是进入else。遇到动作Aprintdigits(123 / 10)也就是要召唤一个分身去处理12。⚠️【极其致命的底层机制】电脑是一个单线程的死脑筋。此时它绝对不会往下执行动作B去打印3它会在这里按下一个死死的暂停键把打印3的任务暂存在大脑深处然后纵身一跃跟着分身进入第二层梦境。2. 第二层梦境一号分身拿到了12电脑问12 10吗不是进入else。遇到动作Aprintdigits(12 / 10)召唤二号分身去处理1。⚠️ 再次按下暂停键把打印尾巴2的任务暂存起来纵身一跃进入第三层梦境。3. 第三层梦境二号分身拿↩️ 第二阶段触底反弹找到出口到了1电脑问1 10吗是的终于不再召唤分身了触发了出口条件直接执行printf(%d\n, 1)。【屏幕第一次亮起打印出第一个数字】1第三层梦境的任务圆满完成梦境坍塌电脑的控制权退回到上一层。⬆️ 第三阶段苏醒解除暂停清算旧账4. 回到第二层梦境此时 n 还是12刚刚这层梦境卡在了哪里卡在了召唤分身的动作A。现在二号分身回来了暂停键解除电脑终于可以往下走执行这层梦境遗留的动作Bprintf(%d\n, 12 % 10)。【屏幕第二次亮起打印出第二个数字】2第二层梦境任务彻底清空坍塌消失退回到最外层。5. 回到第一层梦境此时 n 还是123大老板也终于等回了一号分身解除暂停执行大老板遗留的动作Bprintf(%d\n, 123 % 10)。【屏幕第三次亮起打印出第三个数字】3第一层梦境彻底结束。函数圆满下班实验10-10 十进制转换二进制十进制转二进制采用除二取余法十进制转二进制的本质是除 2 取余倒序排列基础版用数组存储余数后倒序输出递归版利用递归天然实现倒序。实验11-1-2 输出月份英文名函数生命周期与指针if (n 1) { char str[] January; return str; // ❌ 致命错误 }str是一个在这个函数内部临时开辟的“小房间局部变量”。当函数执行完return准备下班时系统会瞬间把这个房间拆除回收内存 虽然你把房间的门牌号地址交给了外面的主函数但当主函数顺着门牌号找过去时那里已经是一片废墟乱码了。这叫做“悬空指针”。要让函数下班后数据依然存活最好的办法就是使用双引号括起来的“字符串常量”。 在 C 语言中双引号里的字符串是“永生”的它们被强制保存在系统的“只读数据区”直到整个程序彻底结束才会销毁。所以我们只需要建一个“指针数组查表”把这 12 个“永生”字符串的地址存起来用户要几月我们就直接把对应的地址飞镖一样扔给他// 2. 核心武器建立“永生”的字符串地址查找表 // 这是一个指针数组里面装了 13 个地址。 char *months[] { Padding, // 下标 0纯粹用来占位永远用不到 January, // 下标 1 February, // 下标 2 March, // 下标 3 April, // 下标 4 May, // 下标 5 June, // 下标 6 July, // 下标 7 August, // 下标 8 September, // 下标 9 October, // 下标 10 November, // 下标 11 December // 下标 12 };实验11-1-3 查找星期遇到“给数字求字符串”比如上题的月份直接用return 数组名[n]。遇到“给字符串求数字”比如这题的星期直接写个for循环搭配strcmp去数组里搜搜到了就return i。