一次循环条件下最短

问题描述 投票:-5回答:3

有时我需要goto语句到函数的近端,并避免感觉我在汇编程序中,并且要有严格定义的块来逃避...我使用替代,一次循环,并在其中使用BREAK,它看起来更好。

do {
     ...regular code with break possibility
} while (false);

所以一切都运行良好,正如我想的那样,但我想知道是否有更漂亮的方式,因为如果代码更大,你不会在开始时看到什么是循环。什么会更好看的想法。

喜欢:for (int i=1;i;i=0) { ... }(开始时很明显,但是从那时起不是更好看。或者也许是while (true) { ... ... ... ; break}。最好的是while (something) { ... }哪里有什么东西最短,而且显然它是什么。

现实世界的例子:

#define onceloop() for (int iIi=0;!iIi++;)
void somefunction()
{                                                       onceloop() {
   if ((s=socket(AF_INET, ...)<0) { printf("create error"); break; }
   if (bind(s, addrIp,    ...)<0) { printf("bind error");   break; }
   if (c=accept(s, ...)       <1) { printf("accept error"); break; }
   ...usefull code on indent1 ...                                  
                                                                   }
   printf("something important just before the end of function");
}

看起来比我好:

void somefunction()
{  ...
   if ((s=socket(AF_INET, ...)<0) printf("create error");
   else {
      if (bind(s, addrIp,    ...)<0) printf("bind error");
      else {
         if (c=accept(s, ...)       <1) printf("accept error");
         else {
            ...usefull code on indent4 (or more indent for more ifs)...
         }
      }
   }
   printf("something important just before the end of function");
}

更新:似乎我的意思是duplicate of this question

best answer可能是:switch(0){case 0:

c loops
3个回答
2
投票

这样的goto用法可以用一个函数代替:

void inner() {
     //...regular code with return possibility
}

void outer() {
    inner();
    printf("something more just before end;");
}

但最好使用goto,这是惯用的。它更漂亮,更短,并没有引入新的功能名称。

就在c ++类里面,它需要更多的代码

我不明白为什么它在C ++中会有所不同。但是您可以避免使用lambda定义命名函数。

void outer() {
    [] {
        //...regular code with return possibility
    }();
    printf("something more just before end;");
}

虽然,你可能不一定会以这种方式避免读者的错误评论:)


2
投票

规范解决方案:

#define onceloop() for (int iIi=1;!iIi++;)
void somefunction()
{                                                       onceloop() {
   if ((s=socket(AF_INET, ...)<0) { printf("create error"); break; }
   if (bind(s, addrIp,    ...)<0) { printf("bind error");   break; }
   if (c=accept(s, ...)       <1) { printf("accept error"); break; }
   ...usefull code on indent1 ...                                  }
   printf("something just before the end of function");
}

这是:

void somefunction()
{
    const char *error = NULL;

    if (!error && ((s=socket(AF_INET, ...)<0))
        error = "create error";

    if (!error && (bind(s, addrIp,    ...)<0))
        error = "bind error";

    if (!error && (c=accept(s, ...)  <1))
        error = "accept error";

    if (!error)
    {
        ...usefull code on indent1 ...
    }

    if (error)
        printf (error);
}

根据需要进行调整以匹配您的使用案例。


1
投票

更新:

根据您更新的代码示例,我建议您使用return而不是break并完全删除onceloop()。您还需要引入另一个功能:

void somefunction()
{  ...
   otherfunction();
   printf("something important just before the end of function");
}

void otherfunction()
{
   if ((s=socket(AF_INET, ...)<0) { printf("create error"); return; }
   if (bind(s, addrIp,    ...)<0) { printf("bind error");   return; }
   if (c=accept(s, ...)       <1) { printf("accept error"); return; }
   ...usefull code on indent1 ...                                  
}

您应该考虑更进一步并返回错误代码而不是打印错误消息。然后,调用者可以根据返回的代码确定要执行的操作。

这里有两个一般原则:

  1. 每个函数应该只做一件事并且做得很好。一个功能应该负责网络通信,另一个功能应该负责向用户打印消息。
  2. 方法中的每一行代码都应该处于相同的抽象级别。同样,一种方法应该处理低级网络通信。另一个函数应该将其抽象为业务逻辑。

原始答案:

while循环旨在重复代码,直到满足某些条件。通常这意味着重复多次,尽管在第一次迭代时可以满足条件。

如果您事先知道代码只执行一次,那么if...else语句比while循环更合适。

© www.soinside.com 2019 - 2024. All rights reserved.