我们都知道goto语句经常被人所诟病,原因是:
首先,由于goto语句可以灵活跳转会导致破坏结构化设计风格,若一段代码多次使用goto语句会降低代码的可读性。
其次,goto语句的执行可能会跳过变量的初始化、重要的计算语句等,甚至影响到整个程序的运行。
下面笔者介绍一种可以代替goto语句的方法。
void SearchInfo(MailList* ml,char* find)
{
char *ret;
char age[4] = "0";
//sprintf(age,"%d",g_allMsg[i].age);返回值是strlen()
//scanf()的用法
//sprintf()和ctrcpy有什么区别?
int i=0;
int j = 1;
int flag = 0;
int count = 0;
/*for (;j<100;++j)
{
save[j] = 0;
}*/
for (i = 0; i < ml->size; ++i)
{
/*printf("%d", ml->size);
printf("%s", find);*/
flag = 1;
do
{
ret = strstr(ml->data[i].name, find);
if (ret)
{
++count;
break;
}
ret = strstr(ml->data[i].addr, find);
if (ret)
{
++count;
break;
}
ret = strstr(ml->data[i].sex, find);
if (ret)
{
++count;
break;
}
sprintf(age, "%d", ml->data[i].age);//把数字转化成字符串了
ret = strstr(age, find);
if (ret)
{
++count;
break;
}
ret = strstr(ml->data[i].tel, find);
if (ret)
{
++count;
break;
}
flag = 0;
} while (0);//goto的解决方案do while(0)
if (flag)
{
save[j] = i;
++j;
}
}
if (count)
{
save[0] = count;
}
/*else
{
printf("找到0条信息\n");
}*/
showsearchdata(ml);
}
可以看到笔者想要在多条信息中查找想要的字符串并将它对应的编号存储到一个全局数组中,如果按照传统思维,每对比一条信息的年龄,电话等等都要跳出循环去记录数据。此时可以用到goto语句,但这会大大增加代码的长度,增加执行流程的不确定性。
在这里替代的方式是,将查找的过程放到do{........}while(0)当中,借助循环自带的break语句就可以实现随时跳出,去执行记录数据的操作,而且do{........}while(0)每次只执行一次,不会破坏程序执行的流程,continue也可以达到这样的效果,它也会去跳到条件判断处,进行判断。