[C] tableau de chars en paramètre d'une fonction

Bonjour tout le monde,

je suis un débutant en C et je me demandais comment faire pour passer un tableau de chars en paramère d’une fonction.

Je crée le tableau et l’initialise

char Liste [64][4] = {…

Ensuite vient ma fonction. En fait j’aimerais copier l’élément Liste[Indice], mais j’obtiens une erreur d’initialisation…

int fonct( int Indice, char** Liste)
{
char temp = Liste[Indice];
}

Quelqu’un sait ce que je fais faux?

merci!!

Hum je suis pas une brute loin de là :stuck_out_tongue:
Mais si tu initialise un tableau à deux dimensions : char [][] alors tu dois avoir deux indices non ?
pour imager un indice colonne et un autre ligne

Après je sais pas si c’est bon

stfw :stuck_out_tongue:

http://c-faq.com/aryptr/pass2dary.html

Liste est un tableau de tableaux de caractères (char **, ou char Liste[64][4]).
Temp est un caractère.

Liste[0] renvoie un tableau de 4 caractères, et ca tient pas dans un caractère. En fait, c’est pas le meme type (char vs char*/char[])

Ca pourrait valoir de coup de choper un cours de fac premier niveau sur le ouèbe, j’t"e l’dis. Mais recois tous nos encouragements…

[quote=“vectra, post:4, topic: 29479”]Liste est un tableau de tableaux de caractères (char **, ou char Liste[64][4]).
Temp est un caractère.

Liste[0] renvoie un tableau de 4 caractères, et ca tient pas dans un caractère. En fait, c’est pas le meme type (char vs char*/char[])

Ca pourrait valoir de coup de choper un cours de fac premier niveau sur le ouèbe, j’t"e l’dis. Mais recois tous nos encouragements…[/quote]

en fait, j’ai écrit ca rapidement pour le faire, mais en fait l’erreur est aussi valable avec le

char temp[4] = Liste[indice];

je vais essayer avec:
int fonc( int Indice, char (*liste)[64])

[quote=“moctesuma, post:1, topic: 29479”]int fonct( int Indice, char** Liste)
{
char temp = Liste[Indice];
}

Quelqu’un sait ce que je fais faux?

merci!![/quote]
pour la fonction, je te conseille

C’est pareil pour le compilo mais c’est mieux niveau lecture, tu sais que tu passe un tableaux a 2 dimensions plutot qu’un pointeur de pointeur char

Pour le reste, c’est:

char *temp; temp=liste[indice];
Apres, comme on sait pas ce que tu veux faire…

Mais bon, on a l’habitude de voir des debutants ici qui commencent par ce qu’il y a de plus complique en C, a savoir les pointeurs

LoneWolf
People never learn

[quote=« LoneWolf, post:6, topic: 29479 »]pour la fonction, je te conseille

int fonct( int Indice, char Liste[][])

C’est pareil pour le compilo mais c’est mieux niveau lecture, tu sais que tu passe un tableaux a 2 dimensions plutot qu’un pointeur de pointeur char[/quote]
Sauf que non, en C on doit définir la taille de toutes les dimensions sauf éventullement la première. Donc ce serait plutôt « Liste[4]. »

Les pointeurs c’est méchamment la base du C quand même. C’est pas évident à comprende, mais c’est pas évident de faire quoi que ce soit d’intéressant en C sans toucher un pointeur.

[quote]LoneWolf
People never learn[/quote]
Eh ouais,
/me file un livre de C à LoneWolf :stuck_out_tongue:

Personne a rien dit ou je suis mal réveillé.
Si c’est un int la fonction, faudrait un p’tit return :stuck_out_tongue:
Sinon c’est un void.

Pour le probleme du tableau a double dimensions si on ne connait rien sur les dimensions on peut faire :

int f(char * liste, int nrows, int ncolumns);

On y accede via

liste[i * ncolumns + j]

Car dans le cas de Lone, le compilo ne connait le nombre de colonnes ce qui coince.
Note: en cherchant dans cafzone on retrouve ça : http://www.cafzone.net/ipb/index.php?showtopic=32354
Je savais bien que cette question avait déjà été posée :stuck_out_tongue:

Aaaha? bon je verifierais parce que je suis pas sur la.

LoneWolf
Non je mets pas ta parole en doute, Drealmer :stuck_out_tongue:

[quote=“LoneWolf, post:9, topic: 29479”]Aaaha? bon je verifierais parce que je suis pas sur la.

LoneWolf
Non je mets pas ta parole en doute, Drealmer :P[/quote]

A ta décharge, j’avoue que j’ai déjà vu des compilos qui acceptaient la notation [][]. Mais je n’ai jamais vu ça employé que dans le cas de argv, et je pense que c’était en Borland C, mais pas sûr. En fait, je ne sais pas trop d’où ça sort parmi les différentes normes C (K&R, ANSI, C99) et les approximations des implémentations. Ce qui est sûr, c’est que c’est pas une notation à recommander.

Moi j’ai debute sur Turbo C 2.0 de Borland, donc je pense que ca vient de la.
Effectivement, la notation que j’ai signale est fausse avec gcc. En fait, si on declare char tab[4][10] et qu’on veut le passer a une fonction, ca fait ca:

int read(char **tab,int x, int y)

Erreur a la compilation

int read(char *tab[],int x, int y)

Erreur a la compilation

int read(char tab[][],int x, int y)

Erreur a la compilation

int read(char tab[][10],int x, int y)

Ca marche.

Donc, mea culpa tout ca, je suis rouille en C, c’est MAL, je vais apprendre le C# a la place :stuck_out_tongue:

LoneWolf
Coup d’vieux :stuck_out_tongue:

Ami ! :stuck_out_tongue:

En fait, pour ajouter une petite précision, on dit souvent à tort que pointeurs et tableaux sont deux concepts interchangeables, en fait non y’a quelques différences qui ont leur importance, et auxquelles on se heurte ici. La différence entre un tableau de tableaux et un tableau de pointeurs, c’est que dans le premier cas tous les éléments sont contigus, et si on a un truc genre array[4][12], l’addresse de array[2], c’est array + 24 (c’est pour ça que le 12 est une information nécessaire lors d’un passage en paramètre). Alors que par contre, le fameux « char * argv » n’en a pas besoin, car c’est un véritable tableau de pointeurs.

Et si avec tout ça moctesuma n’est toujours pas dégoûté du C, je ne sais pas ce qu’il faut… Non je déconne, le C c’est un langage que j’aime énormément, un peu comme j’aime les 3C509 ISA et les Trident 9440, parce que c’est mon enfance. Mais c’est pas ce qui se fait de plus agréable à utiliser de nos jours :stuck_out_tongue:

[quote=« Ptit_boeuf, post:2, topic: 29479 »]Hum je suis pas une brute loin de là :stuck_out_tongue:
Mais si tu initialise un tableau à deux dimensions : char [][] alors tu dois avoir deux indices non ?
pour imager un indice colonne et un autre ligne

Après je sais pas si c’est bon[/quote]
Pareil pour moi, je suis loin d’etre une brute, mais il me semblait qu’on pouvait accéder à n’importe quel indice d’un tableau a 2 dimension avec un indice unique en fait, genre si t’a un tableau a deux dimensions genre tableau[a][b] et que tu veux récupérer un des éléments, mettons tableau[x][y], tu peux aussi le faire avec tableau[x*a+y] (dès lors qu’on utilise un pointeur) (mais si mes souvenirs très flous ne me trahissent pas, de toutes facons un tableau c’est une espece d’abstraction d’un pointeur sur le début du tableau).

Non, c’est pas « xa+y" mais ce serait plutôt "xb+y », et encore ça va renvoyer un truc du mauvais type et si les éléments contenus n’ont pas la taille d’un pointeur, va falloir caster avant. Bref, faut surtout jamais faire un truc pareil :stuck_out_tongue: Sinon je recommande chaudement la lecture des posts compris entre le début et la fin du thread :stuck_out_tongue:

Normalement (je prends des pincettes maintenant), si on a tab[4][10], on peut faire ca:
(tab+(210sizeof(char))) <-equivalent de tab[2]
(((tab+(2
10sizeof(char))))+4sizeof(char)) <–equivalent de tab[2][4]

Moi perso, je trouve pas ca tres lisible.

LoneWolf
Vieux souvenirs d’algebre des pointeurs

[quote=« LoneWolf, post:15, topic: 29479 »]Normalement (je prends des pincettes maintenant), si on a tab[4][10], on peut faire ca:
(tab+(210sizeof(char))) <-equivalent de tab[2]
(((tab+(2
10sizeof(char))))+4sizeof(char)) <–equivalent de tab[2][4][/quote]
Euh non :stuck_out_tongue:

Si t’as un tableau de type X, ajouter 1 ajoute sizeof(X) à l’addresse de base. Donc pas besoin de « tab+(210sizeof(char)) », « tab + 2 » suffit. Voici plutôt à quoi ça ressemble, ici p0==p1 et p2==p3.

[code]char * p0 = *(tab + 2);
char * p1 = tab[2];

char * p2 = *(tab + 2) + 4;
char * p3 = &(tab[2][4]);[/code]

LoneWolf va finir par croire que je lui en veux :stuck_out_tongue:

edit: légère simplification du code par suppresion des cast inutiles :stuck_out_tongue:

Drealmer : tu n’aurais pas fait une erreur pour p2 ? Je vois mal comment il pourrait être égal à p3, à moins que tab[2] contienne une valeur magique qui fasse que l’addition donne le bon résultat (et avec un char dans le tableau, pour donner une adresse mémoire ça va être limité :P)

char * p2 = tab + 2*10 + 4; char * p3 = &(tab[2][4]);

[quote=« Drealmer, post:16, topic: 29479 »]Euh non :stuck_out_tongue:

Si t’as un tableau de type X, ajouter 1 ajoute sizeof(X) à l’addresse de base. Donc pas besoin de « tab+(210sizeof(char)) », « tab + 2 » suffit. Voici plutôt à quoi ça ressemble, ici p0==p1 et p2==p3.

[code]char * p0 = *(tab + 2);
char * p1 = tab[2];

char * p2 = *(tab + 2) + 4;
char * p3 = &(tab[2][4]);[/code]

LoneWolf va finir par croire que je lui en veux :stuck_out_tongue:

edit: légère simplification du code par suppresion des cast inutiles :P[/quote]
Je crois plutot que je confonds tout en fait.
Tu dis la que si on fait un tableau de taille constante, le compilo sait quel est le nombre d’octets pour chaque case. C’etait pas le cas quand on m’a appris les pointeurs.
J’ai fait un programme qui teste ca:

[code]#include<stdio.h>
#include <stdlib.h>

int main(void)
{
int pi,tabi[10],i;
for(i=0;i<10;i++) tabi[i]=i;
pi=malloc(10
sizeof(int));
for(i=0;i<10;i++) pi[i]=i;

	for(i=0;i<10;i++)
	{
			printf("pos(tab):%X:%d\n",tabi+i,(int)*(tabi+i));
			printf("pos(p):%X:%d\n",pi+i,(int)*(pi+i));

	}
	return 0;

}[/code]
En fait, meme si j’utilise pi ou tabi, j’ai le meme resultat, qui est correct en plus. Je pense que ca ne fonctionne plus si on utilise void, mais c’est tricher dans ce cas la.

Comme quoi, je suis UBER rouille B)

LoneWolf
Ca y est, j’suis deja has been :stuck_out_tongue:

Le coup de l’arithmétique des indices, ca ne marche que si on alloue tout le bousin statiquement, non?

En fait, pour ne pas s’y perdre, mieux vaut TOUT faire à partir des pointeurs, et manipuler des char*, char** ou char***: c’est tout de suite moins prise de tête (on passe son temps à faire des casts: au moins, en explictant le type tout le temps, on sait bien ce qu’on fait). L’avantage, d’ailleurs, c’est qu’on peut allouer des plages de mémoire plus grosses, et on demand, alors que la version statique, il faut qu’il trouve un bloc assez gros tout de suite pour tout mettre.

En meme temps, au niveau de l’OS, tout ca doit pas être beau à voir au niveau de la pagination. Enfin, un problème à la fois siouplé. :stuck_out_tongue:

Mmmh… Je ne vois pas trop l’idée derrière ton programme LoneWolf, surtout que tes casts en int ne sont pas nécessaires, le compilo sait que déréférencer tabi et pi par [] ou * donne un int.

Pour kineox, la réponse est non y’a pas d’erreur dans “*(tab + 2) + 4;”, j’explique:

  1. le type de tab est char[4][10]
  2. or a[x] et *(a+x) sont équivalents
  3. donc le type de *(tab+2) est le même que celui de tab[2], càd char[10].
  4. même raisonnement pour le +4.

Vu d’une autre façon, on a:

[code]*(tab + 2) + 4;

tab[2] + 4;

&tab[2][4];[/code]

(notez l’introduction du & au niveau de la dernière ligne)