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
Senhon
a écrit dans le message de groupe de discussion
:

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 variables
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.



Y'a pas d'erreur.

Maintenant, on peut dire que :
T1 contient 100 char initialisés avec la valeur 0x00.
T2 contient 1 char initialisé avec la valeur 0x30, suivi de 99 char
initialisés avec la valeur 0x00.
T3 contient 1 char initialisé avec la valeur 0x30, suivi de 99 char
initialisés avec la valeur 0x00.
T4 contient 1 char initialisé avec la valeur 0x30, suivi de 99 char
initialisés avec la valeur 0x00.

La valeur hexadécimale 0x30 étant le code ASCII du caractère affichable
zéro.

soit :
T1 = { 0, 0,0,0, .... }
T2 = { '0', 0,0,0, .... }
T3 = { '0', 0,0,0, .... }
T4 = { '0', 0,0,0, .... }

Ou :
T1 = { 0x00, 0x00, 0x00, 0x00, .... }
T2 = { 0x30, 0x00, 0x00, 0x00, .... }
T3 = { 0x30, 0x00, 0x00, 0x00, .... }
T4 = { 0x30, 0x00, 0x00, 0x00, .... }
Avatar
Antoine Leca
Le 18/08/2009 12:28, Marc Espie écrivit :
In article ,
wrote:
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.



C'est la raison principale.

Mais qui plus est, l'initialisation à 0 remplit l'objet de 0 binaires...
qui ne sont pas obligatoirement identiques (pour les nombres en virgule
flottante et les pointeurs) équivalents à la constante 0.

De plus, c'est un bon moyen (au sens de la documentation du programme)
d'expliciter la valeur que prend au départ la variable ainsi créée.


Antoine
Avatar
Jean-Marc Bourguet
Antoine Leca writes:

Mais qui plus est, l'initialisation à 0 remplit l'objet de 0 binaires...
qui ne sont pas obligatoirement identiques (pour les nombres en virgule
flottante et les pointeurs) équivalents à la constante 0.



Heu... les objets a duree de vie statique non intialises explicitement sont
initialises a la valeur 0 pour les variables de type arithmetique et avec
un pointeur null pour les variables de type pointeur. (6.5.7 pour C90,
6.7.8/10 pour C99).

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
bpascal123
On Aug 20, 2:27 pm, "Senhon" wrote:
a écrit dans le message de groupe de discus sion
:





>> 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 var iables
> 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.

Y'a pas d'erreur.

Maintenant, on peut dire que :
    T1 contient 100 char initialisés avec la valeur 0x00.
    T2 contient 1 char initialisé avec la valeur 0x30, suivi de 99  char
initialisés avec la valeur 0x00.
    T3 contient 1 char initialisé avec la valeur 0x30, suivi de 99  char
initialisés avec la valeur 0x00.
    T4 contient 1 char initialisé avec la valeur 0x30, suivi de 99  char
initialisés avec la valeur 0x00.

 La valeur hexadécimale 0x30 étant le code ASCII du caractère aff ichable
zéro.

soit :
    T1 = { 0, 0,0,0, .... }
    T2 = { '0', 0,0,0, .... }
    T3 = { '0', 0,0,0, .... }
    T4 = { '0', 0,0,0, .... }

Ou :
    T1 = { 0x00, 0x00, 0x00, 0x00, .... }
    T2 = { 0x30, 0x00, 0x00, 0x00, .... }
    T3 = { 0x30, 0x00, 0x00, 0x00, .... }
    T4 = { 0x30, 0x00, 0x00, 0x00, .... }



Bonjour,

Quelle est l'utilité de travailler avec des valeurs hexadécimales ?
Est-ce que printf avec le % hexadecimale va afficher un resultat là ou
un simple printf %d n'affiche rien pour une valeur arithmétique de
type tableau et nulle pour une valeur pointeur ?

Cette démonstration peut -elle se faire avec des valeurs binaires?

Autrement que pour la programmation d'appareils électroniques, drivers
et pilotes des périphériques informatiques quelle est l'utilité de
travailler avec des des données hexadecimales ou binaires?

Je pose cette question car pour commencer à apprendre la programmation
à partir dezéro, je ne me suis pas trop attardé sur les chapitres de
conversion et autres manipulations de données binaires ou
hexadecimales.

Cordialement,

Pascal
Avatar
-ed-
On 20 août, 11:41, ""
wrote:

Je suppose que  "initialized by a character string literal..." ça veu t
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" }.



Admettons. Pas sûr que les {} aient un sens ici ...

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



Très bonne initiative. L'expérimentation permet d'asseoir ses
connaissances.


#include <stdio.h>

int main(void)

{

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



Une façon compliquée d'écrire

char T2[100] = "0" ;

Pourquoi pas

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

tant qu'on y est ...


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

        int i ;

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



Ce qui ne prouve rien. Je suggère d'afficher la valeur numérique,
c'est plus clair (%d). Le résultat dépend du charset. En ASCII, 0 est
0 et '0' est 48.

printf("Resultat 10 : %d"n, T1[0]) ; /*
affiche 0 */


        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é*/



Avec "%d", on voit bien que la valeur est 0.


        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é*/



idem.


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



Comportement indéfini. Le résultat est imprévisible. A partir de là ,
le comportement du programme n'a plus aucun sens. Ne pas faire ça.


        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  */




Pour les chaines, je recommande '%s', c'est plus clair. On voit tout
de suite si il y a des caractères 'parasites' (espaces, par exemple).

        printf("nn") ;



Il vaut mieux mettre l'indicateur de fin de ligne en ... fin de ligne.
C'est plus logique, non ?


        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.



Et c'est le cas. La valeur est soit la valeur explicite, soit 0.

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.



Ben si. Il sont complétés par des 0 comme l'exige la norme. Tu le
verras en remplaçant %c par %d...
Que signifie 'vidé ?'


Alors est-ce que l'initialisation au-delà de l'indice 0 pour T1, T2,



Au delà de l'indice, la valeur est indéterminée. 0 est une valeur
indéterminée comme une autre. Sur une machine où les chars font 8
bits, la valeur est représentée par une combinaison de bits allant de
0000 0000 à 1111 1111. Si le char est non signé, ça signifie 0 à 25 5.


T3 et T4 vide le contenu des variables (SANS INSCRIRE 0) ?



J'ai rien compris... Vérifie, tu verras que le contenu de chaque case
est bien 0.

(prend un tableau de 10, ce sera plus simple à vérifier...)

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.



Refait tes essais. Tu verras que le comportement est conforme à la
norme.

Ceci :

donne

#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 : %d", T1[0]) ; /* rien
n'est affiché */

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

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

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

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

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

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

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

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

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

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

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

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 ;

}

Resultat 10 : 0

Resultat 11 : 48

Resultat 12 : 48

Resultat 13 : 48

Resultat 20 : 0

Resultat 21 : 0

Resultat 22 : 0

Resultat 23 : 0

Resultat 30 : 0

Resultat 31 : 0

Resultat 32 : 0

Resultat 33 : 0

Resultat 100 : ''

Resultat 101 : '0'

Resultat 102 : '0'

Resultat 103 : '0'


Process returned 0 (0x0) execution time : 0.095 s
Press any key to continue.
Avatar
-ed-
On 20 août, 13:41, "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.



Si. Ici, elles sont initialisée explicitement... Merci de ne pas
induire le débutant en erreur ... C'est déjà assez compliqué comme
ça...
Avatar
-ed-
On 20 août, 17:24, Jean-Marc Bourguet wrote:
Antoine Leca writes:
> Mais qui plus est, l'initialisation à 0 remplit l'objet de 0 binaires ...
> qui ne sont pas obligatoirement identiques (pour les nombres en virgule
> flottante et les pointeurs) équivalents à la constante 0.

Heu... les objets a duree de vie statique non intialises explicitement so nt
initialises a la valeur 0 pour les variables de type arithmetique et avec
un pointeur null pour les variables de type pointeur. (6.5.7 pour C90,
6.7.8/10 pour C99).



C'est ce qui me semblait aussi. Je suis un,peu surpris par la réponse
d'Antoine ...

@Antoine, tu ne confonds pas avec memset() ?
Avatar
-ed-
On 21 août, 03:13, ""
wrote:

Quelle est l'utilité de travailler avec des valeurs hexadécimales ?



Il n'y a pas de 'valeurs hexadécimales '. Une valeur est une
combinaison de bits. C'est tout. Ce qui peut changer, c'est sa
représentation textuelle. La représentation hexadécimale (en C/
printf : %x, %X) est une des représentations textuelles possible d'une
valeur (en C/printf : %d, %o). Si la valeur tient dans un char, la
représentation textuelle peut être le glyphe d'un caractère (en C/
printf : %c).

Est-ce que printf avec le % hexadecimale va afficher un resultat là ou
un simple printf %d n'affiche rien  pour une valeur arithmétique de
type tableau et nulle pour une valeur pointeur ?



%x et %d vont toujours afficher une valeur numérique si le type est
unsigned int (%x) ou int (%d).

"%c" affichera un glyphe si il existe, sinon, il n'affichera rien (à
ne pas confondre avec 'espace')

Cette démonstration peut -elle se faire avec des valeurs binaires?



Ceci n'a aucun sens. Comme je l'ai fait remarqué précédemment. Ce qui
compte ici est que l'affichage soit correct. Tu peux utiliser %x ou
%d, peu importe. Par contre comme déjà expliqué, %c est insuffisammen t
précis.


