Problème de tableau (langage C 89)

Discutez d'informatique ici !
PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

Problème de tableau (langage C 89)

par PrépaQuébec » 04 Juil 2008, 20:05

Bonjour,

je m'initie actuellement au langage C; jusqu'ici tout se passait bien, jusqu'à ce que je fasse connaissance avec les tableaux...
J'ai un petit sushi avec cet exercice:

Exercice 1 : créer une fonction sommeTableau qui renvoie la somme des valeurs contenues dans le tableau (utilisez un return pour renvoyer la valeur).
Pour vous aider, voici le prototype de la fonction à créer :

double moyenneTableau(long tableau[], long tailleTableau);

Voici mon code:

#include
#include

long sommeTableau(long tableau[], long tailleTableau);

int main()
{
long tableau[4]={2,1,5,1};
sommeTableau (tableau, 4);

return 0;
}

long sommeTableau (long *tableau, long tailleTableau)

{
long s=0;
s=tableau[0]+tableau[1]+tableau[2]+tableau[3];
printf("somme= %ld", s);

return 0;
}

Bon ça fonctionne bien, mais quelque chose me dit que j'aurais pu faire mieux au niveau de la fonction sommeTableau (ou alors c'est juste un manque de confiance en moi?) peut-être avec une incrémentation, mais je ne vois pas comment.. en plus j'ai triché, je n'utilise pas de return pour renvoyer la valeur de la somme :marteau:

Vous avez des idées?

Stef



bombastus
Membre Complexe
Messages: 2295
Enregistré le: 29 Nov 2007, 23:35

par bombastus » 04 Juil 2008, 22:02

Bonjour,

2 remarques par rapport à ce qui est demandé dans l'énoncé :
- On te demande d'utiliser un return pour envoyer la valeur de la somme et toi tu l'utilises pour sortir de la fonction donc le fait que ta fonction renvoie un long ne te sert à rien...

- Dans le prototype de ta fonction, il y a la variable tailleTableau et tu ne l'utilises pas, essaie d'écrire la somme du tableau en fonction de cette variable.

Après tu peux aussi faire remplir le tableau par un utilisateur (qui peut commencer à donner la longueur du tableau par exemple) puis tu affiches la somme).

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 05 Juil 2008, 14:02

Voilà pour le retour:

#include
#include

long sommeTableau(long tableau[], long tailleTableau);
long s=0;
int main()
{
long tableau[4]={2,1,5,1};
sommeTableau (tableau, 4);
printf("somme= %ld", s);
return 0;
}

long sommeTableau (long *tableau, long tailleTableau)

{
s=tableau[0]+tableau[1]+tableau[2]+tableau[3];
return s;
}

Stef

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

par abcd22 » 05 Juil 2008, 14:19

Bonjour,
Je pense que tu as mal compris l'énoncé, la fonction sommeTableau doit pouvoir faire la somme des éléments de n'importe quel tableau si on lui donne le tableau et la longueur du tableau en arguments, si je remplace le tableau de main par un tableau à 3 ou 5 éléments je devrais avoir à modifier seulement l'appel à sommeTableau pour que ça marche (pour mettre la bonne longueur), là il faut modifier aussi sommeTableau, ce n'est pas pratique...
Ce n'est pas la peine de copier 2 fois le prototype, ni d'utiliser une variable globale.

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 05 Juil 2008, 14:30

Je suis obligé de mettre un prototype en début de code (je ne l'ai mis qu'une fois?) , ça ne marche pas sinon (je suis sous code::blocks).

J'ai compris l'énoncé, mais je ne parviens pas à faire autrement pour l'instant... j'ai un problème pour écrire la somme si je veux n'utiliser que la taille du tableau... je voudrais faire défiler les valeurs une à une en utilisant "for" et une incrémentation, mais rien à faire (pour l'instant!) ça ne marche pas...

je continue à creuser...

Stef

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 05 Juil 2008, 14:47

Bon j'ai trouvé...
en fait j'avais eine kolossal trou dans la raquette au niveau de mes connaissances sur les sommes:

#include
#include

long sommeTableau(long tableau[], long tailleTableau);
long s=0;
int main()
{
long tableau[4]={2,1,5,1};
sommeTableau (tableau, 4);
printf("somme= %ld", s);
return 0;
}

long sommeTableau (long *tableau, long tailleTableau)

