'while(1)`替代简化分支

我不时用while(1)块来压扁一连串的if..else 。 它沿着这些线。

而不是做:

 // process if (success) { // process if (success) { //process if (success) { // etc } } } 

我做:

 while (1) { // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc break; } 

在这段时间结束的while我有点懊恼。 我可以逃避一个精简的构造(即最终没有break )吗?

我可以用一个variables(或注册?)交易最后的break 。 这不完全是更清楚或更清楚。

 int once = 1; while (once--) { // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc } 

for循环看起来会更好一些(C99):

 for (int once = 1 ; once--; once) { // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc } 

我想过使用开关盒。 它看起来不太好,尽pipe它会起作用。

 switch (1) { default: // process if (!success) break; // process if (!success) break; // process if (!success) break; // etc } 

在这种特殊情况下,标签的概念似乎无与伦比。

 // process if (!success) goto end; // process if (!success) goto end; // process if (!success) goto end; // etc end: 

你们还有什么其他的方法可以使用?

以下是一个非常类似于你正在做的循环的方法,但最后不需要计数器或break语句。

 do { // process if (!success) break; // process if (!success) break; // process if (!success) break; ... // No need for a break statement here } while(0); 

你们还有什么其他方法可以使用?

你可以将你的while循环封装在一个函数中(并且在你有while循环的地方调用这个函数):

 static void process(void) { // process if (!success) return; // process if (!success) return; // process if (!success) return; // process } 

任何中途体面的编译器(例如,即使禁用了优化的gcc )也会内嵌一个static函数,如果它被调用一次。 (当然,一些variables可能必须在process函数的词汇范围内,在这种情况下,只是将它们作为函数的参数提供)。

请注意,从上到下写代码而不是水平(例如,你的例子嵌套if )被称为duffing 。 这里有一个很好的文章:

“从上到下阅读代码”

另外,在Linux内核编码风格中 ,针对横向代码有一个特定的警告书写:

“如果你需要超过3个缩进级别,你总是搞砸了,而且应该修复你的程序”

如果您安排每个条件块生成success的主体是一个如下所示的函数,或者每个// process可以被简化为一个布尔expression式,例如:

 success = f1() ; if( success ) { success = f2() ; if( success ) { success = f3() ; if( success ) { success = f4() } } } 

然后,您可以利用短路评估将其缩减为单个布尔expression式:

 success = f1() && f2() && f3() && f4() ; 

如果f1()返回false,并且对于每个连续调用都相同,那么f2()将不会被调用 – expression式评估在第一个&&操作数子expression式上中止以返回false。

不清楚为什么你需要窝或打破。 我一直这样做,当一个序列需要首次失败保释时:

 // process if (success) { // more process } if (success) { // still more process } if (success) { // even more process } 

摆弄位提供了一个通用的方法。 另一种常见的方法是使用单个状态variables/标志来获得类似的结果。

 bool bErr = false; if (!bErr && success) { // do something } else { bErr = true; } if (!bErr && success2) { // do something } else { bErr = true; } if (bErr) { // hanlde cleanup from errors } 

另一种select是使用一个简单的标志variables

 bool okay = true; if(okay &= success){ // process } if(okay &= success){ // process } if(okay &= success){ // process }