Autrement que pour la programmation d'appareils électroniques, drivers
et pilotes des périphériques informatiques quelle est l'utilité de
travailler avec des des données hexadecimales ou binaires?



Ceci n'a aucun sens. Toutes les données sont binaires sur les
ordinateurs actuels. Ne pas confondre la valeur (qui est binaire) et
sa représentation textuelle...

Je pose cette question car pour commencer à apprendre la programmation
à partir dezéro, je ne me suis pas trop attardé sur les chapitres d e
conversion et autres manipulations de données binaires ou
hexadecimales.



C'est pourtant fondamental ...
Avatar
Senhon
a écrit dans le message de groupe de discussion
:
On Aug 20, 2:27 pm, "Senhon" wrote:
a écrit dans le message de groupe de
discussion
:





>> 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 variables
> 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.

Y'a pas d'erreur.

Maintenant, on peut dire que :
T1 contient 100 char initialisés avec la valeur 0x00.
T2 contient 1 char initialisé avec la valeur 0x30, suivi de 99 char
initialisés avec la valeur 0x00.
T3 contient 1 char initialisé avec la valeur 0x30, suivi de 99 char
initialisés avec la valeur 0x00.
T4 contient 1 char initialisé avec la valeur 0x30, suivi de 99 char
initialisés avec la valeur 0x00.

La valeur hexadécimale 0x30 étant le code ASCII du caractère affichable
zéro.

soit :
T1 = { 0, 0,0,0, .... }
T2 = { '0', 0,0,0, .... }
T3 = { '0', 0,0,0, .... }
T4 = { '0', 0,0,0, .... }

Ou :
T1 = { 0x00, 0x00, 0x00, 0x00, .... }
T2 = { 0x30, 0x00, 0x00, 0x00, .... }
T3 = { 0x30, 0x00, 0x00, 0x00, .... }
T4 = { 0x30, 0x00, 0x00, 0x00, .... }



Bonjour,

Quelle est l'utilité de travailler avec des valeurs hexadécimales ?



Le choix de l'hexadécimal était principalement motivé pour distinguer les
valeurs numériques des valeurs alphabétiques.
Il n'en reste pas moins que l'hexadécimale est un fondement à ne pas
occulter.

Est-ce que printf avec le % hexadecimale va afficher un resultat là ou
un simple printf %d n'affiche rien pour une valeur arithmétique de
type tableau et nulle pour une valeur pointeur ?



Houlala ! j'ai pas tout compris, mais bon ... le mieux dans ce genre de cas
c'est la pratique.


Cette démonstration peut -elle se faire avec des valeurs binaires?



C'est affaire de choix, suivant les circonstances, d'utiliser une base ou
une autre. je peux indifféremment écrire :

char Car = 'A' ;
char Car = 0b01000001 ;
char Car = 0x41 ;
char Car = 65 ;

J'ai au final initialisé avec la même valeur, seul l'interprétation que j'en
fais a changée.


Autrement que pour la programmation d'appareils électroniques, drivers
et pilotes des périphériques informatiques quelle est l'utilité de
travailler avec des des données hexadecimales ou binaires?

Je pose cette question car pour commencer à apprendre la programmation
à partir dezéro, je ne me suis pas trop attardé sur les chapitres de
conversion et autres manipulations de données binaires ou
hexadecimales.



C'est un insignifiant B-A BA.
Avatar
bpascal123
> C'est un insignifiant B-A BA.



Bonjour,

Je suis d'accord c'est le b-a ba... mais ca demande du temps pour
apprendre ce chapitre même si c'est le premier. Quoiqu'il y a des
livres de programmation qui survolent de très haut ces passages...Ce
ne sont peut-être pas les ouvrages les plus exhaustifs.

Cependant, pour conduire un charriot élévateur, je ne pense pas qu'il
n'est pas nécessaire d'avoir le permis B. Je veux dire que si mon
objectif est de faire du web development ou être capable de faire
quelques macros open office ou google cloud app... en C ou dans un
autre langage (je crois qu'apprendre la rigueur du C aide pour
apprendre d'autres langages ...? ).

Je ne comprends pas alors l'utilité de savoir manipuler des valeurs
binaires. Peut-être je serais amené à apprendre ce chapitre dans le
futur mais pour l'instant ce n'est pas un besoin. Et puis il y a aussi
des professionnels qui ont étudié l'informatique et des consultants,
ça sera alors à moi de voir si dans le cadre d'un projet sérieux,
cette dépense ne serait pas plus rentable plutôt qu'acquérir une
connaissance supplémentaire que je ne considère pas simple (les maths
n'ont pas été mes meilleurs amis).
Je pense aussi que c'est une question d'orientation professionnelle.

Pascal
1 2 3 4 5