【问题标题】:array of N pointers to functions returning pointers to functionsN 个指向函数的指针数组,返回指向函数的指针
【发布时间】:2011-01-12 15:39:30
【问题描述】:

这是在一次采访中问我的! 我真的很困惑

  • 如何声明一个包含 N 的数组 指向函数返回的指针 指向函数返回的指针 指向字符的指针

有人可以帮忙吗?

【问题讨论】:

  • 多么愚蠢的面试问题。互联网是有原因的。这样我们就可以在需要时查找晦涩难懂的语法,而不必用它来混淆我们的大脑。
  • apt-get install cdecl; echo declare array of pointer to function returning pointer to function returning pointer to char | cdecl; >>> char *(*(*var[])())()
  • @Doug T:对我来说这听起来很合理。不幸的是,知道如何处理复杂的声明是 C 语言中非常有用的技能。
  • @David 即使它不是晦涩难懂的语法,我也认为它不是很有价值。这是很容易学习和忘记的东西——非常容易缓存的知识。我宁愿知道是否有人从根本上理解了这些概念。如果我给他们一张带有古怪声明语法的备忘单,他们能坐下来写一个合理的程序吗?能否深入探讨问题?
  • @Doug T:这就是为什么,如果我要问这个问题,我会对方法而不是最终答案感兴趣。面试问题与认证考试问题不同。您是否可以从 cdecl 口中说出 Mehrdad 的回答并不重要,这将是令人印象深刻但没有必要的,但不幸的是,真正感到困惑并不是一个好兆头。

标签: c types


【解决方案1】:
typedef char* (* tCharRetFunc)();
typedef tCharRetFunc (* tFuncRetCharFunc)();

tFuncRetCharFunc arr[N];

【讨论】:

  • 我认为这个问题的目的是看被采访者是否理解 typedef 并给出一个像这样一个清晰人性化的解决方案,或者一个像其他答案中给出的技术讨厌的解决方案。因此,随着这些事情的发展,这是一个相当不错的问题。
【解决方案2】:

把大问题分解成小部分:

/* char_func_ptr is pointer to function returning pointer to char */
typedef char* (*char_func_ptr)();

/* func_func_ptr is a pointer to function returning above type */
typedef char_func_ptr (*func_func_ptr)();

/* the_array is array of desired function pointers */
func_func_ptr the_array[42];

【讨论】:

    【解决方案3】:

    这是你要找的东西吗:

    typedef char* charptr;
    typedef charptr (*innerfun)();
    typedef innerfun (*outerfun)();
    
    const size_t N = 10;
    outerfun my_outerfun_array[N];
    

    希望我答对了,这对我来说似乎是一个奇怪的问题,尤其是在面试中:(

    【讨论】:

      【解决方案4】:

      像 Christopher 告诉你的那样使用 typedef 确实是声明此类事情的唯一人道方式。没有 tyedefs ,它会变成:

      char *(*(*arr[10])(void ))(void );
      

      (是的,我不得不作弊逃跑 cdecl> 将 arr 声明为指向函数(void)的指针的数组 10,返回指向函数的指针(void),返回指向 char 的指针)

      【讨论】:

        【解决方案5】:

        Typedef 是为 wusses 准备的。下面是一个简单的、机械的方法来找出毛茸茸的声明:

                  a                 -- a
                  a[N]              -- is an N-element array
                 *a[N]              -- of pointers
                (*a[N])()           -- to functions
               *(*a[N])()           -- returning pointers
              (*(*a[N])())()        -- to functions
             *(*(*a[N])())()        -- returning pointers
        char *(*(*a[N])())()        -- to char.  
        

        所以,答案就在char *(*(*a[N])())(); 附近。我说“在附近”,因为它从未指定函数采用什么参数。

        这是一个令人讨厌的面试问题(这种丑陋的类型在 IME 中确实很少见),但它确实让面试官知道你对声明符的理解程度。要么就是这样,要么他们很无聊,只是想看看他们是否能让你的大脑紧张。

        编辑

        其他大多数人都建议使用 typedef。我唯一推荐使用 typedef 的情况是该类型是真正不透明的(即,不是由程序员直接操作,而是传递给 API,有点像 FILE 类型)。否则,如果程序员打算直接操作该类型的对象,那么 IME 最好在声明中提供所有这些信息,尽管它可能很丑陋。例如,像

         NameFuncPickerPointer a[N];
        

        没有告诉我如何实际使用a[i]。我不知道 a[i] 是可调用的,或者它返回什么,或者它应该采用什么参数(如果有的话),或者其他任何东西。我得去找typedef

        typedef char *NameFunc();
        typedef NameFunc *NameFuncPicker();
        typedef NameFuncPicker *NameFuncPickerPointer;
        

        并从这个谜题中找出如何编写实际调用其中一个函数的表达式。虽然使用“裸”、非类型定义的声明,但我立即知道调用的结构是

        char *theName = (*(*a[i])())();
        

        【讨论】:

        • 现在这个即使不是c程序员也能理解。
        • 关于名字的问题,我想我想看看StringGetter_Getter a[N],或StringGetter_Getter_Array a,或FunctionTable a。它在代码的上下文中必须有一些含义,我宁愿看到StringGetter_Getter 到处重复,而不是char *(*(*)())()。但这很容易演变为与是否命名常量相同的论点:“我不想去查找 DEFAULT_HTTP_PORT 的值,如果有人使用 80,我想在源代码中看到 80”。作为程序员,间接性是我们所有问题的原因和解决方案。
        • ... 最终,如果您的 C 代码具有返回工厂函数的工厂函数表,那么您可能在通往“痛苦复杂的企业 Java”类的路上走错了路;-)
        【解决方案6】:

        N 个指向函数的指针数组返回指向函数的指针返回一个字符:

        int (*(*arr_fp[n])(void))(void)
        

        【讨论】:

          猜你喜欢
          • 2013-04-10
          • 2021-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多