Langage C

Discutez d'informatique ici !
Billball
Membre Complexe
Messages: 2669
Enregistré le: 31 Mar 2006, 19:13

par Billball » 15 Jan 2010, 18:18

*zzzz tjs les maths* oki, c'est noté, merci bien !



Billball
Membre Complexe
Messages: 2669
Enregistré le: 31 Mar 2006, 19:13

par Billball » 23 Jan 2010, 14:17

euuuh finalement un corrigé de l'exo2 m'intéresserait :

on considére un tableau tab de 20 entiers que l'on suppose correctement initianilisé dans cette question. ecrire le prog qui compte et affiche le nombre de zéros du tableau tab

j'ai validé mon sem mais bon, histoire d'obtenir les 6 derniers ects j'ai choisi de repasser l'info !

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 23 Jan 2010, 14:29

re,

Code: Tout sélectionner
procedure SommeZeros(tab)
debut
int nombreZeros = 0; //nombre de zeros trouves dans le tableau
pour chaque element e de tab
 si e % 10 == 0
 //alors on a un multiple de 10, donc au moins un zero
   nombreZeros = nombreZeros + compteZero(valeurCourante);
 finsi
fin pour
fin


Il faut une procedure pour compter le nombre de zero present dans un nombre (10 contient un zero, 100 en contient deux).
Mais jcrois qu'on avait fait une procedure pour ca
la vie est une fête :)

Avatar de l’utilisateur
Olympus
Membre Irrationnel
Messages: 1668
Enregistré le: 12 Mai 2009, 11:00

par Olympus » 23 Jan 2010, 14:39

Bah tu peux te faire tes propres exercices :

- Écrire "Hello World" à l'écran sans stdlib ( donc pas de printf, etc... ), en supposant que la mémoire vidéo est située à l'adresse 0xB800 et que chaque caractère y occupe 2 octets ( Donc "H"->"0xB800", "e" -> "0xB02", "l" -> "0xB04" etc... ), et plus généralement, réécrire printf .
- Réécrire strlen, fonction qui retourne la longueur d'une chaîne de caractères .
- Convertir une chaîne de caractères représentant un nombre ( par exemple "121" ) en un nombre int ( 121 ), sans employer des fonctions comme atoi .
- Réécrire une fonction qui t'intéresse etc...

Avatar de l’utilisateur
Olympus
Membre Irrationnel
Messages: 1668
Enregistré le: 12 Mai 2009, 11:00

par Olympus » 23 Jan 2010, 15:02

fatal_error a écrit:re,

Code: Tout sélectionner
procedure SommeZeros(tab)
debut
int nombreZeros = 0; //nombre de zeros trouves dans le tableau
pour chaque element e de tab
 si e % 10 == 0
 //alors on a un multiple de 10, donc au moins un zero
   nombreZeros = nombreZeros + compteZero(valeurCourante);
 finsi
fin pour
fin


Il faut une procedure pour compter le nombre de zero present dans un nombre (10 contient un zero, 100 en contient deux).
Mais jcrois qu'on avait fait une procedure pour ca


Je ne suis pas sûr d'avoir compris l'énoncé ... Si je comprends bien, si on a un tableau 2100|2010|2009|100, la fonction doit retourner 8 ?

Donc, pour compter les zeros d'un seul nombre, on peut employer cette fonction récursive :

Code: Tout sélectionner
int compte_zeros( int nombre ){
  if( nombre % 10 == 0) return(1 + compte_zeros(nombre/10));
  return(0);
}

Billball
Membre Complexe
Messages: 2669
Enregistré le: 31 Mar 2006, 19:13

par Billball » 23 Jan 2010, 15:29

oué mais je comprend pas ... par exemple pour 208

208%10= 8 mais comment il me retournerait le 1 zéro du 20 que j'attend?

oui c'est ça olympus

Avatar de l’utilisateur
Olympus
Membre Irrationnel
Messages: 1668
Enregistré le: 12 Mai 2009, 11:00

par Olympus » 23 Jan 2010, 15:41

Ha, oublié ça .

Je crois que ça marcherait mieux comme ça :

Code: Tout sélectionner
int compte_zeros( int nombre ){
  int i=0;
  if( nombre % 10 == 0 && nombre !=0) return(1 + compte_zeros(nombre/10));
  i=floor( nombre/10 ); // 20.8 => 20
  if( i != 0) return(compte_zeros(i));
  return(0);
}


Pour floor() : http://en.wikipedia.org/wiki/Floor_and_ceiling_functions .

EDIT : quelques corrections, et enlevé quelques lignes inutiles .

PS : code écrit à la vite fait, pas testé, mais devrait marcher .

abcd22
Membre Complexe
Messages: 2426
Enregistré le: 13 Jan 2006, 14:36

par abcd22 » 23 Jan 2010, 16:42

Billball a écrit:oué mais je comprend pas ... par exemple pour 208

208%10= 8 mais comment il me retournerait le 1 zéro du 20 que j'attend?

oui c'est ça olympus

Tu es vraiment sûr que c'est ça ? En lisant la question je comprends que c'est le nombre de nombres égaux à zéro dans le tableau.

Avatar de l’utilisateur
Olympus
Membre Irrationnel
Messages: 1668
Enregistré le: 12 Mai 2009, 11:00

par Olympus » 23 Jan 2010, 16:51

abcd22 a écrit:Tu es vraiment sûr que c'est ça ? En lisant la question je comprends que c'est le nombre de nombres égaux à zéro dans le tableau.


