Différence entre char et char[1]

en C++ quelle est la différence (le cas échéant) entre l'utilisation de char et char[1].

exemples:

struct SomeStruct
{
   char x;
   char y[1];
};

est-ce que les mêmes raisons s'appliquent à char non signé?

54
demandé sur Steve Jessop 2010-11-08 04:20:32

3 réponses

La principale différence est juste la syntaxe que vous utilisez pour accéder à votre un char.

par "accès" Je veux dire, agir sur elle en utilisant les différents opérateurs dans la langue, la plupart ou toutes qui font des choses différentes lorsqu'elles sont appliquées à un char par rapport à un char tableau. Cela donne l'impression que x et y sont presque entièrement différents. Si fait, ils "comprennent" un char, mais que le char a été représenté d'une manière très différente.

la mise en œuvre pourrait cause d'autres différences, par exemple, il pourrait aligner et pad la structure différemment selon lequel vous utilisez. Mais je doute qu'il le fera.

un exemple des différences de l'opérateur est qu'un char est assignable, et un tableau n'est pas:

SomeStruct a;
a.x = 'a';
a.y[0] = 'a';
SomeStruct b;
b.x = a.x; // OK
b.y = a.y; // not OK
b.y[0] = a.y[0]; // OK

mais le fait que y ne soit pas assignable n'empêche pas SomeStruct d'être assignable:

b = a; // OK

tout cela est indépendamment du type, char ou non. Un objet d'un type, et un tableau de ce type avec la taille 1, sont à peu près les mêmes en termes de ce qui est en mémoire.

mis de côté, il y a un contexte dans lequel il fait une grande différence que vous" utilisez "à partir de char et char[1] , et qui aide parfois à confondre les gens en pensant que les tableaux sont vraiment des pointeurs. Pas votre exemple, mais comme une fonction paramètre:

void foo(char c);     // a function which takes a char as a parameter
void bar(char c[1]);  // a function which takes a char* as a parameter
void baz(char c[12]); // also a function which takes a char* as a parameter

les nombres fournis dans les déclarations de bar et baz sont complètement ignorés par le langage C++. Apparemment quelqu'un à un moment donné a estimé qu'il serait utile aux programmeurs comme une forme de documentation, indiquant que la fonction baz attend son argument pointeur pour pointer vers le premier élément d'un tableau de 12 char.

dans bar et baz, c n'a jamais le type de tableau - il ressemble à un type de tableau, mais il ne l'est pas, c'est juste une syntaxe de cas spécial de fantaisie avec la même signification que char *c . C'est pourquoi j'ai mis les guillemets sur "Utiliser" - vous n'utilisez pas vraiment char[1] du tout, ça y ressemble.

39
répondu Steve Jessop 2010-11-08 02:56:30

si vous avez réellement vu la construction char y[1] comme le dernier membre d'une struct en code de production, alors il est assez probable que vous avez rencontré une instance du struct hack .

ce short array est un stand-in pour un real, mais de longueur variable array (rappelez-vous qu'avant c99 il n'y avait pas une telle chose dans la norme c). Le programmeur attribuait toujours de telles structures sur le tas, en prenant soin de s'assurer que l'attribution était assez grand pour la taille réelle du tableau qu'il voulait utiliser.

11
répondu dmckee 2017-05-23 12:33:20

ainsi que les différences notionnelles dans l'usage souligné par Steve, char[1] peut être passé à par exemple template <int N> void f(char(&a)[N]) , où char x = '" 151910920 "'; f(&x); ne correspondrait pas. Capturer de manière fiable la taille des arguments de tableau est très pratique et rassurant.

cela peut aussi impliquer quelque chose de différent: soit que la longueur réelle soit plus longue (comme expliqué par dmckee), ou que le contenu soit logiquement une chaîne ASCIIZ (qui se trouve être vide dans ce cas), ou un tableau de caractères (qui arrive à avoir un élément). Si la structure était l'une de plusieurs structures connexes (par exemple un vecteur mathématique où la taille du tableau était un argument de modèle, ou un encodage de la disposition de la mémoire nécessaire pour une opération d'E/S), alors il est tout à fait possible qu'une certaine similitude avec d'autres domaines où les tableaux peuvent être plus grands suggérerait une préférence pour un tableau à un seul caractère, permettant au code de support d'être plus simple et/ou plus universellement applicable.

3
répondu Tony Delroy 2010-11-08 03:15:37