Maison  >  Article  >  Tutoriel système  >  Pourquoi goto est-il largement utilisé dans le noyau Linux, alors que de nombreux livres ne préconisent pas son utilisation ?

Pourquoi goto est-il largement utilisé dans le noyau Linux, alors que de nombreux livres ne préconisent pas son utilisation ?

PHPz
PHPzavant
2024-02-05 13:25:271225parcourir

Il y a beaucoup de controverses autour de l'instruction goto en langage C, et de nombreux livres recommandent de "l'utiliser avec prudence ou même d'éviter de l'utiliser". Cependant, dans la pratique de Linus, le père de Linux, il a largement utilisé l'instruction goto sous Linux, ce qui nous a également incité à utiliser cette fonctionnalité de manière raisonnable.

En raison de la controverse, il est nécessaire que nous apprenions à utiliser les instructions goto. Examinons quelques syntaxes de base et des exemples d'instructions goto :

1. Syntaxe de base de goto

L'instruction goto se compose de deux parties : le mot-clé goto et le nom de la balise. Les règles de dénomination des étiquettes sont les mêmes que celles des variables. Exemple :

goto label;

Pour que cette instruction fonctionne correctement, la fonction doit également contenir une autre instruction intitulée label, qui commence par le nom de l'étiquette suivi de deux points, tel que :

label:printf(« allez ici.n »);

2. Exemple de goto

Faites glisser votre doigt vers la gauche ou la droite pour afficher tous les codes>>>>

/*
编译环境: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();
}

Résultat de l'exécution :

Pourquoi goto est-il largement utilisé dans le noyau Linux, alors que de nombreux livres ne préconisent pas son utilisation ?

D'après les résultats d'exécution, nous pouvons évidemment connaître l'utilisation de goto, qui peut sortir de plusieurs boucles. Lorsque l'instruction goto est rencontrée lors de l'exécution du programme, elle peut accéder à l'étiquette pour continuer l'exécution.

Une chose à noter est la suivante : l'instruction goto et son étiquette de saut doivent être dans la même fonction.

3. Quelle est la différence entre goto, break et continue ?

C'est aussi une instruction jump. Quelle est la différence entre l'instruction goto et les instructions break et continue ?

En fait, break et continue sont des formes spéciales de goto. L'avantage d'utiliser break et continue est que leurs noms indiquent déjà leur utilisation.

Jetons un coup d'œil à l'utilisation de break et continuons à travers des exemples de code :

1. Fonction de test de rupture

Utilisez le programme de test ci-dessus pour créer une fonction void TestBreak(void); pour tester l'instruction break, telle que :

Faites glisser votre doigt vers la gauche et la droite pour afficher tous les codes>>>>

/* 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!");
}

Résultat de l'exécution :

Pourquoi goto est-il largement utilisé dans le noyau Linux, alors que de nombreux livres ne préconisent pas son utilisation ?

D'après les résultats en cours d'exécution, nous pouvons évidemment savoir que le break peut sortir de la boucle en cours.

Dans cet exemple, la première instruction break sort de la boucle for actuelle et la deuxième instruction break sort de la boucle while actuelle. On voit qu’une pause peut sortir d’une boucle.

Donc, selon les caractéristiques de break et goto, si vous souhaitez sortir de plusieurs niveaux de boucles, il sera plus pratique d'utiliser goto.

2. continuer la fonction de test

De même, créez une fonction void TestContinue(void); pour tester l'instruction continue, telle que :

Faites glisser votre doigt vers la gauche ou la droite pour afficher tous les codes>>>>

/* 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!");
}

Résultat de l'exécution :

Pourquoi goto est-il largement utilisé dans le noyau Linux, alors que de nombreux livres ne préconisent pas son utilisation ?

Nous pouvons évidemment savoir à partir des résultats en cours d'exécution que continuer peut terminer cette boucle (pas la boucle entière) et entrer dans la boucle suivante (i représente le nombre de boucles).

四、支持与反对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来处理错误!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer