在这里,我找到了如何在C中使用varargs的示例.
#include <stdarg.h>
double average(int count, ...)
{
va_list ap;
int j;
double tot = 0;
va_start(ap, count); //Requires the last fixed parameter (to get the address)
for(j=0; j<count; j++)
tot+=va_arg(ap, double); //Requires the type to cast to. Increments ap to the next argument.
va_end(ap);
return tot/count;
}
Run Code Online (Sandbox Code Playgroud)
我只能在某种程度上理解这个例子.
我不清楚为什么使用它们va_start(ap, count);.据我所知,通过这种方式我们将迭代器设置为它的第一个元素.但是为什么默认情况下它没有设置到开头?
我不清楚为什么我们需要count作为一个论点.C不能自动确定参数的数量?
我不清楚为什么使用它们va_end(ap).它有什么变化?它是否将迭代器设置为列表的末尾?但它是不是通过循环设置到列表的末尾?而且,为什么我们需要它呢?我们不再使用ap了; 我们为什么要改变它?
请考虑以下代码:
public class Converter {
public <K> MyContainer<K> pack(K key, String[] values) {
return new MyContainer<>(key);
}
public MyContainer<IntWrapper> pack(int key, String[] values) {
return new MyContainer<>(new IntWrapper(key));
}
public static final class MyContainer<T> {
public MyContainer(T object) { }
}
public static final class IntWrapper {
public IntWrapper(int i) { }
}
public static void main(String[] args) {
Converter converter = new Converter();
MyContainer<IntWrapper> test = converter.pack(1, new String[]{"Test", "Test2"});
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码编译没有问题.但是,如果一个人改变String[],以String...在两个pack签名和 …
如何在Rust中创建具有可变数量参数的函数?
像这个Java代码:
void foo(String... args) {
for (String arg : args) {
System.out.println(arg);
}
}
Run Code Online (Sandbox Code Playgroud) 我想用泛型和varargs实现一个函数.
public class Question {
public static <A> void doNastyThingsToClasses(Class<A> parent, Class<? extends A>... classes) {
/*** something here ***/
}
public static class NotQuestion {
}
public static class SomeQuestion extends Question {
}
public static void main(String[] args) {
doNastyThingsToClasses(Object.class, Question.class, SomeQuestion.class); // OK
doNastyThingsToClasses(Question.class, SomeQuestion.class); // OK
doNastyThingsToClasses(Question.class, Object.class, SomeQuestion.class); // compilation failure
}
}
Run Code Online (Sandbox Code Playgroud)
这里的目的是断言传递给该函数的所有参数都是Class对象,扩展了作为第一个参数给出的Class.因此,main方法的两个第一行将编译,第三行将生成错误.
我的问题是:为什么我得到"类型安全:为varargs参数创建类的通用数组"消息前两行?
我在这里错过了什么吗?
附加问题:如何重新设计它以防止在每行调用"doNastyThingsToClasses"函数时显示此警告?我可以将其更改为"doNastyThingsToClasses(Class <A> parent,Class <?> ... classes)"并删除警告,但这也会删除编译时类型检查 - 如果我想要的话,那就太好了确保正确使用此功能.更好的解决方案?
我有一个带有varargs模板参数的模板函数,就像这样
template<typename Args...>
void ascendingPrint(Args... args) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
我想写
template<typename Args...>
void descendingPrint(Args... args) {
/* implementation using ascendingPrint()? */
}
Run Code Online (Sandbox Code Playgroud)
如何在传递参数包之前反转参数包 的顺序args,即在伪代码中:
template<typename Args...>
void descendingPrint(Args... args) {
ascendingPrint( reverse(args) );
}
Run Code Online (Sandbox Code Playgroud) 我想在Objective-C中编写一个函数,例如下面的函数,它接受可变数量的参数,并将这些参数传递给+stringWithFormat:.我知道vsnprintf,但这意味着将NSString'格式'转换为C并返回(并且还意味着转换其中的格式化占位符......).
下面的代码编译,但当然不按我想要的行为:)
NSString *estr(NSString *format, ...) {
va_list args;
va_start(args, format);
NSString *s = [NSString stringWithFormat:format, args];
va_end(args);
return s;
}
Run Code Online (Sandbox Code Playgroud)
基本上:是否有方法的va_list友好版本+stringWithFormat:,还是可以写一个?
如何在C++中的函数中包含可变数量的参数.
C#中的模拟:
public void Foo(params int[] a) {
for (int i = 0; i < a.Length; i++)
Console.WriteLine(a[i]);
}
public void UseFoo() {
Foo();
Foo(1);
Foo(1, 2);
}
Run Code Online (Sandbox Code Playgroud)
Java中的模拟:
public void Foo(int... a) {
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public void UseFoo() {
Foo();
Foo(1);
Foo(2);
}
Run Code Online (Sandbox Code Playgroud) 根据C标准(6.5.2.2第6段)
如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有float类型的参数提升为double.这些被称为默认参数促销.如果参数的数量不等于参数的数量,则行为未定义.如果函数是使用包含原型的类型定义的,并且原型以省略号(,...)结尾,或者促销后的参数类型与参数类型不兼容,则行为未定义.如果函数是使用不包含原型的类型定义的,并且促销后的参数类型与促销后的参数类型不兼容,则行为未定义,但以下情况除外:
- 一个提升类型是有符号整数类型,另一个提升类型是相应的无符号整数类型,并且该值可在两种类型中表示;
- 这两种类型都是指向字符类型或空格的限定或不合格版本的指针.
因此,一般来说,只要传递的值适合两种类型,传递int到需要unsigned int(或反之亦然)的可变函数是没有错的.但是,printf读取规范(7.19.6.1第9段):
如果转换规范无效,则行为未定义.如果任何参数不是相应转换规范的正确类型,则行为未定义.
签名/未签名不匹配也不例外.
这是否意味着printf("%x", 1)调用未定义的行为?
小例子:
function varargout = wrapper(varargin)
varargout = someFunction(varargin);
Run Code Online (Sandbox Code Playgroud)
这就是我先做的事情.但是,例如,如果someFunction = ndgrid这产生了未定义的单元格数组错误,那么下一次尝试就是使用了someFunction(varargin{:}).这是一个成功的通话,但是通话[a,b] = wrapper([1,2], [3,4])不会产生与直接通话相同的结果ndgrid,所以我做错了什么?
我有一个方法,应该接受最多2个参数.它的代码是这样的:
def method (*args)
if args.length < 3 then
puts args.collect
else
puts "Enter correct number of arguments"
end
end
Run Code Online (Sandbox Code Playgroud)
是否有更优雅的方式来指定它?