Rechercher : dans
Par :

Declaration fonction en C HELP

Dernière réponse le 19 oct 2008 à 15:58:42 crazyghandi, le 18 oct 2008 à 10:28:21 
 Signaler ce message aux modérateurs

Bonjour,

Je démarre un programme en C par une fonction toute simple déclarée de la facon suivante :

int verif(char t[], int x){

instructions

}

le compilateur rend l'erreur suivante :

error parsing parameter list, found "[" when expecting ........

Je comprends pas, aidez moi svp

merci d'avance

Configuration: Windows Vista
Opera 9.50

Meilleures réponses pour « declaration fonction en C HELP » dans :
Langage C - Les fonctions Voir La notion de fonction On appelle fonction un sous-programme qui permet d'effectuer un ensemble d'instructions par simple appel de la fonction dans le corps du programme principal. Les fonctions permettent d'exécuter dans plusieurs parties du...
Les templates en C++ VoirIntroduction Avantages Inconvénients Quand utiliser des templates ? Que dois-je mettre dans les .hpp et dans les .cpp ? Convention de notations Quelques templates célèbres STL BGL Premiers pas Spécifications de templates Template par...
Les files en langage C VoirLes files - Premier Entré Premier Sorti Requis I. INTRODUCTION II. Définition III. La construction du prototype d'un élément de la file IV. Opérations sur les files A. Initialisation B. Insertion d'un élément dans la file C. Oter un...
Introduction à la STL en C++ (standard template library) VoirIntroduction Principales classes de la STL std::pair std::list std::vector std::set std::map Les iterators iterator et const_iterator reverse_iterator et const_reverse_iterator Les algorithmes ...
Langage C++ - Les fonctions VoirLa notion de fonction On appelle fonction un sous-programme qui permet d'effectuer un ensemble d'instructions par simple appel de la fonction dans le corps du programme principal. Les fonctions permettent d'exécuter dans plusieurs parties du...
Les structures en langage C++ VoirDifférence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de...

1

fiddy, le 18 oct 2008 à 11:50:27

Salut,
Mets ton message d'erreur en entier ;)
Google is your friend

Répondre à fiddy

2

tatou_38, le 18 oct 2008 à 11:51:09

Int verif(char *t, int x){

instructions

}

marcherait beaucoup mieux. L'argument t passé à la fonction est un pointeur sur caractères.
Tu peux donc faire :


char cMaChaine[50];

rc = verif( cMaChaine , 1 );


tatou_38
Angers

Répondre à tatou_38

3

fiddy, le 18 oct 2008 à 11:57:22

Ce qu'il a mit est strictement la même chose ;)
Google is your friend

Répondre à fiddy

4

bizu53, le 18 oct 2008 à 12:22:27

Je ne saurais plus te dire la différence mais non ce n'est pas "strictement" la même chose (même si cela permet d'obtenir de 2 façons différentes la même chose).

Répondre à bizu53

5

fiddy, le 18 oct 2008 à 12:25:27

Si, c'est strictement.
La différence est que l'une est dans la pile et l'autre dans le tas. Sauf que là tu passes le tout en appel de fonction et qu'on ne passe que le pointeur quelque soit la notation.
Donc int fonction(char buffer[10]) est équivalent à int fonction(char buffer[]), encore équivalent à int fonction(char *buffer)
Google is your friend

Répondre à fiddy

6

saly_inf, le 18 oct 2008 à 12:36:10

Salut...
je veux savoir seulement si la declaration "char buffer[]" veut dir que buffer est un string (pas de longueur spécifiée)...
merci d'avance..
@+

Répondre à saly_inf

7

fiddy, le 18 oct 2008 à 13:09:43

Pas bien de piquer le topic des autres.
char buffer[] dans une fonction ne veut rien dire sauf si tu l'initialises à la déclaration (exemple char buffer[]="coucou")
Dans les autres cas, il faut spécifier un nombre entre les crochets pour que le compilateur réalise l'allocation statique.
Google is your friend

Répondre à fiddy

9

saly_inf, le 18 oct 2008 à 13:19:04

Je pense pas que je pique!!!!
merci pour ta repense serieuse..
@+

Répondre à saly_inf

8

bizu53, le 18 oct 2008 à 13:11:55

Tu dois confondre avec un autre langage ... mais pas en langage C.
Déjà tu peux t'en rendre compte simplement en débuggant : lorsque tu as un * l'espion ne t'affiche pas la chaîne entière mais seulement son premier caractère, contrairement au [].
J'ai déjà eu quelques cas dans mes développements où [] m'était imposé si je ne voulais pas modifier mon code pour utiliser *

Répondre à bizu53

10

fiddy, le 18 oct 2008 à 13:20:33

Non c'est toi qui confonds ;)
Je suis d'accord avec toi dans le corps d'une fonction. Mais pas dans le passage d'arguments en C.
Tiens, je te crée un programme pour te le prouver :

#include <stdio.h>

void fonction(char buffer[]){
    printf("%d\n",sizeof(buffer));
}

int main(void){
    char buffer[10];
    printf("%d\n",sizeof(buffer));
    fonction(buffer);
    return 0;
}

Tu vois bien que ce n'est pas le tableau qui est envoyé dans la fonction mais bien l'adresse du pointeur.
Tu peux t'amuser à modifier char buffer[] dans le prototype de la fonction "fonction" en char *buffer et tu verras que c'est exactement pareil ;)
Google is your friend

Répondre à fiddy

13

saly_inf, le 18 oct 2008 à 13:33:20

C exactement ca que j'ais voulu dir ... puisque je sais que dans les appels des procedures ou des fonctions on met que les pointeur(pas de déclaration). autrement dit j'ai jamais utilisé la syntaxe "chr t[]" dans le c++ sans specifier un nombre entre les crochets...
merci autrefoi..
@+

Répondre à saly_inf

11

guillaume_74, le 18 oct 2008 à 13:21:33

Nan c'est exactement la même chose
les [] signifie que l'allocation est static, et * signifie que c'est dynamique c'est juste une allocation....
je viens de le faire chez moi, et ça marche très bien....
c'est ptètre tout simplement ce que tu lui envoie...

#include <stdio.h>

int fonfon(char t[ ],int val)
{
printf("%s\n%i\n",t,val);
system("pause");
return val+2;
}

int main()
{
int val=6;
char tab[23]={"coucou les amis"};
val= fonfon(tab,val);
printf("%i\n",val);
system("pause");
return 0;
}

Répondre à guillaume_74

12

fiddy, le 18 oct 2008 à 13:27:13

Clique sur les "répondre à" quand tu parles à une personne en particulier. Là je sais pas, si c'est pour me contredire ou contredire bizu ;)
Google is your friend

Répondre à fiddy

15

guillaume_74, le 18 oct 2008 à 21:52:54

Non je ne te contredit pas du tout^^ c'est juste que je voulais répondre :D mais... j'ai du faire un truc ou deux, et quand je suis revenu, des gens avaient posté entre temps :D lol
Moi je pensais juste qu'il avait fait une erreur dans le passage de paramètre, après je sais pas...

Répondre à guillaume_74

14

bizu53, le 18 oct 2008 à 21:38:10

"Nan c'est exactement la même chose les [] signifie que l'allocation est static, et * signifie que c'est dynamique c'est juste une allocation.... "
=> tu le dis toi même ce n'est pas la même chose (même si au final on peut faire les mêmes choses avec, ce que je disais..)

Ce que je disais c'est que ce n'est pas "strictement" la même chose dans le sens où si on déclare en [], on peut l'utiliser comme * mais pas toujours (ou alors c'est l'inverse jsais plus).

Répondre à bizu53

16

guillaume_74, le 18 oct 2008 à 22:00:25
  • +1

Ouais mais ce que je voulais dire, c'est que c'était une question de normalisme... pour la compréhension.
Comme pour les classes en prog objet, il faut les nommer avec des majuscules... c'est inutile, mais c'est une norme.
Mais je suis conscient que je ne m'y connais pas plus que ça.
Je ne dirai plus rien qui contredirai quelqu'un!

Répondre à guillaume_74

17

fiddy, le 18 oct 2008 à 23:31:11

Non et non.
C'est bien strictement la même chose dans le cadre d'une fonction.
Par exemple int fonction(char *toto) est équivalent à int fonction (char toto[]). Exactement pareil. Vérifie par toi même en regardant les différences entre les sizeof. Tu verras aucune différence, et pour cause c'est strictement pareil.

En revanche, dans le corps d'une fonction, ce n'est pas du tout pareil. Le char toto[5] va initialiser statiquement une zone dans la pile alors que le char *buffer, initialisera un pointeur qui pointera dans une zone qu'on devra déclarer dans le heap à l'aide de malloc ou cie.
Google is your friend

Répondre à fiddy

18

bizu53, le 19 oct 2008 à 00:02:37

Je sais bien tout ça, mais encore une fois je ne parlais pas de ça... Je sais bien qu'en mémoire c'est la même place qui est utilisée et je n'ai jamais dit le contraire.
J'ai plusieurs exemples de projets que j'ai fait où je ne pouvais pas mettre : int mafonction(..., char *toto, ...)
et je devais mettre : int mafonction(..., char toto[], ...) si je voulais que ça fonctionne correctement.

Je ne prends aucun plaisir à contredire ce que tu dis ... je le dis en connaissance "de conséquence". (car la cause je ne la connais pas).

Répondre à bizu53

19

fiddy, le 19 oct 2008 à 00:09:07

Impossible lol. Désolé d'insister sur ce point, mais je te garantie que c'est strictement et rigoureusement la même chose. Et je te l'ai même démontré par un exemple.
Par contre c'est vrai que des fois, il peut y avoir des cas où l'un doit être utilisé et non l'autre. Mais dans le cas du prototype de fonction, c'est exactement la même chose.
Google is your friend

Répondre à fiddy

20

bizu53, le 19 oct 2008 à 00:22:44

J'ai voulu chercher sur google pour appuyer mes dire (car mes bouts de codes qui m'ont posés pb sont bien trop longs, et google ne cherche pas les crochets ni les étoiles).
Cependant peut-être serait-ce un élément de réponse (je ne sais pas) : http://mapage.noos.fr/emdel/notes#chaine_litterale
Ou alors peut-être les options du compilateur (je ne sais pas car j'y connais rien du côté compilation, je me contente de compiler avec les options de base).
Il y a certaines petites différences entraînées par le fait d'utiliser statique/dynamique, celle-ci en fait parti, et c'est tout.

De toute façon, moi je m'arrête sur ce sujet car je sais ce que je dis, et ça m'est égal ce que t'en penses. Le jour où tu tomberas dessus tu penseras à moi ;-) lol

Répondre à bizu53

21

fiddy, le 19 oct 2008 à 00:55:26
  • +1

Quand on fournit un lien, faut savoir lire entre les lignes. Le lien que tu donnes dis clairement ce que je dis.

Je cite :

Le langage C n'autorise pas le passage d'un tableau en paramètre à une fonction. La raison est probablement une recherche d'efficacité, afin d'éviter des copies inutiles. Un paramètre 'pointeur' est donc exactement ce qu'il faut.

Rappelons que lorsqu'on définit un paramètre, les syntaxes type *param et type param[] sont sémantiquement équivalentes.

Ca, plus mon petit programme que je t'ai concocté pour te convaincre que c'est pareil. Que veux-tu de plus ?
Je vois très bien ce que tu veux dire, je suis tombé plein de fois sur ces cas. Mais dans le prototype de fonction non, et c'est normal car il y a équivalence (dixit par ton site) ;)
Google is your friend

Répondre à fiddy

22

bizu53, le 19 oct 2008 à 00:58:35
  • +1

Pour en terminer, tu le dis toi-même alors qu'en dire ... pour le reste du site je l'ai lu, et c'est d'ailleurs marqué sémantiquement équivalentes et non pas strictement. Tu peux toujours dire que je chipote, oui, j'appelle un chat un chat, ce n'est pas "strictement" équivalent.

Répondre à bizu53

23

fiddy, le 19 oct 2008 à 01:51:38

Pour ma part, je te l'ai démontré par a+b avec le programme du début. On ne peut pas faire passer un tableau dans une fonction, juste son pointeur. Voilà pourquoi, c'est strictement la même chose
Et puisque t'as l'air dubitatif, je t'envoie un lien : http://cermics.enpc.fr/polys/info1/main/node72.html
Je cite :
Contrairement à ce nous venons d'écrire pour l'affectation t = p;, qui est illégale, il se trouve que dans la situation inverse, une fonction void f(int t[]) sur les tableaux, peut être appelée avec un pointeur en argument, f(p). Ceci provient du fait que ce n'est pas l'objet tableau qui est passé en argument, mais seulement son adresse, et que cette adresse est une valeur de type int*. Les deux déclarations suivantes de fonctions sont donc exactement équivalentes :

void f(int t[]); // ÉQUIVALENT
void f(int *t); // ÉQUIVALENT


Et si t'es toujours pas convaincu, Je te demande juste de me montrer un exemple où ça marche pas. Car, si c'est juste suivant des "souvenirs", on pourra pas aller plus loin.
Google is your friend

Répondre à fiddy

24

bizu53, le 19 oct 2008 à 15:40:02

Je crois que tu n'as pas compris "De toute façon, moi je m'arrête sur ce sujet car je sais ce que je dis, et ça m'est égal ce que t'en penses."
(En plus t'as l'air de vouloir m'apprendre les pointeurs lol...)

Pour ma crédibilité j'ai quand même regardé si j'avais toujours le code, version avant d'avoir rectifié ce qu'il fallait pour éviter le [] que je trouve moche, mais je n'ai que celui qui fonctionne bien avec le *.

Au passage : montrer un exemple de programme qui marche n'est en rien une démonstration. C'est pas parce que 1000 choses marchent que toutes marchent. Et ce que je dis n'est pas "ce n'est pas équivalent", je dis simplement que ce n'est pas "strictement" équivalent.

Répondre à bizu53

25

crazyghandi, le 19 oct 2008 à 15:40:35

Ouah ca suscite des discussions mon sujet

bon au final j'ai reussi en faisant passer le pointeur.

en revanche j'ai une nouvelle question sur la manipulation de chaine de caracteres

j'aimerai extraire n caracteres d'une chaine par exemple

const char ch = {"bonjou"};

char m = ch[2]; //me renvoie 'n' bien sur

comment faire pour recuperer 'nj'?

j'ai essaye les fonctions str et des chipotages du genre

char m=ch[2,3]
char m=ch[2:3]
char m=ch[2;3]
char m=ch[2][3]

mais je ne trouve pas

quelqu'un sait?

encore merci pour vos reponses

Répondre à crazyghandi

26

bizu53, le 19 oct 2008 à 15:43:36

Ouais tu fais une petite fonction qui prend en paramètres ta chaîne de caractères + 2 entier.
et tu parcours du premier au 2ème entier en concaténant les caractères ;-)

pour concaténer tu peux utiliser strcat() (je crois, je ne l'utilise jamais), j'utilise sprintf()

Répondre à bizu53

27

fiddy, le 19 oct 2008 à 15:45:16

"nj" n'est pas un char.
Si tu veux récupérer "nj".
La façon la plus simple :
char m[3];
m[0]=ch[2];
m[1]=ch[3];
m[2]='\0';
Sinon tu peux passer aussi par strncpy ;)
Par exemple
strncpy(ch,m+2,2);
m[2]='\0';
Google is your friend

Répondre à fiddy

29

crazyghandi, le 19 oct 2008 à 15:48:01

Oui alors justement avec strncpy comment demarrer la copie a partir d'un element de la chaine et non pa forcement par le premier element de la chaine

Répondre à crazyghandi

31

fiddy, le 19 oct 2008 à 15:49:52

Ben en ajoutant tout simplement.
Par exemple dans l'exemple que je te donne. Ca copie à partir de l'indice 2.
strncpy(ch,m+2,2);
Google is your friend

Répondre à fiddy

28

crazyghandi, le 19 oct 2008 à 15:46:46

"une petite fonction qui prend en paramètres ta chaîne de caractères + 2 entier"

je comprend pa tu peux illustrer avec un peu de code svp?

merci

Répondre à crazyghandi

30

fiddy, le 19 oct 2008 à 15:48:36
  • +1

Pas besoin de faire cette fonction qui existe déjà. strncpy.
char m[3);
strncpy(ch,m+2,2);
m[2]='\0';
Google is your friend

Répondre à fiddy

32

bizu53, le 19 oct 2008 à 15:49:57

Je l'avais oubliée celle là c'est vrai ^^

Répondre à bizu53

33

crazyghandi, le 19 oct 2008 à 15:53:50

Ok ca marche

mais donc je suis force d'utiliser une fction pas de m=ch[1:3] comme en fortran?

Répondre à crazyghandi

34

bizu53, le 19 oct 2008 à 15:54:32
  • +1

Ouais "obligé" comme tu dis ^^
enfin, il y a peut-être d'autres astuces mais en tout cas tu ne peux pas faire de ch[1:3] ou rien comme ça.

Répondre à bizu53

35

 crazyghandi, le 19 oct 2008 à 15:58:42

Ok merci beaucoup pour votre aide je vais me debrouiller avec ca

a +

Répondre à crazyghandi