拆一個C宣告

於 2026/07/28 (臺北標準時)
#c
int *(*(*(**x[])(char*, int*(*)(char*)))[])(char**, char*(*)());

x 是一個陣列,存了指向函式指標的指標

這個函式指標接受一個char指標,和另外一個接受一個char指標回傳一個int指標的函式指標

其回傳一個指向陣列的指標,陣列裏面存的還是一個函式指標

這個函式指標接受一個char雙重指標,和一個回傳char指標的函式指標

其回傳一個int指標

用法大概是送一個字串和一個轉換函式,拿到一組行爲,再挑一個送資料和輔助函式,拿到int*

其集合了工廠,策略表和結果三位一體

唯一的問題是是否真的需要兩段式決策帶來的動態轉圜空間

另外如果存在複數個工廠導引表(在某種複雜的外掛系統)

其實可以改進成

    int*(*(*(**x[])(char*, int* (* (* (*const volatile)(int))[])(const char*)))[])(char**, char*(*)());

加了一個函數陣列,每個函數接受一個 唯讀char*,返回 int*,而這個函數陣列本身是另一個函數的返回值

其爲一個不能被重新賦值,但每次讀取都必須視為可能變化的函式指標物件,接受一個 int 作參數,實際上是開始用數字選導引表本身

變成三段式動態決策,且一段決策在高危環境

當然導引表,策略表這兩個是現說的,有相近的概念自動對應即可

雖然這種程度的大解耦是否值得有待商榷,但可以肯定的是絕對不可能出現在協作環境

實際測試下來,至少在功能上該做的都做了:

#include <stdio.h>
#include <stdlib.h>

int global_val = 1;

int* final_target(char** a, char*(*b)()) {
    printf("%s Says: %s\n",*a,b());
    return &global_val;
}

int* (*level2_array[2])(char**, char*(*)()) = { final_target, NULL };

/*
 * 這一個系列都沒被invoke,佔位用,雖然也可以invoke
*/
int* inner_func(const char* s) {
    (void) s;
    return NULL; 
}
int* (*inner_ptr_array[1])(const char*) = { inner_func };
int* (* (* complex_arg_func(int n))[])(const char*) {
    (void) n;
    return &inner_ptr_array;
}

int* (*(*target_func(char* s, int* (* (* (p)(int))[])(const char*)))[])(char**, char*(*)()) {
    /* 這裏就可以動 msg s 和那個 complex_arg_func(int) 
     *  比如什麼 result = (*(*complex_arg_func(1))[0])("テスト");
     * */
    (void) s;
    (void) p;
    return &level2_array;
}

int* (*(*(*ptr_to_target_func)(char*, int* (* (* (*)(int))[])(const char*)))[])(char**, char*(*)()) = target_func;
int* (*(*(*(*ptr_to_ptr_to_target_func))(char*, int* (* (* (*)(int))[])(const char*)))[])(char**, char*(*)()) = &ptr_to_target_func;

char* callback_impl() { return "彼方への光はこちらを照らす"; }

int main() {
    int* result = 0;
    char* msg = "Texas0295";
    char** msg_ptr = &msg;
    int* (*(* (* const volatile func)(int))[])(const char*) = complex_arg_func;

    int* (*(*(**x[1])(char*, int* (*(* (* const volatile)(int))[])(const char*)))[])(char**, char*(*)());
    x[0] = ptr_to_ptr_to_target_func;

     /* 
     * x[0]解一次,*x[0]解一次拿到target_func -> 一次週轉拿工廠導引表
     * 現在執行那個target_func,傳一個msg和comple_arg_func。最後拿到一個level2_array -> 二次週轉拿策略表
     * 寫0拿函式,傳msg_ptr,和callback_impl給那個函式 -> 三次週轉執行選定策略
     * 最後拿到一個1
    */
    result = (*(*(*x[0])(msg, func))[0])(msg_ptr, callback_impl);

    if (result) {
        printf("Result: %d\n", *result);
    }

    return 0;
}

實際結果:

~/c_note > gcc -Wall -Wextra -Wpedantic -Werror -std=c89 -o main pointer.c && ./main
Texas0295 Says: 彼方への光はこちらを照らす
Result: 1
~/c_note > 

用typedef翻過來也一樣

#include <stdio.h>
#include <stdlib.h>

typedef int* (*tableDirector)(const char*);
typedef char* (*hardwareStrategy)();

typedef int* (*hardwareExecutor)(char**, hardwareStrategy);
typedef tableDirector* (*const volatile hardwareChooser)(int); /* 工廠導引表 */

typedef hardwareExecutor* (*hardwareExecutorGetter)(char*s, hardwareChooser);

int global_val = 42;

int* final_target(char** a, hardwareStrategy b) {
    printf("%s Says: %s\n",*a,b());
    return &global_val;
}

hardwareExecutor executors[2] = {final_target, NULL};

int* inner_func(const char* s) { 
    (void) s; /* 必要的佔位,下同*/
    return NULL; 
}
tableDirector directors[1] = { inner_func };
tableDirector * hw_chooser(int n) {
    (void) n;
    return directors;
}

hardwareExecutor* choose(char* s, hardwareChooser p) {

    const tableDirector* directors = p(1);
    tableDirector director = directors[0];
    const int* result = director(s);

    (void) result;
    /*
     * 剩下的可以拿着director算出來的結果進行互動,拿到所有支援的Executor
     */

    return executors;
}

char* get_a_str() { return "彼方への光はこちらを照らす"; }

int main(){

    char* msg = "Texas0295";
    char** msg_ptr = &msg;
    hardwareExecutorGetter getters[1];
    hardwareExecutorGetter getter;
    hardwareExecutor* executors;
    hardwareExecutor executor;
    hardwareStrategy strategy = get_a_str;
    hardwareChooser chooser = hw_chooser;
    int* result = NULL;
    getters[0] = choose;

    getter = getters[0]; /* 一次週轉拿導引表 */

    executors = getter(msg, chooser); /* 二次週轉拿執行列 */
    executor = executors[0];
    result = executor(msg_ptr, strategy); /* 三次週轉執行選定策略*/

    if (result) {
        printf("Result: %d\n", *result);
    }

    return 0;
}

如無特殊說明,所有內容採用 CC BY 4.0 協議共享