礦[S]沒有計算器的帳戶[/ S](@Francesco)的朋友已經重新闡述了@WhozCraig答案(由蘭迪·邁爾斯感謝great article)將(很老)X macro打造通用結構數組和枚舉女巫有助於訪問數組的結構,讓用戶只編輯一個點;
回到工作我告訴過他,我想嘗試使特定的結構getter(因爲在數組中沒有REPEATED STRUCT TYPE,如果你弄錯了,編譯時錯誤,所以在當你在開發的時候你會彎下腰,但是一旦編譯它就會更加健壯),所以我們將對所請求的結構的類型進行編譯檢查; 回到家他已經實施了。獎勵!
然後我又失去了一些時間,使開發人員只需鍵入一次結構,以防止在那一側的錯位; 這已經是優化螺旋的開始;
- 因爲專門get和put,不再需要大小排列的,所以刪除了通用的結構
- 沒有初始化的結構需要,我們使用「匿名」結構初始化
- 因爲「匿名」初始化,它是很難直接訪問結構
- 直接訪問需要的知識體系,有導致意識
- 代碼的可讀性更強
- 容易導出
GENERIC_TABLE
和外部獨立的文件結構定義
- #ifdef的
GENERIC_TABLE
正常工作,將其移動到外部頭以增加可讀性
- 外局部變量不需要動態初始化(無垃圾,嵌入型)
- 使用極爲方便
成本
- 也許有點臃腫預處理器?
- 看來很多OOP的xD
- 可以撥打得到與外行指針
TL放; DR:這裏完整的編譯代碼和基本的例子:
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
/* BEGIN: just some struct to test, fell free to move them on external header file */
struct A
{
int a1;
long a2;
};
struct B
{
float b1;
char b2[6];
};
struct C
{
unsigned int c1;
double c2[5];
};
/* END: just some struct to test, fell free to move them on external header file */
/* this macro will create the right X macro element, and also initiliaze the "anonymous" struct */
#define ADD_STRUCT_TO_ARRAY(xu) X(xu, &(struct xu){})SEP
/* BEGIN: add or remove your own struct here!
* fell free to move them on external header file
* just need to pass struct name without "struct" to ADD_STRUCT_TO_ARRAY macro */
#define GENERIC_TABLE \
ADD_STRUCT_TO_ARRAY(A) \
ADD_STRUCT_TO_ARRAY(B) \
ADD_STRUCT_TO_ARRAY(C)
/* END: add or remove your own struct here! */
/* here we initialize the enum, where the type of the struct is the key, and its position in the array the value */
#define SEP ,
#define X(a,b) a
enum STRUCT {
GENERIC_TABLE
};
#undef X
/* here we initalize the array of pointer to the structure */
#define X(a,b) b
void * const generic[] =
{
GENERIC_TABLE
};
#undef X
#undef SEP
/* here we create all the getter function. add here your array locking code */
#define SEP ;
#define X(a,b) void get_##a(struct a * dest){memcpy(dest, generic[a], sizeof(struct a));}
GENERIC_TABLE
#undef X
#undef SEP
/* here we create all the putter function. add here your array locking code */
#define SEP ;
#define X(a,b) void put_##a(struct a * source){memcpy(generic[a], source, sizeof(struct a));}
GENERIC_TABLE
#undef X
#undef SEP
/*run, code, run!*/
int main()
{
struct A a_copy;
struct B b_copy;
struct C c_copy;
get_A(&a_copy);
get_B(&b_copy);
get_C(&c_copy);
printf("STRUCTURE IN ARRAY BEFORE INITIALIZATION\n");
printf("A = %d\n", a_copy.a1);
printf("B = %f\n", b_copy.b1);
printf("C = %x\n", c_copy.c1);
a_copy.a1 = -1;
b_copy.b1 = 2.3;
c_copy.c1 = 3;
printf("STRUCTURE CHANGED TO\n");
printf("A = %d\n", a_copy.a1);
printf("B = %f\n", b_copy.b1);
printf("C = %x\n", c_copy.c1);
printf("STRUCTURE SAVED\n");
put_A(&a_copy);
put_B(&b_copy);
put_C(&c_copy);
get_A(&a_copy);
get_B(&b_copy);
get_C(&c_copy);
printf("STRUCTURE LOADED\n");
printf("A = %d\n", a_copy.a1);
printf("B = %f\n", b_copy.b1);
printf("C = %x\n", c_copy.c1);
a_copy.a1 = 1000;
b_copy.b1 = -50.576;
c_copy.c1 = 700;
printf("STRUCTURE CHANGED TO\n");
printf("A = %d\n", a_copy.a1);
printf("B = %f\n", b_copy.b1);
printf("C = %x\n", c_copy.c1);
get_A(&a_copy);
get_B(&b_copy);
get_C(&c_copy);
printf("STRUCTURE RELOADED WITHOUT SAVING\n");
printf("A = %d\n", a_copy.a1);
printf("B = %f\n", b_copy.b1);
printf("C = %x\n", c_copy.c1);
return 0;
}
我覺得你的問題是,「我可以寫一個函數,它需要一個'struct'和一個索引和'struct'目標地址作爲輸入 - 這樣特定的'struct'被綁定'別的地方'?」 – 2014-09-23 22:06:35
「有沒有辦法在編譯時自動化sizeof數組的初始化?」唯一可用的機制是預處理器。這是抽象這種功能最常用的工具。 – 2014-09-23 22:07:13
是否可以將每個結構的大小存儲在它自己內部?即,在每個結構中添加一個成員int mySize作爲第一個成員,並將它(在運行時)設置爲'x.mySize = sizeof(struct x)'。 – usr2564301 2014-09-23 22:09:36