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 !
-
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

-
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...
-
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
-
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.
-
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).
-
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:
-
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

-
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
-
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.
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités