C语言typedef完全指南:别名、函数指针与const细节一次搞懂
C语言中的typedef很多初学者把它当“给类型起小名”用熟了感觉也就那么回事。真正到了维护老项目、读第三方源码、或者做嵌入式跨平台开发的时候才发现typedef的水远比想象的深函数指针要不要typedef、结构体要不要typedef、typedef和#define到底差在哪、const和typedef凑到一起又是谁修饰谁……这些坑我前几年都踩过今天一次性讲透。这篇内容适合正准备进阶的C语言学习者、刚入行的嵌入式开发者以及那些写了好几年C但遇到复杂声明还是忍不住“百度一下”的朋友。读完之后你至少能看懂90%以上的类型声明并且知道什么时候该用typedef、什么时候别滥用。1. typedef到底在干什么从“类型小名”说起1.1 typedef的本质别名不是新类型先说最基础的定义。typedef是C语言提供的一个关键字作用是给已有的数据类型起一个新的名字。注意关键词是“已有的数据类型”——它不创造新类型只是给现有类型一个额外的称呼。typedef unsigned int uint32; uint32 count 0; unsigned int count2 0; // 两个变量类型完全相同这里uint32和unsigned int在编译器的眼里就是同一个东西count和count2的类型一模一样不存在任何差异。很多人容易在这一点上犯迷糊总觉得typedef造出了一个“新类型”。实际上C语言标准里说得非常清楚typedef并没有创建新类型它只是建立了一个“同义词”。这个特性和后面要讲的#define有本质区别后续我会专门花一节来讲。1.2 为什么说typedef是编译期的“翻译”不是预处理的“替换”typedef发生在编译阶段由编译器来处理而#define发生在预处理阶段纯粹是文本替换。这个区别在平时写小demo时体现不出来一旦代码规模上来就会产生完全不同的行为。举个简单例子#define PINT int* PINT a, b; // 预处理后变成int* a, b;b在宏展开之后实际上是int b并不是int* b。宏就是“无脑替换”替换完了该是什么就是什么。如果用typedeftypedef int* PINT; PINT a, b; // a和b都是 int*因为typedef是在编译期被编译器当作类型处理PINT就是int*的别名所以a和b的类型都是int*。别小看这一个区别多少线上事故就是从这种“看着一样、实际不同”的地方冒出来的。2. typedef与#define看着像实际差十万八千里2.1 宏替换的“无脑”和typedef的“聪明”有些历史悠久的代码库里喜欢用#define来定义类型别名比如#define BYTE unsigned char这种做法在简单场景下能跑但遇到复杂一点的类型就露馅了。宏是在预处理阶段做文本替换编译器看到的已经是替换之后的代码它对BYTE这个“名字”完全没有概念。而typedef会让编译器在“类型表”里注册一个新名字编译器是知道BYTE和unsigned char是同一类型的。这带来一个直接后果typedef可以用在需要“类型”语法位置的地方宏不一定行。比如typedef unsigned char BYTE; BYTE x; unsigned char y; x y; // 合法同一类型 #define BYTE2 unsigned char BYTE2 x2;看起来也没差多少那看下面这种写法typedef char* STRING; STRING s1, s2; // 两个都是 char* #define STRING2 char* STRING2 s3, s4; // s3是 char*s4是 char同一个“起别名”的需求宏就没办法做到对struct、union、函数指针这类复杂类型的安全包装而且它完全不懂作用域和类型系统。所以现代C代码里用#define做类型别名基本可以认为是坏味道除非你有特别强的理由。2.2 深层对比const修饰的指针暴露出的经典差异typedef和#define最经典的一个分歧点我单独拿出来讲因为它太容易出事故了。看这段代码typedef char* PCHAR; const PCHAR p; #define PCHAR2 char* const PCHAR2 p2;这里p和p2的类型一样吗答案不一样。typedef char* PCHAR之后PCHAR是一个完整的类型名。const PCHAR p修饰的是整个PCHAR类型也就是“指向char的指针”这个整体被const修饰所以p的实际类型是char * const即指针本身不可变但指针指向的内容可变。而#define PCHAR2 char*经过预处理后变成const char* p2这是“指向const char的指针”即指向的内容不可变但指针本身可以动。PCHAR p; p[0] A; // OK内容可以改 p; // 编译错误指针本身不可改 PCHAR2 p2; p2[0] A; // 编译错误内容不可改 p2; // OK指针本身可以移动我在代码审查里不止一次看到这种问题有人用typedef定义了一个“指向const数据的指针”但实际得到的是“const指针”。这个坑非常隐蔽因为平时很少同时用到typedef、const和指针这三样东西一旦组合起来就很容易翻车。2.3 一张表看懂typedef与#define的全部关键差异对比维度typedef#define处理阶段编译期由编译器处理预处理期纯文本替换是否创造新类型不创造只是已有类型的别名不创造且编译器不知道这个名字作用域遵循C语言作用域规则从定义位置开始直到文件结束或#undef类型检查参与编译器类型检查不参与只是文本替换能否用于结构体/函数指针可以处理得很好能但易出错指针组合时的行为符合类型语义安全纯文本替换容易产生意外能否被#undef撤销不能可以调试器支持大多数调试器能识别并显示预处理后就没了调试器看不到结论很明确给类型起别名用typedef别用#define。3. typedef的经典场景从结构体到函数指针3.1 结构体与联合体告别每次写struct的烦恼在C语言里定义一个结构体变量得写struct关键字struct Point { int x; int y; }; struct Point p1;每次声明变量都要带struct写多了手累。于是很自然的做法就是加一个typedeftypedef struct Point { int x; int y; } Point; Point p1; // 简洁 struct Point p2; // 这样也仍然合法还有一种更紧凑的写法直接把结构体标签都省了typedef struct { int x; int y; } Point;这种写法叫“匿名结构体typedef”它的好处是代码短坏处是结构体本身没有名字不能在结构体内部自引用比如链表节点需要指向下一个节点的情况也无法在其他地方用struct声明这个类型。需要自引用的场景必须保留标签名。// 错误示例匿名结构体无法自引用 typedef struct { int data; Node* next; // 编译错误Node未定义 } Node; // 正确做法保留标签 typedef struct Node { int data; struct Node* next; } Node;同理union和enum也可以用typedef简化写法套路完全一样。3.2 函数指针让回调函数像普通函数一样优雅函数指针大概是typedef最能发挥价值的地方。没有typedef时声明一个函数指针变量那画风是这样的int (*handler)(int, char*);读起来绕写起来也绕。一旦涉及函数指针数组、函数指针作为参数代码就会变得非常酸爽void register_callback(int (*callback)(int, char*), int index);但有了typedef世界就清净了typedef int (*Callback)(int, char*); Callback handler; // 一个函数指针 Callback handlers[10]; // 函数指针数组 void register_callback(Callback cb, int index); // 作为参数你看一旦把函数指针类型抽出来后面所有地方都只需要写Callback这个干净的名字。回调函数注册、状态机跳转表、命令分发器……这些靠函数指针吃饭的场景typedef几乎是必备工具。3.3 数组类型与跨平台整数类型的妙用typedef还可以给数组类型起别名typedef int Matrix3x3[3][3]; Matrix3x3 m; // m 是 int[3][3]sizeof(m)的结果和直接用int m[3][3]没有区别。这种写法在需要多处声明同维度数组比如图形变换矩阵、状态表格时很有用修改维度只需要改一处typedef。跨平台整数类型更是typedef的主场。C语言标准里int、long在不同平台上的位数并不统一所以很多跨平台项目会自己定义一套固定宽度整数类型typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; typedef unsigned long long uint64;然后在代码里只用这些自定义类型。换平台时只需要修改这一小段typedef整个代码库不需要动。现代C标准其实已经提供了stdint.h里面定义了uint8_t、int32_t这些标准类型不用自己再造轮子。但了解这个思路仍然很重要因为很多老项目、嵌入式底层库还是直接使用自己定义的别名。4. 一网打尽typedef的进阶玩法4.1 函数指针数组用typedef搭建命令分发器综合运用上面这些知识可以做点实际的东西。比如一个命令行工具需要根据用户输入的命令字符串调用不同函数typedef int (*CommandHandler)(int argc, char* argv[]); int cmd_help(int argc, char* argv[]); int cmd_quit(int argc, char* argv[]); int cmd_debug(int argc, char* argv[]); typedef struct { const char* name; CommandHandler handler; } CommandEntry; CommandEntry commands[] { {help, cmd_help}, {quit, cmd_quit}, {debug, cmd_debug}, };遍历commands数组比对name字段找到匹配项之后直接handler(argc, argv)调用。这段代码如果没有typedef会复杂很多可读性也差很多。CommandEntry和CommandHandler两个typedef一配合结构体和函数指针都用得明明白白。4.2 与enum结合枚举类型也可以有别名枚举类型同样可以加typedeftypedef enum { STATE_IDLE, STATE_RUNNING, STATE_PAUSED, STATE_STOPPED } State; State current_state STATE_IDLE;这样做的好处一方面是不用每次都写enum另一方面可以在头文件里把状态类型作为一个完整的类型导出方便做参数类型限制虽然C语言的类型限制比较弱但至少让代码意图更清晰。这点我多说一句很多初学者觉得typedef enum是画蛇添足。但等你做大型项目几十个枚举类型散落在多个头文件里经常要和函数参数类型对齐有别名和没别名的差别就出来了。4.3 复杂声明的读法右左法则实战既然讲typedef就不能回避读复杂声明这件事。C语言的声明语法确实反人类但有一个“右左法则”可以帮助快速拆解找到声明中的标识符变量名或typedef的名字。先往右看遇到括号/符号则按优先级处理圆括号优先。然后往左看。循环往复直到类型名或关键字结束。以这个为例typedef int (*Handler)(void*);读法Handler向右看到)向左看到*于是“Handler是指针”在括号内完成继续向右看到(void*)于是“指向一个以void为参数、返回int的函数”。组合起来Handler是一个“指向返回int、参数为void的函数的指针”的别名。再看一个经典考题typedef void (*SignalHandler)(int); SignalHandler old_handler;old_handler是一个指向“参数为int、返回void的函数”的指针。看到这行你能知道它大概是个信号处理函数这就够了。开发中你真正需要能读懂的复杂类型绝大多数是函数指针和指针数组的组合。5. 实操中的几个深坑与排查技巧5.1 const与typedef组合的“顶层/底层”陷阱前面2.2已经讲过const PCHAR和const char*的区别这里再扩展一个更隐蔽的场景。typedef int* IPTR; const IPTR p;p的类型是int * const不是const int *。如果你想要“指向const int的指针”必须写typedef int* IPTR; const int* p1; // OK int const* p2; // 同上一句话总结typedef只对“整个类型”加const时是“顶层const”——修饰别名本身。想修饰底层数据得自己在typedef类型名前写清楚。这个细节在写只读数据接口时极容易踩坑一旦返回类型写错调用方就能通过这个指针改数据直接破坏只读约束。5.2 typedef与存储类关键字“誓不两立”typedef本身属于存储类关键字和auto、extern、register、static是一组的。所以你不能把typedef和这些关键字混用typedef static int s32; // 编译错误多个存储类 static typedef int s32; // 同样错误在文件作用域用typedef没问题因为文件作用域里的东西默认就有外部链接属性不需要也不能再加extern。但如果你想给一个“静态内部类型”起别名抱歉C的语法不支持。遇到这种需求通常的处理办法是直接定义一个结构体或者改用宏。5.3 头文件中的typedef防重定义与条件编译typedef在头文件里的写法有讲究。同一个typedef名字在一个编译单元里重复定义是不允许的typedef unsigned int size_t; typedef unsigned int size_t; // 编译错误重定义为了解决重复包含头文件的问题标准做法是加include guard#ifndef MY_TYPES_H #define MY_TYPES_H typedef unsigned int my_uint32; #endif这基本是所有头文件的标准模板。另外C11标准引入了_Generic等新特性但typedef的重复定义规则没有变——同一个作用域内同一个名字不能typedef两次。所以跨模块共享typedef时一定要通过头文件统一管理不能在多个源文件里各自定义。一旦有人修改了其中一个定义而其他文件里的旧定义还在那才是真正的灾难开始。5.4 函数指针数组的“数组名陷阱”用typedef定义函数指针后声明函数指针数组时容易写错typedef int (*Handler)(int); Handler handlers[10]; // 正确数组元素是函数指针 Handler* handler_ptrs; // 正确指向Handler的指针但如果你想定义一个“指向函数指针数组的指针”就复杂了Handler (*p)[10]; // 指向“包含10个Handler的数组”的指针p是一个指针指向一个数组数组的每个元素是Handler。这个声明如果你用typedef来“拆”会更好读typedef Handler HandlerArray[10]; HandlerArray* p;这两种写法等价但后者明显更容易理解。多写几年代码你就会发现复杂声明永远可以靠typedef拆成多行逐层起别名不要试图一次写成。6. typedef的边界什么时候该用它什么时候别瞎用6.1 提高可读性与可移植性的正面案例typedef用得好代码像散文一样舒服。我在实际项目里体会最深的两个收益一是可移植性。前面提到的固定整数位宽typedef在跨平台代码中几乎是必备。项目从32位平台迁移到64位平台时可能只需要改一处typedef而不是满屏搜索int和long。二是指针参数的声明简化。尤其是接口函数接受结构体指针时typedef struct Device Device; void device_init(Device* dev); void device_start(Device* dev); void device_stop(Device* dev);Device本身是一个不透明结构体opaque struct外界只能使用Device*看不到内部字段。这种“不透明指针”模式在C语言里是封装信息的重要手段配合typedef可以写出非常优雅的接口。6.2 滥用typedef的典型反面教材typedef也不是越多越好。我见过一些代码把基本类型全部包一层读起来反而更费劲typedef int my_int; typedef char my_char; typedef float my_float;这种“为了typedef而typedef”的做法完全没有意义。它既没有增加可移植性也没有隐藏实现细节只是让老手看着头疼让新人更加迷惑。还有一些人把函数指针typedef成特别短的名字还和业务类型混在一起读代码时根本分不清这是数据还是逻辑。我的判断标准很简单如果这个typedef不能让代码更清楚地表达意图或者不能解决跨平台/兼容性问题那就别用。不是所有类型都需要别名普通int就是int写清楚了比什么都强。6.3 命名风格让typedef自己会说话C代码的typedef命名常见的业界习惯是后缀_t。比如size_t、time_t、uint32_t都是这种风格。我个人的习惯是自定义的typedef统一加_t后缀一眼就能看出这是类型名而不是变量名。结构体、枚举类型用大写首字母或全小写下划线风格关键是和项目已有代码保持一致。函数指针类型通常加Handler或Callback之类的关键词让读者立刻知道它是回调。typedef struct WifiConfig WifiConfig_t; typedef int (*TimeoutCallback)(void*); typedef enum { OFF, ON } PowerState_t;命名风格这件事没有绝对的对错但有一个原则必须坚持一个项目里必须统一。混用几种风格比选哪种风格糟糕得多。7. 常见问题速查表问题可能原因解决方案typedef后变量声明成不同类型误用了#define做类型别名改用typedef尤其是带指针的场景const PCHAR不是预期的const char*typedef配合const时产生的是顶层const明确写const char*或调整typedef定义typedef加static报错static和typedef都是存储类关键字调整设计不要在typedef语句加static同一个typedef名重复定义报错多个头文件重复定义使用include guard或统一放入唯一头文件匿名结构体typedef后无法自引用结构体没有标签名用typedef struct Tag {...} Name;调试器看不到typedef名字类型信息在预处理时不适用检查是否用了#define改用typedef再补一个经验慎用typedef来隐藏struct关键字。虽然typedef struct {...} Foo;省了写struct但C语言里struct Foo这种写法自带“我叫一个结构体”的信息有时候多写几个字母反而更清晰。在C与C混编的代码库里这种规范化表达尤其重要。我在实际项目里见过的最“伤”的一次事故某底层模块用一个带指针字段的typedef结构体对外暴露接口结果在某个版本重构时有人把内部字段顺序调整了但因为外部代码都用的是typedef别名编译器根本查不出类型不匹配的问题直到运行期内存错乱才暴露。后来我养成了习惯跨模块边界用typedef暴露类型时一定要保持结构体布局的稳定并且对外隐藏内部字段。非必要不通过typedef对外暴露结构体的完整定义。C语言的typedef说白了就是个“别名的别名”。它不复杂但和C语言的类型系统、声明语法、预处理机制纠缠在一起之后就处处有讲究。把它用好了你的C代码能少写三分之一无意义的修饰读代码的人能少掉一大半头发。平时写代码时多用用它遇到复杂类型时大胆拆解时间长了自然就能驾驭。

