variable-length argument lists

本文深入探讨了C语言中变量参数列表的功能与实现机制,重点介绍了如何使用标准头文件`<stdarg.h>`中的宏定义来遍历未知数量和类型的参数列表,并提供了一个简化版的`printf()`函数实现作为示例。

The best example of variable-length argument lists function is printf()

the proper declaration for printf() is 

                                                             int printf(char * format,...)

where the declaration ... means that the number and types of these arguments may vary.the declaration ... can only appear at the end of an argument list, ourmainprintfis declared as

                      int minprintf(char * fmt,...)

since we will not return the character count the the printf does.

      the tricky bit is how  minprintf  walks along the argument list when the list doesn't even have a name. the standard header<stdarg.h> contains a set of macro definitions that define how to step through an argument list.the implementation of this header will vary from machine to machine,but the interface it presents is uniform.

      the type va_list is used to declare a variable that will refer to each argument in turn; in minprintf ,this variable is call ap.for "argument pointer" the macro va_start initialize ap to point to the first unnamed argument.it must be called once beforeapis used.there must be at least one named argument;the final argument is used by va_start to get started.each call ofva_argreturns one argument and steps ap to the next; va_arg uses a type name to determine what type to return and how big a step to take.finally ,va_end does whatever cleanup is necessary.it must be called before the function returns.

    the properties form the basis of our simplified printf:

     

[code=C/C++]
#include<stdarg.h>
void minprintf(char * fmt,...) 
{ 
    va_list ap; char * p,*sval;
    int ival; double dval; 
    va_start(ap,fmt);//make ap point to first unnamed arg
    for(p=fmt;*p;p++) 
    {
	 if(*p != '%') 
	 {
		 putchar(*p);
		 continue;
	 }
	 switch(*++p) 
	 { 
		case 'd':
			 ival = va_arg(ap,int);
			 printf("%d",ival);
			 break;
		 case 'f': 
			 dval = va_arg(ap,double);
			 printf("%f",dval); 
			 break;
		 case 's':
			 for(sval = va_arg(ap,char *);*sval;sval++)
			 {
				 putchar(*sval);
			 }
			 break; 
		 default: 
			 putchar(*p); 
			 break; 
	 } 
    }
    va_end(ap);//clean up when done
 }
[/code]



Main.java:7: error: no suitable method found for println(String,double,double) System.out.println("%.2f %.2f",square.getPerimeter(),square.getArea()); ^ method PrintStream.println() is not applicable (actual and formal argument lists differ in length) method PrintStream.println(boolean) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(char) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(int) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(long) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(float) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(double) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(char[]) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(String) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(Object) is not applicable (actual and formal argument lists differ in length) Main.java:11: error: no suitable method found for println(String,double,double) System.out.println("%.2f %.2f",rec.getPerimeter(),rec.getArea()); ^ method PrintStream.println() is not applicable (actual and formal argument lists differ in length) method PrintStream.println(boolean) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(char) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(int) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(long) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(float) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(double) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(char[]) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(String) is not applicable (actual and formal argument lists differ in length) method PrintStream.println(Object) is not applicable (actual and formal argument lists differ in length) Main.java:14: error: cannot find symbol System.out.println("%.2f %.2f",circle.getPerimeter(),circle.getArea()); ^ symbol: variable circle location: class Main Main.java:14: error: cannot find symbol System.out.println("%.2f %.2f",circle.getPerimeter(),circle.getArea()); ^ symbol: variable circle location: class Main Main.java:19: error: cannot find symbol return perimeter; ^ symbol: variable perimeter location: class Shape Main.java:22: error: cannot find symbol return area; ^ symbol: variable area location: class Shape Main.java:57: error: cannot find symbol return radic*2*(Math.Pi); ^ symbol: variable Pi location: class Math Main.java:60: error: cannot find symbol return radic*radic*(Math.Pi); ^ symbol: variable Pi location: class Math 8 errors
06-12
180 warnings generated. [ 0% 10/1154] target Java: framework (out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes) FAILED: /bin/bash out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes-full-debug.jar.rsp frameworks/base/core/java/android/content/pm/PackageParser.java:3077: error: cannot find symbol if ("com.dangbei.launcher".equals(pkg.packageName)) { ^ symbol: variable pkg location: class PackageParser frameworks/base/core/java/android/content/pm/PackageParser.java:3078: error: cannot find symbol for (Activity a : pkg.activities) { ^ symbol: variable pkg location: class PackageParser frameworks/base/core/java/android/content/pm/PackageParser.java:3080: error: no suitable constructor found for IntentFilter(String,String,String) a.intents.add(new IntentFilter( ^ constructor IntentFilter.IntentFilter() is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(String) is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(String,String) is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(IntentFilter) is not applicable (actual and formal argument lists differ in length) constructor IntentFilter.IntentFilter(Parcel) is not applicable (actual and formal argument lists differ in length) Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 3 errors ninja: build stopped: subcommand failed. build/core/ninja.mk:148: recipe for target 'ninja_wrapper' failed make: *** [ninja_wrapper] Error 1 #### make failed to build some targets (43 seconds) ####
07-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值