抽象代码:下划线完形填空
先上代码。下面是一个完整的、可以编译、可以运行的 C 语言程序,它是一个从 9 倒数到 0 的倒计时器。请欣赏: _.c123456789101112131415161718192021222324252627#include <stdio.h>#define _ int#define __ main#define ___ while#define _____ x#define ______ ;#define _______ ()#define ________ {#define _________ }#define __________ (#define ___________ )#define ____________ =#define _____________ -->#define ______________ "%d\n",#define _______________ printf#define ________________ return_ __ ________________ _____ _______...
从黑窗口到窗口:我的 Win32 学习轨迹
学 C 语言的前半年,我的程序全都活在一个黑窗口里——printf 进,scanf 出。2023 年 2 月,我决定去摸一摸 Windows 真正的样子:窗口、消息、控件、对话框。到 7 月,我已经能在内存里徒手拼出一个对话框、写出一个带菜单和列表视图的课程设计。这篇文章按时间顺序复盘这条轨迹的四个站点:鼠标热身 → 第一个窗口 → 内存里手搓对话框 → 学生考勤管理系统。 热身:做一个鼠标监听器进 Win32 的世界之前,先在控制台里热身。目标很简单:实时显示鼠标坐标、统计左右键点击次数。核心是两个 API——GetAsyncKeyState 查按键状态、GetCursorPos 拿坐标: 鼠标检测.cpp12345678910111213141516171819202122232425262728293031323334#include <windows.h> //GetAsyncKeyState所需头文件#include <iostream>#define KEY_DOWN(VK_NONAME) ((GetAsyn...
通用链表 glist 开发记:从 void* 到函数指针
教科书里的线性表长一个样:int a[MAX],或者 struct Node { int data; struct Node* next; }——从头到尾只能装一种类型。2023 年 4 月,我决定写一个”什么都能装”的列表:同一个列表里同时放 int、char、float、double,甚至自定义结构体,不光存得进去,还得一个一个打印出来。 这个项目最后叫 glist(general list),从 V1.0 迭代到 V1.2,源码整理在 GitHub 仓库 glist 里,三个版本各占一个标签。三个版本不多,恰好是 C 语言里实现”泛型”的三条思路的进化史:只存地址 → 给类型发身份证 → 让数据自己带说明书。 V1.0:先把”存”解决——void* 数组一切的起点是一个朴素的问题:一个格子不知道自己装的是什么类型,怎么装? 答案就是 void*。普通指针绑定着类型,所以它知道数据从哪开始、到哪结束;void* 只有起始地址,什么类型都不绑,所以任何指针都能不加转换地赋给它。那 list 就别存数据,存地址: list.h123456789101112131415161718...
C 语言自己也想要函数重载
📌 更新(2026-09-01):归档这篇旧笔记,代码用 GCC 15.1.0 复测,输出与当年一致——顺带收获了几枚新编译器对老代码的唠叨,见文内。 C++ 有函数重载,add(int,int) 和 add(float,float) 可以同名共存,编译器按实参类型自动分发。C 没有这个待遇——但 C11 给了一个官方替代品:_Generic 选择宏。根据表达式的类型,在编译期挑一个分支: 123456#define ADD(x,y) _Generic((x),\ /*S:add_stu(x,y),*/\ int:add_int(x,y),\ float:add_float(x,y),\ double:add_float((float)x,(float)y),\ default:unsupport()) _Generic 的第一个参数是”钥匙”,后面是一串 类型: 结果 的锁眼。编译时看钥匙的类型(不是值)挑锁眼,选中的表达式才会被展开,没选中的连求值都不会发生——所以它是零运行时分发的免费午餐。实测三连: 123printf("%...
Matrix 开发记:用 C 写一个矩阵运算库
2023 年 2 月 28 日,我开了自己的第一个”系统级”项目:mathematics-system,目标是用 C 写一套数学工具。打头阵的就是这个矩阵库 Matrix——创建、加减、数乘、转置、行列式、求逆、求秩,一天之内从 V1.0 迭代到 V1.0.1。后来这个屋檐下又住进了字符串大整数 BigInterge,整个项目都在 GitHub 的 Mathematics-System 仓库里。 📌 更新(2026-08-31):为写这篇重新编译复现了全套测试,并当场抓到了行列式一节的堆崩溃——详见复盘一节。 头文件是当年最流行的 Doxygen 风格大注释,认真到标了”取代版本”: 123456789101112/* * 文件名称:Matrix.h * 摘 要:本文件主要是矩阵相关函数的声明 * * 当前版本:1.0.1 * 作 者:寰宇体(Cosmical Container) * 完成日期:2023年3月1日 * * 取代版本:1.0.0 * 原作者 :寰宇体(Cosmical Container) * 完成日期:2023年2月28日 */ 数据结构:...
C-复刻printf函数1
其实很久之前就想问C语言里面的printf()是怎么实现的,主要是对printf()的参数比较感兴趣,你想我们随便定义一个函数,都得确定参数的个数,但是像printf()函数,可以根据第一个参数也就是字符串”%c %d %f %s”根据有多少个格式输入来确认参数的个数。于是我去了解到了一种叫变参函数的东西,在stdarg.h里面定义有,在加上简单的字符串合成,最后用putchar()函数来输出,简单实现了My_printf();代码如下: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>char * in...
C-返回值为函数指针的函数
返回值为函数指针的函数本质上是一个函数,返回值为函数指针 123456789101112131415#include<stdio.h>int (*drink(void)) (void){ static int i; i++; printf("(%d)\n", i); return (int(*)(void))drink;}int main(){ drink()(); return 0;} 运行结果如下: 那能否实现一直调用下去呢?求大佬写一个能运行 drink()()()()()()()()()()() 的代码
我的分数开发记:手写一个分数运算库
📌 更新(2026-09-01):整理归档这篇旧文,顺手用 GCC 15.1.0 把整个库重新编译复测了一遍。不测不知道:pow 函数里藏着一个参数传反的 bug,而被注释掉的多参数运算一旦复活,在 -O2 优化下会当场段错误——2022 年它们全都”看起来没问题”。详见复盘两节。 2022 年 11 月的一个晚上,我又一次看到了那个经典画面:0.1 + 0.2 = 0.30000000000000004。浮点数这东西,平时看着人模狗样,一涉及精度就开始表演。刚学完结构体的我突发奇想:既然分数是精确的,为什么不自己写一个分数运算库? 于是有了这个文件夹——我的分数,主文件也叫 我的分数.c。对,起名的时候一点都没客气,这是我的分数,从头到脚都是我的。这个库后来搬进了 Mathematics-System 仓库的 Fraction/ 目录,和 Matrix、BigInterge 住在一起——数学三件套,聚齐了。 一、分数怎么表示分数的核心数据结构简单到不能再简单:一个分子,一个分母。 1234567typedef long long ll;typedef struc...
四舍五入:浮点数当着我的面撒谎
📌 更新(2026-09-01):归档这篇 2022 年的旧作业,顺手用 GCC 15.1.0 复测——结果一组测试数据当场翻车,挖出了下文的浮点罗生门现场。 我手里最老的存货之一:头上顶着”英文教材 P12 作业 1.3”的注释,从判题平台的 Begin/End 填空标记看,这是一道在线作业题——不用 printf 的格式化功能,自己把一个 double 逐位打印出来,还要处理四舍五入。 主框架是教材 P10 的递归打印函数 PrintOut——高位递归完了才打印当前位,个位数作递归出口,这是”递归打印整数”的经典范本。要填的空有三处:RoundUp 里凑出四舍五入的加数,DecPart 里取小数部分,PrintFractionPart 里为下一位循环做准备。填法本身不难,核心的 RoundUp 长这样: 123456789double RoundUp( double N, int DecPlaces ) // 画龙点睛部分:四舍五入处理{ int i; double AmountToAdd = 0.5; for(i = 0;i < De...
Wechat_public_platform
之前搞的微信公众号欢迎关注