相关新闻

从手工到自动化:用OpenClaw Skill与glab改造GitLab内部协作流程的TaoToken实践

从手工到自动化:用OpenClaw Skill与glab改造GitLab内部协作流程的TaoToken实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 13:46:46 阅读更多 →
北大清华阿里联合发布OmniEcho:让具身智能体真正听懂空间声音

北大清华阿里联合发布OmniEcho:让具身智能体真正听懂空间声音

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 13:46:46 阅读更多 →
AI时代程序员必看:脱离大模型,你还能独立工作吗?Vibe Coding挑战与应对

AI时代程序员必看:脱离大模型,你还能独立工作吗?Vibe Coding挑战与应对

本文探讨了Vibe Coding(氛围编码)如何借助AI改变编程方式,引发对程序员核心能力的思考。文章指出,AI擅长生成代码,但复杂系统判断、风险识别仍需人类智慧。强调基础知识和底层原理的重要性,提出程序员应驾驭…

2026/10/17 13:45:46 阅读更多 →

最新新闻

具身智能进阶开发:从感知到控制的完整技术链路与工程实践

具身智能进阶开发:从感知到控制的完整技术链路与工程实践

做具身智能这几年,我最大的感受是:这个方向不缺热度,缺的是能把系统跑通的人。很多人一上来就追大模型、追VLA,结果连ROS2的坐标变换都没搞明白,仿真环境里物体抓得稳稳的,一上真机就到处乱撞。我之前在团队…

