拆一個C宣告
於 2026/07/28 (臺北標準時)
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 協議共享
