捕获变量传递给没有参数的函数

时间:2013-10-30 08:52:54

标签: c

我不知道是否可能,但维基百科上的文章Compatibility of C and C++说明如下:

  

在C中,没有参数的函数原型,例如int foo();,   意味着参数未指定。因此,这是合法的   用一个或多个参数调用这样的函数,例如foo(42, "hello world")

     

相比之下,在C ++中没有参数的函数原型   意味着该函数不带参数,并调用这样的   带参数的函数是不正确的。

     

在C中,正确的方法   声明一个不带参数的函数是使用void,如   int foo(void);

我做了以下代码来测试它并捕获传递的变量(这不能正常工作)

#include<stdio.h>
#include<stdarg.h>

void foo();

int main()
{
    int i = 3;
    foo(i);
    return 0;
}

void foo()
{
//    va_list args;
//    va_start(args);
//
//    int x = va_arg (args, int);
//    printf("%d", x);
//    va_end(args);
}

是否有可能抓住传递的i或维基百科谈论完全不同的东西?

5 个答案:

答案 0 :(得分:5)

你不能,至少不是标准C.维基百科的文章意味着什么是这段代码:

void foo();

int main()
{
    int i = 3;
    foo(i);
    return 0;
}

void foo(int i)
{
    (void)i;
}

在C中编译很好,但在C ++中它是无效的,因为参数的数量不匹配。

答案 1 :(得分:4)

如果您阅读va_start的文档,您将看到它需要参数列表中的最后一个“真实”参数。因此,如果你没有声明任何参数,那么在普通的C中就不可能获得参数。

可以做的是在没有参数的情况下声明函数原型,并在实际定义中包含参数。

答案 2 :(得分:2)

这来自旧的C日,当时语言的严格性很好......,放松了。

基本思想是,如果您在翻译单元中有一个功能,请说foo.c

float foo(int x) 
{
     return 2.0F * x;
}

然后你想在另一个翻译单元中使用它,比如说main.c,但是你不想费心写一个头文件,你可以这样做:

int main()
{
    float foo();
    float r;
    r = foo(42);
}

并且您不必编写函数的参数。公平地说,你根本不必编写原型,但编译器会认为函数总是返回int,这可能不是你需要的。

然后,随着语言的成熟,这种函数声明被认为是一个非常糟糕的主意,所以一般来说你不应该(尝试)使用它。如果你想要一个可变参数函数,那么一定要使用它,但是如此声明它。而且你必须至少给它一个真实的论点,把呼叫锚定到va_start()

答案 3 :(得分:0)

您可以使用任何参数调用该函数,但不能在函数范围内访问它们。无论如何,如果你没有将原型声明为int foo (void);,一些编译器会给你警告,因为你可能不想这样做。

答案 4 :(得分:0)

有一种方法可以在C程序中访问这些参数,但我认为这是一个很大的黑客,应该避免。

下一个示例显示了如何访问int参数:

#include<stdio.h>
#include<stdarg.h>

void foo();

int main()
{
    int i = 3;
    foo(i);
    return 0;
}

void foo(int p)
{
    printf("%d",p);
}

现在,我不确定如果您传递其他内容然后传递int(例如char *)会发生什么,但它可能会导致未定义的行为。

在c ++中(如上所述),你不能将参数传递给不带参数的函数。