听起来您想按名称传递参数。假设是这种情况,我想到了两种方法。
如果您的集合名称确实是单字符名称,例如 A、D、R 等,您可以构建一个由字符索引的 set 指针数组:
set *sets[128]; // will result in a lot of unused sets, but
// indexing is fast and dead easy
sets['A'] = &A;
sets['D'] = &D;
sets['R'] = &R;
...
char s1, s2, s3;
scanf( " %c %c %c", &s1, &s2, &s3 ); // Note a complete lack of error checking
func( *sets[s1], *sets[s2], *sets[s3] ); // You *will* want to validate your inputs
如果你不想浪费太多空间,你可以这样做
set *sets[26]; // just uppercase letters
int base = 'A';
sets['A'-base] = &A;
sets['D'-base] = &D;
sets['R'-base] = &R;
...
scanf( " %c %c %c", &s1, &s2, &s3 ); // Again, absolutely no error checking
func( *sets[s1-base], *sets[s2-base], *sets[s3-base] ); // You have been warned
这假设您使用的编码是所有大写字母都是连续的(ASCII 或 UTF-8)。
如果你是一个聪明的代码猴子并为你的集合使用有意义的名称,你可以使用一个由字符字符串索引的查找表,类似于以下内容:
set foo, bar, bletch...;
struct lut_entry {
char *name;
set *data;
};
struct lut_entry lut[] = {
{"foo", &foo},
{"bar", &bar},
{"bletch", &bletch},
...
{ NULL, NULL } // sentinel value
};
然后您可以在此表中搜索每个输入:
set *lookup( const char *name, struct lut_entry *lut )
{
struct lut_entry *cur = lut;
while ( cur->name && strcmp( cur->name, name ) )
cur++;
return cur->data;
}
你会这样称呼它:
scanf( "%s %s %s", name1, name2, name3 );
set *s1 = lookup( name1, lut );
set *s2 = lookup( name2, lut );
set *s3 = lookup( name3, lut );
if ( s1 && s2 && s3 )
func( *s1, *s2, *s3 ); // note dereference operations!
else
// one or more of name1, name2, and name3 are invalid
// handle as appropriate
根据您管理的集合数量以及对这个应用程序的速度有多重要,您可能希望研究比无序线性数组搜索更复杂的东西,但如果它更少,则不值得付出努力十几个左右。
为什么我不直接将名称传递给func 并让它完成所有查找工作?你绝对可以这样做,但这意味着func 必须通过全局变量与其调用者共享状态,我尽量避免这样做,这意味着func 总是 必须这样做无论您是否想要查找。最好让func 按原样接收集合并让调用函数进行查找,因为调用函数知道它是否由用户输入驱动。