一次循环条件下最短

时间:2018-01-22 00:48:43

标签: c loops

有时我需要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");
}

更新 我的意思似乎是users machine

duplicate of this question可能是:switch(0){case 0:

3 个答案:

答案 0 :(得分: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;");
}

尽管如此,您可能不一定会以这种方式避免读者的错误评论:)

答案 1 :(得分: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);
}

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

答案 2 :(得分: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. 方法中的每一行代码都应该处于相同的抽象级别。同样,一种方法应该处理低级网络通信。另一个函数应该将其抽象为业务逻辑。

  3. 原始回答:

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

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