根据输入向函数发送参数
sending parameters to a function according to input
我有一个简单的 typedef (typedef int set [4]) 和它的创作。
我有一个函数可以获取其中的 3 个 typedef 作为参数。
现在,我想根据输入参数调用函数。
例如,如果输入是 A、D、R(假设这些都已创建),那么函数将被调用为 func(A,D,R)。
我试过使用 swich 来匹配字符,然后发送适当的参数,但是太乱了,我也尝试了一些其他的东西,但我无法在输入和对象名称之间建立联系。
我顺便用C写的。
任何帮助将不胜感激
如果我对问题的理解正确,你有一些字符要转换为具有该名称的变量。也就是说 'A'
变成 set A
?
根据这个假设,这里有一个方法可以做到:
#include <assert.h>
set func(set x, set y, set z);
// Global definitions for all set variables.
struct sets {
set A;
set B;
set C;
...
set Z;
} allSets;
set callFuncForParams(char c1, char c2, char c3)
{
set *x, *y, *z;
// Make sure the input is legal
assert(c1 >= 'A' && c1 <= 'Z');
assert(c2 >= 'A' && c2 <= 'Z');
assert(c3 >= 'A' && c3 <= 'Z');
x = (set *)&allSets + c1 - 'A';
y = (set *)&allSets + c2 - 'A';
z = (set *)&allSets + c3 - 'A';
return func(*x, *y, *z);
}
另一种方法(如果您没有将所有字母都作为变量特别有用)是创建一个 struct { char c; set s; }
数组,然后遍历该数组以找到您的变量。您可以使用宏和 # 运算符来生成该数组。
听起来你想按名称传递参数。假设是这种情况,我想到了两种方法。
如果您的集合名称确实是单字符名称,如 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
如果你不想浪费那么多space,你可以这样做
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)。
如果您是一个聪明的代码猴子并且为您的集合使用有意义的 名称,您可以使用由字符 [=41= 索引的查找 table ]string,类似于以下内容:
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
};
然后您可以搜索此 table 以获取每个输入:
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
按原样接收集合并让调用函数进行查找,因为调用函数知道它是否由用户输入驱动。
我有一个简单的 typedef (typedef int set [4]) 和它的创作。 我有一个函数可以获取其中的 3 个 typedef 作为参数。
现在,我想根据输入参数调用函数。 例如,如果输入是 A、D、R(假设这些都已创建),那么函数将被调用为 func(A,D,R)。
我试过使用 swich 来匹配字符,然后发送适当的参数,但是太乱了,我也尝试了一些其他的东西,但我无法在输入和对象名称之间建立联系。
我顺便用C写的。 任何帮助将不胜感激
如果我对问题的理解正确,你有一些字符要转换为具有该名称的变量。也就是说 'A'
变成 set A
?
根据这个假设,这里有一个方法可以做到:
#include <assert.h>
set func(set x, set y, set z);
// Global definitions for all set variables.
struct sets {
set A;
set B;
set C;
...
set Z;
} allSets;
set callFuncForParams(char c1, char c2, char c3)
{
set *x, *y, *z;
// Make sure the input is legal
assert(c1 >= 'A' && c1 <= 'Z');
assert(c2 >= 'A' && c2 <= 'Z');
assert(c3 >= 'A' && c3 <= 'Z');
x = (set *)&allSets + c1 - 'A';
y = (set *)&allSets + c2 - 'A';
z = (set *)&allSets + c3 - 'A';
return func(*x, *y, *z);
}
另一种方法(如果您没有将所有字母都作为变量特别有用)是创建一个 struct { char c; set s; }
数组,然后遍历该数组以找到您的变量。您可以使用宏和 # 运算符来生成该数组。
听起来你想按名称传递参数。假设是这种情况,我想到了两种方法。
如果您的集合名称确实是单字符名称,如 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
如果你不想浪费那么多space,你可以这样做
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)。
如果您是一个聪明的代码猴子并且为您的集合使用有意义的 名称,您可以使用由字符 [=41= 索引的查找 table ]string,类似于以下内容:
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
};
然后您可以搜索此 table 以获取每个输入:
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
按原样接收集合并让调用函数进行查找,因为调用函数知道它是否由用户输入驱动。