2013-03-28 130 views
2

這是關於C編程語言。C中的字符串連接問題

我有大量的二維數組(sizes are not fixed)。考慮下面的例子。

bool sym_a[][]={{...},{...},...}; //consider these are initialized properly 
bool sym_b[][]={{...},{...},...}; 
... 
bool sym_z[][]={{...},{...},...}; 
bool sym_0[][]={{...},{...},...}; 
bool sym_1[][]={{...},{...},...}; 
... 
bool sym_9[][]={{...},{...},...}; 
... 

注意命名約定,所有的名字都是一樣的。只有數組名稱的最後一個字符發生更改(如果它可以多於一個字符,則更好,但這並不重要)。

好吧,現在我有一個功能。它根據傳遞的參數選擇其中一個二維數組。然後用選定的數組做一些任務。請注意,該任務是常用任務,只有選定的數組纔會更改。

例如,根據我現在可以想到的,是切換的情況下,我可以實現如下功能。

void doStuff(char letter){ 
    switch(letter){ 
     case 'a': 
      sym_a[0][0]=1; //just for demonstration :D 
     break; 
     case 'b': 
      sym_b[0][0]=1; //same thing, only the character 'a' changed to 'b' 
     break; 
     ... 
     case 'z': 
      sym_z[0][0]=1; 
     break; 
     case '0': 
      sym_0[0][0]=1; 
     break; 
     case '1': 
      sym_1[0][0]=1; 
     break; 
     ... 
     ... 
    }  
} 

但是一定有更好的辦法。如果我有1000個這樣的數組,那麼我必須寫1000個這樣的例子嗎?對於所有情況,內容完全相同。變量名稱只有一個字符被更改。

這將是很好,如果有像字符串連接的東西。

#define conc(a,b) a ## b 

然後conc(sym_,a)將代表sym_a。但這不能直接應用於此。因爲我無法將確切字母傳遞給conc(a,b)的右側參數,所以只能傳遞包含所需字母的變量。

void doStuff(char letter){ 
    conc(sym_,letter)[0][0]=1; 
} 

conc(sym_,letter)給出sym_letter。但我需要連接sym_與字符變量letter的內容。

例如,如果我打電話給doStuff('b');,應給予他們sym_b,而不是sym_letter

希望我的要求清楚。這件事看起來很簡單,但我想不出擺脫這種方式。請注意,2D陣列的大小(行數/列數)不固定。否則,我可以使用3D數組。

任何想法是讚賞。

+0

爲什麼你需要這麼多的2D變量? – akshay202 2013-03-28 04:50:49

+1

我不認爲C語言有bool數據類型。您可以創建一個int數組,並使用位移運算符存儲所有的bool數據。 – akshay202 2013-03-28 04:54:03

+1

@ akshay202好吧,他們一直都不活着(你是什麼意思?)。他們就像在程序中硬編碼一樣,只在需要時才考慮。無論如何,猜這不是問題。但你有沒有看到更好的選擇? 而上面的代碼是我目前使用的(是的,它的工作原理)。但我需要一個簡單的替代方案 – Anubis 2013-03-28 04:58:07

回答

1

你有大量的靜態數組,所以它可能是一個自然的擴展,你最終會有大量的條件來訪問它們。

您可以定義一個額外的靜態數組,將字符代碼映射到數組。然後

static const struct { 
    char* lookup_code; 
    bool **array; 
} char_code_lookup[] = { 
    { .lookup_code = "a", sym_a }, 
    { .lookup_code = "b", sym_b }, 
    /* ... */ 
    { .lookup_code = NULL, NULL }, /* Terminator */ 
}; 

doStuff功能可以掃描數組,尋找合適的查找代碼,以配合靜態定義的數組。

有了一些宏觀魔法,你可以同時生成靜態數組和靜態查找數組以減少重複,但上面列出的方法可能更易於閱讀。

或者,您可以使用malloc動態分配陣列,同時在運行時創建陣列時關聯查找代碼。

+0

如果真的有'1000'這樣的數組(意味着寬字符),寫入這可能會有點慢。可以使用'qsort'來進行二進制搜索,或者更有可能重新設計一點,以允許直接跳轉(取決於查找代碼的細節)。 – Keith 2013-03-28 05:18:54

+0

確實,這樣的實現會很慢。如圖所示,每個查找代碼將有一個「strcmp」,直到找到匹配。改進的設計可以動態分配數組,並將查找鍵與散列值相關聯,從而允許O(1)散列查找。 – 2013-03-28 05:28:13

1

是否有這樣的幫助? [如果這裏有一些C++,請諒解。 ]

bool** sym_a; 
bool** sym_b ; 
bool** sym_z; 
bool** sym_0; 
bool** sym_1; 
bool** sym_9 ; 


unsigned lowestEntry = 'a'; 
unsigned highestEntry = '9'; 
const unsigned numEntries = highestEntry - lowestEntry; 

size_t size = sizeof(bool**)* numEntries; 

bool*** lookup = (bool***)malloc(size); 

#define conc(a,b) a ## b 
#define index(a) #a[0]-'a' 
#define add(a) lookup[index(a)] = conc(sym_,a) 

void init() 
{ 
    memset(lookup, 0, size); 
    add(a); 
    add(b); 
    add(z); 
    add(9); 
    add(k); // does not compile, sym_k not defined. 
} 

bool** findSymbolTable(char val) 
{ 
    return lookup[val - lowestEntry]; 
} 
1

分配一個大型的int數組併爲其他變量進行分區。

例如。

int data [2600];

將有前sym_a的前100個整數,接下來是sym_b的100個,等等。您將能夠在這些數組中存儲8 * 100 * 4布爾值。

現在訪問sym_p [X] [Y]你會說是你必須總R行和C列:

INT *開始=數據+(ASCIValue(P) - ASCIValue的(a))* 100 ;

你必須從頭開始讀/寫位數(C * x + y)。