可变参函数的定义和使用

宏定义(define)和可变参数函数(variable arguments) 宏定义(define)和可变参数函数(variable arguments) 1,宏定义(define) 宏定义是在编译时对程序进行文本替换,在宏定义替换过程中,只有字符串替换操作,没有运算操作 宏定义分两种,一是普通的无参数宏定义;二是带实参的宏定义; (1) 无参数宏定义 #define 宏名(标识符) 替换的文本 范例: #define PI 3.14 double i = PI; --> 编译时,替换 double i = 3.14; #define N 5 #def 阅读详情
作者:茂叶

实现一个加法函数(fnAdd), 要求参数个数由使用者确定.
比如,这个加法函数要做到:
fnAdd(1,2,0)返回值是3
fnAdd(1,2,5,0)返回值是8
fnAdd(1,2,4,5,0)返回值是12


-------------------------------------------------------


#include <stdio.h>
#include <conio.h>
#include <stdarg.h>   ////用变参函数所必须的


////C99 标准,不能在老的编译器下通过。是我的设计的核心
#define fnAdd(...) _fnAdd(0,__VA_ARGS__)    

///实际调用的函数,start是用来得到函数参数地址的,没有实际意义
int _fnAdd(int start,...)
{
///关于va_list va_start和va_end请参看相关资料,或者直接看stdarg.h也可以。
///比较好理解,只有一点,最上面那个
///define是为了字节对齐用的。其实没有什么意义。
///如果做成template,把va_arg中的int和返回的sum的类型参数化,就更通用了

    va_list arg_ptr;
    int sum=0,t=0;
    va_start(arg_ptr,start);            ///得到参数表的首地址
    while(t=va_arg(arg_ptr,int))sum+=t; ////不知道有没有比这还好的写法,想了半天没有想出来。
    va_end(arg_ptr);                    ///把arg_ptr=NULL
    return sum;        
}

////网友写的,可能调试很好用。  
////思路也很好,因为参数都是int,所以干脆第一个也是int,这样。。。大家自己可以想明白吧。
////我觉得比我的那个要好。

int __fnAdd(int start,...)
{
    va_list arg_ptr;
    int sum=0;
    int nArgValue =start;  /////第一个参数直接加进去了。我觉得也可以。
    int nArgCout=0;
    va_start(arg_ptr,start);
    do {sum+=nArgValue;
       ++nArgCout;
printf("the %d th arg: %d/n",nArgCout,nArgValue);
printf("/n");
nArgValue = va_arg(arg_ptr,int);
    } while(nArgValue != 0);
    printf("/n");
    printf("the sum= %d/n",sum);
va_end(arg_ptr);
    return sum;
}

