VA_FIRST
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgVaFirst
- 最后更新: 2019-03-10
返回指向可变参数列表中第一个参数的指针
语法
pointer_variable = va_first()描述
va_first 函数提供一个无类型指针值,该值指向传递给函数的第一个可变参数。
使用 -gen gcc 时不支持此功能。使用 cva_list 可变参数列表类型以实现跨平台兼容性。
示例
start GeSHi
vb
Function average CDecl(count As Integer, ... ) As Double
Dim arg As Any Ptr
Dim sum As Double = 0
Dim i As Integer
arg = va_first()
For i = 1 To count
sum += va_arg(arg, Double)
arg = va_next(arg, Double)
Next
Return sum / count
End Function
Print average(4, 3.4,5.0,3.2,4.1) '' 所有传入的可变参数必须为 double 类型
Print average(2, 65.2,454.65481) '' 所有传入的可变参数必须为 double 类型
Sleepend GeSHi
输出结果如下:
3.925
259.927405start GeSHi
vb
'' 简单自定义 printf 示例
Sub myprintf CDecl(ByRef formatstring As String, ...)
'' 获取指向第一个可变参数的指针
Dim As Any Ptr arg = va_first()
'' 遍历格式字符串中的每个字符...
Dim As UByte Ptr p = StrPtr(formatstring)
Dim As Integer todo = Len(formatstring)
While (todo > 0)
Dim As Integer char = *p
p += 1
todo -= 1
'' 是格式字符吗?
If (char = Asc("%")) Then
If (todo = 0) Then
'' % 位于末尾
Print "%";
Exit While
End If
'' 下一个字符应告知类型
char = *p
p += 1
todo -= 1
'' 根据类型打印可变参数
Select Case char
'' 整数?
Case Asc("i")
Print Str(va_arg(arg, Integer));
'' 注意,与 C 不同:必须使用 va_next(),
'' 因为 va_arg() 不会更新指针。
arg = va_next(arg, Integer)
'' 长整数?(64 位)
Case Asc("l")
Print Str(va_arg(arg, LongInt));
arg = va_next(arg, LongInt)
'' 单精度或双精度?
'' 注意:由于 C ABI,所有通过可变参数传递的单精度值都会被转换为双精度。
Case Asc( "f" ), Asc( "d" )
Print Str(va_arg(arg, Double));
arg = va_next(arg, Double)
'' 字符串?
Case Asc("s")
'' 字符串按值传递,因此长度未知
Print *va_arg(arg, ZString Ptr);
arg = va_next(arg, ZString Ptr)
End Select
'' 普通字符,直接打印
Else
Print Chr( char );
End If
Wend
End Sub
Dim As String s = "bar"
myprintf(!"integer=%i, longint=%l single=%f, double=%d, string=%s, string=%s\n", _
1, 1ll Shl 32, 2.2, 3.3, "foo", s)
Sleepend GeSHi
方言差异
- 在 -lang qb 方言中不可用,除非使用别名
__Va_first引用。
与 QB 的区别
- FreeBASIC 新增
参见
- ... (Ellipsis)
va_argva_next
返回 目录