2013-03-28 111 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)。