int main()
{
///试用了一下,在dev-cpp下成功,但不能在turboc 2.0下用,

printf("%d/n",fnAdd(1,2,3,0);
printf("%d/n",fnAdd(1,2,3,5,0);
getch();
return 0;
}

-----------------------------------------------------------


__cdecl 的参数传递使用栈方式,入栈顺序是从右往左,他支持可变的参数个数。

由于支持可变的参数个数,函数无法校正栈顶,所以这个活就留给了调用者。

可变参数的使用很危险,如果不知道怎样结束的话,va_arg_arg宏会执行到出现内存访问错误为止, 而且对参数的类型控制和识别也很麻烦。

我所说的危险在于开发者对参数的操作和处理上。

在实现可变参数的函数时,由于其特殊性,导致参数的个数未知,如果要处理每一个参数就需要知道参数的个数,在printf函数实现中,是通过检查 ’%’的个数而得知参数的个数,在这个例子中,我用’/0’标记了参数的结束。在这些方式中,无一不是使用指针进行数据的读取,而且,如果操作不慎,导致指针越界,指向了参数表之外,这时候编译器不会报告任何错误,而这类错误不但后果严重,而且错误隐蔽,很难查到。

多参函数的优点是使用灵活,定参函数的优点是稳定,高效。

在实际开发中,多参函数通常可以改用定参函数实现,所以,我的建议是,若非万不得已,尽量少定义多参函数。


下划线没有任何意义,只是内部函数的一般表示方法。如果被.h文件包起来看,对用户来说就只有一个fnAdd()函数,隐藏了具体的实现细节。因为实际的实现最前面有个无用的参数,对用户来说是不雅的,仅此而以。

任何技术都有自己的用处,只要用的适当的地方就好,没有什么别的要求,只要最终实现的代码简洁,高效,这才是最重要的。





---------------------------------------------------------------

[转帖]可变参数学习笔记
前言:本文在很大程度上改编自网友kevintz的"C语言中可变参数的用法"一文,在行文之前先向这位前辈表示真诚的敬意和感谢。
一、什么是可变参数
我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为:
int printf( const char* format, ...);
它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点"…"做参数占位符),实际调用时可以有以下的形式:
    printf("%d",i);
    printf("%s",s);
    printf("the number is %d ,string is:%s", i, s);    
以上这些东西已为大家所熟悉。但是究竟如何写可变参数的C函数以及这些可变参数的函数编译器是如何实现,这个问题却一直困扰了我好久。本文就这个问题进行一些探讨,希望能对大家有些帮助.

二、写一个简单的可变参数的C函数
先看例子程序。该函数至少有一个整数参数,其后占位符…,表示后面参数的个数不定. 在这个例子里,所有的输入参数必须都是整数,函数的功能只是打印所有参数的值.
函数代码如下:
//示例代码1:可变参数函数的使用
#include "stdio.h"
#include "stdarg.h"
void simple_va_fun(int start, ...)
{
    va_list arg_ptr;
    int nArgValue =start;
    int nArgCout=0;     //可变参数的数目
    va_start(arg_ptr,start); //以固定参数的地址为起点确定变参的内存起始地址。
    do {
       ++nArgCout;
        printf("the %d th arg: %d/n",nArgCout,nArgValue);     //输出各参数的值
        nArgValue = va_arg(arg_ptr,int);                    //得到下一个可变参数的值
    } while(nArgValue != -1);                
    return;
}
int main(int argc, char* argv[])
{
    simple_va_fun(100,-1);
    simple_va_fun(100,200,-1);
    return 0;
}

下面解释一下这些代码

从这个函数的实现可以看到,我们使用可变参数应该有以下步骤:

⑴由于在程序中将用到以下这些宏:
    void va_start( va_list arg_ptr, prev_param );
    type va_arg( va_list arg_ptr, type );
    void va_end( va_list arg_ptr );
va在这里是variable-argument(可变参数)的意思.
这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.

⑵函数里首先定义一个va_list型的变量,这里是arg_ptr,这个变量是存储参数地址的指针.因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。

⑶然后用va_start宏初始化⑵中定义的变量arg_ptr,这个宏的第二个参数是可变参数列表的前一个参数,即最后一个固定参数.

⑷然后依次用va_arg宏使arg_ptr返回可变参数的地址,得到这个地址之后,结合参数的类型,就可以得到参数的值。

⑸设定结束条件,这里的条件就是判断参数值是否为-1。注意被调的函数在调用时是不知道可变参数的正确数目的,程序员必须自己在代码中指明结束条件。至于为什么它不会知道参数的数目,读者在看完这几个宏的内部实现机制后,自然就会明白。

(二)可变参数在编译器中的处理
我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的, 由于1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下面看一下VC++6.0中stdarg.h里的代码(文件的路径为VC安装目录下的/vc98/include/ stdarg.h)
    typedef char *  va_list;
    #define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
    #define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
    #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
    #define va_end(ap)      ( ap = (va_list)0 )

下面我们解释这些代码的含义:

1、首先把va_list被定义成char*,这是因为在我们目前所用的PC机上,字符指针类型可以用来存储内存单元地址。而在有的机器上va_list是被定义成void*的

2、定义_INTSIZEOF(n)主要是为了某些需要内存的对齐的系统.这个宏的目的是为了得到最后一个固定参数的实际内存大小。在我的机器上直接用sizeof运算符来代替,对程序的运行结构也没有影响。(后文将看到我自己的实现)。

3、va_start的定义为 &v+_INTSIZEOF(v) ,这里&v是最后一个固定参数的起始地址,再加上其实际占用大小后,就得到了第一个可变参数的起始内存地址。所以我们运行va_start(ap, v)以后,ap指向第一个可变参数在的内存地址,有了这个地址,以后的事情就简单了。

这里要知道两个事情:
    ⑴在intel+windows的机器上,函数栈的方向是向下的,栈顶指针的内存地址低于栈底指针,所以先进栈的数据是存放在内存的高地址处。
    (2)在VC等绝大多数C编译器中,默认情况下,参数进栈的顺序是由右向左的,因此,参数进栈以后的内存模型如下图所示:最后一个固定参数的地址位于第一个可变参数之下,并且是连续存储的。
|--------------------------|
|  最后一个可变参数             |   ->高内存地址处
|--------------------------|
|--------------------------|
|  第N个可变参数              |     ->va_arg(arg_ptr,int)后arg_ptr所指的地方,
|                               |     即第N个可变参数的地址。
|--------------- |    
|--------------------------|
|  第一个可变参数               |     ->va_start(arg_ptr,start)后arg_ptr所指的地方
|                               |     即第一个可变参数的地址
|--------------- |    
|------------------------ --|
|                               |
|  最后一个固定参数             |    -> start的起始地址
|-------------- -|       .................
|-------------------------- |
|                               |  
|--------------- |  -> 低内存地址处

(4) va_arg():有了va_start的良好基础,我们取得了第一个可变参数的地址,在va_arg()里的任务就是根据指定的参数类型取得本参数的值,并且把指针调到下一个参数的起始地址。
因此,现在再来看va_arg()的实现就应该心中有数了:
    #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
这个宏做了两个事情,
   ①用用户输入的类型名对参数地址进行强制类型转换,得到用户所需要的值
   ②计算出本参数的实际大小,将指针调到本参数的结尾,也就是下一个参数的首地址,以便后续处理。

(5)va_end宏的解释:x86平台定义为ap=(char*)0;使ap不再 指向堆栈,而是跟NULL一样.有些直接定义为 ((void*)0),这样编译器不会为va_end产生代码,例如gcc在linux的x86平台就是这样定义的. 在这里大家要注意一个问题:由于参数的地址用于va_start宏,所以参数不能声明为寄存器变量或作为函数或数组类型. 关于va_start, va_arg, va_end的描述就是这些了,我们要注意的 是不同的操作系统和硬件平台的定义有些不同,但原理却是相似的.

(三)可变参数在编程中要注意的问题
因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢, 可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能 地识别不同参数的个数和类型. 有人会问:那么printf中不是实现了智能识别参数吗?那是因为函数 printf是从固定参数 format字符串来分析出参数的类型,再调用va_arg 的来获取可变参数的.也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的. 例如,在C的经典教材《the c programming language》的7.3节中就给出了一个printf的可能实现方式,由于篇幅原因这里不再叙述。

(四)小结:
1、标准C库的中的三个宏的作用只是用来确定可变参数列表中每个参数的内存地址,编译器是不知道参数的实际数目的。
2、在实际应用的代码中,程序员必须自己考虑确定参数数目的办法,如
⑴在固定参数中设标志-- printf函数就是用这个办法。后面也有例子。
⑵在预先设定一个特殊的结束标记,就是说多输入一个可变参数,调用时要将最后一个可变参数的值设置成这个特殊的值,在函数体中根据这个值判断是否达到参数的结尾。本文前面的代码就是采用这个办法.
无论采用哪种办法,程序员都应该在文档中告诉调用者自己的约定。
3、实现可变参数的要点就是想办法取得每个参数的地址,取得地址的办法由以下几个因素决定:
①函数栈的生长方向
②参数的入栈顺序
③CPU的对齐方式
④内存地址的表达方式
结合源代码,我们可以看出va_list的实现是由④决定的,_INTSIZEOF(n)的引入则是由③决定的,他和①②又一起决定了va_start的实现,最后va_end的存在则是良好编程风格的体现,将不再使用的指针设为NULL,这样可以防止以后的误操作。
4、取得地址后,再结合参数的类型,程序员就可以正确的处理参数了。理解了以上要点,相信稍有经验的读者就可以写出适合于自己机器的实现来。下面就是一个例子

(五)扩展--自己实现简单的可变参数的函数。
下面是一个简单的printf函数的实现,参考了<The C Programming Language>中的156页的例子,读者可以结合书上的代码与本文参照。
#include "stdio.h"
#include "stdlib.h"
void myprintf(char* fmt, ...)        //一个简单的类似于printf的实现,//参数必须都是int 类型
{
    char* pArg=NULL;               //等价于原来的va_list
    char c;
    pArg = (char*) &fmt;    //注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值
    pArg += sizeof(fmt);         //等价于原来的va_start          
   do
    {
        c =*fmt;
        if (c != ’%’)
        {
            putchar(c);            //照原样输出字符
        }
        else
{
//按格式字符输出数据
            switch(*++fmt)
{
            case ’d’:
                printf("%d",*((int*)pArg));          
                break;
            case ’x’:
                printf("%#x",*((int*)pArg));
                break;
            default:
                break;
            }
            pArg += sizeof(int);               //等价于原来的va_arg
        }
        ++fmt;
    }while (*fmt != ’/0’);
    pArg = NULL;                               //等价于va_end
    return; }
int main(int argc, char* argv[])
{
    int i = 1234;
    int j = 5678;
    myprintf("the first test:i=%d/n",i,j);
    myprintf("the secend test:i=%d; %x;j=%d;/n",i,0xabcd,j);
    system("pause");
    return 0;
}
在intel+win2k+vc6的机器执行结果如下:
the first test:i=1234
the secend test:i=1234; 0xabcd;j=5678;
官网下载STM32系列芯片的产品选型手册 官方提供了产品选型手册,便于工程师们进行产品选型。 那么,在哪下载"产品选型手册"呢?请看下文。 阅读详情

相关推荐

el-transfer和el-tree进行结合搞一个树形穿梭框

由于业务需求需要在穿梭框里使用树形结构,但是本身element里并不支持,于是参考了别的大佬发的文章作为思路及后续自己新增了一些处理功能。

bbkhhvv的博客 6307

[C语言]可变参数函数

在C语言中,函数可以定义固定数量和类型的参数,但是编程过程种可能会遇到函数传入的参数个数是不确定的情况,例如printf,sprintf等,这时可变参数是非常有用的。通过使用可变参数功能,可以编写出更灵活和通用的函数。

weixin_45587854的博客 1099

SpringBoot不用三方框架,怎么动态调度定时任务,ScheduledExecutorService 详解

Spring Boot 提供了强大的定时任务支持,无需依赖任何第三方框架,即可轻松实现可配置的定时任务。通过使用 `@EnableScheduling` 注解启用定时任务支持后,我们可以利用 `@Scheduled` 注解来定义定时任务的方法,这些方法可以在指定的时间间隔或特定时间点自动执行。 我们还可以通过集成 `ScheduledExecutorService` 来实现灵活的定时任务管理。`ScheduledExecutorService` 是 Java 标准库的一部分,能够以固定速率或延迟执行任务,

横竖撇折点 1940

C语言可变参数函数(printf/scanf)

C 语言允许定义参数数量可变的函数,这称为可变参数函数(variadic function)。这种函数需要固定数量的强制参数(mandatory argument),后面是数量可变的可选参数(optional argument)。 这种函数必须至少有一个强制参数。可选参数的类型可以变化。可选参数的数量由强制参数的值决定,或由用来定义可选参数列表的特殊值决定。 平时我们写C语言函数时,一般是固定参数的,但是像打印输出格式化内容时,其参数个数就不确定了,类似如下: printf("This is a s.

DayDayUp 5119

直线型一阶倒立摆1---从理论到实践的桥梁

本文深入探讨了直线型一阶倒立摆在控制理论中的核心地位,从非线性控制、鲁棒性到实时反馈等关键问题。通过实际案例和硬件搭建指南,帮助读者理解从理论到实践的过渡,特别适合控制工程初学者和研究人员。文章还提供了算法选型建议和硬件避坑手册,是掌握倒立摆控制的实用指南。

weixin_29047545的博客 321

霍尔电流传感器在新能源汽车中的应用综述

本文旨在全面剖析霍尔电流传感器在新能源汽车领域的应用现状、技术挑战及发展趋势。通过系统梳理其在电池管理系统、电机控制、车载充电等核心系统的应用场景,深入分析面临的技术瓶颈与创新解决方案,并基于最新技术动向展望未来发展方向,为相关领域的技术创新提供参考依据。

m0_46819860的博客 2260

python--通过可变参数计算n个数的乘积

通过可变参数计算n个数的乘积:代码如下:list = [] def the_input(count=eval(input("输入乘数的总个数:"))): for i in range(count): N=eval(input("依次输入乘数:")) list.append(N) print("一共有",count,"个要相乘的数") print

周作业的博客 1万+

OpenWebUI外部模型配置异常排查与修复指南

本文详细解析了OpenWebUI外部模型配置异常的常见问题及解决方案,包括隐藏字符、数据库锁死等典型现象。通过错误日志分析和数据库修复实战指南,帮助开发者快速定位并解决配置问题,确保OpenWebUI与第三方大模型的稳定连接。

weixin_29205061的博客 314

【C】可变参数函数

可变参数函数,也称为变参函数,是一类可以接受不定数量参数的函数。与普通函数不同,它的参数列表中包含一个或多个可变参数,通常使用省略号...来表示。这些函数是 C 语言中用于处理可变参数的输出函数,它们是标准库提供的函数。它们都具有格式化输出的功能,同时支持可变数量的参数。

m0_61476090的博客 678

【图像去噪】论文复现:降维打击!图像对输入变成像素对输入!Pytorch实现Noise2Void(N2V),基于U-Net模型训练,简洁明了理解N2V核心思想!附训练好的灰度图和RGB图的模型文件!

论文题目:Noise2Void-Learning Denoising from Single Noisy Images —— Noise2Void -从单个噪声图像中学习去噪【图像去噪】论文精读:Noise2Void-Learning Denoising from Single Noisy Images(N2V)由于源码是tensorflow版本,本文将基于Pytorch复现。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1356

知道LPDDR和DDR什么关系吗?

话不多说,先上大白话,一个网友总结的很好:简单地说DRR4是标准电压版的PC和服务器内存,LPDDR4属于手机等嵌入式移动设备使用的低电压低功耗内存,LPDDR4X则是LPDDR4的升级版,下面详细看看老哥的博客。LPDDR4是与DDR4内存等效的移动设备。。LPDDR4具有两个16位通道,从而使每个DIMM的总线总长度为32位。相比之下,DDR4每个DIMM具有64位通道。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 2806

C语言可变参数函数的原理和实现,及如何编写自定义可变参数函数

C语言中的可变参数函数是一种可以接受不定数量和类型的参数的函数,它可以用来实现一些灵活和通用的功能。本文介绍了C语言中的可变参数函数的原理和实现,以及如何编写自定义的可变参数函数。

极客代码 5306

罗克韦尔AB PLC_FactoryTalk无法登录的解决方法

罗克韦尔AB PLC_FactoryTalk无法登录的解决方法

Robot_PLC_HMI_Automation 3575

C/C++]可变参函数的定义和使用【转】

C/C++]可变参函数的定义和使用【转】2008-03-14 11:37<br />实现一个加法函数(fnAdd), 要求参数个数由使用者确定. <br />比如,这个加法函数要做到: <br />fnAdd(1,2,0)返回值是3 <br />fnAdd(1,2,5,0)返回值是8 <br />fnAdd(1,2,4,5,0)返回值是12 <br />------------------------------------------------------ #include <stdio.h> <br

mxf999的专栏 425

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C++ 定义和使用可变参数函数

1 #include<iostream> 2 using namespace std; 3 void PrintAll(int n,...){ 4 int *ptr; 5 ptr = &n; 6 while(*ptr){ 7 cout<<*ptr<<endl; 8 ...

weixin_30312557的博客 92

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

值传递和引用传递、可变参数、作用域、构造函数、this关键字、对象的定义和使用

定义格式为 class + 类名 此时的类名就相当于新定义的一个数据类型(作用如同 int)创建一个class对象,格式:类名 + 类变量名 = new 类名();用变量名.属性的方法,可以改变属性值,不改变为默认值(String 为null,int 为0)在对象内定义方法(或者称函数)格式为:关键字 + 返回值类型 + 函数名 +(参数)+函数体p1.name = "小明";System.out.print("名字是:" + p1.name + "\n年龄是:" +p1.age)

m0_63762870的博客 1291

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

python中函数的可变参数_Python函数中的可变参数

在Python函数中,还可以定义可变参数。如:给定一组数字a,b,c……,请计算a2+b2+ c2 + ……。要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:defcalc(numbers):sum=0for n innumbers:sum= sum + n *nreturn sum但是...

weixin_39727976的博客 237

python可变参数的定义_Python函数可变参数

Python函数可变参数教程在Python 中函数的可变参数又被称为不定长参数,Python 中的可变参数不是必须是函数的最后一个参数,但如果不是函数的最后一个参数,那么普通参数必须使用Python 中定义可变参数有两种形式,分别为:形参前添加一个 * 和形参前添加两个 *。Python函数可变参数定义详解语法def func_name(param1, *params):pass参数参数描述def...

weixin_39640090的博客 1870

python函数如何实现可变参数_Python 函数(可变参数)

在python函数中,可以定义可变参数,顾名思义,可变参数就是,传入的参数是可变的例如,给定一组数字a,b,c... 请计算a2 + b2 + c2 + ……要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c....作为一个list或者tuple传进来,这样,函数可以定义如下:def calc(numbers):sum=0for n in numbe...

weixin_39898248的博客 423

Python 函数(可变参数)

在python函数中,可以定义可变参数,顾名思义,可变参数就是,传入的参数是可变的 例如,给定一组数字a,b,c...  请计算a2 + b2 + c2 + ……  要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c....作为一个list或者tuple传进来,这样,函数可以定义如下: 1 2 3 4 5 ...

sunny_happy08的博客 5145

python 函数的可变参数

python学习笔记,特做记录,分享给大家,希望对大家有所帮助。 可变参数 在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。 我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。 在定义函数之前需要先引入math包,并允许后续代码引用math包里的sin、cos等函数: impor...

记录从移动端、鸿蒙到物联网与AI的完整实战与思考。专注于分享可复用的工程方案与产品思维,尤其深入鸿蒙生态与全栈开发。以十年工程与管理沉淀,为你提供清晰的技术纵深路径。坚信技术的价值在于“贯通”与“落地”。 1292
上一篇: CodeCrypt
下一篇: Vista Worm
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值