C 语言中的循环结构有四种,分别是 goto ,do while ,while ,for。下面对这四种循环结构在执行循序,性能,以及用途上进行说明。

        goto 

        goto 好比是一个又不好管,又没有能耐的一种人。因为破坏程序的可读性,和流程的流水线,因此一直被语法界骂成狗。刚开始学 C 的时候,老师说过,知道有 goto 这么一回事就行了,一定不要用。

        但是 C 标准发展到现在,一次次更新,goto 却一直没有被干掉,证明在某些场合 goto 是有发展空间的,并除 goto 没有更好的取代方案。在 360 写 poc 时,遇到循环多层嵌套的情况,例如:有好多层循环嵌套,如下面程序。

        但是想在最里面 for 执行到某个条件时,退出所有循环,执行 A 处,如果不用 goto 就很难实现。break 只可跳出一层循环,如果跳出多层循环,就要多次 if break ,if break。

while(1){  for()  {    for()    {      for()      {      }    }  }  }A

        遇到这类情况,就要用到 goto ,可以完美的解决这类问题。

while(1){  for()  {    for()    {      for()      {        goto END_LOOP;      }    }  }  }END_LOOP:  A

        do while

        do while 类似于在大餐厅吃饭的情况,先吃饭后给钱。下面给出程序,用 do while 实现 1-100 相加。

int main(){  int n = 1;  int nSum = 0;  do  {    nSum = nSum + n;    n++;  }while(n <= 100);  printf("%d\r\n", nSum);  return 0;}

        进行调试反汇编,可以看到 do while 的执行顺序。先执行 nSum = nSum + n,再执行 n++,当 n <=100 时,跳转到 07FF769B018B8,也就是 Sum = nSum + n。

android 嵌套for循环 嵌套for循环执行顺序_循环结构

        根据上面的执行顺序和跳转,用 goto 实现 do while 

#include int main(){  int n = 1;  int nSum = 0;  DO_BEGIN:  nSum = nSum + n;  n++;  if (n <= 100)  {    goto DO_BEGIN;  }  printf("%d\r\n", nSum);  return 0;}

        while

        while 类似于在小餐厅吃饭的情况,先给钱后吃饭。下面给出程序,用 while 实现 1-100 相加。

#include int main(){  int n = 1;  int nSum = 0;    while (n <= 100)  {    nSum = nSum + n;    n++;  }  printf("%d\r\n", nSum);    return 0;}

        进行调试反汇编,可以看到 while 的执行顺序。先执行 n <= 100 的判断,在执行 nSum = nSum +n;n++,然后跳转到 07FF6764818B8,也就是 n <= 100 的判断。

android 嵌套for循环 嵌套for循环执行顺序_循环结构_02

        利用上面的执行顺序和跳转,用 goto 实现 while 

#include int main(){  int n = 1;  int nSum = 0;  DO_BEGIN:  if(n <= 100)  {    nSum = nSum + n;    n++;    goto DO_BEGIN;  }    printf("%d\r\n", nSum);  return 0;}

        for

        for 是在开发中最常用的循环结构。下面给出程序,用 for 实现 1-100 相加。

#include int main(){  int n = 1;  int nSum = 0;  for (n = 1;     n <= 100;     n++)  {    nSum = nSum + n;  }  printf("%d\r\n", nSum);    return 0;}

        进行调试反汇编,可以看到 for 的执行顺序。首先赋初值 n = 1,接下来跳转到 07FF68D7E18C9 ,也就是 做 n <= 100 的判断,然后执行 nSum = nSum + n,然后跳转到 07FF68D7E18C1 ,也就是 n++ 处。

android 嵌套for循环 嵌套for循环执行顺序_执行顺序_03

        利用上面的执行顺序和跳转,用 goto 实现 for

#include int main(){  int n = 1;  int nSum = 0;    n = 1;  goto JUDGE;STEP_SIZE:    n++;JUDGE:  if (n <= 100)  {    nSum = nSum + n;    goto STEP_SIZE;  }    printf("%d\r\n", nSum);  return 0;}

利用 goto 实现 do while ,while ,for 后。可以观察到,实现 do while ,while 只用了一个 goto ,而实现 for 需要两个 goto ,明显多一跳。所以,在效率上 do while ,while 相较于 for 是高的。

do while 虽然效率高,但有一个副作用,就是不管怎样都会执行一次,类似于现实中的,吃完饭,发现钱包忘记带了。

往往编程中,只要用到循环结构,几乎大多数人都用 for 。这又是为什么呢?技术圈有一个定理,凡是用的顺手的,效率肯定低。凡是用的不顺手的,效率肯定高。某个问题难度系数一定是常量,假设这个问题难度系数为:5,当使用工具 A 时感到方便,是因为工具 A 做的事情比你多,在解决问题上,工具 A 占了 4/5 ,而你只占了 1/5 ,所以才会觉得方便。当使用工具 B 不方便,是因为你比工具 B 做的事情多,在解决问题上,工具 B 占了 2/5 ,而你却占了 3/5,所以才会觉得不方便。