Heim  >  Artikel  >  System-Tutorial  >  Warum wird goto im Linux-Kernel häufig verwendet, obwohl viele Bücher seine Verwendung nicht befürworten?

Warum wird goto im Linux-Kernel häufig verwendet, obwohl viele Bücher seine Verwendung nicht befürworten?

PHPz
PHPznach vorne
2024-02-05 13:25:271219Durchsuche

Es gibt viele Kontroversen über die goto-Anweisung in der C-Sprache, und in vielen Büchern wird empfohlen, sie mit Vorsicht zu verwenden oder sogar zu vermeiden. In der Praxis von Linus, dem Vater von Linux, verwendete er jedoch häufig die goto-Anweisung in Linux, was uns auch dazu inspirierte, diese Funktion sinnvoll zu nutzen.

Aufgrund der Kontroverse ist es notwendig, dass wir lernen, goto-Anweisungen zu verwenden. Schauen wir uns einige grundlegende Syntax und Beispiele für goto-Anweisungen an:

1. Grundlegende Syntax von goto

Die goto-Anweisung besteht aus zwei Teilen: dem Schlüsselwort goto und dem Tag-Namen. Die Benennungsregeln für Beschriftungen sind dieselben wie für Variablen. Beispiel:

goto label;

Damit diese Anweisung ordnungsgemäß funktioniert, muss die Funktion auch eine weitere Anweisung mit der Bezeichnung „label“ enthalten, die mit dem Labelnamen gefolgt von einem Doppelpunkt beginnt, wie zum Beispiel:

label:printf(“goto here.n”);

2. Beispiel für goto

Wischen Sie nach links oder rechts, um alle Codes anzuzeigen>>>>

/*
编译环境:mingw32  gcc6.3.0
*/
#include 
#include 

/* goto测试 */
void TestGoto(void)
{
    int i;
 
    while (1)
    {
 for (i = 0; i if (i > 6)
     {
  goto label;
     }
     printf("%s : i = %d\n", __FUNCTION__, i);
 }
    }
 label:
     printf("test goto end!");
}
 
int main(void)
{
    TestGoto();
}

Laufergebnis:

Warum wird goto im Linux-Kernel häufig verwendet, obwohl viele Bücher seine Verwendung nicht befürworten?

Aus den laufenden Ergebnissen können wir offensichtlich die Verwendung von goto erkennen, die aus mehreren Schleifen springen kann. Wenn während der Ausführung des Programms auf die goto-Anweisung gestoßen wird, kann sie zum Label springen, um die Ausführung fortzusetzen.

Bemerkenswert ist: Die goto-Anweisung und ihre Sprungmarke müssen sich innerhalb derselben Funktion befinden.

3. Was ist der Unterschied zwischen Gehe zu, Pause und Fortfahren?

Es ist auch eine Sprunganweisung. Was ist der Unterschied zwischen der goto-Anweisung und den break- und continue-Anweisungen?

Tatsächlich sind Break und Continue Sonderformen von Goto. Der Vorteil der Verwendung von break und continue besteht darin, dass ihre Namen bereits auf ihre Verwendung hinweisen.

Werfen wir einen Blick auf die Verwendung von break und fahren wir mit Codebeispielen fort:

1. Bruchtestfunktion

Verwenden Sie das obige Testprogramm, um eine Funktion void TestBreak(void); zum Testen der Break-Anweisung zu erstellen, wie zum Beispiel:

Wischen Sie nach links oder rechts, um alle Codes anzuzeigen>>>>

/* break测试 */
void TestBreak(void)
{
    int i;
 
    while (1)
    {
 for (i = 0; i if (i > 6)
     {
         break; /* 第一个break:跳出for循环 */
     }
     printf("%s : i = %d\n", __FUNCTION__, i);
 }
 printf("Now i = %d\n", i);
 break;     /* 第一个break:跳出while循环 */
    }
    printf("test break end!");
}

Laufergebnis:

Warum wird goto im Linux-Kernel häufig verwendet, obwohl viele Bücher seine Verwendung nicht befürworten?

Aus den laufenden Ergebnissen können wir offensichtlich erkennen, dass break die aktuelle Schleife verlassen kann.

In diesem Beispiel verlässt die erste break-Anweisung die aktuelle for-Schleife und die zweite break-Anweisung verlässt die aktuelle while-Schleife. Es ist ersichtlich, dass ein Break eine Schleife verlassen kann.

Wenn Sie also aus vielen Schleifenebenen springen möchten, ist es gemäß den Eigenschaften von break und goto bequemer, goto zu verwenden.

2. Testfunktion fortsetzen

Erstellen Sie auf ähnliche Weise eine Funktion void TestContinue(void);, um die continue-Anweisung zu testen, wie zum Beispiel:

Wischen Sie nach links und rechts, um alle Codes anzuzeigen>>>>

/* continue测试 */
void TestContinue(void)
{
    int i;
 
    for (i = 0; i if (i > 6)
 {
     printf("i = %d, continue next loop\n", i);
     continue; /* continue:结束本次循环(而不是终止这一层循环)继续进入下一次循环 */
 }
 printf("%s : i = %d\n", __FUNCTION__, i);
    }
    printf("test break end!");
}

Laufergebnis:

Warum wird goto im Linux-Kernel häufig verwendet, obwohl viele Bücher seine Verwendung nicht befürworten?

Aus den laufenden Ergebnissen können wir natürlich erkennen, dass continue diese Schleife (nicht die gesamte Schleife) beenden und in die nächste Schleife eintreten kann (i steht für die Anzahl der Schleifen).

四、支持与反对goto的理由是什么?

1、不提倡使用goto

不提倡使用goto的占比应该比较多,不提倡的原因主要是:很容易把逻辑弄乱且难以理解。

2、使用goto的理由

这一部分人认为goto可以用在以下两种情况比较方便:

(1)跳出多层循环。

这个例子就类似于我们上面的goto测试程序。

(2)异常处理。

一个函数的执行过程可能会产生很多种情况异常情况。下面有几种处理方式,以代码为例:

方法一:做出判断后,如果条件出错,直接return。

*左右滑动查看全部代码>>>*

int mystrlen(char *str)
{
   int count = 0;
   if (str == NULL)
   {
      return-1;
   }

   if (*str == 0)
   {
      return0;
   }

   while(*str != 0 )
   {
      count++;
      str++;
   }
   return count;
}

方法二:先设置一个变量,对变量赋值,只有一个return。

*左右滑动查看全部代码>>>*

int mystrlen(char *str)
{
   int ret;
   if (str == NULL)
   {
      ret = -1;
   }
   elseif (*str == 0)
   {
      ret = 0;
   }
   else
   {
      ret = 0;
      while(*str != 0 )
      {
         ret++;
         str++;
      }
   }
   return ret;
}

方法三:使用goto语句。

*左右滑动查看全部代码>>>*

int mystrlen(char *str)
{
   int ret;
   if (str == NULL)
   {
      ret = -1;
      goto _RET;
   }

   if (*str == 0)
   {
      ret = 0;
      goto _RET;
   }
       
   while(*str !=0 )
   {
      ret++;
      str++;
   }

_RET:
   return ret;
}

其中,方法三就是很多人都提倡的方式。统一用goto err跳转是最方便且效率最高的,从反汇编语句条数可以看出指令用的最少,消耗的寄存器也最少,效率无疑是最高的。

并且,使用goto可以使程序变得更加可扩展。当程序需要在错误处理时释放资源时,统一到goto处理最方便。这也是为什么很多大型项目,开源项目,包括Linux,都会大量的出现goto来处理错误!

Das obige ist der detaillierte Inhalt vonWarum wird goto im Linux-Kernel häufig verwendet, obwohl viele Bücher seine Verwendung nicht befürworten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:lxlinux.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen