2017-10-20 18 views
1

Je me demandais comment faire qu'une fonction considère un paramètre donné comme une variable statique. Par exemple, je l'ai essayé, sans succès, pour générer des nombres de grêlon:Elaborer un paramètre de fonction comme variable statique

#include<stdio.h> 
int hailstone(int); 
int n;       /* n is an extern variable*/ 

int main(){ 
    hailstone(n); 
    return 0; 
} 

int hailstone(int n){ 
    static int m = n;   /*not possible because n is not constant*/ 
    if(m % 2 == 0 && m != 1) 
     hailstone(m /= 2); 
    else if(m != 1) 
     hailstone((m *= 3) + 1); 
    else 
     exit(0);     /*Is the use of exit() correct, in this case?*/ 
    return 0; 
} 

Je voudrais utiliser une variable statique pour élaborer n. Sinon, chaque appel récursif fonctionnerait sur l'ensemble du paramètre n, continuant sans fin, n'atteignant jamais la base de casse.

Peu de questions:

  1. Est-ce que cette idée représente une approche réaliste du problème?
  2. Est-ce que cette idée représente une approche raisonnable/efficace au problème?
  3. Est-ce que exit(0) est utilisé correctement, dans un cas similaire?
+2

'statique m int; m = n; 'est possible, cependant. – Bathsheba

+3

L'utilisation d'une variable globale dans une fonction récursive élimine le point de récursivité. Vous devez donc absolument repenser votre solution. Dans tous les cas, votre fonction ne montre aucun cas de base (autre que 0, qui ne peut être atteint). Quel est le cas de base, à votre avis, et pourquoi pensez-vous que la récursivité ne l'atteindra pas? – rici

+0

@ricie, la base de cas n'est-elle pas représentée par 'm <1'? Peut-être, puisque le résultat final devrait être 1, 'm == 1' pourrait être un meilleur cas de base, vous avez raison. En outre, j'étais précisément en train de me demander comment dépasser le problème de la variable globale. – Worice

Répondre

3

Vous n'avez pas besoin d'une variable statique pour cela. Il suffit de passer la nouvelle valeur pour fonctionner et l'utiliser. En outre, la valeur 1 est votre cas de base, vérifiez donc pour arrêter la récursivité et imprimez la valeur de n afin que vous puissiez réellement voir ce qui se passe.

void hailstone(int n){ 
    printf("n=%d\n", n); 
    if(n % 2 == 0 && n > 1) { 
     hailstone(n/2); 
    } else if(n > 1) { 
     hailstone((n*3) + 1); 
    } 
} 

Étant donné que cette fonction pourrait se poursuivre pendant quelques itérations, une solution récursive pourrait finir par causer un débordement de pile. Mieux vaut aller avec une solution itérative:

void hailstone(int n){ 
    while (n > 1) { 
     printf("n=%d\n", n); 
     if(n % 2 == 0) { 
      n = n/2; 
     } else { 
      n = (n*3) + 1; 
     } 
    } 
} 
+0

Merci à @rici commentaire j'ai ajusté la base de cas, merci. – Worice

+1

Je vais faire un peu de pratique de votre code. Merci pour le double exemple. La récursivité n'est toujours pas si intuitive pour moi, donc être capable de la comparer avec une approche itérative est vraiment utile. – Worice

1

Voici l'algorithme récursif pour orage de grêle, il n'y a pas besoin de static

#include <assert.h> 
#include <stdio.h> 

void hailstone(unsigned int n) 
{ 
    assert(n>0); 
    printf("%u\n", n); 
    if (n == 1) 
     return; 
    if(n & 1) { 
     hailstone(3*n + 1); 
    } 
    else { 
     hailstone(n >> 1); 
    } 
} 

int main() { 
    hailstone(5); 
} 
+0

Merci pour votre exemple, il me donne un bon aperçu sur le problème! – Worice