C语言核心:深入理解a、*a、a的内存访问与指针本质
1. 从一次内存访问异常说起理解a、*a、a为何是C语言的灵魂那天下午我正调试一个处理图像数据的模块程序毫无征兆地崩溃了调试器指向一行看似人畜无害的代码int *ptr array;。控制台冷冰冰地抛出一个“Segmentation fault”。我盯着这行代码看了足足一分钟心里咯噔一下——问题不在array而在于我潜意识里对array这个变量本身的理解出现了偏差。这个看似简单的错误其根源恰恰在于对C语言中最基础也最核心的三个表达式a、*a、a的混淆。很多C语言教材会把指针单独列为一章讲得玄之又玄但实际上指针不是独立于变量的“高级特性”它就是变量身份的一部分。不理解a、*a、a这三者的关系写出的C代码就像在布满暗礁的海域航行崩溃只是时间问题。a、*a、a这三个符号是打开C语言内存世界大门的钥匙。它们分别代表了变量的值、通过地址访问的值、变量的地址。这不仅仅是语法更是C语言“贴近硬件”哲学的直接体现。无论你是正在学习翁恺老师C语言练习题的学生还是在单片机上进行ADC值滤波的工程师或是纠结于head指针在链表操作中的用法透彻理解这三者都能让你从“代码搬运工”进阶为“内存布局的设计师”。接下来我将抛开教科书式的说教用一个老码农的视角结合实际的代码片段和内存模型图当然是文字描述带你彻底厘清这三者的区别、联系与应用场景。2. 变量a的“双重人格”左值与右值的精分现场当我们声明一个变量int a 10;时这个a在程序中就扮演着两个截然不同的角色这取决于它出现在赋值运算符的左边还是右边。这就是C语言中经典的“左值”lvalue和“右值”rvalue概念。2.1 作为右值的a我是数据的搬运工当a出现在赋值号的右边或者作为一个表达式的一部分被使用时它代表的是存储在这个变量内存单元中的那个具体的数值。int a 10; // 初始化此时a是左值被写入 int b a; // 这里右边的 a 是右值代表数字10 int c a 5; // a 作为右值参与计算其值10被取出 printf(“%d”, a); // 输出时a 也是右值输出其值10在这个场景下你可以把a想象成一个贴着标签“a”的盒子盒子里装着数字10。当a作为右值时我们做的就是打开这个盒子把里面的数字10拿出来用。这个过程在编译后通常对应一条CPU的“加载”Load指令从内存地址中把数据读到寄存器。注意这里容易和Python等高级语言混淆。在Python中b a可能传递的是引用对于可变对象。但在C语言中对于基本类型如intb a永远意味着值的拷贝。b会获得一份和a当前值10一模一样的副本此后a和b在内存中是两个完全独立的盒子。2.2 作为左值的a我是空间的拥有者当a出现在赋值号的左边时它的身份发生了根本变化。此时a不再代表盒子里的内容而是代表那个盒子本身即内存中那块存储区域的位置。a 20; // 这里的 a 是左值代表“名为a的内存单元”这条语句的含义是“找到标签为a的那个盒子把里面的东西扔掉放入新的数字20。”编译器看到作为左值的a知道它需要生成一条“存储”Store指令将值20写入a对应的内存地址。为什么区分左右值如此重要因为不是所有的表达式都能作为左值。能作为左值的表达式必须有一个可被标识和修改的内存位置。这解释了为什么以下代码是错的int b 10; (a b) 30; // 编译错误(ab)是一个临时计算结果没有固定的内存位置不能作为左值。理解a的这种“双重人格”是理解后续*a和a的基础。当你看到a时必须立刻根据上下文判断此刻它代表的是“值”还是“位置”这个简单的判断能避免一大半的概念错误。3. 取址操作符a揭开变量的“家庭住址”如果说a作为右值时是盒子里的“内容”那么a就是找到这个盒子在“内存货架”上的具体“位置编号”也就是内存地址。被称为“取址操作符”Address-of operator。3.1a的本质与输出int a 10; printf(“a的值 %d\n”, a); // 输出a的值 10 printf(“a的地址 %p\n”, (void*)a); // 输出a的地址 0x7ffeeda2c3bc (一个类似这样的十六进制数)第二行a产生了一个值这个值的类型是“指向整型的指针”即int*。它表示变量a在内存中的起始地址。这个地址值是由操作系统在程序运行时分配的每次运行可能不同得益于地址空间布局随机化ASLR。3.2的操作对象与常见误区的操作数必须是一个左值因为它需要有一个明确的内存位置来获取地址。这带来了几个关键点不能对常量或表达式取址10; // 错误10是字面常量没有内存地址。 (a5); // 错误(a5)是表达式计算结果是临时值无固定地址。数组名array的特殊性这是最容易踩坑的地方之一也是我开头那个崩溃案例的根源。int array[5] {1, 2, 3, 4, 5}; printf(“%p\n”, array); // 输出数组首元素地址类型是 int* printf(“%p\n”, array); // 输出数组本身的地址类型是 int (*)[5]从数值上看array和array打印出来的地址是相同的都指向内存中数组开始的那个位置。但是它们的类型完全不同array在大多数表达式中会“退化”decay为指向其首元素array[0]的指针类型是int*。array则是一个“指向整个数组的指针”类型是int (*)[5]。这种类型差异在进行指针算术时天差地别int *ptr1 array; // int* 指针 int (*ptr2)[5] array; // 数组指针 printf(“ptr1 %p\n”, ptr1); printf(“ptr1 1 %p\n”, ptr1 1); // 地址增加 sizeof(int) 4 字节 printf(“ptr2 %p\n”, ptr2); printf(“ptr2 1 %p\n”, ptr2 1); // 地址增加 sizeof(int[5]) 20 字节我的崩溃代码int *ptr array;就是把一个int (*)[5]类型的值试图赋给一个int*类型的变量。虽然在某些编译器下可能只给出警告而非错误但后续对ptr的操作如ptr[1]会基于错误的类型解释进行内存访问极易导致越界和段错误。正确的写法应该是int *ptr array;或int *ptr array[0];。函数名func与数组类似函数名func本身就可以当作函数地址使用func得到的也是同样的地址两者通常可以互换。但在涉及函数指针类型推导的复杂场景下使用func是更明确和推荐的做法。理解a就是理解每一个数据在内存中的“锚点”。它是连接变量名和物理内存的桥梁也是指针得以存在的前提。4. 解引用操作符*a按图索骥的寻宝之旅有了地址地图我们自然想看看地址里存放着什么宝藏。*作为一元操作符时就是“解引用操作符”Dereference operator它根据一个指针值地址去访问该地址处存储的数据。4.1*的基本用法从地址到值int a 10; int *p a; // p 是一个指针变量里面存储着 a 的地址 printf(“a %d\n”, a); // 直接访问值10 printf(“*p %d\n”, *p); // 通过指针间接访问值10 *p 20; // 通过指针间接修改值 printf(“现在 a %d\n”, a); // 输出20*p这个表达式的行为是“取出指针变量p中存储的地址然后去那个地址对应的内存位置读取或写入数据。” 此时*p整体作为一个表达式其类型就是p所指向的类型这里是int并且因为它是通过一个明确的地址访问一个明确的内存位置所以*p可以作为一个左值使用如*p 20。4.2*操作的风险与必须的前置条件解引用是C语言中最危险的操作之一因为它直接操作内存。一个无效的指针解引用轻则读取出垃圾数据重则直接导致程序崩溃段错误。进行*ptr操作有一个绝对前提ptr必须是一个已经被正确初始化、指向一块合法且可访问内存的指针。常见错误示例野指针解引用int *p; // 未初始化p的值是随机的垃圾地址 *p 10; // 灾难试图向一个随机地址写入数据。空指针解引用int *p NULL; // 明确初始化为空 *p 10; // 崩溃NULL地址通常不可访问。指针越界后解引用int arr[3] {1,2,3}; int *p arr; for(int i0; i3; i) { // 错误地循环到了 i3 printf(“%d ”, *(pi)); // 当i3时访问了arr[3]越界 }返回局部变量地址后解引用栈内存失效int* bad_func() { int local 42; return local; // 返回局部变量的地址 } int main() { int *p bad_func(); // p 指向一个已经失效的栈帧 printf(“%d\n”, *p); // 行为未定义可能输出垃圾值或崩溃。 }实操心得在解引用任何指针之前心里必须过一遍安检1. 它初始化了吗2. 它指向NULL吗3. 它指向的内存还在有效期内吗对于动态分配的内存是否已释放4. 这次访问会越界吗养成这个习惯能帮你避开90%的指针相关崩溃。4.3*与的互逆关系这是一个非常优雅且重要的特性*和在某种意义上是一对互逆操作对于左值表达式。int a 10; assert(a *(a)); // 这个断言永远为真a取得a的地址*(a)又根据这个地址取回a的值。这就像你记下自己家的门牌号a然后根据这个门牌号一定能找到自己的家*(a)。理解这种互逆性对于分析复杂的指针表达式非常有帮助。5. 综合演练在复杂声明与数据结构中穿梭理解了单个的a、*a、a后我们需要将它们组合起来应对更真实的场景。C语言的复杂性往往就体现在指针与不同类型、结构的嵌套上。5.1 指针的指针int **pp当我们需要修改一个指针变量本身时比如在一个函数里改变外部传入的指针的指向就需要用到指向指针的指针。void allocate_memory(int **pp) { *pp (int*)malloc(sizeof(int) * 10); // 修改了main函数中p的指向 if (*pp) { (*pp)[0] 100; // 注意括号先解引用pp得到p再像数组一样使用 } } int main() { int *p NULL; allocate_memory(p); // 传入指针p的地址 if (p) { printf(“%d\n”, p[0]); // 输出 100 free(p); } }这里pp的类型是int**它存储的是p的地址。*pp解引用一次得到的是p类型int*。**pp解引用两次得到的是p所指向的整数值。函数调用allocate_memory(p)是关键它传递了指针变量p的地址使得函数内部能够改变p本身的值从NULL变为一块堆内存的地址。5.2 指针与数组的纠缠arr[i]与*(arri)C语言中数组下标操作arr[i]本质上就是指针算术和解引用的语法糖。根据定义arr[i]完全等价于*(arr i)。int arr[5] {10, 20, 30, 40, 50}; int *ptr arr; // ptr指向arr[0] // 以下四行代码完全等价都访问arr[2]的值30 int val1 arr[2]; int val2 *(arr 2); int val3 ptr[2]; int val4 *(ptr 2);编译器在处理arr[2]时实际做的事情是先计算arr的首地址然后加上2 * sizeof(int)的偏移量最后解引用那个地址。这也解释了为什么数组下标可以是负数当指针指向数组中间元素时但必须极度小心因为很容易越界。5.3 结构体与指针-操作符的真相-操作符是结合了*和.的便捷写法。对于结构体指针struct MyStruct *p访问其成员有三种方式typedef struct { int x; int y; } Point; Point pt {1, 2}; Point *p pt; // 方式1先解引用再用点号 int a (*p).x; // 方式2使用箭头操作符推荐 int b p-x; // (*p).x 完全等价于 p-xp-x可以理解为(*p).x的简写它先对指针p解引用得到结构体变量再访问其成员x。在处理链表、树等数据结构时-操作符无处不在。5.4 函数指针(*func_ptr)()的调用函数指针存储的是函数的入口地址。通过函数指针调用函数也需要解引用。int add(int a, int b) { return a b; } int main() { int (*func_ptr)(int, int); // 声明一个函数指针 func_ptr add; // 或 func_ptr add; 取址可省略 // 调用方式1显式解引用 int result1 (*func_ptr)(3, 4); // 调用方式2直接使用指针名更常见 int result2 func_ptr(3, 4); printf(“%d, %d\n”, result1, result2); // 都输出 7 }虽然func_ptr(3,4)这种直接调用方式更简洁但理解其本质是(*func_ptr)(3,4)有助于看清我们是通过一个存储了地址的变量间接地跳转到代码段执行特定函数。6. 内存视角下的终极图谱变量、地址与值的三角关系让我们把所有的点串联起来画一张内存中的关系图用文字描述。假设我们有如下代码片段int main() { int a 0x11223344; // 一个具体的值 int *p a; int **pp p; }程序运行时在内存的栈区假设可能会形成这样的布局内存地址 (示例) | 变量名 (标识符) | 存储的值 (十六进制) | 说明 ------------------|----------------|--------------------------|----------------------------------- 0x7ffeeda2c3b8 | pp | 0x7ffeeda2c3b4 | 指针变量pp里面存着p的地址 0x7ffeeda2c3b4 | p | 0x7ffeeda2c3ac | 指针变量p里面存着a的地址 0x7ffeeda2c3ac | a | 0x0000000011223344 | 整型变量a里面存着数字0x11223344现在我们来解读各种操作a:作为右值代表从地址0x7ffeeda2c3ac开始的4个字节里存储的数据0x11223344。作为左值代表内存位置0x7ffeeda2c3ac本身。a:操作取a的地址。结果产生一个值0x7ffeeda2c3ac类型是int*。这个值被用来初始化了指针p。p:作为变量它自己的地址是0x7ffeeda2c3b4。它里面存储的值是0x7ffeeda2c3ac即a的地址。*p:操作解引用。先取出p的值0x7ffeeda2c3ac然后去那个地址访问数据。结果得到0x11223344即a的值。所以*p等价于a。p:操作取指针变量p本身的地址。结果产生一个值0x7ffeeda2c3b4类型是int**。这个值被用来初始化了pp。pp:存储的值是0x7ffeeda2c3b4p的地址。*pp:操作解引用pp。取出pp的值0x7ffeeda2c3b4去那个地址访问。结果得到0x7ffeeda2c3ac即p的值。所以*pp等价于p。**pp:操作双重解引用。等价于*(*pp)。先解引用pp得到p(0x7ffeeda2c3ac)再解引用p得到a的值 (0x11223344)。所以**pp等价于*p也等价于a。这张“内存地图”清晰地展示了变量名、内存地址和存储值三者之间通过和*建立的桥梁关系。任何复杂的指针嵌套都可以通过这样一层层地追踪地址和解引用来理解。7. 避坑指南与最佳实践从知道到用好理解了原理最终是为了写出健壮、清晰的代码。下面是一些结合了多年踩坑经验的忠告。7.1 声明与初始化的纪律指针声明时立即初始化这是铁律。// 坏习惯 int *p; // 野指针后患无穷 // 好习惯 int *p NULL; // 或指向有效的内存地址 int *p some_var; int *p malloc(sizeof(int) * N); if (p NULL) { /* 处理分配失败 */ }使用const保护数据const和指针结合能明确表达意图防止误操作也是API设计的一部分。const int *p1; // 指向常量整数的指针不能通过p1修改数据 int * const p2; // 常量指针p2的指向不能改 const int * const p3; // 指向常量整数的常量指针两者都不能改7.2 指针运算的陷阱指针算术的单位是“指向类型的大小”ptr 1增加的字节数是sizeof(*ptr)。这对于遍历数组是福音但对于指向非数组内存的指针则是灾难。避免对void*指针进行算术运算void*是通用指针但sizeof(void)未定义void*的算术运算在C标准中是未定义行为。GCC等编译器将其视为char*步长为1但这不具备可移植性。需要运算时应先转换为具体的指针类型。7.3 数组与指针的“退化”规则再审视牢记数组名在大多数情况下会退化为指向其首元素的指针但有两个例外sizeof(array)返回整个数组的字节大小而不是指针大小。array产生的是指向整个数组的指针类型不同。在函数参数传递中数组总是退化为指针。因此void func(int arr[])和void func(int *arr)是完全等价的。在函数内部你无法通过sizeof(arr)获取数组元素个数。7.4 调试技巧如何观察a、*a、a在现代IDE如VSCode、CLion或GDB调试器中充分利用监视窗口Watch添加a查看变量的值。添加a查看变量的地址通常以十六进制显示。添加p和*p可以同时观察指针变量本身存储的地址值以及它指向的内容。对于数组可以添加arr和arr,10查看前10个元素。当程序因指针问题崩溃时第一件事就是检查相关指针变量的值。一个常见的错误值是0x0NULL、0xccccccccVC调试模式下未初始化的栈内存或0xdeadbeef某些环境标记已释放内存这些都能给你明确的线索。回到我开头遇到的那个崩溃根本原因就是混淆了array退化为int*和array类型为int(*)[5]的类型。在将array赋值给int*指针时编译器可能只是警告但类型系统的错位已经为后续的非法内存访问埋下了地雷。修正的方法很简单就是使用正确的类型int *ptr array;。这件事让我再次深刻体会到在C语言里对每一个表达式尤其是涉及和*的表达式保持对其类型的清醒认知是多么重要。这不仅仅是语法更是对程序所操纵的那片内存的尊重。