Ce serait trop facile alors ( comparer chaque nombre à 0, puis ajouter 1 à une variable i dans le cas d'égalité, retourner à la fin de la boucle ce i ) ... Sinon, supposons que ce soit bien le nombre de fois que le chiffre zéro est présent dans le tableau pour pimenter un peu :zen:

abcd22
Membre Complexe
Messages: 2426
Enregistré le: 13 Jan 2006, 14:36

par abcd22 » 23 Jan 2010, 16:55

Olympus a écrit:Ce serait trop facile alors

Ben l'exo 4 est aussi facile que ça donc ce n'est pas invraisemblable.

abcd22
Membre Complexe
Messages: 2426
Enregistré le: 13 Jan 2006, 14:36

par abcd22 » 23 Jan 2010, 17:06

Olympus a écrit:
Code: Tout sélectionner
int compte_zeros( int nombre ){
  int i=0;
  if( nombre % 10 == 0 && nombre !=0) return(1 + compte_zeros(nombre/10));
  i=floor( nombre/10 ); // 20.8 => 20
  if( i != 0) return(compte_zeros(i));
  return(0);
}

Le floor est inutile car en C a/b retourne le quotient de la division euclidienne. D'après la norme du C99 :
[#5] The result of the / operator is the quotient from the
division of the first operand by the second; the result of
the % operator is the remainder. In both operations, if the
value of the second operand is zero, the behavior is
undefined.

[#6] When integers are divided, the result of the / operator
is the algebraic quotient with any fractional part
discarded.76) If the quotient a/b is representable, the
expression (a/b)*b + a%b shall equal a.


Ton code marche à part qu'il retourne 0 comme nombre de zéros pour 0.
Comme code qui marche sinon j'avais :
Code: Tout sélectionner
int compte_zeros(int nombre)
{
   if (nombre == 0)
      return 1;
   if (nombre < 10)
      return 0;
   if (nombre % 10 == 0)
      return 1 + compte_zeros(nombre/10);
   return compte_zeros(nombre/10);
}

(ce serait peut-être plus clair avec des « else if » même si ça ne changerait pas le comportement).

Avatar de l’utilisateur
Olympus
Membre Irrationnel
Messages: 1668
Enregistré le: 12 Mai 2009, 11:00

par Olympus » 23 Jan 2010, 17:18

abcd22 a écrit:Le floor est inutile car en C a/b retourne le quotient de la division euclidienne. D'après la norme du C99


Merci, jamais remarqué ! :briques:
Ton code marche à part qu'il retourne 0 comme nombre de zéros pour 0.


Pas remarqué aussi .

Ton code est le bon sinon :we:

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 23 Jan 2010, 19:16

jtrouve ca particulièrement dangereux d'utiliser la propriété de la division qui donne le quotient, même si c'est dans la norme. Ok on peut, mais c'est pe mieux d'avoir un code clair...

je préfèrerais donc écrire un
return((compteZeros- compteZeros%10)/10);

Cqui est plus compréhensible pour celui qui passe par la... et moins farfelu sur une copie.
la vie est une fête :)

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 23 Jan 2010, 19:41

je trouve ca genant dutiliser la propriété nombre/10 donne quotient, même si c'est dans la norme. D'une part, parce qu'il faut le savoir (ou alors le commenter dans le code), d'autre part, parce que sur la feuille de papier, s'il faut citer le passage, ... c'est assez joyeux.

bref, pour ma part, je prefere pour ce cas la une fonction non recursive simpliste :
Code: Tout sélectionner
int compteZeros(nombre)
{
 int nombreCourant = nombre;
 int nbZeros = 0;
 int reste = 0;//le reste de la division de nombreCourant par 10
 //cas particulier ou le nombre vaut 0
 if(nombreCourant == 0) return 1;
//le but c'est de regarder le chiffre de droite, de compter le zero si c'est un zero
//pis denlever le chiffre de droite et de recommencer
 while(nombreCoutant != 0){
  reste = nombreCourant % 10;
  if(reste == 0){
   nbZeros++;
  }
  //on enleve le chiffre de droite
  nombreCourant = (nombreCourant - reste)/10;
 }
 return nbZeros;
}
la vie est une fête :)

Billball
Membre Complexe
Messages: 2669
Enregistré le: 31 Mar 2006, 19:13

par Billball » 23 Jan 2010, 21:28

un petit printf à la place du return marcherait..? j'ai po vu return

Avatar de l’utilisateur
fatal_error
Membre Légendaire
Messages: 6610
Enregistré le: 22 Nov 2007, 12:00

par fatal_error » 24 Jan 2010, 00:06

je sais pas... il faut tester :id:
la vie est une fête :)

abcd22
Membre Complexe
Messages: 2426
Enregistré le: 13 Jan 2006, 14:36

par abcd22 » 24 Jan 2010, 00:54

Billball a écrit:un petit printf à la place du return marcherait..? j'ai po vu return

Même la fonction main ne retourne rien chez toi ?
return c'est pour donner le résultat de la fonction, par exemple si la fonction déclarée est « int comptezeros(int nombre) », la dernière instruction exécutée lors d'un appel à la fonction doit être « return ».
Dans la fonction donnée par fatal_error, on peut mettre un display("%d", nbZeros); avant de mettre return 0; (mais si on fait ça on ne peut pas écrire « compteZeros(50301) » pour désigner le nombre de zéros de 50301 dans une autre fonction du fichier, car compteZeros(50301) sera une valeur qui n'a rien à voir avec le nombre de zéros de 50301). Dans les fonctions récursives (données par Olympus et moi) on ne peut pas remplacer le return par display car on a besoin du résultat.

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite