J'ai une fonction, f(char **p)
, et je voulais l'appeler de la manière la plus simple possible.
J'ai essayé
char ** p = {"a", "b"};
f(p);
et a obtenu:
l'objet scalaire nécessite un élément dans l'initialiseur
donc je l'ai changé en
char * p[2] = {"a", "b"};
f(p);
et ça s'est bien passé [ça aurait été aussi bien avec juste char * p[]
].
Pourquoi ne puis-je pas créer un tableau de pointeurs à la volée comme suit?
f({"a", "b"});
Cela donne un avertissement:
char ** p = {"a", "b"};
parce que p
n'est pas un tableau.
Ce n'est pas non plus légal:
f({"a", "b"});
car les accolades en elles-mêmes ne sont pas autorisées dans une expression (mais peuvent être utilisées comme initialiseur).
Il est possible de créer un tableau à la volée comme cela en utilisant un littéral composé :
f((char *[]){"a", "b"});
Vous pouvez également utiliser un littéral composé pour initialiser un temporaire:
char ** p = (char *[]){"a", "b"};
Contrairement à la première instruction, cela est valide car le littéral est un tableau de type char *[2]
et se décomposera en char **
qui peut être utilisé pour initialiser une variable de ce type.
Voir la section 6.5.2.5 de la norme C pour plus de détails sur les littéraux composés.
Cette déclaration char ** p = {"a", "b"};
déclenche un avertissement car C ne sait pas interpréter le contenu de {
}
accolades:
char**
suggère qu'il s'agit d'un seul pointeur vers pointeur vers caractère{
}
spécifie deux éléments.Vous devez dire à C que vous initialisez un pointeur à pointeur avec un pointeur sur l'élément initial d'un tableau anonyme en spécifiant un type devant les accolades:
char ** p = (char*[]){"a", "b"}
Cette construction est appelée "littéral composé". Il pourrait être utilisé dans une déclaration, mais il fonctionne également comme une expression.
Remarque: si vous prévoyez de passer un tableau comme celui-ci à une fonction, vous devez fournir un moyen de déterminer la taille du tableau. Une approche consiste à passer NULL
pour "terminer" le tableau, comme ceci:
void f(char **p) {
int i = 0;
while (*p) {
printf("%d:%s\n", i++, *p++);
}
}
int main(void) {
f((char*[]){"a", "b", NULL});
return 0;
}
C99 et versions ultérieures ajoutées littéraux composés dans le but exact: création de tableaux et de structures à la volée
Exemple:
struct foo {int a; char b[2];} structure;
structure = ((struct foo) {1, 'a', 0});
int *y = (int []) {1, 2, 3};
int *z = (int []) {1};
Mis à part std C99 et versions ultérieures, GCC fournit également cette fonctionnalité en tant qu'extension.
Dans votre cas, cela fonctionnera
f((char *[]){"a","b"});
(char *[]){"a","b"}
est un littéral composé qui crée un tableau de 2 pointeurs vers char
à la volée.