相关新闻

从思维链到证据链:构建可信AI写作助手的CoE技术实践

从思维链到证据链:构建可信AI写作助手的CoE技术实践

1. 项目概述:当AI开始为论文结论“上证据” 最近在学术圈和技术圈,一个由Google提出的新概念“CoE”被频繁讨论。它并非一个全新的AI模型,而是一种旨在解决当前AI应用,特别是在学术写作领域,最核心痛点的方法论。这个痛…

2026/8/15 8:20:00 阅读更多 →
Python与PyCharm环境配置全攻略:从安装、配置到深度卸载

Python与PyCharm环境配置全攻略:从安装、配置到深度卸载

1. 项目概述:为什么需要一个彻底的安装与卸载指南? 如果你正准备踏入Python编程的世界,或者已经在路上但被环境配置搞得焦头烂额,那么这篇内容就是为你准备的。Python和PyCharm,一个是当今最热门的编程语言&#xff0c…

2026/8/15 8:20:00 阅读更多 →
DeepSeek V4 Pro 正式版全平台上线:Agent 与 Coding 能力接近顶级模型,8 月 17 日起调价

DeepSeek V4 Pro 正式版全平台上线:Agent 与 Coding 能力接近顶级模型,8 月 17 日起调价

更新日期 2026.8.13 内容来源 https://vibecoding.dreamfree.space V4 Pro 正式版已同步上线 APP、网页和 API,网页和 APP 可在「专家模式」中使用。API 模型名仍为 deepseek-v4-pro,支持 Responses API、Tool Calls、Anthropic API,并适配 …

2026/8/15 8:20:00 阅读更多 →

最新新闻

AI Agent开发实战:MCP协议与Skill设计赋能智能体高效执行

AI Agent开发实战:MCP协议与Skill设计赋能智能体高效执行

1. 项目概述:当AI Agent学会“套路”最近在折腾AI Agent开发的朋友,估计没少被两个词刷屏:MCP和Skill。乍一看,这俩词儿挺唬人,一个叫“模型上下文协议”,一个叫“技能”,听起来像是某种高深莫测…

2026/8/15 9:10:20 阅读更多 →
FPGA常用型号参考

FPGA常用型号参考

FPGA市场主要由国际巨头和快速崛起的国内厂商两大阵营构成。国际厂商凭借深厚的技术积累和广泛的产品线,覆盖从顶尖数据中心到低功耗边缘计算的全场景;国内厂商则在通信、工业控制和汽车电子等特定市场加速追赶,部分已实现中高端突破。下表汇…

2026/8/15 9:10:20 阅读更多 →
汽车零部件大批量生产,单件检测时间如何压到 30 秒?

汽车零部件大批量生产,单件检测时间如何压到 30 秒?

汽车零部件大批量生产,单件检测时间如何压到 30 秒? Equator 比对仪是雷尼绍(Renishaw)推出的车间级在线比对测量系统,专门面向中大批量生产场景,以"标准件比对"为原理,在 2μm&#…

2026/8/15 9:10:20 阅读更多 →
多线程同时调用通信接口,为什么会出现数据乱码?

多线程同时调用通信接口,为什么会出现数据乱码?

在工业上位机开发中,这是非常经典的“玄学故障”:单线程调试一切正常,设备多了、业务模块多了之后,就开始偶发数据乱码、CRC校验失败、返回值对不上;错误率时高时低,压力越大出错越频繁;很多人第…

2026/8/15 9:10:20 阅读更多 →
PDF.js Viewer.html 实战指南:快速集成与深度定制

PDF.js Viewer.html 实战指南:快速集成与深度定制

1. 项目概述:为什么需要Viewer.html这种“现成”方案?如果你在前端开发中处理过PDF预览,大概率听说过甚至用过pdf.js这个库。它的第一种方式——直接使用PDFViewer等API进行编程式集成——给了开发者极大的灵活性,你可以自定义UI、…

2026/8/15 9:10:20 阅读更多 →
Agent Skills:将个人经验转化为AI可复用的团队能力

Agent Skills:将个人经验转化为AI可复用的团队能力

1. 项目概述:从“一次性经验”到“可复用能力”的进化在任何一个团队里,你肯定都见过这样的场景:某个同事为了解决一个棘手问题,花了整整两天时间,查遍了各种文档、试了无数种方法,最后终于搞定。他长舒一口…

2026/8/15 9:09:20 阅读更多 →

日新闻

内景 空间站内部 中国空间站 太空 内仓

内景 空间站内部 中国空间站 太空 内仓

本项目为前几天收费帮学妹做的一个项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 空间站内部 中国空间站 太空 内仓 地址:本地PC端运行(或Web…

2026/8/15 0:00:30 阅读更多 →
重新定义数据接口:3个突破性场景让通达信数据读取更智能

重新定义数据接口:3个突破性场景让通达信数据读取更智能

重新定义数据接口:3个突破性场景让通达信数据读取更智能 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 当我们面对海量金融数据时,传统的数据获取方式往往让我们陷入困境—…

2026/8/15 0:00:30 阅读更多 →
一文读懂快消WMS怎么选?2026年国内外10大主流WMS品牌盘点

一文读懂快消WMS怎么选?2026年国内外10大主流WMS品牌盘点

快消品(FMCG)是流通速度较快、竞争较为激烈的行业之一。一瓶饮料从出厂到消费者手中,往往只有几十天甚至几天的周转窗口。这决定了快消行业的仓储管理系统(WMS)与制造业、电商行业存在明显区别:它不仅需要管…

2026/8/15 0:02:30 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/13 10:41:52 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/13 10:41:51 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/14 13:40:53 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/14 14:06:45 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/15 2:35:29 阅读更多 →