【问题标题】:Call function with arguments without parenthesis in C?在C中使用不带括号的参数调用函数?
【发布时间】:2013-08-20 01:37:10
【问题描述】:

当函数没有任何参数时,可以通过define as 不带括号调用它

#define test test()

是否可以调用带有参数而不带括号的函数?类似的东西

#define test test(char *arg)

test "argument 1";

【问题讨论】:

  • 你为什么要这样做?
  • 函数优先级的规则是:foo x + bar y foo(x) + bar(y) 还是 foo(x + bar(y))?无论哪种方式,我都 99% 确定在纯 C 语言中无法做到这一点。
  • 可能不在 C 中,但在 C++ 中可以将test 定义为std::stringstream() << ,其中紧随其后的字符串参数将被发送到其operator <<
  • 用 C 开发高级语言和试图将 C 变成高级语言之间有很大的不同。伪装的 C 仍然是具有所有缺陷的 C,并且重新排列函数调用构造以模仿其他语言使用的样式不会改变这一点。如果您需要高级语言,请使用高级语言。
  • C + 预处理器宏!= 一种高级语言。它是低级系统语言和低级文本处理语言的结合,具有两者的所有问题。

标签: c function


【解决方案1】:

这在 C 语言中是不可能的。标准(C99)的第 6.5.2 节描述了后缀表达式,并且没有类似的语法。函数调用是(§6.5.2.2):

后缀表达式后跟括号 () 包含可能为空的逗号分隔的表达式列表是一个函数调用。后缀表达式表示被调用的函数。表达式列表指定函数的参数。

括号不是可选的,它们需要包装所有参数,因此您需要一个类似函数的宏(在“调用”站点需要括号)或两个单独的东西(一个用于插入起始括号,一个用于插入结束语)。

你可以这样做:

#define test puts(
#define end  );
#define int_proc int
#define proc_body {
#define proc_end  }
#define no_args (void)
#include <stdio.h>

int_proc main no_args
proc_body
  test "hello" end
proc_end

但是……真的吗?

C++ 提供了更多的可能性,特别是运算符重载。如果你想“自定义”一些语法,你可能想研究一下。

这是一个可怕的例子:

#include <iostream>

struct Foo {
    void operator=(char const* str)
    {
        std::cout << str << std::endl;
    }
};
Foo global_foo;

#define test global_foo =

int main()
{
    test "hello";
}

请注意,您可能会发现一些合理的方法很有吸引力,例如Qt 的qDebug 实用程序类。从示意图上看,它是这样的:

#include <iostream>

struct debug {
    debug() {}
    ~debug()
    {
        std::cout << std::endl;
    }
    debug const& operator<<(char const* msg) const
    {
        std::cout << msg << " ";
        return *this;
    }
};

通常的使用方式是:

debug() << "this" << "works";

如果你添加一个接受char const*的构造函数:

debug(char const*msg)
{
    std::cout << msg << " ";
}

然后你可以使用强制转换符号并写:

(debug) "Hello";

这与您所拥有的非常接近(并且是可宏化的)。

然后您可以对所有其他运算符感兴趣(operator, 将是主要候选者),但优先规则可能会有点破坏乐趣。

【讨论】:

  • +1:在旁观者的眼中是可怕的。见googletestASSERT_EQ(expected, actual) &lt;&lt; "message to show if fails";
  • @rwong:该语句至少类似于有效的 C++ 语句。 test "hello"; 没有,因此任何使其合法的东西都是可怕的。 googletest 所做的不是恕我直言。
猜你喜欢
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
相关资源
最近更新 更多