用于双字符串比较的 C case 语句
C case statement for double string comparison
我觉得必须有比我尝试过的极其漫长的方法更好的方法来做到这一点。我有两个标记(token3 和 token4),它们可以是字符串 R1 到 R6。我还有同名的 int 变量,R1 到 R6。我基本上希望案例陈述是
(variable of name token3) += (variable of name token4);
我实现这个的方式看起来很荒谬而且太重复了,但我不知道其他方式。一定有什么方法可以简化这个吧?
// ADD COMMAND
else if (!strcmp(token2_instr, "ADD")) {
printf("%s\n", token2_instr);
token3_arg1 = strtok_r(NULL, ", ", &line_save);
token4_arg2 = strtok_r(NULL, " \n", &line_save);
int num = atoi(token4_arg2);
// ADD Reg, Reg
if (num == 0) {
if (!strcmp(token3_arg1, "R1")) {
if (!strcmp(token4_arg2, "R1"))
R1 += R1;
else if(!strcmp(token4_arg2, "R2"))
R1 += R2;
else if(!strcmp(token4_arg2, "R3"))
R1 += R3;
else if(!strcmp(token4_arg2, "R4"))
R1 += R4;
else if(!strcmp(token4_arg2, "R5"))
R1 += R5;
else if(!strcmp(token4_arg2, "R6"))
R1 += R6;
}
else if(!strcmp(token3_arg1, "R2")) {
if (!strcmp(token4_arg2, "R1"))
R2 += R1;
else if(!strcmp(token4_arg2, "R2"))
R2 += R2;
else if(!strcmp(token4_arg2, "R3"))
R2 += R3;
else if(!strcmp(token4_arg2, "R4"))
R2 += R4;
else if(!strcmp(token4_arg2, "R5"))
R2 += R5;
else if(!strcmp(token4_arg2, "R6"))
R2 += R6;
}
else if(!strcmp(token3_arg1, "R3")) {
if (!strcmp(token4_arg2, "R1"))
R3 += R1;
else if(!strcmp(token4_arg2, "R2"))
R3 += R2;
else if(!strcmp(token4_arg2, "R3"))
R3 += R3;
else if(!strcmp(token4_arg2, "R4"))
R3 += R4;
else if(!strcmp(token4_arg2, "R5"))
R3 += R5;
else if(!strcmp(token4_arg2, "R6"))
R3 += R6;
}
else if(!strcmp(token3_arg1, "R4")) {
if (!strcmp(token4_arg2, "R1"))
R4 += R1;
else if(!strcmp(token4_arg2, "R2"))
R4 += R2;
else if(!strcmp(token4_arg2, "R3"))
R4 += R3;
else if(!strcmp(token4_arg2, "R4"))
R4 += R4;
else if(!strcmp(token4_arg2, "R5"))
R4 += R5;
else if(!strcmp(token4_arg2, "R6"))
R4 += R6;
}
else if(!strcmp(token3_arg1, "R5")) {
if (!strcmp(token4_arg2, "R1"))
R5 += R1;
else if(!strcmp(token4_arg2, "R2"))
R5 += R2;
else if(!strcmp(token4_arg2, "R3"))
R5 += R3;
else if(!strcmp(token4_arg2, "R4"))
R5 += R4;
else if(!strcmp(token4_arg2, "R5"))
R5 += R5;
else if(!strcmp(token4_arg2, "R6"))
R5 += R6;
}
else if(!strcmp(token3_arg1, "R6")) {
if (!strcmp(token4_arg2, "R1"))
R6 += R1;
else if(!strcmp(token4_arg2, "R2"))
R6 += R2;
else if(!strcmp(token4_arg2, "R3"))
R6 += R3;
else if(!strcmp(token4_arg2, "R4"))
R6 += R4;
else if(!strcmp(token4_arg2, "R5"))
R6 += R5;
else if(!strcmp(token4_arg2, "R6"))
R6 += R6;
}
}
// ADD Reg, Immediate
else {
if (!strcmp(token3_arg1, "R1"))
R1 += num;
else if(!strcmp(token3_arg1, "R2"))
R2 += num;
else if(!strcmp(token3_arg1, "R3"))
R3 += num;
else if(!strcmp(token3_arg1, "R4"))
R4 += num;
else if(!strcmp(token3_arg1, "R5"))
R5 += num;
else if(!strcmp(token3_arg1, "R6"))
R6 += num;
}
}
这是一个丑陋的 hack,但至少它避免了重复和 strcmp() 链:
static inline int *regname2ptr( char *regname, int *p1, int *p2, int *p3, int *p4, int *p5, int *p6)
{
if (*regname, || *regname != 'R') return NULL; // let it go boom
switch(reg[1] - '0' ) {
case 1: return p1;
case 2: return p2;
case 3: return p3;
case 4: return p4;
case 5: return p5;
case 6: return p6;
default: return NULL; // let it go boom encore
}
the_func()
{
int r1,r2,r3,r4,r5,r6;
int *src, *dst;
dst = regname2ptr(token4_arg1, &r1,&r2,&r3,&r4,&r5,&r6);
src = regname2ptr(token4_arg2, &r1,&r2,&r3,&r4,&r5,&r6);
*dst += *src;
}
这个问题可以通过引入正确的数据结构以优雅的方式解决。 Paul Griffiths 在他的评论中提到了这一点。
首先,让我们建立一个数据结构:
const int numberOfVariables = 6;
int R[numberOfVariables];
for (int i=0; i<numberOfVariables; i++) {
R[i] = 0;
}
char* tokenNames[] = {"R1", "R2", "R3", "R4", "R5", "R6"};
numberOfVariables
和 tokenNames
是您可以改变行为的点,如果您有更多或更少的名称或其他变量名称。所以基本上,我们不是有六个变量,而是有一个数组用于它们的名称,一个用于它们的值。
然后:
// Assumptions for this snippet.
char token3_arg1[] = "R3";
char token4_arg2[] = "R4";
// Find the index of the name of token 3.
int indexToken3 = 0;
for (; indexToken3<numberOfVariables; indexToken3++) {
// (debug) printf("check: %s", tokenNames[indexToken3]);
if (!strcmp(token3_arg1, tokenNames[indexToken3])) {
break;
}
}
// Find the index of the name of token 4.
int indexToken4 = 0;
for (; indexToken4<numberOfVariables; indexToken4++) {
// (debug) printf("check: %s", tokenNames[indexToken4]);
if (!strcmp(token4_arg2, tokenNames[indexToken4])) {
break;
}
}
Paul Griffiths 正在通过将变量名中的数字转换为数字来查找索引。在这里,我更喜欢更灵活的方式 - 假设你有 R33
.
有了两个索引,最后:
R[indexToken3] += R[indexToken4];
背后的技巧是每个 Rn
的计数器与它们的名称位于相同的索引处。
如果项目变大了,我强烈建议写一个查找索引的函数,甚至使用一个完成的库函数。
我觉得必须有比我尝试过的极其漫长的方法更好的方法来做到这一点。我有两个标记(token3 和 token4),它们可以是字符串 R1 到 R6。我还有同名的 int 变量,R1 到 R6。我基本上希望案例陈述是
(variable of name token3) += (variable of name token4);
我实现这个的方式看起来很荒谬而且太重复了,但我不知道其他方式。一定有什么方法可以简化这个吧?
// ADD COMMAND
else if (!strcmp(token2_instr, "ADD")) {
printf("%s\n", token2_instr);
token3_arg1 = strtok_r(NULL, ", ", &line_save);
token4_arg2 = strtok_r(NULL, " \n", &line_save);
int num = atoi(token4_arg2);
// ADD Reg, Reg
if (num == 0) {
if (!strcmp(token3_arg1, "R1")) {
if (!strcmp(token4_arg2, "R1"))
R1 += R1;
else if(!strcmp(token4_arg2, "R2"))
R1 += R2;
else if(!strcmp(token4_arg2, "R3"))
R1 += R3;
else if(!strcmp(token4_arg2, "R4"))
R1 += R4;
else if(!strcmp(token4_arg2, "R5"))
R1 += R5;
else if(!strcmp(token4_arg2, "R6"))
R1 += R6;
}
else if(!strcmp(token3_arg1, "R2")) {
if (!strcmp(token4_arg2, "R1"))
R2 += R1;
else if(!strcmp(token4_arg2, "R2"))
R2 += R2;
else if(!strcmp(token4_arg2, "R3"))
R2 += R3;
else if(!strcmp(token4_arg2, "R4"))
R2 += R4;
else if(!strcmp(token4_arg2, "R5"))
R2 += R5;
else if(!strcmp(token4_arg2, "R6"))
R2 += R6;
}
else if(!strcmp(token3_arg1, "R3")) {
if (!strcmp(token4_arg2, "R1"))
R3 += R1;
else if(!strcmp(token4_arg2, "R2"))
R3 += R2;
else if(!strcmp(token4_arg2, "R3"))
R3 += R3;
else if(!strcmp(token4_arg2, "R4"))
R3 += R4;
else if(!strcmp(token4_arg2, "R5"))
R3 += R5;
else if(!strcmp(token4_arg2, "R6"))
R3 += R6;
}
else if(!strcmp(token3_arg1, "R4")) {
if (!strcmp(token4_arg2, "R1"))
R4 += R1;
else if(!strcmp(token4_arg2, "R2"))
R4 += R2;
else if(!strcmp(token4_arg2, "R3"))
R4 += R3;
else if(!strcmp(token4_arg2, "R4"))
R4 += R4;
else if(!strcmp(token4_arg2, "R5"))
R4 += R5;
else if(!strcmp(token4_arg2, "R6"))
R4 += R6;
}
else if(!strcmp(token3_arg1, "R5")) {
if (!strcmp(token4_arg2, "R1"))
R5 += R1;
else if(!strcmp(token4_arg2, "R2"))
R5 += R2;
else if(!strcmp(token4_arg2, "R3"))
R5 += R3;
else if(!strcmp(token4_arg2, "R4"))
R5 += R4;
else if(!strcmp(token4_arg2, "R5"))
R5 += R5;
else if(!strcmp(token4_arg2, "R6"))
R5 += R6;
}
else if(!strcmp(token3_arg1, "R6")) {
if (!strcmp(token4_arg2, "R1"))
R6 += R1;
else if(!strcmp(token4_arg2, "R2"))
R6 += R2;
else if(!strcmp(token4_arg2, "R3"))
R6 += R3;
else if(!strcmp(token4_arg2, "R4"))
R6 += R4;
else if(!strcmp(token4_arg2, "R5"))
R6 += R5;
else if(!strcmp(token4_arg2, "R6"))
R6 += R6;
}
}
// ADD Reg, Immediate
else {
if (!strcmp(token3_arg1, "R1"))
R1 += num;
else if(!strcmp(token3_arg1, "R2"))
R2 += num;
else if(!strcmp(token3_arg1, "R3"))
R3 += num;
else if(!strcmp(token3_arg1, "R4"))
R4 += num;
else if(!strcmp(token3_arg1, "R5"))
R5 += num;
else if(!strcmp(token3_arg1, "R6"))
R6 += num;
}
}
这是一个丑陋的 hack,但至少它避免了重复和 strcmp() 链:
static inline int *regname2ptr( char *regname, int *p1, int *p2, int *p3, int *p4, int *p5, int *p6)
{
if (*regname, || *regname != 'R') return NULL; // let it go boom
switch(reg[1] - '0' ) {
case 1: return p1;
case 2: return p2;
case 3: return p3;
case 4: return p4;
case 5: return p5;
case 6: return p6;
default: return NULL; // let it go boom encore
}
the_func()
{
int r1,r2,r3,r4,r5,r6;
int *src, *dst;
dst = regname2ptr(token4_arg1, &r1,&r2,&r3,&r4,&r5,&r6);
src = regname2ptr(token4_arg2, &r1,&r2,&r3,&r4,&r5,&r6);
*dst += *src;
}
这个问题可以通过引入正确的数据结构以优雅的方式解决。 Paul Griffiths 在他的评论中提到了这一点。
首先,让我们建立一个数据结构:
const int numberOfVariables = 6;
int R[numberOfVariables];
for (int i=0; i<numberOfVariables; i++) {
R[i] = 0;
}
char* tokenNames[] = {"R1", "R2", "R3", "R4", "R5", "R6"};
numberOfVariables
和 tokenNames
是您可以改变行为的点,如果您有更多或更少的名称或其他变量名称。所以基本上,我们不是有六个变量,而是有一个数组用于它们的名称,一个用于它们的值。
然后:
// Assumptions for this snippet.
char token3_arg1[] = "R3";
char token4_arg2[] = "R4";
// Find the index of the name of token 3.
int indexToken3 = 0;
for (; indexToken3<numberOfVariables; indexToken3++) {
// (debug) printf("check: %s", tokenNames[indexToken3]);
if (!strcmp(token3_arg1, tokenNames[indexToken3])) {
break;
}
}
// Find the index of the name of token 4.
int indexToken4 = 0;
for (; indexToken4<numberOfVariables; indexToken4++) {
// (debug) printf("check: %s", tokenNames[indexToken4]);
if (!strcmp(token4_arg2, tokenNames[indexToken4])) {
break;
}
}
Paul Griffiths 正在通过将变量名中的数字转换为数字来查找索引。在这里,我更喜欢更灵活的方式 - 假设你有 R33
.
有了两个索引,最后:
R[indexToken3] += R[indexToken4];
背后的技巧是每个 Rn
的计数器与它们的名称位于相同的索引处。
如果项目变大了,我强烈建议写一个查找索引的函数,甚至使用一个完成的库函数。