2017-01-26 1 views
1

Tout nouveau pour C, je viens d'un arrière-plan Java.Fonction Prototypes avec tableaux en tant que paramètres

J'ai un problème où je ne peux pas compiler parce que le compilateur veut savoir à la compilation la taille de mon tableau. Par exemple, je veux imprimer mon tableau sur la console. Il ne me permettra pas de déclarer un prototype de fonction en tant que tel:

void printRoom(char[][], int, int); //not allowed 

Que dois-je faire à la place? N'y a-t-il pas moyen de contourner cela? Les ressources en ligne que j'ai trouvées semblent indiquer que je DOIS connaître les dimensions si je veux utiliser un prototype de fonction. Il semble que cela nécessite également que l'en-tête de la fonction ait aussi la taille du tableau.

void printRoom(char room[][], int height, int width){ // not allowed, missing array bounds 

Est-ce que une solution valable à ce problème juste de dire que le tableau est de taille 1000 * 1000 (la taille du tableau maximum que je peux attendre)? Cela me semble bâclé mais je suis à peu près sûr que cela fonctionnerait tant que je resterais dans les limites de ce que la taille du tableau est supposée être.

Je ne suis pas intéressé par pointeurs et malloc en ce moment.

Répondre

2

Si le compilateur prend en charge les tableaux de longueur variable, vous pouvez déclarer la fonction de la manière suivante

void printRoom(int, int, char[*][*]); 

ou tout simplement

void printRoom(int, int, char[][*]); 

Voici un programme démonstratif

#include <stdio.h> 
#include <string.h> 

void printRoom(int, int, char[*][*]); 

void printRoom(int m, int n, char a[m][n]) 
{ 
    for (int i = 0; i < m; i++) 
    { 
     printf("%3s ", a[i]); 
     putchar(' '); 
    } 
    printf("\n"); 
} 

int main(void) 
{ 
    const int M = 2; 
    const int N = 10; 
    char a[M][N]; 

    strcpy(a[0], "Hello"), 
    strcpy(a[1], "World"); 

    printRoom(M, N, a); 

    return 0; 
} 

Sa sortie est

Hello World 

Si le compilateur ne prend pas en charge les VLA, le nombre de colonnes doit être une constante. Par exemple

#define N 100 

//... 

void printRoom(char[][N], int, int); 
+0

Ah il le supporte (en C89). Cependant, il faut toujours que je déclare la taille dans la fonction. Je le saurais déjà pour que ça ne pose pas de problème, mais savez-vous d'une autre façon que je pourrais accomplir cela sans connaître la taille en passant dans une fonction? – frillybob

+0

@frillybob Voir ma mise à jour. –

+1

@frillybob Si vous ne connaissez pas les tailles du tableau, vous devez utiliser soit VLA, soit allouer dynamiquement un tableau de tableaux. –

1

La norme C dit dans §6.7.6.3 déclarateurs de fonction (y compris les prototypes):

¶12 Si la fonction déclarateur ne fait pas partie d'une définition de cette fonction, les paramètres peut avoir le type incomplet et peut utiliser la notation [*] dans leurs séquences de spécificateurs de déclarant pour spécifier des types de tableau de longueur variable.

C'est standard parlent pour: Vous pouvez écrire une déclaration de fonction, mais pas à la définition de la fonction, en utilisant une notation telle que:

void printRoom(int, int, char [*][*]); 

où les arguments sont réordonnés dans la déclaration car dans la définition de la fonction, vous devez spécifier les tailles b VANT spécifier le tableau:

void printRoom(int height, int width, char room[height][width]) 
{ 
    … 
} 

Vous pouvez inverser l'ordre des height et width dans la fonction, mais normalement en C vous nommeriez les dimensions de l'ordre dans lequel ils sont utilisés. Vous n'êtes pas obligé de spécifier la taille de la cote principale; tous les autres doivent avoir une taille associée à eux. Cela signifie que vous pouvez écrire:

void printRoom(int, int, char [][*]); 

et:

void printRoom(int height, int width, char room[][width]) 
{ 
    … 
} 

La fonction doit encore connaître la hauteur afin qu'il puisse traiter le tableau avec précision, mais il ne doit pas faire partie de la définition de tableau.

§6.9.1 Fonction Définition

¶10 Lors de l'entrée à la fonction, les expressions de la taille de chaque paramètre variable modifiée sont évaluées et la valeur de chaque expression d'argument est converti en le type de le paramètre correspondant comme si par l'affectation. (expressions Array et fonction désignateurs comme arguments ont été convertis en pointeurs avant l'appel.)

Votre room est un paramètre modifié variablement.