{
int i;
for(i = 0; i < tailleTableau; i++)
s += tableau[i];
return s;

}

C'est ça qui me manquait, je ne savais pas comment écrire cette f**** somme:

s += tableau[i];

Stef

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

par abcd22 » 05 Juil 2008, 15:10

PrépaQuébec a écrit:Je suis obligé de mettre un prototype en début de code (je ne l'ai mis qu'une fois?), ça ne marche pas sinon (je suis sous code::blocks).

En définissant sommeTableau avant main ça ne marche pas? Il n'y a pas besoin de rajouter le prototype avant normalement, c'est ce que je voulais dire.
Tu remarqueras aussi que la définition de sommeTableau n'est pas la même que le prototype, ça marche à cause de la correspondance tableau/pointeur en C, mais c'est à éviter.

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

par abcd22 » 05 Juil 2008, 15:25

PrépaQuébec a écrit:long s=0;
int main()
{
long tableau[4]={2,1,5,1};
sommeTableau (tableau, 4);
printf("somme= %ld", s);
return 0;
}


Les variables globales inutiles c'est mal. À chaque appel à sommeTableau la variable globale s est modifiée, mais pas réinitialisée, si on appelle plusieurs fois la fonction le résultat de sommeTableau sera faux. Il faut initialiser s dans sommeTableau, et pour afficher le résultat on définit une nouvelle variable dans main dans laquelle on met la valeur de retour de sommeTableau (long resultat = sommeTableau(tableau, 4);) avant de l'afficher, ou alors on peut faire
printf("somme = %ld\n", sommeTableau(tableau, 4));
directement pour éviter l'utilisation d'une variable intermédiaire (j'ai rajouté « \n » qui signifie « retour à la ligne », ça fait plus joli pour l'affichage).
C'est ça qui me manquait, je ne savais pas comment écrire cette f**** somme:

s += tableau[i];

On peut écrire aussi s = s + tableau[i];, les « = » dans les programmes en C ne sont pas des égalités mathématiques.

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 05 Juil 2008, 15:47

Exercice 2, calculer la moyenne cette fois, avec ce prototype:

double moyenneTableau(long tableau[], long tailleTableau);

Mon code:

#include
#include

double moyenneTableau (double tableau[],double tailleTableau);
double m=0;

int main()
{
double tableau[4]={10,5,10,10};
moyenneTableau (tableau, 4);
printf("moyenne= %lf", m);
return 0;
}

double moyenneTableau (double tableau[],double tailleTableau)

{
double s=0;
int i;
for(i = 0; i < tailleTableau; i++)
s += tableau[i];
m=s/(tailleTableau);
return m;

}

Ça fonctionne...

abcd22 je ne vois pas comment faire sans variable globale, on utilise la variable m ici dans la fonction main et dans moyenneTableau, donc comment faire sans??

Stef

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

par abcd22 » 05 Juil 2008, 16:27

PrépaQuébec a écrit:abcd22 je ne vois pas comment faire sans variable globale, on utilise la variable m ici dans la fonction main et dans moyenneTableau, donc comment faire sans??

Je l'ai dit dans mon message précédent. Ce qu'il faut comprendre c'est qu'on n'a pas besoin de m (ou s), mais de la valeur retournée par sommeTableau et moyenneTableau (qui est justement m ou s), qu'on peut récupérer en écrivant
long res = sommeTableau(...);
ou en utilisant directement sommeTableau(...) quand on en a besoin.

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 06 Juil 2008, 15:59

Il y a de l'amélioration dans l'air: voici l'énoncé de l'exercice 3:

"créer une fonction copierTableau qui prend en paramètre 2 tableaux. Le contenu du premier tableau devra être copié dans le second tableau.
Prototype :

void copie(long tableauOriginal[], long tableauCopie[], long tailleTableau);"

Mon code:

#include
#include

void copie(long tableauOriginal[], long tableauCopie[], long tailleTableau);

int main()
{
int j=0, k=0;
long tableauOriginal[4]={1,3,6,2};
long tableauCopie [4]={0};
for (j=0; j<4; j++)
{
printf("%ld\n", tableauOriginal[j]);// pour vérification
}
for (k=0; k<4; k++)
{
printf("%ld\n", tableauCopie[k]);// idem vérif
}
copie(tableauOriginal, tableauCopie, 4);
return 0;
}

void copie(long tableauOriginal[], long tableauCopie[], long tailleTableau)
{
int i=0, j=0;
for (i=0; i {
tableauCopie[i]+=tableauOriginal[i];
}
for (j=0; j {
printf("%ld\n", tableauCopie[j]); // j'ai les bonnes valeurs
}
}

Des recommandations?

abcd22, l'énoncé de ces exercices est basé sur un prototype à utiliser; d'où mon choix d'écrire la fonction main avant, et d'où l'obligation de déclarer une variable globale...
...non?

Stef

Dominique Lefebvre
Membre Légendaire
Messages: 8007
Enregistré le: 03 Déc 2005, 14:00

par Dominique Lefebvre » 06 Juil 2008, 16:05

PrépaQuébec a écrit:Il y a de l'amélioration dans l'air: voici l'énoncé de l'exercice 3:

"créer une fonction copierTableau qui prend en paramètre 2 tableaux. Le contenu du premier tableau devra être copié dans le second tableau.
Prototype :

void copie(long tableauOriginal[], long tableauCopie[], long tailleTableau);"

Mon code:

#include
#include

void copie(long tableauOriginal[], long tableauCopie[], long tailleTableau);

int main()
{
int j=0, k=0;
long tableauOriginal[4]={1,3,6,2};
long tableauCopie [4]={0};
for (j=0; j<4; j++)
{
printf("%ld\n", tableauOriginal[j]);// pour vérification
}

for (k=0; k<4; k++)
{
printf("%ld\n", tableauCopie[k]);// idem vérif
}

J'aurais mis cette boucle après la copie...

copie(tableauOriginal, tableauCopie, 4);
return 0;
}

void copie(long tableauOriginal[], long tableauCopie[], long tailleTableau)
{
int i=0, j=0;
for (i=0; i<tailleTableau; i++)
{
tableauCopie[i]+=tableauOriginal[i];

Es-tu sur que c'est ce que tu voulais faire? A quoi sert le "+=" lorsqu'il s'agit de copier?
}
for (j=0; j<tailleTableau; j++)
{
printf("%ld\n", tableauCopie[j]); // j'ai les bonnes valeurs
}
}

Des recommandations?

abcd22, l'énoncé de ces exercices est basé sur un prototype à utiliser; d'où mon choix d'écrire la fonction main avant, et d'où l'obligation de déclarer une variable globale...
...non?

Stef

Tu pourrais faire l'exo avec des pointeurs, si tu as abordé le sujet...

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 06 Juil 2008, 16:14

Oui je suis sûr de ce que je voulais faire: comme j'ai initialisé tableauCopie à 0, il suffisait de faire la somme tableauCopie+tableauOriginal pour effectuer la copie... astucieux, non?? hi hi hi :briques:
J'ai abordé le sujet "pointeur", qui arrivait avant celui des tableaux...
La boucle dont tu parles, je l'ai mise avant la copie (pour être sûr d'avoir un tableau initialisé) et après pour vérifier que la copie s'est bien faite.

Stef

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

par abcd22 » 06 Juil 2008, 16:20

PrépaQuébec a écrit:abcd22, l'énoncé de ces exercices est basé sur un prototype à utiliser; d'où mon choix d'écrire la fonction main avant, et d'où l'obligation de déclarer une variable globale...

Je ne vois pas le rapport, ils précisent le prototype pour dire ce que les fonctions doivent prendre en argument et ce qu'elles renvoient, on peut tout à fait définir les fonctions avant main plutôt que d'écrire le prototype avant main et la fonction après, c'est ce qui est fait d'habitude. Je vois encore moins le rapport avec les variables globales...

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 06 Juil 2008, 16:24

Je SAIS que ça marche sans, mais si je DOIS utiliser un prototype dans mon code, à quoi bon écrire la fonction juste après?
Je ne lutte pas contre l'énoncé... d'autant que je suis supposé maintenant créer un header regroupant tous les prototypes des différents exos.

Stef

Dominique Lefebvre
Membre Légendaire
Messages: 8007
Enregistré le: 03 Déc 2005, 14:00

par Dominique Lefebvre » 06 Juil 2008, 16:43

PrépaQuébec a écrit:Oui je suis sûr de ce que je voulais faire: comme j'ai initialisé tableauCopie à 0, il suffisait de faire la somme tableauCopie+tableauOriginal pour effectuer la copie... astucieux, non?? hi hi hi

Bof, je ne trouve pas cela vraiment très astucieux... Ce n'est pas cohérent avec le principe de la copie d'une case mémoire vers une autre. ça marche dans ton cas parce que tu utilises un tableau de long, mais imagine le topo si tu avais un tableau de caractéres, ou de pointeurs. Tu vas me dire que x + 0 ça donne toujours x, que x soit un pointeur ou un caractère, mais ce n'est pas dans la logique d'une affectation mémoire. En plus, tu fais deux opérations (une addition et une affection) au lieu d'une (une affectation),ce qui n'est pas très efficace...

Dominique Lefebvre
Membre Légendaire
Messages: 8007
Enregistré le: 03 Déc 2005, 14:00

par Dominique Lefebvre » 06 Juil 2008, 16:45

Autre remarque: tu es parti du principe que les deux tableaux avaient la même taille. Je n'ai pas vu cela dans l'énoncé!

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 06 Juil 2008, 16:56

Ok vu comme ça ce n'est pas astucieux... :--:
Bon, je bosse avec un tuto sur un langage que j'ai découvert il y a quoi... trois semaines... je suis issu de la Marine, j'ai travaillé sur de vieux bâtiments où ce qui se rapproche le plus de l'informatique est constitué de logique à relais.
C'est dur d'avoir votre vue d'ensemble... pour le moment j'en suis à chercher des trucs pour que ça marche; ça l'a fait sur l'exercice 3.
Merci de m'aider à m'améliorer.

Sinon, si le tableauOriginal avait été plus grand que tableauCopie, ça aurait buggé (je vais tester ça) pour cause de défaut d'adressage, non? Pour l'inverse, les dernières valeurs de tableauCopie seraient restées à zéro.

En plus, tu fais deux opérations (une addition et une affection) au lieu d'une (une affectation),ce qui n'est pas très efficace...


Je ne comprend pas là?

Merci, Stef, pas découragé! :livre:

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

par abcd22 » 06 Juil 2008, 17:00

PrépaQuébec a écrit:Je SAIS que ça marche sans, mais si je DOIS utiliser un prototype dans mon code, à quoi bon écrire la fonction juste après?

Le prototype est donné « pour vous aider », ce n'est pas écrit qu'il est obligatoire de séparer prototype et définition de fonction (une définition de fonction remplit aussi le rôle de prototype).
Je ne lutte pas contre l'énoncé... d'autant que je suis supposé maintenant créer un header regroupant tous les prototypes des différents exos.

Voilà, dans le header il faut écrire les prototypes, dans le fichier principal on peut facilement s'en passer ici donc je ne vois pas pourquoi compliquer le code avec ça.

Bon les prototypes c'est un problème secondaire, ce sont les variables globales qui sont gênantes, si je fais :
Code: Tout sélectionner
#include
#include

long sommeTableau(long tableau[], long tailleTableau)
{
    long s = 0;
    int i;
    for(i = 0; i < tailleTableau; i++)
        s += tableau[i];
    return s;
}

int main()
{
    long tableau[4] = {2,1,5,1};
    printf("somme = %ld\n", sommeTableau(tableau, 4));
    return 0;
}

je n'utilise pas de variable globale, je ne comprends pas pourquoi tu penses que c'est obligatoire d'en utiliser.
En plus si je remplace main par :
Code: Tout sélectionner
int main()
{
    long tableau[4] = {2,1,5,1};
    long tableau2[5] = {1, 2, 3, 4, 5};
    printf("somme tableau = %ld\n", sommeTableau(tableau, 4));
    printf("somme tableau2 = %ld\n", sommeTableau(tableau2, 5));
    return 0;
}

J'ai la bonne somme pour les deux tableaux, ce qui n'est pas le cas si je sors la ligne « long s = 0; » de la définition de sommeTableau.

PrépaQuébec
Membre Relatif
Messages: 253
Enregistré le: 26 Juin 2007, 15:57

par PrépaQuébec » 06 Juil 2008, 17:11

Ça ne m'a jamais effleuré l'esprit! Appeler la fonction dans le printf...
:ptdr: :ptdr: :ptdr:
C'est en forgeant...

merci abcd22!

Stef

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 3 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