一步一步写算法(之 可变参数)

合集下载

Python-3.5.2--官方入门指南-中文版

Python-3.5.2--官方入门指南-中文版

Python 入门指南目录Python 入门指南 (1)1. 开胃菜 (5)2. 使用Python 解释器 (6)2.1. 调用Python 解释器 (6)2.1.1. 参数传递 (8)2.1.2. 交互模式 (8)2.2. 解释器及其环境 (8)2.2.1. 源程序编码 (8)3. Python 简介 (9)3.1. 将Python 当做计算器 (10)3.1.1. 数字 (10)3.1.2. 字符串 (12)3.1.3. 列表 (16)3.2. 编程的第一步 (18)4. 深入Python 流程控制 (19)4.1. if 语句 (20)4.2. for 语句 (20)4.3. range() 函数 (21)4.4. break 和continue 语句, 以及循环中的else 子句 (22)4.5. pass 语句 (23)4.6. 定义函数 (24)4.7. 深入Python 函数定义 (26)4.7.1. 默认参数值 (26)4.7.2. 关键字参数 (28)4.7.3. 可变参数列表 (30)4.7.4. 参数列表的分拆 (30)4.7.5. Lambda 形式 (31)4.7.6. 文档字符串 (31)4.7.7. 函数注解 (32)4.8. 插曲:编码风格 (33)5. 数据结构 (34)5.1. 关于列表更多的内容 (34)5.1.1. 把列表当作堆栈使用 (35)5.1.2. 把列表当作队列使用 (36)5.1.3. 列表推导式 (37)5.1.4. 嵌套的列表推导式 (39)5.2. del 语句 (40)5.3. 元组和序列 (40)5.4. 集合 (42)5.6. 循环技巧 (44)5.7. 深入条件控制 (46)5.8. 比较序列和其它类型 (46)6. 模块 (47)6.1. 深入模块 (48)6.1.1. 作为脚本来执行模块 (49)6.1.2. 模块的搜索路径 (50)6.1.3. “编译的” Python 文件 (51)6.2. 标准模块 (51)6.3. dir() 函数 (52)6.4. 包 (55)6.4.1. 从* 导入包 (57)6.4.2. 包内引用 (58)6.4.3. 多重目录中的包 (58)7. 输入和输出 (58)7.1. 格式化输出 (59)7.1.1. 旧式的字符串格式化 (63)7.2. 文件读写 (63)7.2.1. 文件对象方法 (63)7.2.2. 使用json 存储结构化数据 (66)8. 错误和异常 (67)8.1. 语法错误 (67)8.2. 异常 (67)8.3. 异常处理 (68)8.4. 抛出异常 (71)8.5. 用户自定义异常 (71)8.6. 定义清理行为 (73)8.7. 预定义清理行为 (74)9. 类 (75)9.1. 术语相关 (75)9.2. Python 作用域和命名空间 (76)9.2.1. 作用域和命名空间示例 (78)9.3. 初识类 (78)9.3.1. 类定义语法 (79)9.3.2. 类对象 (79)9.3.3. 实例对象 (80)9.3.4. 方法对象 (81)9.3.5. 类和实例变量 (82)9.4. 一些说明 (83)9.5. 继承 (85)9.5.1. 多继承 (86)9.6. 私有变量 (87)9.7. 补充 (88)9.9. 迭代器 (89)9.10. 生成器 (91)9.11. 生成器表达式 (91)10. Python 标准库概览 (92)10.1. 操作系统接口 (92)10.2. 文件通配符 (93)10.3. 命令行参数 (93)10.4. 错误输出重定向和程序终止 (93)10.5. 字符串正则匹配 (94)10.6. 数学 (94)10.7. 互联网访问 (95)10.8. 日期和时间 (95)10.9. 数据压缩 (96)10.10. 性能度量 (96)10.11. 质量控制 (97)10.12. “瑞士军刀” (98)11. 标准库浏览– Part II (98)11.1. 输出格式 (98)11.2. 模板 (100)11.3. 使用二进制数据记录布局 (101)11.4. 多线程 (102)11.5. 日志 (103)11.6. 弱引用 (103)11.7. 列表工具 (104)11.8. 十进制浮点数算法 (105)12. 虚拟环境和包 (106)12.1. 简介 (106)12.2. 创建虚拟环境 (107)12.3. 使用pip 管理包 (108)13. 接下来? (110)14. 交互式输入行编辑历史回溯 (112)14.1. Tab 补全和历史记录 (112)14.2. 其它交互式解释器 (112)15. 浮点数算法:争议和限制 (112)15.1. 表达错误 (116)16. 附录 (118)16.1. 交互模式 (118)16.1.1. 错误处理 (118)16.1.2. 可执行Python 脚本 (118)16.1.3. 交互式启动文件 (119)16.1.4. 定制模块 (119)Python 是一门简单易学且功能强大的编程语言。

c 可变参数

c 可变参数

c 可变参数C语言是现今最流行的编程语言之一,也是计算机科学家和程序员们一直在使用的一种语言。

在C语言中,可变参数是一种重要的特性,它可以让程序员在使用函数时可以操作不确定数量的参数。

这样可以让程序员更轻松自如地实现复杂的功能。

本文将通过一些示例来讲解C语言中可变参数的相关知识,以及它在编程中的应用。

首先,让我们从可变参数的定义开始,可变参数是指函数可以接受不确定数量的参数。

在C语言中,可变参数函数使用三个点(...)来表示,如下所示:int func(int a, int b,…{…}可变参数函数在C语言中也被称为变参函数,它允许程序员在定义函数时,对可变参数进行控制和限制,这样可以有效地避免错误和恶意攻击。

例如,可变参数函数可以用来限定参数的数量,并且可以检查参数的类型,以及其他的错误检查。

可变参数函数的使用非常实用,最常见的用途就是为函数提供不定量的参数。

例如,有一个计算n个数字之和的函数,如下所示:int sum(int a, int b, int c, int d);在这种情况下,如果要求计算4个数字之和,则该函数可以正常使用,但是如果要求计算5个数字或以上的和,则要么使用循环结构,要么重新定义一个函数,这两种方式都很不便捷。

但如果使用可变参数函数,就可以简化上述操作,例如,定义如下的函数:int sum(int n,);这样,在调用sum函数时,只需给出可变参数中的第一个参数(n),即可实现对不同数量参数的计算。

另外,可变参数函数还可以用来处理变参列表,也就是函数调用中的参数列表,可以方便地用来处理自定义参数。

例如,可以编写一个可变参数函数,它能够接受任意数量的字符串,并对这些字符串进行排序和拼接,例如:char* sort_strings(int n, char *str1, char *str2,) {// code to sort strings}可变参数函数的另一个应用是在固定参数的前面接受一个可变参数,它可以用来接收可变参数的数量,例如:int calc(int n, ...) {// code to calculate the nth number}可变参数函数非常有用,它可以有效地解决复杂的问题,以及实现各种复杂的功能。

c语言可变参数用法

c语言可变参数用法

c语言可变参数用法C语言可变参数用法C语言作为一种高度灵活和强大的编程语言,为程序员提供了丰富的编程工具和特性。

其中之一就是可变参数,它允许函数接受不定数量的参数。

在本文中,我们将深入探讨C语言可变参数的用法和实现。

一、什么是可变参数首先,我们需要了解可变参数的概念。

在C语言中,可变参数是指一个函数接受不定数量的参数。

这意味着我们可以使用不同数量的参数来调用函数,而函数内部可以根据需要处理这些参数。

这为我们处理各种情况和需求带来了极大的灵活性。

二、可变参数的声明在C语言中,使用可变参数之前,我们需要在函数声明中使用`...`来表示参数的可变性。

例如,下面是一个使用可变参数的函数声明:cint sum(int count, ...);在这个例子中,`...`表明该函数将接受可变数量的参数,而`count`参数指定了传递给函数的参数数量。

三、可变参数的使用接下来,我们将了解如何在函数内部使用可变参数。

在C语言中,我们可以使用`stdarg.h`头文件中的一些宏来处理可变参数。

让我们逐一了解这些宏。

1. `va_list`类型`va_list`类型用于定义一个变量来保存可变参数列表。

我们可以通过`va_start`宏初始化这个变量。

cvoid func(int count, ...) {va_list args;va_start(args, count);...在上面的例子中,我们使用了`va_list`类型的变量`args`来保存可变参数。

2. `va_start`宏`va_start`宏用于初始化`va_list`类型的变量。

它接受两个参数,第一个参数是保存可变参数的`va_list`类型变量,第二个参数是最后一个固定参数的标识符。

cvoid func(int count, ...) {va_list args;va_start(args, count);...在上面的例子中,我们使用了`va_start(args, count)`来初始化`args`变量,并指定`count`作为最后一个固定参数的标识符。

可变参数函数详解

可变参数函数详解

可变参数函数详解可变参数函数⼜称参数个数可变函数(本⽂也简称变参函数),即函数参数数⽬可变。

原型声明格式为:type VarArgFunc(type FixedArg1, type FixedArg2, …);其中,参数可分为两部分:数⽬确定的固定参数和数⽬可变的可选参数。

函数⾄少需要⼀个固定参数,其声明与普通函数参数相同;可选参数由于数⽬不定(0个或以上),声明时⽤"…"表⽰(“…”⽤作参数占位符)。

固定参数和可选参数共同构成可变参数函数的参数列表。

由于参数数⽬不定,使⽤可变参数函数通常能缩短编码,灵活性和易⽤性较⾼。

典型的变参函数如printf(及其家族),其函数原型为:int printf(const char* format, ...);printf函数除参数format固定外,后续参数的数⽬和类型均可变。

实际调⽤时可有以下形式:printf("string");printf("%d", i);printf("%s", s);printf("number is %d, string is:%s", i, s);……1 变参函数实现原理C调⽤约定下可使⽤va_list系列变参宏实现变参函数,此处va意为variable-argument(可变参数)。

典型⽤法如下:#include <stdarg.h>int VarArgFunc(int dwFixedArg, ...){ //以固定参数的地址为起点依次确定各变参的内存起始地址va_list pArgs = NULL; //定义va_list类型的指针pArgs,⽤于存储参数地址va_start(pArgs, dwFixedArg); //初始化pArgs指针,使其指向第⼀个可变参数。

该宏第⼆个参数是变参列表的前⼀个参数,即最后⼀个固定参数int dwVarArg = va_arg(pArgs, int); //该宏返回变参列表中的当前变参值并使pArgs指向列表中的下个变参。

C语言中可变参数函数实现原理浅谈

C语言中可变参数函数实现原理浅谈

C语言中可变参数函数实现原理浅析1、C函数调用的栈结构可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈。

例如,对于函数:void fun(int a, int b, int c){int d;...}其栈结构为0x1ffc-->d0x2000-->a0x2004-->b0x2008-->c对于任何编译器,每个栈单元的大小都是sizeof(int), 而函数的每个参数都至少要占一个栈单元大小,如函数void fun1(char a, int b, double c, short d) 对一个32的系统其栈的结构就是0x1ffc-->a (4字节)(为了字对齐)0x2000-->b (4字节)0x2004-->c (8字节)0x200c-->d (4字节)因此,函数的所有参数是存储在线性连续的栈空间中的,基于这种存储结构,这样就可以从可变参数函数中必须有的第一个普通参数来寻址后续的所有可变参数的类型及其值。

2. C语言通过几个宏来实现变参的寻址根据函数调用的栈结构,标准C语言中,一般在stdarg.h头文件定义了下面的几个宏,用于实现变参的寻址及可变函数的设计,其中有可能不同的商业编译器的发行时实现的具体代码可能不一样,但是原理都是一样的。

//Linux 2.18内核typedef char * va_list;/*Storage alignment properties -- 堆栈按机器字对齐其中acpi_native_int是一个机器字,32位机的定义是:typedef u32 acpi_native_int*/#define _AUPBND (sizeof (acpi_native_int) - 1)#define _ADNBND (sizeof (acpi_native_int) - 1)/* Variable argument list macro definitions -- 变参函数内部实现需要用到的宏*/#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))#define va_end(ap) (void) 0在X86 32位机器中,以上这几个宏的用途主要是:C语言传递参数是与__stdcall相同的,C语言传递参数时是用push指令从右到左将参数逐个压栈,因此C语言里通过栈指针来访问参数。

详解C语言可变参数valist和vsnprintf及printf实现

详解C语言可变参数valist和vsnprintf及printf实现

C语言的变‎长参数在平‎时做开发时‎很少会在自‎己设计的接‎口中用到,但我们最常‎用的接口p‎r intf‎就是使用的‎变长参数接‎口,在感受到p‎r intf‎强大的魅力‎的同时,是否想挖据‎一下到底p‎r intf‎是如何实现‎的呢?这里我们一‎起来挖掘一‎下C语言变‎长参数的奥‎秘。

先考虑这样‎一个问题:如果我们不‎使用C标准‎库(libc)中提供的F‎a cili‎t ies,我们自己是‎否可以实现‎拥有变长参‎数的函数呢‎?我们不妨试‎试。

一步一步进‎入正题,我们先看看‎固定参数列‎表函数,void fixed‎_args‎_func‎(int a, doubl‎e b, char *c){print‎f("a = 0x%p\n", &a);print‎f("b = 0x%p\n", &b);print‎f("c = 0x%p\n", &c);}对于固定参‎数列表的函‎数,每个参数的‎名称、类型都是直‎接可见的,他们的地址‎也都是可以‎直接得到的‎,比如:通过&a我们可以‎得到a的地‎址,并通过函数‎原型声明了‎解到a是i‎n t类型的‎;通过&b我们可以‎得到b的地‎址,并通过函数‎原型声明了‎解到b是d‎o uble‎类型的; 通过&c我们可以‎得到c的地‎址,并通过函数‎原型声明了‎解到c是c‎h ar*类型的。

但是对于变‎长参数的函‎数,我们就没有‎这么顺利了‎。

还好,按照C标准‎的说明,支持变长参‎数的函数在‎原型声明中‎,必须有至少‎一个最左固‎定参数(这一点与传‎统C有区别‎,传统C 允许‎不带任何固‎定参数的纯‎变长参数函‎数),这样我们可‎以得到其中‎固定参数的‎地址,但是依然无‎法从声明中‎得到其他变‎长参数的地‎址,比如:void var_a‎r gs_f‎u nc(const‎char * fmt, ... ){... ...}这里我们只‎能得到fm‎t这固定参‎数的地址,仅从函数原‎型我们是无‎法确定"..."中有几个参‎数、参数都是什‎么类型的,自然也就无‎法确定其位‎置了。

C语言中可变参数函数实现原理

C语言中可变参数函数实现原理

C语⾔中可变参数函数实现原理C函数调⽤的栈结构可变参数函数的实现与函数调⽤的栈结构密切相关,正常情况下C的函数参数⼊栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先⼊栈。

例如,对于函数:void fun(int a, int b, int c){int d;...}其栈结构为0x1ffc-->d0x2000-->a0x2004-->b0x2008-->c对于在32位系统的多数编译器,每个栈单元的⼤⼩都是sizeof(int), ⽽函数的每个参数都⾄少要占⼀个栈单元⼤⼩,如函数 void fun1(char a, int b, double c, short d) 对⼀个32的系统其栈的结构就是0x1ffc-->a (4字节)(为了字对齐)0x2000-->b (4字节)0x2004-->c (8字节)0x200c-->d (4字节)因此,函数的所有参数是存储在线性连续的栈空间中的,基于这种存储结构,这样就可以从可变参数函数中必须有的第⼀个普通参数来寻址后续的所有可变参数的类型及其值。

先看看固定参数列表函数:void fixed_args_func(int a, double b, char *c){printf("a = 0x%p\n", &a);printf("b = 0x%p\n", &b);printf("c = 0x%p\n", &c);}对于固定参数列表的函数,每个参数的名称、类型都是直接可见的,他们的地址也都是可以直接得到的,⽐如:通过&a我们可以得到a的地址,并通过函数原型声明了解到a是int类型的。

但是对于变长参数的函数,我们就没有这么顺利了。

还好,按照C标准的说明,⽀持变长参数的函数在原型声明中,必须有⾄少⼀个最左固定参数(这⼀点与传统C有区别,传统C允许不带任何固定参数的纯变长参数函数),这样我们可以得到其中固定参数的地址,但是依然⽆法从声明中得到其他变长参数的地址,⽐如:void var_args_func(const char * fmt, ...){... ...}这⾥我们只能得到fmt这固定参数的地址,仅从函数原型我们是⽆法确定"..."中有⼏个参数、参数都是什么类型的。

Windows下CC++可变参数宏实现技巧(转)

Windows下CC++可变参数宏实现技巧(转)

Windows下CC++可变参数宏实现技巧(转)在开发过程中,有很多阶段,每个阶段可能会注重不同的重点,我们可能会在不同阶段让程序输出或者打印不同的信息以反应运⾏的情况,所以我们必须分阶段的使得程序输出我们在每个阶段所要关⼼的信息,甚⾄在最后让程序不再输出信息。

这就要⽤到了宏定义!我们知道,在linux下很⽅便的就能实现可变参数宏的定义,⽐如:#define myprint(fmt, a...) printf("%s,%s(),%d:" fmt "/n", __FILE__,__FUNCTION__,__LINE__, ##a)就定义了⾃⼰的输出宏,当不必再输出这些可能是调式,跟踪,断⾔,⽇志...的信息时,可以再定义宏为空:#define myprintf(fmt,a...)这样,重新编译后,这些宏引⽤的地⽅将全部没有语句,从⽽省去这些开销。

但是,在windows下,⼀般我们采⽤的VC6.0,VS2003,VS2005,VS2008(待定)编辑器中⾃带的C/C++编译器并不⽀持变参宏的定义,gcc编译器⽀持,据说最新版本的C99也⽀持。

可以在windows下这样定义宏:#define myprint printf但是,当后期不想再要宏输出了,只能定义 #define myprint为空,在那些有宏调⽤的代码区会留下类似 ("DEBUG:>>%d,%s,%f",idx,"weide001",99.001);这样的语句,它应该会被程序运算⼀次,应该会像函数参数那样被压栈,出栈⼀次,从⽽增加了程序的运⾏开销,不是⼀个上策。

所以,在windows下需要变通⼀下,以下四种⽅式可以作为今后windows下定义可变参宏定义的参考:(1)引⽤系统变参函数:#include <stdarg.h>#ifdef _WIN32#define vsnprinf _vsnprintf#define vsprinf _vsprintf#endifint my_print(const char* file,cosnt char* fun,const char* line,const char *fmt, ...){int t = 0;char out[1024]="";va_list ap;/*Test Env:gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)Result:使⽤vsprintf时:当fmt的长度⼤于1024时出现: 段错误当fmt的长度⼩于1024时出现: 正常使⽤vsnprintf时:当fmt的长度⼤于1024时出现: 多余的字符不保存到out中当fmt的长度⼩于1024时出现: 正常vsnprintf的返回值同snprintf很相似---------------------------------------------------Test Env:Microsoft Windows XP [版本 5.1.2600]Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86Result:使⽤_vsprintf时:当fmt的长度⼤于1024时出现: 段错误当fmt的长度⼩于1024时出现: 正常使⽤_vsnprintf时:当fmt的长度⼤于1024时出现: 多余的字符不保存到out中当fmt的长度⼩于1024时出现: 正常_vsnprintf的返回值同_snprintf很相似*/va_start(ap, fmt);t = vsnprintf(out, 1024, fmt, ap);va_end(ap);printf("%s,%s(),%d: %s/n", file,fun,line,out);return (t);}#define myprint(str) my_print(__FILE__,__FUNCTION__,__LINE__,str)只能输出⼀个字符串参数。

c语言 可变参数传递

c语言 可变参数传递

C语言可变参数传递1. 简介在C语言中,函数的参数通常是固定的,即在函数定义时需要指定参数的个数和类型。

然而,在某些情况下,我们希望能够传递不定数量或不定类型的参数给函数,这就是可变参数传递的概念。

可变参数传递是C语言中的一种特性,它允许函数接受任意数量的参数。

通过使用标准库中的宏和函数,我们可以在C语言中实现可变参数传递。

本文将详细介绍C语言中可变参数传递的原理、使用方法以及常见的应用场景。

2. 可变参数传递的原理C语言中的可变参数传递是通过使用stdarg.h这个标准库头文件来实现的。

该头文件中定义了一些宏和函数,用于处理可变参数。

可变参数传递的原理是基于C语言中的栈帧结构。

栈帧是函数在运行时分配的一块内存区域,用于保存局部变量、函数参数和返回地址等信息。

可变参数传递就是通过在栈帧中存储额外的参数信息来实现的。

在函数定义时,我们需要使用stdarg.h中的宏和函数来声明可变参数的类型和数量。

然后,在函数体内部,我们可以使用这些宏和函数来访问和处理可变参数。

3. 可变参数传递的使用方法要使用可变参数传递,我们需要按照以下步骤进行操作:1.在函数定义中,使用stdarg.h中的宏和函数来声明可变参数的类型和数量。

常用的宏有va_list、va_start、va_arg和va_end。

2.在函数体内部,使用va_list类型的变量来定义一个可变参数列表。

3.使用va_start宏来初始化可变参数列表,将其与函数定义中的最后一个固定参数进行关联。

4.使用va_arg宏来逐个访问可变参数列表中的参数。

5.使用va_end宏来结束可变参数列表的访问。

下面是一个示例代码,演示了可变参数传递的使用方法:#include <stdarg.h>#include <stdio.h>void print_numbers(int count, ...) {va_list args;va_start(args, count);for (int i = 0; i < count; i++) {int num = va_arg(args, int);printf("%d ", num);}va_end(args);}int main() {print_numbers(3, 1, 2, 3);return 0;}在上面的代码中,函数print_numbers接受一个整数参数count和任意数量的整数参数。

c语言 可变数组

c语言 可变数组

c语言可变数组详解在C语言中,可变数组通常指的是使用指针和动态内存分配来创建的数组,这种数组的大小在运行时动态确定。

C语言中没有内置的动态数组类型,但是通过指针和内存管理函数(如`malloc`和`free`)可以实现可变数组的功能。

以下是创建和使用可变数组的基本步骤:1. 动态内存分配:使用`malloc` 函数来为数组分配内存。

`malloc` 接受一个参数,即所需内存的字节数,并返回一个指向分配内存起始地址的指针。

例如:```cint *variableArray;int size = 10;// 分配内存variableArray = (int *)malloc(size * sizeof(int));```这里,`variableArray` 是一个指向整数的指针,`size` 是数组的大小。

2. 使用数组:通过指针访问数组元素。

数组的元素可以像普通数组一样使用,例如:```cfor (int i = 0; i < size; i++) {variableArray[i] = i * 2;}```3. 释放内存:在使用完可变数组后,使用`free` 函数释放内存,防止内存泄漏:```cfree(variableArray);```注意:在释放内存后,将指针设置为`NULL` 可以避免悬挂指针(dangling pointers)。

```cvariableArray = NULL;```完整的例子:```c#include <stdio.h>#include <stdlib.h>int main() {int *variableArray;int size = 10;// 分配内存variableArray = (int *)malloc(size * sizeof(int));// 使用数组for (int i = 0; i < size; i++) {variableArray[i] = i * 2;}// 打印数组元素for (int i = 0; i < size; i++) {printf("%d ", variableArray[i]);}// 释放内存free(variableArray);variableArray = NULL;return 0;}```需要注意的是,使用动态内存分配带来了责任,即在使用完毕后必须手动释放内存,否则可能导致内存泄漏。

PHP函数可变参数

PHP函数可变参数
array_sum() 对数组所有值求和
//得到传入参数平均值 }
在PHP5.6及更新版本中,由...实现;
function avg(...$args) {
print_r($args); //这个参数就是数组 }
func_get_arg() 获取传递给函数的参数列表的某一项
func_get_args() 获取传递给函数的参数列表数组
func_num_args() 获取传递给函数的参数数量
我们举个例子,求参数的平均值
function avg() {
$args = func_get_args(); //得到调用函数时传递过来的所求和 echo array_sum($args);
$argNums = func_num_args(); //取得参数的数量 echo array_sum($args)/$argNums;
得到调用函数时传递过来的所有参数列表args得到传进来参数组成的数组我们给它求和echoarraysumargs
PHP函 数 可 变 参 数
PHP自定义函数中支持可变数量的参数
在PHP 5.5 及更早的版本中,使用函数func_num_args() , func_get_arg() , func_get_args()实现;

java中可变参数的定义

java中可变参数的定义

java中可变参数的定义Java中的可变参数是一种特殊的语法,它允许方法接收数量可变的参数。

可变参数在编程中具有很大的灵活性和实用性,可以简化代码,提高开发效率。

在本文中,我们将详细探讨Java中可变参数的定义,包括其语法、使用方法、注意事项以及示例应用。

一、什么是可变参数?可变参数是Java中的一个特性,允许方法接收数量可变的参数。

通过使用可变参数,方法可以接受不定数量的参数,这些参数统一存储在一个数组中,并且可以像操作数组一样对其进行处理。

在调用方法时,可以传递任意数量的参数,从而使得方法的调用更加灵活和简洁。

二、可变参数的语法在Java中,使用三个连续的省略号(...)来表示可变参数。

可变参数只能作为方法的最后一个参数,并且一个方法只能有一个可变参数。

我们来看一个示例:public void printValues(String... values) {方法体}在上述示例中,printValues方法使用了可变参数。

在方法体中,我们可以像操作数组一样处理values参数,例如遍历数组、获取数组长度等。

三、使用可变参数使用可变参数的最常见操作是在方法内部对参数进行遍历处理。

我们可以使用for-each循环对可变参数进行迭代操作,也可以使用索引访问特定位置的参数值。

以下代码示例演示了如何使用可变参数对参数进行遍历操作:public void printValues(String... values) {for (String value : values) {System.out.println(value);}}在上述示例中,我们使用for-each循环遍历values数组,并使用System.out.println方法打印每个元素的值。

另外,Java还提供了一些方法可以处理可变参数。

例如,我们可以使用Arrays 类的静态方法将可变参数转化为List类型:public void processValues(String... values) {List<String> valueList = Arrays.asList(values);对valueList进行后续操作}在上述示例中,我们使用Arrays.asList方法将values数组转化为List类型的valueList,从而方便后续对参数进行处理。

在Delphi中编写参数个数可变的函数

在Delphi中编写参数个数可变的函数

在Delphi中编写参数个数可变的函数在Delphi中编写参数个数可变的函数变体开发数组参数允许向单个过程或函数传递不同类型表达式的数组。

要定义含有变体开放数组参数的例程,需要指定array of const 作为参数类型。

如,procedure DoSomething(A: array of const);这里声明了一个叫做DoSomething的过程,该过程可以操作不同种类的数组。

array of const结构等价于array of TVarRec。

TVarRec,在单元System中声明,用于表示一个记录,记录中有一个可以保存多种值(整数、布尔、字符、实数、串、指针、类、类引用、接口、变体等)的变体部分。

TVarRec中的VType字段表示数组中每个元素的类型。

一些类型作为指针传递而不传递值;特别是长串,作为指针传递并且必需转换为string类型。

下面的例子在函数中使用了变体开放数组参数,该函数对接受的每个元素创建一个串表示法,最后连接成一个串。

该函数中调用的串处理例程都定义在SysUtils单元中。

function MakeStr(const Args: array of const): string;constBoolChars: array[Boolean] of Char = ('F', 'T');varI: Integer;beginResult := '';for I := 0 to High(Args) dowith Args[I] docase VType ofvtInteger: Result := Result + IntToStr(VInteger); vtBoolean: Result := Result + BoolChars[VBoolean]; vtChar: Result := Result + VChar;vtExtended: Result := Result + FloatT oStr(VExtended^); vtString: Result := Result + VString^;vtPChar: Result := Result + VPChar;vtObject: Result := Result + VObject.ClassName; vtClass: Result := Result + VClass.ClassName;vtAnsiString: Result := Result + string(VAnsiString);vtCurrency: Result := Result + CurrT oStr(VCurrency^);vtVariant: Result := Result + string(VVariant^);vtInt64: Result := Result + IntToStr(VInt64^);end;end;可以用一个开放数组构造器(见开放数组构造器)来调用该函数。

2024新高考浙江版高中信息技术专题二 算法与程序基础知识点归纳讲解PPT

2024新高考浙江版高中信息技术专题二 算法与程序基础知识点归纳讲解PPT

4.变量与赋值 1)变量:在程序运算过程中变量的值可以改变。为了能对变量进行访问 需要对变量进行命名。在Python中,变量名可以由字母、数字、下划线 组成,但不能以数字开头,而且字母区分大小写,同时不能使用保留字。 2)赋值运算符:“=”“-=”“+=”“*=”“/=”“%=”等。 5.字符串、列表和字典 1)字符串 ①字符串用单引号、双引号或三引号表示;②字符串是不可变对象;③通 过索引来访问字符串的字符;④通过切片操作可以获得字符串的一个子 串。
2
3
3
2.关系运算符
运算符 >
<
优先级 4
4
>=
<=
==
!=
in
4
4
4
4
5
3.逻辑运算符
运算符
not
优先级
6
and
or
7
8
注意:数字越大,优先级越低,优先级相等时,按照自左向右的顺序执行。
2)列表 ①用方括号“[]”表示,元素之间用逗号“,”分隔;②由0个或多个元素组 成的序列,其中的元素可以是数字、字符串、其他列表等混合类型的数 据;③列表的大小是可变的,可以根据需要扩大或缩小;④列表中的元素可 通过索引来定位。 3)字典 ①字典可包含多个元素,每个元素包含两部分内容:键和值;②键常用字符 串或数值表示,值可以是任意类型的数据;③键和值两者一一对应,且每个 键只能对应一个值;④字典中的元素是没有顺序的,引用元素时以键为索 引。
例1 下列有关算法的与程序的关系叙述中正确的是 ( ) A.算法是对程序的描述 B.算法决定程序 ,是程序设计的核心 C.算法是唯一的,程序可以多种 D.程序决定算法,是算法设计的核心 解析 程序是对算法的描述;解决一个问题可以有多种算法,一种算法可 以用多种语言编写程序;算法是程序设计的核心。

C++技巧(可变参数详解及Printf实现方法)

C++技巧(可变参数详解及Printf实现方法)

在开发MTK的时候,总习惯⼀直跟踪代码,⼀层⼀层的跳进去看个究竟。

看到dbg_print(char *fmt,...) 这个函数,看了函数体,发现它实现了我从前⼀直疑惑的⼀个问题,Printf的格式化输出是怎么实现的,查了⼀些关于可变参数函数的资料,并把mtk中printf格式化字符串的实现⽅式附上,希望对⼤家有⽤: 1.要在函数中使⽤参数,⾸先要包含头⽂件。

这个头⽂件声明了⼀个va_list类型,定义了四个宏,⽤来遍历可变参数列表。

void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_end(va_list ap); void va_copy(va_list dest, va_list src); 下⾯详细介绍这些宏定义: 2.void va_start(va_list ap, last) va_start必须第⼀个调⽤,它初始化va_list类型的变量ap,使ap指向第⼀个可选参数。

参数 last 是可变参数列表(即函数原型中的省略号…)的前⼀个参数的名字,也就是最后类型已确定的函数参数名。

因为这个参数的地址将会被宏va_start⽤到,所以不要是寄存器变量,函数,或者数组。

对于有可变长参数,但是在可变长参数前没有任何的固定参数的函数,如int func (...)是不允许的。

这是ANSI C所要求的,变参函数在...之前⾄少得有⼀个固定参数。

这个参 数将被传递给va_start(),然后⽤va_arg()和va_end()来确定所有实际调⽤时可变长参数的类型和值。

type va_arg(va_list ap, type) 宏va_arg展开后是关于下⼀个参数的类型和值的表达式,参数type是明确的类型名。

va_arg返回参数列表中的当前参数并使ap指向参数列表中的下⼀个参数。

void va_end(va_list ap) 每次调⽤va_start就必须相应的调⽤va_end销毁变量ap,即将指针ap置为NULL。

如何制作可变数据

如何制作可变数据

如何制作可变数据首先要把委托单上的要求仔细阅读,从整体上把这个订单计划好。

第一步打开模板文件看一下大小,看一下可变区域在哪里,可变数据的类型。

(如图1)图1从图1里面可以看出,文件大小为200*70 mm。

数据类型为三位数,要求从001-500,共500个可变数据。

第二步,因为001这个编号区域是可变的。

我们要做一个不带数据的模板,以用做后期可变数据的背景。

这时要考虑到数量较多,裁切的时候要有出血,所以,模板的文件四周得做2/3 mm 的出血位。

其效果(如图2)因为后期是在pdf里面添加背景的,所以做好的背景模板我们导出为pdf格式(如图3)图 2图 3第三步,我们要利用Excel软件来制作可变的数据源。

制作过程中要注意几点。

其一就是选中第一列,并将第一列的单元格格式设置为“文本”其二就是在输入的第一个数字应该比要求的第一个数字向前一位,这里就应该是“000”。

向下拉,使这一列得到数据从000到500.然后就是另存到指定位置。

但是另存的格式得选“CSV (逗号分隔)”。

如下图所示。

其三使用记事本打开刚刚存好的“CSV (逗号分隔)”格式的Excel 文件。

并将其另存为,并覆盖打开的文件,但是编码要改为UTF-8其效果如下图(注意另存的时候文件名千万不能改成其它,要和原先打开的文件保持一致。

)到此,我们的数据源制作就算是完成了。

第四步,接下来使用Corel Draw 12软件制作可变数据,并将其发布成pdf格式。

首先用CDR12打开带有数据区域的文件,如下图接下来点文件——合并打印——创建/装入合并域(C):如上图所示,单击读取文件的箭头,找到我们存好的数据源文件(即csv格式的文件)打开的时候,文件类型选择*.csv。

单击下一步,选中“合并中使用的域”进行重命名,将前面的三个方框去掉。

(效果就左图到右图的变化)继续单击下一步,下一步,接着点完成,直到出现下面的菜单栏。

接下来就点击最右边的箭头,如下图一样。

可变参数和不可变参数的比较

可变参数和不可变参数的比较

可变参数和不可变参数的⽐较package com.Summer_;import java.util.Arrays;/*** @author Summer* 可变参数和不可变参数⽐较;* 基本上所有⽤数组做参数的⽅法都可以把数组参数替换成可变参数 , 可变参数更强⼤ ;*/public class Test02 {public static void main(String[] args) {//可变参数的影响int [] a={18, 79, 62, 59, 15, 39, 75, 62, 10};int [] a1={18, 79, 62, 59, 15, 39, 75, 62, 10};int [] a2={18, 79, 62, 59, 15, 39, 75, 62, 10};int [] a3={18, 79, 62, 59, 15, 39, 75, 62, 10};arr1(a,a1,a2,a3);arr1(12,12);System.out.println(Arrays.toString(a));arr1(19,1919);}public static void arr1(int its,int b) {System.out.println("不可变参数!!");}//可变参数默认由0或者n多个参数构成但是必须传参类型必须⼀致// 和不可变参数参数列表相同时以不可变参数优先//传递⼀个该类型的数组//不可以传递了1个或多个实参之后再传递给类型数组;//可变参数⽆法重载public static void arr1(int[]...its) {//its[0]=1;//可变参数⽆法重载System.out.println("可变参数!!");}}。

Python-函数参数之必传参数、默认参数、可变参数、关键字参数的详细使用

Python-函数参数之必传参数、默认参数、可变参数、关键字参数的详细使用

Python-函数参数之必传参数、默认参数、可变参数、关键字参数的详细使⽤Python函数参数列表必传参数:平时最常⽤的,必传确定数量的参数默认参数:在调⽤函数时可以传也可以不传,如果不传将使⽤默认值可变参数:可变长度参数关键字参数:长度可变,但是需要以 key-value 形式传参必传参数(位置参数)def add(a, b):return a + bsum = add(1, 2)print(sum)# 输出结果3add 函数有两个参数,第⼀个参数是 a,第⼆个参数是 b传⼊的两个整数按照位置顺序依次赋给函数的参数 a 和 b,参数 a 和参数 b 被称为位置参数传递的参数个数必须等于参数列表的数量根据函数定义的参数位置来传递参数,要求传递的参数与函数定义的参数两者⼀⼀对应如果 “传递的参数个数” 不等于 “函数定义的参数个数”,运⾏时会报错# 错误栗⼦def add(a, b):return a + bsum = add(1, 2, 3)# 输出结果sum = add(1, 2, 3)E TypeError: add() takes 2 positional arguments but 3 were given默认参数使⽤默认参数,可以简化函数的调⽤,尤其是在函数需要被频繁调⽤的情况下# 必传参数a,默认参数bdef test1(a, b=3):print(a, b)test1(0)test1(0, 1)执⾏结果0 30 1Python 字符串 index 函数str.index(sub, start=None, end=None)知识点声明函数时,当同时存在必传参数和默认参数,形参的顺序必须是 (必传参数 , 默认参数),不能默认参数在前可变参数为什么会需要可变参数假设需要⼀个 2 个数的求和函数def add(a, b):return a + badd(1, 2)此时,有需要⼀个 3 个数的求和函数def add3(a, b, c):return a + b + cadd3(1, 2, 3)问题来了那么,如果还需要⼀个 4 个数的求和函数,可以通过上述⽅式再加⼀个函数,但显然很⿇烦所以,可变参数诞⽣了希望只编写⼀个计算求和的函数 add,但函数的参数个数是不确定的,这样就可以复⽤了可变参数的表⽰⽅式def函数(*args):函数体该函数被设定为能够接受可变数量的参数args 的类型是元组调⽤该函数时,所有的参数被合并成⼀个元组合并后的元组被赋值给 args,通过遍历 args 可以访问传递的参数求和的可变参数函数栗⼦# 累加的可变参数函数def add(*args):print(args)sum = 0for arg in args:sum += argprint('len = %d, sum = %d' % (len(args), sum))add(1)add(1, 2)add(1, 2, 3)# 输出结果(1,)len = 1, sum = 1(1, 2)len = 2, sum = 3(1, 2, 3)len = 3, sum = 6混合栗⼦def test2(num, num2=2, *args):print(num, num2, args)test2(1)test2(1, 3)执⾏结果知识点args 是⼀个元组类型可变参数可不传,也可以传很多个值,在元组or 列表前⾯加⼀个 ,代表将⾥⾯的每个元素独⽴出来,单独作为⼀个形参传进去,也称为元组解包不懂*(1,2,3)可以看看这段代码注意点⼀可变参数之前的参数不能指定参数名必传参数跟在关键字参数后⾯是不允许的注意点⼆函数传⼊实参时,可变参数(*)之后的参数必须指定参数名,否则就会被归到可变参数之中c 输出了 None ,没有拿到参数值test2(1, 3, 3, 3, 3, 3, 3)test2(1, *(2, 3, 4, 5))test2(1, *[2, 3, 4, 5])1 2 ()1 3 ()1 3 (3, 3, 3, 3, 3)1 2 (3, 4, 5)1 2 (3, 4, 5)*(2, 3, 4, 5)*print (*(1, 2, 3, 4))# 输出1 2 3 4# 可变参数def myfun(a, *b):print (a)print (b)myfun(a =1, 2, 3, 4)# 输出结果myfun(a=1, 2, 3, 4)^SyntaxError: positional argument follows keyword argument# 可变参数def myfun(a, *b, c=None):print (a)print (b)print (c)myfun(1, 2, 3, 4)# 输出结果1(2, 3, 4)None关键字传参解决这个问题# 可变参数def myfun(a, *b, c=None):print(a)print(b)print(c)myfun(1, 2, 3, c=4)# 输出结果1(2, 3)4关键字参数什么是关键字参数Python 允许调⽤函数时,以 “参数名 = 参数值” 的形式传递参数def add(a, b):return a + badd(a = 1, b = 2)"参数名 = 参数值" 形式的参数,例如 a = 1 和 b = 2,被称为关键字参数包含关键字参数的函数语法格式在参数前加上符号 ** 参数表⽰函数可以接收关键字参数def函数(**kwargs):函数体该函数被设定为能够接受关键字参数kwargs 的类型是字典调⽤该函数时,所有的关键字参数被合并成⼀个字典合并后的字典被赋值给 kwargs,通过访问 kwargs 可以访问参数名和参数值关键字参数栗⼦# 关键字参数函数栗⼦def create_full_name(**kwargs):# 打印就是⼀个字典print(kwargs)name = kwargs.get("name")password = kwargs.get("password")if name and password:print("name is :", name, " and password is :", password)if name and not password:print("only name is:", name)# ⽅式⼀:通过 key=value 的⽅式传参create_full_name(name="⼩菠萝", password="123456")dict_ = {"name": "yy"}# ⽅式⼆:传字典,然后加 ** 进⾏解包create_full_name(**dict_)混合栗⼦执⾏结果知识点kwargs 是⼀个字典类型关键字参数可传可不传传值的时候需要传键值对,如果要传dict需要在前⾯加上 ,表⽰将这个dict 的所有key-value 当成独⽴的关键字参数(变成 key = value )传⼊到 kwargs ,⽽修改 kwargs 不会影响原来的 dict不⽤ dict 的话也可以直接 的写法,如果和默认参数重名,若前⾯没有传值的话,会当成默认参数传值;若有的话会直接报错声明函数时,默认参数不可以放在关键字参数后⾯**dict ,也叫字典解包Python 库某个关键字函数栗⼦这是 ⽅法的最终调⽤函数,可以看到除了method、url是必传参数,还能通过 kwargs 传很多个参数# 输出结果{'name': '⼩菠萝', 'password': '123456'}name is : ⼩菠萝 and password is : 123456{'name': 'yy'}only name is : yydef test3(a, b=2, **kwargs):print (a, b, kwargs)test3(1)test3(1, 3)test3(1, **{"key": "value"})test3(1, 3, **{"key": "value", "key1": "val", "key2": 'val2'})test3(1, name="yy", key="value")test3(1, 3, name="yy", key="value")test3(1, name="yy", key="value",b=222222)# test3(1, 22222,name="yy", key="value",b=222222) 会报错,因为第⼆个值已经传给默认参数b 了1 2 {}1 3 {}1 2 {'key': 'value'}1 3 {'key': 'value', 'key1': 'val', 'key2': 'val2'}1 2 {'name': 'yy', 'key': 'value'}1 3 {'name': 'yy', 'key': 'value'}1 222222 {'name': 'yy', 'key': 'value'}**key=value requests.get()四种参数类型都有的函数def test4(a, b=2, *args, **kwargs):print(a, b, args, kwargs)test4(1)test4(1, 1)test4(1, *(1, 2, 3, 3, 4,))test4(1, *(1, 2, 3, 3, 4,), cc=123, c=123) lists = ["a", "b"]dicts = {"key": 123}test4(1, *lists, **dicts)执⾏结果1 2 () {}1 1 () {}1 1 (2, 3, 3, 4) {}1 1 (2, 3, 3, 4) {'cc': 123, 'c': 123}1 a ('b',) {'key': 123}拓展:Python 解包详解。

Python求可变参数的最大值最小值以及参数个数

Python求可变参数的最大值最小值以及参数个数

Python求可变参数的最⼤值最⼩值以及参数个数求可变参数的最⼤值最⼩值以及参数个数简介: ⾸先要做这个题,我们要使⽤函数来解决,这就要求我们要掌握函数的定义以及函数的调⽤。

函数是⼀段具有特定功能的、可重⽤的,⽤来实现单⼀,或相关联功能的代码段。

⽤函数名来表⽰并通过函数名进⾏功能调⽤。

函数能提⾼应⽤的模块性,和代码的重复利⽤率。

,⽐如print()就是Python中的内建函数。

我们也可以⾃⼰创建函数,这被叫做⽤户⾃定义函数。

你可以定义⼀个由⾃⼰想要功能的函数,以下是简单的规则:函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。

任何传⼊参数和⾃变量必须放在圆括号中间。

圆括号之间可以⽤于定义参数。

函数的第⼀⾏语句可以选择性地使⽤⽂档字符串—⽤于存放函数说明。

函数内容以冒号起始,并且缩进。

return [表达式] 结束函数,选择性地返回⼀个值给调⽤⽅。

不带表达式的return相当于返回 None。

函数调⽤: 定义⼀个函数只给了函数⼀个名称,指定了函数⾥包含的参数,和代码块结构。

这个函数的基本结构完成以后,你可以通过另⼀个函数调⽤执⾏,也可以直接从Python提⽰符执⾏。

例题:1、⽐较参数的最⼤值最⼩值以及参数个数def max(*a):#定义函数,max是函数名,括号内部为函数的参数m = a[0]for x in a:if x>m:m = x #m为最⼤值return mdef min(*a): #定义函数,min是函数名,括号内部为函数的参数m = a[0]for x in a:if x<m:m = x #m为最⼩值return mdef num(*a): #定义函数,num是函数名,括号内部为函数的参数m = len(a) #m是参数个数,Python len() ⽅法返回对象(字符、列表、元组等)长度或项⽬个数.return mif__name__ == '__main__':x,y,z = 1,10,20print("max:",max(x,y,z))print("min:",min(x,y,z))print("num:",num(x,y,z))2、⽤input输⼊参数并且参数间⽤空格隔开,求参数的最⼤值最⼩值以及参数个数if__name__ == '__main__':x = input("请输⼊数字,并⽤空格隔开:").split() #Python split() 通过指定分隔符对字符串进⾏切⽚lst = []for i in x:lst.append(int (i)) #append() ⽅法⽤于在列表末尾添加新的对象。

python函数的可变数量的参数

python函数的可变数量的参数

python函数的可变数量的参数在Python中,函数可以接受不定数量的参数,这称为可变数量的参数。

可变数量的参数允许用户向函数传递任意数量的参数值,从而增加了函数的灵活性和适用性。

要在函数中定义可变数量的参数,需要在参数前面添加一个星号(*)。

这个星号告诉解释器将传递给函数的所有参数作为一个元组进行处理。

下面是一个示例代码,说明了如何定义和使用可变数量的参数:```pythondef sum_numbers(*numbers):total = 0for number in numbers:total += numberreturn totalresult = sum_numbers(1, 2, 3, 4, 5)print(result) # 输出结果为15```在上面的代码中,我们定义了一个名为`sum_numbers`的函数,并在参数前面添加了一个星号。

这意味着我们可以将多个参数传递给这个函数。

在函数体内部,我们使用了一个循环来遍历传递给函数的参数元组,并将它们相加。

最后,我们返回总和。

通过调用`sum_numbers`函数并传递一系列数字作为参数,我们得到了它们的总和。

在上面的示例中,我们传递了1、2、3、4和5这五个数字,函数计算并返回它们的总和(即15)。

这种可变数量的参数的特性非常适用于处理不定数量的元素。

它允许我们编写更加通用和灵活的函数,能够适应各种输入情况。

总结起来,Python的可变数量的参数允许函数接受不定数量的参数值,使用起来非常方便。

我们只需要在函数的参数前面加上一个星号即可。

通过这种方式,我们可以处理不同数量的参数,从而增加了函数的灵活性和可用性。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一步一步写算法(之可变参数)
【声明:版权所有,欢迎转载,请勿用于商业用途。

联系信箱:feixiaoxing @】
可变参数是C语言编程的一个特色。

在我们一般编程中,函数的参数个数都是确定的,事先定下来的。

然而就有那么一部分函数,它的个数是不确定的,长度也不一定,这中间有什么秘密吗?
其实,我们可以回忆一下哪些函数是可变参数的函数?其实也就是sprintf、printf这样的函数而已。

那么这些函数有什么规律吗?关键就是在这个字符串上面。

我们可以举一个例子看看,
[cpp]view plaincopy
test函数里面也就是一个简单的打印函数。

那么这个函数有什么特别的地方呢,那就是%s、%d和后面的字符是一一对应的,所以有多少个这样的字符,首参数后面就会剩下多少个参数。

那么后面参数的地址怎么获取呢?我们可以回想一下,堆栈一般是怎么压栈处理的,
[cpp]view plaincopy
因为参数是按照从右向左依次压入的,所以后面参数的地址依次根据“%”处理即可。

下面我们就可以自己写一个PrintInt打印int数据的函数,首先创建一个框架,
[cpp]view plaincopy
然后验证buffer参数中是否有%d,如果存在这样的一个字符,就需要打印一个整数,
[cpp]view plaincopy
为了验证我们的函数是否正确,可以编写测试函数验证一下,[cpp]view plaincopy。

相关文档
最新文档