2026/10/17 14:40:24 阅读更多 →
C#实现梯形分幅图幅编号:国标GB/T 13989-2012的生产级转换引擎

C#实现梯形分幅图幅编号:国标GB/T 13989-2012的生产级转换引擎

简介:本资源是面向地理信息系统开发与测绘类竞赛选手的实战型算法实现资料,聚焦梯形分幅法下多级比例尺地图图幅编号的正向计算与反算功能。基于湖北省省赛真题,完整呈现C#窗体程序的设计逻辑、核心算法推导(含1:100万至1:1万共7级…

2026/10/17 14:40:24 阅读更多 →
jsPDF配合jspdf-autotable导出PDF中文乱码的完整解决方案

jsPDF配合jspdf-autotable导出PDF中文乱码的完整解决方案

做导出功能遇到中文乱码,我猜你已经搜了不少文章,代码复制了一堆,结果要么还是乱码,要么直接白屏。这个问题在我这儿折腾了一整个下午,最后发现根子不在代码,而在PDF文件本身的字体机制。今天的主题就是把使…

2026/10/17 14:40:24 阅读更多 →
大模型分布式优化实战:从DDP到ZeRO-3的底层调优路径

大模型分布式优化实战:从DDP到ZeRO-3的底层调优路径

1. 项目概述:这不是“调参”,而是重构大模型训练的底层逻辑“大模型分布式优化技术(一)”这个标题,乍看像一篇论文小节,但实际是当前工业界最硬核、也最容易被误解的一类实操课题。我带过多个千卡级训练项目…

2026/10/17 14:40:24 阅读更多 →
ComfyUI自定义节点实战:数值转字符串转换器开发与类型映射解析

ComfyUI自定义节点实战:数值转字符串转换器开发与类型映射解析

1. 为什么值得动手写这个节点最近在折腾ComfyUI工作流的时候,我发现一个很实际的问题:工作流里经常需要把数字类型的数据(比如自定义步数、种子值、某个节点的评分输出)转成字符串,用作文件名后缀、提示词拼装或者API参…

2026/10/17 14:40:24 阅读更多 →
input按钮onclick事件的可靠性设计与实战避坑指南

input按钮onclick事件的可靠性设计与实战避坑指南

1. 这个看似简单的onclick到底在解决什么问题?“input按钮中的onclick事件”——光看标题,很多人第一反应是:“这有什么好讲的?不就是点一下触发个函数吗?”但我在一线带过几十个前端新人、参与过十几个中大型系统重构…

2026/10/17 14:39:23 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →