OVH Cloud OVH Cloud

Initialisation d'un tableau de char par une chaine constante

42 réponses
Avatar
candide
Bonjour,

Les déclaration (de portée une fonction) suivantes :

char t1[100]={0};

et

char t2[100]="0";

initialisent-elles les tableaux de la même façon ?

Il est clair que la valeur de chaque élément de t1 est 0 et que la valeur du
premier élément de t2 aussi mais peut-on dire plus concernant t2 ?

De son côté la Norme dit :

An array of character type may be initialized by a character string literal,
optionally enclosed in braces. Successive characters of the character string
literal (including the terminating null character if there is room or if the
array is of unknown size) initialize the elements of the array.

et l'initialisation y est définie par :

An initializer specifies the initial value stored in an object.

(ce que je trouve assez peu précis).

Merci

10 réponses

1 2 3 4 5
Avatar
ld
On 18 août, 09:41, -ed- wrote:
On 17 août, 18:08, ""

wrote:

> char t1[100] = { "0" } ;

N'existe pas.



Ca existe et c'est conforme (voir 6.7.8§14).

a+, ld.
Avatar
bpascal123
On 18 août, 10:19, ld wrote:
On 18 août, 09:41, -ed- wrote:

> On 17 août, 18:08, ""

> wrote:

> > char t1[100] = { "0" } ;

> N'existe pas.

Ca existe et c'est conforme (voir 6.7.8§14).

a+, ld.



Bonjour,

Je pense que ed a raison, ça n'existe pas et ça ne doit pas être
conforme. Le compilateur émet des messages d'erreurs pour :

#include <stdio.h>

int main(void)
{
char Tab1[] = { "a", "b", "c", "" } ;
int i ;

for ( i = 0 ; i < 3 ; i++ )
printf("%c", Tab1[i]) ;

return 0 ;
}

Par contre :

#include <stdio.h>

int main(void)
{
char Arr1[] = { 'a', 'b', 'c', '' } ;
int i ;

for ( i = 0 ; i < 3 ; i++ )
printf("%c", Arr1[i]) ;

return 0 ;
}

fonctionne comme attendu et me paraît cohérent.

En fait les guillemets doublent s'emploieraient dans les déclarations
de tableaux multidimensionnels :

char Arr1[4][6] = { "Alpha", "Beta", "Gamma", "Delta" }
...

J'ai commencé à apprendre le C depuis 2-3 mois et je pense que je dois
encore m'investir avant d'intervenir dans une discussion. "Bon silence
vaut mieux que mauvaise dispute. "

Pascal
Avatar
bpascal123
On 18 août, 10:19, ld wrote:
On 18 août, 09:41, -ed- wrote:

> On 17 août, 18:08, ""

> wrote:

> > char t1[100] = { "0" } ;

> N'existe pas.

Ca existe et c'est conforme (voir 6.7.8§14).

a+, ld.



Bonjour,

D'après mes connaissance, j'ai commencé à apprendre le C il y a
quelques mois, dans le cadre d'une initialisation, char t1[100] =
{ "0" } ; est valable mais dans le cadre d'une affectation, ça ne
l'est pas.
Je me questionne sur l'utilité d'iniatilisé une variable tableau avec
0, c'est automatiquement effectué lors de la déclaration char t1
[100] ; ?

Pascal
Avatar
espie
In article ,
wrote:
On 18 août, 10:19, ld wrote:
On 18 août, 09:41, -ed- wrote:

> On 17 août, 18:08, ""

> wrote:

> > char t1[100] = { "0" } ;

> N'existe pas.

Ca existe et c'est conforme (voir 6.7.8§14).

a+, ld.





Bonjour,



D'après mes connaissance, j'ai commencé à apprendre le C il y a
quelques mois, dans le cadre d'une initialisation, char t1[100] >{ "0" } ; est valable mais dans le cadre d'une affectation, ça ne
l'est pas.
Je me questionne sur l'utilité d'iniatilisé une variable tableau avec
0, c'est automatiquement effectué lors de la déclaration char t1
[100] ; ?



Non, pas si la variable est locale. Celles-ci valent par defaut n'importe
quoi.
Avatar
candide
-ed- a écrit :
On 17 août, 18:08, ""
wrote:

char t1[100] = { "0" } ;



N'existe pas.



C'était pas clair dans la traduction du monsieur :


Une gamme de valeurs de type caractères peut être initialisée
_optionnellement__entre__des__parenthèses__bracelets_, par une chaîne de
caractères au sens textuel.



:))
Avatar
-ed-
On 18 août, 10:19, ld wrote:
> > char t1[100] = { "0" } ;

> N'existe pas.

Ca existe et c'est conforme (voir 6.7.8§14).



OK, techniquement, c'est possible, mais c'est inutile.... gcc fait une
remarque ...
Avatar
bpascal123
On 19 août, 01:28, candide wrote:
-ed- a écrit :

> On 17 août, 18:08, ""
> wrote:

>> char t1[100] = { "0" } ;

> N'existe pas.

C'était pas clair dans la traduction du monsieur :



> Une gamme de valeurs de type caractères peut être initialisée
> _optionnellement__entre__des__parenthèses__bracelets_, par une chaî ne de
> caractères au sens textuel.

:))



Bonjour,

Je suppose que "initialized by a character string literal..." ça veut
dire "initialisée par une chaine de caractères quelconque", comme
"literal" se traduit par textuel alors la chaine quelconque pourrait
être { "0" } ou { "0", "0" }.

Par curiosité, j'ai essayé les possibilités dans le code suivant (pou r
rappel, j'ai une expérience de 3-4 mois en programmation et je suis
comptable de formation)

#include <stdio.h>



int main(void)

{

char T1[100] = { 0 } ;
char T2[100] = { "0" } ;
char T3[100] = "0" ;
char T4[100] = { '0' } ;



int i ;


printf("nnResultat 10 : %c", T1[0]) ; /* rien n'est affiché */

printf("nnResultat 11 : %c", T2[0]) ; /* affiche 0 comme attendu
*/

printf("nnResultat 12 : %c", T3[0]) ; /* affiche 0 comme attendu
*/
printf("nnResultat 13 : %c", T4[0]) ; /* affiche 0 comme attendu
*/

printf("nnResultat 20 : %c", T1[1]) ; /* rien n'est affiché */

printf("nnResultat 21 : %c", T2[1]) ; /* rien n'est affiché */

printf("nnResultat 22 : %c", T3[1]) ; /* rien n'est affiché*/
printf("nnResultat 23 : %c", T4[1]) ; /* rien n'est affiché*/

printf("nnResultat 30 : %c", T1[10]) ; /* rien n'est affiché */

printf("nnResultat 31 : %c", T2[10]) ; /* rien n'est affiché */

printf("nnResultat 32 : %c", T3[10]) ; /* rien n'est affiché*/
printf("nnResultat 33 : %c", T4[10]) ; /* rien n'est affiché*/


printf("nnResultat 40 : %c", T1[101]) ; /* caractere aleatoire en
memoire */

printf("nnResultat 41 : %c", T2[101]) ; /* rien n'est affiché */

printf("nnResultat 42 : %c", T3[101]) ; /* rien n'est affiché */
printf("nnResultat 43 : %c", T4[101]) ; /* rien n'est affiché */

printf("nnResultat 100 : %s", T1) ; /* rien n'est affiché */

printf("nnResultat 101 : %s", T2) ; /* affiche 0 comme attendu */

printf("nnResultat 102 : %s", T3) ; /* affiche 0 comme attendu */
printf("nnResultat 103 : %s", T4) ; /* affiche 0 comme attendu */


printf("nn") ;



return 0 ;

}

Je m'attendais que initialisation voulait dire remplir T1, T2 ou T3
par une même valeur et éviter ainsi tout caractère aléatoire de
l'adresse des variables de T1, T2, T3.

Je m'aperçois cependant que ces tableaux ne sont pas initialisés dans
leur totalité mais au mieux sont vidés de leurs contenus.

Alors est-ce que l'initialisation au-delà de l'indice 0 pour T1, T2,
T3 et T4 vide le contenu des variables (SANS INSCRIRE 0) ?

Peut-être si j'ajoute une ligne de code supplémentaire et que j'accèd e
à une variable quelconque de T à l'aide d'un pointeur, j'aurais la
réponse à ma question. Je ne maîtrise pas encore suffisamment bien le s
pointeurs et je préferre ne pas aller trop vite. Mais si je voulais le
faire, est-ce que je pourrais dire (indice 2 par exemple) : if ((T+2) !
= NULL) {... ? Il me semble que ç'est ce que Pierre dit plus haut.

Pour T4, le code ne confirme pas ce que Ed écrit :

"Quand on fait une initialisation partielle, tout ce qui est implicite
est mis à 0.

char x[3] = {'a'};

donne

{'a', 0, 0}

c'est garanti par la norme. "

T4 de l'exemple plus haut ne donne pas le même résultat.

Pour en revenir sur la traduction, il ne me semble pas avoir été
précis (ou bien je manque d'expérience) car le texte n'indique pas
bien le type de caractères utilisé pour l'initialisation. Il semble
que le mot literal a un sens que je ne connais pas bien et qui peut
prendre de l'importance à savoir;

...may be initialized by a character string literal,
optionally enclosed in braces. Successive characters of the character
string
literal (including the terminating null character if there is room or
if the
array is of unknown size)...

Je pense comprendre que literal et successive ont un rôle important
pour la traduction :
"character string literal" voudra dire {"0"} (pour reprendre le
premier message). Mais "Successive characters of the character string
literal" voudra dire { '0', '0', '0' ... ) et si ça inclut le
caractère null : { '0', '0', '0', '' } ... par conséquent "literal"
voudra dire une chaine de caractères prise dans son ensemble entre
guillemets doubles et une chaine de caracteres successive voudra dire
'0', '0', '0'... avec des guillements simples au sens "literal" ou à
la lettre.

Pour T1, il semble que les guillemets simples ou doubles soit
indispensables s'agissant d'un tableau de type char pour éviter
l'affichage de caractères complètement inattendus. Ca revient à lire
les premières pages du chapitre tableaux d'un livre de programmation
en C.

C'est un peu confus mais il me semble qu'il est possible d'accéder
facilement certaines zone de mémoire en C et que ne pas comprendre ce
qui s'y passe ou bien ne pas poser de question pour comprendre, c'est
prendre un risque d'une erreur peut-être pas lors de la première
implémentation mais de la 10 ou ième.

Cordialement,

Pascal
Avatar
Senhon
>> > On 17 août, 18:08, ""
> wrote:






Je suppose que "initialized by a character string literal..." ça veut
dire "initialisée par une chaine de caractères quelconque", comme
"literal" se traduit par textuel alors la chaine quelconque pourrait
être { "0" } ou { "0", "0" }.

Par curiosité, j'ai essayé les possibilités dans le code suivant (pour
rappel, j'ai une expérience de 3-4 mois en programmation et je suis
comptable de formation)




En tous cas, félicitation ...


#include <stdio.h>



int main(void)

{

char T1[100] = { 0 } ;
char T2[100] = { "0" } ;
char T3[100] = "0" ;
char T4[100] = { '0' } ;




Voulais-tu vraiment que ces variables est un portée locale à une fonction ?
Comme le faisait remarquer Marc Espie, ce type de variables n'est pas
garantie avoir été initialisées.
Avatar
bpascal123
On Aug 20, 1:41 pm, "Senhon" wrote:
>> > On 17 août, 18:08, ""
>> > wrote:

> Je suppose que  "initialized by a character string literal..." ça v eut
> dire "initialisée par une chaine de caractères quelconque", comme
> "literal" se traduit par textuel alors la chaine quelconque pourrait
> être { "0" } ou { "0", "0" }.

> Par curiosité, j'ai essayé les possibilités dans le code suivant (pour
> rappel, j'ai une expérience de 3-4 mois en programmation et je suis
> comptable de formation)

En tous cas, félicitation ...



> #include <stdio.h>

> int main(void)

> {

> char T1[100] = { 0 } ;
> char T2[100] = { "0" } ;
> char T3[100] =  "0" ;
> char T4[100] = { '0' } ;

Voulais-tu vraiment que ces variables est un portée locale à une fonc tion ?
Comme le faisait remarquer Marc Espie, ce type de variables n'est pas
garantie avoir été initialisées.



Oops, je n'avais pas vu la réponse de Marc
Avatar
bpascal123
> Oops, je n'avais pas vu la réponse de Marc



Mais je viens d'essayer :

#include <stdio.h>

char T1[100] = { 0 } ;
char T2[100] = { "0" } ;
char T3[100] = "0" ;
char T4[100] = { '0' } ;

int main(void)
...

J'obtiens le même résultat qu'avec le code précédent ou les variabl es
sont locales.

Je n'ai pas encore beaucoup eu l'occasion de travailer avec des
variables globales alors je ne suis pas sûre si c'est ce code est
correct pour une déclaration de variable globale.
1 2 3 4 5