【问题标题】:Why does printing a function name returns a value?为什么打印函数名会返回一个值?
【发布时间】:2023-03-09 01:56:01
【问题描述】:

我不小心打印了一个没有括号的函数名,它打印了一个值。我只是好奇这是怎么发生的? 无论函数名称或定义如何,输出都是相同的,并且每次我运行它。

编辑:对于正在阅读本文的其他人,答案消除了我的疑问- 将函数名称显式转换为 int 有效, 即 int k=(int)foo;

这个测试代码会让事情更清楚:

#include <iostream>
#include <stdio.h>
#include <conio.h>
using namespace std;

void foo(){cout<<'Á';}      //FUNCTION IS NEVER CALLED

int main()
{
    while(_kbhit())         //JUST TO MAKE SURE BUFFER IS CLEARED
    {   getch();}           //SAME RESULT WITHOUT THESE TWO STATEMENTS

    cout<<foo;              //OUTPUT 1
    printf("\n%u", foo);    //OUTPUT 4199232
    /*int k=foo;            //CANNOT CONVERT VOID(*)() TO 'INT'*/
    return 0;
}

【问题讨论】:

  • 你为什么混合coutprintf
  • printf 不是类型安全的。仅仅因为printf可以做某事,并不意味着它应该

标签: c++


【解决方案1】:

提及不带括号的函数名称被解释为函数指针。该指针被%u 格式说明符解释为unsigned int,这是未定义的行为,但恰好在大多数系统上都有效。

int k = foo 不起作用的原因是函数指针通常需要强制转换才能转换为 int。但是,printf 更为宽松,因为它使用varargs 来解析其参数字符串;假定参数的类型与格式字符串中请求的类型匹配。

【讨论】:

  • “提及不带括号的函数名将被解释为函数指针。” 稍微不准确,至少在 C++ 中是这样。例如。 void (&amp;pf)() = foo;
  • "指针被 %u 格式说明符转换为无符号整数。"实际上,这将是未定义的行为,不是吗?
【解决方案2】:

这条语句printf("\n%u", foo);将函数foo()的地址传递给printf。所以打印出来的值就是这个函数在运行程序内存中的地址。

【讨论】:

    【解决方案3】:
    std::cout << foo;
    

    输出1,因为foo是一个函数指针,它会被转换成boolstd::cout

    要打印它的地址,你需要明确地转换它:

    std::cout << reinterpret_cast<void*>(foo) << std::endl;
    

    使用printf("\n%u", foo);%u 期待unsigned int,你看到的是转换为unsgigned int 的函数指针的值。

    【讨论】:

      猜你喜欢
      • 2015-03-13
      • 2021-12-30
      • 1970-01-01
      • 2022-01-21
      • 2012-01-03
      • 1970-01-01
      • 1970-01-01
      • 2014-02-12
      相关资源
      最近更新 更多