【问题标题】:I do not understand the behaviour of #define macro in C++我不明白 C++ 中#define 宏的行为
【发布时间】:2017-10-31 23:53:33
【问题描述】:

我需要了解这段代码是如何工作的:

#define foo1( a ) (a * a)              // How does this work?
inline int foo2( int a ) { return (a * a); }
int goo1( int x ) { return foo1(foo2(x)); }
int goo2( int& x ) { return x = foo2(foo1(x)); }
int goo3( int& x, int y ) { return foo2(foo1(y + 1)); }
void goo4( int& x, int y ) { x = foo1(foo2(y + 1)); }

int main(){
int i = 2, j = 1, a = 2+3;

cout << "foo1 = " << foo1( 1+2 ) << "\n";  // How does this work?
cout << "foo2 = " << foo2( 2 + 1 ) << "\n";
cout << "goo1 = " << goo1( i ) << "\n";
cout << "goo2 = " << goo2( j ) << "\n";
cout << "goo3 = " << goo3( i, j ) << "\n";  // How does this work?
goo4( i, j );
cout << " i = " << i << " j = " << j << "\n";
}

但我似乎无法理解这个函数的行为:

#define foo1( a ) (a * a)

因此我不明白这两个函数调用的输出:

foo1( 1+2 )
goo3( i, j )

这是程序的输出:

foo1 = 5
foo2 = 9
goo1 = 16
goo2 = 1
goo3 = 9
 i = 16 j = 1

我不明白为什么 foo1 的行为不像 foo2。有人会向我解释这个#define 宏是如何工作的吗?

注意:我不能更改代码,我只是想了解输出。

【问题讨论】:

  • 这就是为什么你使用内联函数而不是#defines
  • 如果必须使用定义,请尝试#define foo1( a ) ((a) *( a))
  • #define foo1(a) ((a) * (a))。在您了解 C 并学会不使用宏之前,您还没有使用过宏。
  • 当我只用一个 int 调用它时,我得到了预期的输出,例如 foo(5) 会给我 25,也就是 5 * 5。但是为什么 foo1(1+2 ) 不是 9(即 3*3)?
  • 我得到了这段代码,我只需要了解输出,所以我无法更改它。 @pm100

标签: c++ macros constants


【解决方案1】:

嗯,真的很简单。

foo1( 1 + 2 )

会变成:

( 1 + 2 * 1 + 2 )

实际上是:

1 + 2 + 2 = 5

这就是宏的工作原理。

【讨论】:

    【解决方案2】:

    宏不是函数。

    宏做 TEXT 替换。所以当你有

    #define foo1( a )   (a * a)
    

    foo1( ... ) 的任何实例以及括号之间的任何内容都将扩展为文本,而不是表达式。因此,当您拥有foo1( 1 + 2 ) 时,它会变成( 1 + 2 * 1 + 2 )

    【讨论】:

    • 嗯,非常感谢!这比我想象的要容易得多。
    【解决方案3】:

    宏不是函数。 编译器将展开所有宏然后编译它。要查看扩展代码,您可以在 gcc 中使用 -E 选项使用以下命令:

    gcc -E <source code> -o <preprocessed file name>
    

    或者在 Visual C++ 中,在 Configuration Properties->C/C++->Preprocessor 下,设置“Generate Preprocessed File”。

    顺便说一句,你的宏有问题。 你应该使用

    #define foo1( a ) ((a) * (a))
    

    而不是

     #define foo1( a ) (a * a)
    

    【讨论】:

    • 谢谢。我只得到了这段代码来理解它的作用,我知道宏是有问题的,但它的目的是为了学习:)
    【解决方案4】:

    不同的是,#define 定义的 foo1 不是函数,而 foo2 是。

    在编译过程中,编译器会将代码中的 foo1(parameter) 关键字替换为 (parameter * parameter)。

    意义,

    cout &lt;&lt; "foo1 = " &lt;&lt; foo1( 1+2 ) &lt;&lt; "\n"; // How does this work?

    将替换为以下代码,

    cout &lt;&lt; "foo1 = " &lt;&lt; ( 1+2 * 1+2 ) &lt;&lt; "\n"; // How does this work?

    (因为这里的参数是1+2,而不是3。)

    结果是 1+2 * 1+2,也就是 5。

    现在看看 foo2,因为它是内联函数,编译器不会替换它。当你的代码编译成可执行文件,并执行该可执行文件时,会先计算出2 + 1表达式,然后将结果3传递给foo2()。

    总之,不同之处在于代码的编译。您可能需要更多关于那里发生的事情的知识。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多