Le 03-05-2011, Marc Espie a écrit :Il y a une autre ENORME difference entre les deux.
Dans le premier cas:
char *str = "abcdefgh";
tu prends une chaine de caractere et tu stockes son adresse dans str.
Ok, et donc je peux modifier l'adresse de str, mais pas modifier les
données pointées par str.
Donc si je veux modifier la chaine de caractères,
je dois écrire des caractères ailleurs, puis faire pointer str vers
le premier caractère de la chaine?
Pourquoi ? parce que la chaine est stockee avec les donnees en RO
Ca se paramètre, non? Le programme en RO, c'est lié à openBSD?
et donc
que la modif, str[2], est inoperante.
(c'est non conforme car la ligne str[2] = 'e'; n'a pas de comportement defini)
Si je remplace par
char str[] = "abcdefgh";
ca va afficher
abedefgh
c'est tres different: je cree un tableau de caracteres que j'initialise
avec les valeurs de la chaine "abcdefgh". Cas tres particulier: je n'ai
pas besoin de preciser la taille du tableau, le compilo se debrouille, et
va me faire un tableau de pile-poil 9 octets.
Mais si dans ce 2e exemple, je fais:
printf("%sn", str);
Le printf s'arrête car il rencontre un . Mais alors si me prends
l'idée de faire:
str[8] = 'e';
alors le printf va lire abcdefghe et ensuite? Tous les octets jusqu'a
rencontrer un ou sortir de la zone allouée (et donc une violation
de mémoire, i.e. segfault)?
Le 03-05-2011, Marc Espie <espie@lain.home> a écrit :
Il y a une autre ENORME difference entre les deux.
Dans le premier cas:
char *str = "abcdefgh";
tu prends une chaine de caractere et tu stockes son adresse dans str.
Ok, et donc je peux modifier l'adresse de str, mais pas modifier les
données pointées par str.
Donc si je veux modifier la chaine de caractères,
je dois écrire des caractères ailleurs, puis faire pointer str vers
le premier caractère de la chaine?
Pourquoi ? parce que la chaine est stockee avec les donnees en RO
Ca se paramètre, non? Le programme en RO, c'est lié à openBSD?
et donc
que la modif, str[2], est inoperante.
(c'est non conforme car la ligne str[2] = 'e'; n'a pas de comportement defini)
Si je remplace par
char str[] = "abcdefgh";
ca va afficher
abedefgh
c'est tres different: je cree un tableau de caracteres que j'initialise
avec les valeurs de la chaine "abcdefgh". Cas tres particulier: je n'ai
pas besoin de preciser la taille du tableau, le compilo se debrouille, et
va me faire un tableau de pile-poil 9 octets.
Mais si dans ce 2e exemple, je fais:
printf("%sn", str);
Le printf s'arrête car il rencontre un . Mais alors si me prends
l'idée de faire:
str[8] = 'e';
alors le printf va lire abcdefghe et ensuite? Tous les octets jusqu'a
rencontrer un ou sortir de la zone allouée (et donc une violation
de mémoire, i.e. segfault)?
Le 03-05-2011, Marc Espie a écrit :Il y a une autre ENORME difference entre les deux.
Dans le premier cas:
char *str = "abcdefgh";
tu prends une chaine de caractere et tu stockes son adresse dans str.
Ok, et donc je peux modifier l'adresse de str, mais pas modifier les
données pointées par str.
Donc si je veux modifier la chaine de caractères,
je dois écrire des caractères ailleurs, puis faire pointer str vers
le premier caractère de la chaine?
Pourquoi ? parce que la chaine est stockee avec les donnees en RO
Ca se paramètre, non? Le programme en RO, c'est lié à openBSD?
et donc
que la modif, str[2], est inoperante.
(c'est non conforme car la ligne str[2] = 'e'; n'a pas de comportement defini)
Si je remplace par
char str[] = "abcdefgh";
ca va afficher
abedefgh
c'est tres different: je cree un tableau de caracteres que j'initialise
avec les valeurs de la chaine "abcdefgh". Cas tres particulier: je n'ai
pas besoin de preciser la taille du tableau, le compilo se debrouille, et
va me faire un tableau de pile-poil 9 octets.
Mais si dans ce 2e exemple, je fais:
printf("%sn", str);
Le printf s'arrête car il rencontre un . Mais alors si me prends
l'idée de faire:
str[8] = 'e';
alors le printf va lire abcdefghe et ensuite? Tous les octets jusqu'a
rencontrer un ou sortir de la zone allouée (et donc une violation
de mémoire, i.e. segfault)?
Le 03-05-2011, Marc Espie a écrit :Il y a une autre ENORME difference entre les deux.
Dans le premier cas:
char *str = "abcdefgh";
tu prends une chaine de caractere et tu stockes son adresse dans str.
Ok, et donc je peux modifier l'adresse de str, mais pas modifier les
données pointées par str.
Donc si je veux modifier la chaine de caractères,
je dois écrire des caractères ailleurs, puis faire pointer str vers
le premier caractère de la chaine?
Or, les chaines de caracteres sont des constantes. Par exemple, soit
le mini programme (non conforme) suivant:
#include<stdio.h>
int main()
{
char *str = "abcdefgh";
str[2] = 'e';
printf("%sn", str);
return 0;
}
chez moi, si je le compile et l'execute, il affiche...
abcdefgh
Pourquoi ? parce que la chaine est stockee avec les donnees en RO
Ca se paramètre, non? Le programme en RO, c'est lié à openBSD?
et donc
que la modif, str[2], est inoperante.
(c'est non conforme car la ligne str[2] = 'e'; n'a pas de comportement defini)
Si je remplace par
char str[] = "abcdefgh";
ca va afficher
abedefgh
c'est tres different: je cree un tableau de caracteres que j'initialise
avec les valeurs de la chaine "abcdefgh". Cas tres particulier: je n'ai
pas besoin de preciser la taille du tableau, le compilo se debrouille, et
va me faire un tableau de pile-poil 9 octets.
Mais si dans ce 2e exemple, je fais:
printf("%sn", str);
Le printf s'arrête car il rencontre un . Mais alors si me prends
l'idée de faire:
str[8] = 'e';
alors le printf va lire abcdefghe et ensuite?
Le 03-05-2011, Marc Espie<espie@lain.home> a écrit :
Il y a une autre ENORME difference entre les deux.
Dans le premier cas:
char *str = "abcdefgh";
tu prends une chaine de caractere et tu stockes son adresse dans str.
Ok, et donc je peux modifier l'adresse de str, mais pas modifier les
données pointées par str.
Donc si je veux modifier la chaine de caractères,
je dois écrire des caractères ailleurs, puis faire pointer str vers
le premier caractère de la chaine?
Or, les chaines de caracteres sont des constantes. Par exemple, soit
le mini programme (non conforme) suivant:
#include<stdio.h>
int main()
{
char *str = "abcdefgh";
str[2] = 'e';
printf("%sn", str);
return 0;
}
chez moi, si je le compile et l'execute, il affiche...
abcdefgh
Pourquoi ? parce que la chaine est stockee avec les donnees en RO
Ca se paramètre, non? Le programme en RO, c'est lié à openBSD?
et donc
que la modif, str[2], est inoperante.
(c'est non conforme car la ligne str[2] = 'e'; n'a pas de comportement defini)
Si je remplace par
char str[] = "abcdefgh";
ca va afficher
abedefgh
c'est tres different: je cree un tableau de caracteres que j'initialise
avec les valeurs de la chaine "abcdefgh". Cas tres particulier: je n'ai
pas besoin de preciser la taille du tableau, le compilo se debrouille, et
va me faire un tableau de pile-poil 9 octets.
Mais si dans ce 2e exemple, je fais:
printf("%sn", str);
Le printf s'arrête car il rencontre un . Mais alors si me prends
l'idée de faire:
str[8] = 'e';
alors le printf va lire abcdefghe et ensuite?
Le 03-05-2011, Marc Espie a écrit :Il y a une autre ENORME difference entre les deux.
Dans le premier cas:
char *str = "abcdefgh";
tu prends une chaine de caractere et tu stockes son adresse dans str.
Ok, et donc je peux modifier l'adresse de str, mais pas modifier les
données pointées par str.
Donc si je veux modifier la chaine de caractères,
je dois écrire des caractères ailleurs, puis faire pointer str vers
le premier caractère de la chaine?
Or, les chaines de caracteres sont des constantes. Par exemple, soit
le mini programme (non conforme) suivant:
#include<stdio.h>
int main()
{
char *str = "abcdefgh";
str[2] = 'e';
printf("%sn", str);
return 0;
}
chez moi, si je le compile et l'execute, il affiche...
abcdefgh
Pourquoi ? parce que la chaine est stockee avec les donnees en RO
Ca se paramètre, non? Le programme en RO, c'est lié à openBSD?
et donc
que la modif, str[2], est inoperante.
(c'est non conforme car la ligne str[2] = 'e'; n'a pas de comportement defini)
Si je remplace par
char str[] = "abcdefgh";
ca va afficher
abedefgh
c'est tres different: je cree un tableau de caracteres que j'initialise
avec les valeurs de la chaine "abcdefgh". Cas tres particulier: je n'ai
pas besoin de preciser la taille du tableau, le compilo se debrouille, et
va me faire un tableau de pile-poil 9 octets.
Mais si dans ce 2e exemple, je fais:
printf("%sn", str);
Le printf s'arrête car il rencontre un . Mais alors si me prends
l'idée de faire:
str[8] = 'e';
alors le printf va lire abcdefghe et ensuite?
char tab[] = "abcdefgh";
Il n'y a que la chaîne (toujours pas modifiable) *identifiée* par s.
Aucun pointeur. Ici, tab n'est pas un pointeur, mais identifie la chaîne.
Quand tu utilises tab ailleurs dans le programme, il se passe
quelque-chose d'assez subtil : un pointeur temporaire est créé pour que
tab se comporte comme un pointeur, comme dans :
printf("%sn", s);
Le pointeur temporaire est détruit juste après son utilisation.
char tab[] = "abcdefgh";
Il n'y a que la chaîne (toujours pas modifiable) *identifiée* par s.
Aucun pointeur. Ici, tab n'est pas un pointeur, mais identifie la chaîne.
Quand tu utilises tab ailleurs dans le programme, il se passe
quelque-chose d'assez subtil : un pointeur temporaire est créé pour que
tab se comporte comme un pointeur, comme dans :
printf("%sn", s);
Le pointeur temporaire est détruit juste après son utilisation.
char tab[] = "abcdefgh";
Il n'y a que la chaîne (toujours pas modifiable) *identifiée* par s.
Aucun pointeur. Ici, tab n'est pas un pointeur, mais identifie la chaîne.
Quand tu utilises tab ailleurs dans le programme, il se passe
quelque-chose d'assez subtil : un pointeur temporaire est créé pour que
tab se comporte comme un pointeur, comme dans :
printf("%sn", s);
Le pointeur temporaire est détruit juste après son utilisation.
RO == Read Only (lecture seule).
Il voulait dire que la chaîne est stockée dans une zone mémoire
supposée être en lecture seule.
Ne pas confondre avec la ROM, ça n'a bien sûr rien à voir, même si le
principe est le même. Quand on parle de mémoire RO en programmation,
généralement, il s'agit d'une zone RAM supposée n'être accessible
qu'en lecture. C'est le système d'exploitation qui crée ces zones
quand il charge un programme.
Ensuite c'est au petit bonheur la chance ! On ne doit pas modifier une
chaîne statique. En l'occurrence ici, tu écrases le ' ' final (mais
comme c'est un comportement indéfini d'écrire dans une chaîne
statique, la tentative peut tout aussi bien échouer sur un
segfault). printf() va tenter d'afficher la chaîne jusqu'à trouver un