IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Initialisation de char qui modifie un autre char


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut Initialisation de char qui modifie un autre char
    Bonjour,
    J'ai actuellement un problème qui peut paraître tout bête mais que je ne parviens pas à résoudre. Je suis en train de programmer en C un pendu (sans interface graphique)(cf M@teo) et je bloque sur une valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        puts(motsecret) ;
        char verif[longchaine] ;
            puts(motsecret) ;
    Voila ce que ça m'affiche sur la cmd :
    les caractères à partir du "&" correspondent à ça : "╝▄<"
    Les deux premiers char s'affichent sans problème jusqu'au moment ou je place char verif, longchaine étant une variable qui marche sur les autres char
    Je vous fournis la partie du code concerné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "entrerlettre.h"
    #include "dico.h"
     
    int main(int argc, char* argv[])
    {
        int continuer = 1 ; while (continuer == 1)
        {
        printf("\n== Bonjour et bienvenue sur le jeu du pendu ! ==") ;
        printf("\n Vous avez 10 essais faux pour chaque partie\n") ;
        char malettre = 0 ; int coups = 0 ; int coupsmax = 10 ;
        char motsecret[] = {0} ;
        piocherMot(motsecret) ;
        int longchaine =0 ;
        longchaine = strlen(motsecret) ;
        char motcode[longchaine] ;
            puts(motsecret) ;
        char (verif[longchaine] );
            puts(motsecret) ;
        int lettretrouvee = 0 ;
        int i = 0 ;
            sprintf(verif,"\n**************") ;
            sprintf(motcode,"\n**************") ;
        while (lettretrouvee != longchaine)
        {
            i = 0 ;
            strcpy(verif,motcode) ;
            if (coups == coupsmax)
                { printf("\n-- Vous etes des a present pendu.. --\n\n") ;
                printf("Voulez-vous faire une autre partie ? \n\n1. OUI\n0.NON\nVotre choix : ") ;
                scanf("%d",&continuer) ; exit(0) ; }
            printf("\n\nDemandez une lettre : ") ;
            malettre = lire() ;
     
            while (i != longchaine)
            {
                if (malettre == motsecret[i])
                    { lettretrouvee++ ; (motcode[i]) = (motsecret[i]) ;}
                printf("%c",motcode[i]) ;
     
                i++ ;
            }
     
        printf("\nVous avez trouvé %d lettre sur les %d ! \n",lettretrouvee,longchaine) ;
        if (strcmp(verif,motcode)==0) {coups++ ;}
        printf("Il vous reste encore %d coups a jouer ! ",coupsmax - coups) ;
        }
        printf("\n==Felicitation, vous avez reussis en %d coups ! ==",coups) ;
        printf("\nVoulez-vous faire une autre partie ? \n\n1. OUI\n0. NON\nVotre choix : ") ;
        scanf("%d",&continuer) ;
        }
        return 0 ;
    }
    C'est surement très brouillon pour vous mais je viens juste de commencer et j'ai fait ce qui me semblait logique et accessible
    Merci de vos réponses et si vous voulez pluss d'info dites le moi
    Cordialement
    Un aspirant à la programmation

  2. #2
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut
    Rebonjour,
    Désolé pour ce double post et cette discussion, j'ai finalement résolu mon problème d'une façon très simple mais que je ne comprend pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char motsecret[100] = {0} ;
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char motsecret[] = {0} ;
    J'ai aussi remarqué différentes telles que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sprintf(verif,"\n**************") ;
    ou il faut enlever le \n

    Encore désolé pour cette discussion mais elle pourrait aider quelqu'un (il y a très peu de discussions parlant de ce problème la, je n'en ai pas trouvé)

  3. #3
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Insère printf("%zu bytes", sizeof motsecret); après la déclaration de ton tableau dans la première version de ton programme, puis constate le souci.

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut
    Warning : Unknow conversion type character 'z' in format
    Et ça m'affiche zu bytes sur le cmd ^^
    il faut faire # include <quelque chose> non?

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Ah, les compilateurs Microsoft..

    Essaie avec : printf("%u bytes", (unsigned int)(sizeof motsecret)); .

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut
    La cmd me marque "1 bytes" Si c'est bien byte et donc octet alors ca fait 8 bit et cela me permet de stocker 8 octets donc 8 char (si je me trompe pas )

    Mais effectivement cela fait toujours 1 bytes quelque soit le mot piocher dans ma bibliothèque. (plus ou moins long)

    Merci pour cette réponse rapide et cette "fonction?" que je connaissais pas, je la réutiliserai ^^

    Je rajoute ceci :
    J'ai maintenant compris ce que tu voulais me dire et pour ceux que ça intéresse : https://fr.wikipedia.org/wiki/D%C3%A...ment_de_tampon
    Ils appellent ça l'overbuffer et c'est super intéressant !

  7. #7
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Overeath Voir le message
    La cmd me marque "1 bytes" Si c'est bien byte et donc octet alors ca fait 8 bit et cela me permet de stocker 8 octets donc 8 char
    Donc 1 byte = 1 octet = 8 bits = 8 octets soit 1 = 8.. en es-tu sûr ?


    Citation Envoyé par Overeath Voir le message
    Mais effectivement cela fait toujours 1 bytes quelque soit le mot piocher dans ma bibliothèque. (plus ou moins long)

    Merci pour cette réponse rapide et cette "fonction?" que je connaissais pas, je la réutiliserai ^^
    Appliqué à un tableau déclaré sur la pile (ton cas) ou dans le segment de données, l'opérateur sizeof (clic) te renvoie sa capacité en octets. On ne peut pas s'en servir pour déterminer la longueur d'une chaîne de caractères, c'est le rôle de strlen. Ce dont tu as pu te rendre compte c'est que la capacité du tableau déclaré de la façon suivante : char motsecret[] = {0} ; est toujours de 1 octet.

    Pourquoi, à ton avis ? Et que crois-tu qu'il se produise lorsque tu essaies d'y stocker une chaîne occupant une taille supérieure à un octet, soit n'importe quelle chaîne autre que la chaîne vide ?

  8. #8
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut
    Effectivement je suis emmêlé les pinceaux, 1 octet = 8bits donc 8 chars ! ( car 1 char = 1 bit sur mon OS)

    Si j'ai bien compris, elle fait 1 Octet parce qu'il n'y a pas d'indice dans "[]" (Je ne sais pas si une adresse est déclarée quand même, même si la valeur de l'adresse ne change pas)
    Et si mes conclusions sont bonnes, il se passe un "overbuffer", c'est à dire qu'à partir de l'adresse déclarée, les caractères vont s'inscrire l'un à la suite de l'autre dans un endroit qu n'a pas été réservé pour eux.
    Ou alors je me trompe complétement et les caractères vont dans le buffer

    Je suis désolé si je dis des bêtises, ça fait 4 jours que j’étudie le comportement de l'ordinateur (et le C) alors j'essaie de restituer ce que j'ai appris sur le tas.
    Si tu peux me dire si c'est bon, je t'en remercierai ^^

  9. #9
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 439
    Points
    2 439
    Par défaut
    Salut

    Citation Envoyé par Overeath Voir le message
    Effectivement je suis emmêlé les pinceaux, 1 octet = 8bits donc 8 chars ! ( car 1 char = 1 bit sur mon OS)
    Non plus. Tu as encore quelques difficultés avec les termes bit et octet.

    1 char = 1 octet = 8 bits oui.
    Par contre 1 char = 1 bit non, (1 char = 8 bits) donc 8 bits ≠ 8 chars !

    Si tu veux t'en convaincre, si 1 char = 1 bit ça voudrait dire qu'une variable de type char ne pourrait avoir que 2 valeurs différentes, 0 ou 1. Or il faut au moins une centaine de valeurs différentes possibles pour avoir toutes les lettres, chiffres, ponctuation et symboles possible. Pour ça, il faut minimum 7 bits (27 soit 128).
    Et ça tombe bien puisqu'il y a 8 bits dans un char, soit 256 combinaisons possibles.

    PS: je ne parle pas volontairement du byte et du cas ou byte ≠ octet pour simplifier.
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut
    Ah oui je me trompe complétement !
    Grace a la fonction de Matt_Houston, j'ai eu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main()
    {
        printf("Un char fait %u octets \n",sizeof(char)); // = 1
        printf("Un int fait %u octets \n",sizeof(int)); // = 4
        printf("Un long fait %u octets \n",sizeof(long)); // = 4
        printf("Un double fait %u octets \n",sizeof(double)); // = 8
        printf("Un float fait %u octets \n",sizeof(float)); // = 4 ???
        return 1;
    }
    Normalement jusque la tout va bien (hormis le float je pensais pas qu'il faisait 4 octets)
    Alors c'est bon je pense avoir compris maintenant ^^'

  11. #11
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En théorie, cette fonction n'est pas tout-à-fait exacte: sizeof retourne un multiple de la taille de char (qui a toujours un sizeof de 1)
    Il existe une constante CHAR_BIT qui indique le nombre de bits dans un char.

    En pratique, CHAR_BIT vaut 8 sur tous les systèmes "normaux". Seuls certains très gros hypercalculateurs et des micro processeurs très spécifiques diffèrent.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  12. #12
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonsoir,
    j’ai du mal avec ce que vous avez écrits :
    Citation Envoyé par ternel Voir le message
    En théorie, cette fonction n'est pas tout-à-fait exacte: sizeof retourne un multiple de la taille de char (qui a toujours un sizeof de 1)
    Il existe une constante CHAR_BIT qui indique le nombre de bits dans un char.
    Si ce n’est pas toujours vrai ce n’est pas du fait de l’opérateur sizeof c’est tout simplement parce que d’une la taille de certaines variables définis avec leurs types respectifs de bases comme int, long etc.. ne sont pas définis de façon définitive et de l’autre parce que cela dépend également de l’architecture machine mais aussi du compilateur. Exemple le type [c]char[\c] vaut 1 octet soit 8 bits minimum pour contenir un caractère ce qui est logique vu que c’est l’unité de données la plus petites en informatique; et de plus, la norme garantit un minimum de 8 bits pour le type char explicitement et obligatoires dans la norme et définis dans le fichiers d’en-tête <limits.h> qui fixent également ces caractéristiques pour chaque implémentation particulière et donc quel que soit le cas particulier ou non le type char à un minimum de 1 octet jusqu’à preuves du contraire. (je dirais même que c’est valable sur des architectures particulières ou spécifiques mais a vérifiée de façon concrète).

    En revanche pour les autres types ce n’est pas forcément le cas exemple le type int. Le type entier a une taille qui correspond à un mot machine donc directement à l’architecture machine. ainsi donc sur une architecture 32 bits (modèle ILP32) un entier fera 32 bits de long ce qui impose alors à ce que les autres types d’entiers respecte la fameuse relation d’inégalité short <= int <= long. Cela ne veut pas dire que sur une architecture 64 bits on obtiendra un int de longueur 64 bits "non". Sur d’autre d'architecture la représentation de données est différente et ont recours à une représentation de données de façon non portable pour definir certain type exemple ILP64 se base sur _int32 pour définir ces types

    Voici la liste de quelque modèle et un lien pour plus de précision sur la chose.

    LP32 : 8(char) 16(short) 16(int) 32(long) 32(pointeur)
    LP64 : 8(char) 16(short) 32(int) 64(long) 64(pointeur)
    ILP32 : 8(char) 16(short) 32(int) 32(long) 32(pointeur)
    ILP64 : 8(char) 16(short) 64(int) 64(long) 64(pointeur)
    LLP64 : 8(char) 16(short) 32(int) 32(long) 64(pointeur) & type long long

    Aux finales cela ne vient pas de l'opérateur sizeof vu qu’elle ne fait que renvoyer la taille mémoire nécessaire en octet pour stocker une donnée ou objet de type type. Autre cas de l'opérateur sizeof: quand vous appliquer l’opérateur sizeof à une structure où union, sizeof vous renvoie comme résultat le nombre d'octets de la structure ou de l'union avec le padding (le rajout d’octets par les compilateurs pour respecter l’alignement) compris.
    Tout compte fais sizeof tient compte également de la représentation physique et intègre des zones inutilisées du cadrage sur un mot machine il faut donc être vigilants quand a la définitions des structure s'il l'on est mania de la mémoire.

    L'opérateur sizeof ne fournie donc pas un multiple de la taille de char contrairement a ce qui a été écris. Elle renvoie la taille mémoire nécessaire en octet pour stocker une donnée ou objet de type type mais cela dépend de l'architecture machine (modèle).

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  13. #13
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Et pourtant, sizeof renvoie bien un multiple de sizeof char.
    La norme exige que sizeof char == 1. Et sizeof retourne un entier.

    Pour le reste on est globalement d'accord.

    Je précisais simplement que la fonction parle d'octets, mais ce n'est pas exact.
    Si sur une architecture, le char fait 2 octets (ce qui est parfaitement légitime), sizeof char retourne quand même 1, et la fonction affichera "Un char fait 1 octets."
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Au sujet de ce qu'a dit sambia39:
    • Le minimum requis par le standard C est le modèle LP32.
    • La plupart des OS 32 bits modernes (Windows, Linux, etc.) utilisent le modèle ILP32 (leurs int font 32 bits).
    • Windows 64 bits utilise le modèle LLP64, comme ça seule la taille des pointeurs change.
    • Linux 64 bits utilise le modèle LP64 (en plus des pointeurs, leurs long font 64 bits).


    @ternel: Il me semble qu'un byte est "la plus petite unité adressable", non? Ce qui voudrait dire qu'en C, un char a toujours une taille d'1 byte?
    (et donc, que sizeof retourne une taille en bytes)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Pourquoi, à ton avis ?
    Citation Envoyé par Overeath Voir le message
    Si j'ai bien compris, elle fait 1 Octet parce qu'il n'y a pas d'indice dans "[]" (Je ne sais pas si une adresse est déclarée quand même, même si la valeur de l'adresse ne change pas)
    C'est la moitié de la vérité : tu n'as pas précisé la capacité du tableau via un nombre d'éléments entre [], laissant donc le compilateur le déduire du nombre de valeurs précisées à l'initialisation, en l'occurrence une seule : 0. La capacité de ton tableau à un seul élément est donc 1 * sizeof *motsecret avec sizeof *motsecret == sizeof(char) == 1.


    Citation Envoyé par Matt_Houston Voir le message
    Et que crois-tu qu'il se produise lorsque tu essaies d'y stocker une chaîne occupant une taille supérieure à un octet, soit n'importe quelle chaîne autre que la chaîne vide ?
    Citation Envoyé par Overeath Voir le message
    Et si mes conclusions sont bonnes, il se passe un "overbuffer", c'est à dire qu'à partir de l'adresse déclarée, les caractères vont s'inscrire l'un à la suite de l'autre dans un endroit qu n'a pas été réservé pour eux.
    Ou alors je me trompe complétement et les caractères vont dans le buffer
    Tu as tout compris : plus exactement un buffer overflow, une erreur très courante et sans doute la cause la plus commune des failles de sécurité informatique.

    Lorsqu'une telle erreur se produit, le comportement du programme est dit indéterminé : il peut se passer absolument n'importe quoi et on ne peut plus prédire l'état du processus. Le système d'exploitation peut - si l'on a de la chance - détecter l'erreur et choisir de suspendre l'exécution (« plantage » contrôlé). Ou pas : ça ne s'est pas produit dans ton cas, par exemple.

    Pour des raisons de performance et contrairement à d'autres langages qui adoptent une approche plus défensive, le C n'offre aucune facilité de vérification de la validité des accès. L'ajout ou non d'une protection est laissée à la discrétion du programmeur.

    Nous ne sommes toutefois pas des robots et les bugs sont inévitables. Il existe donc des outils d'analyse statique ou dynamique pour traquer ce genre d'erreur. En compilant avec GCC par exemple, ajoute l'option -fsanitize=address à la commande de compilation d'une version en développement afin d'insérer des sentinelles qui t'alerteront d'un accès défendu. Alternativement, sous Linux, exécute le programme à travers valgrind.

  16. #16
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    @ternel: Il me semble qu'un byte est "la plus petite unité adressable", non? Ce qui voudrait dire qu'en C, un char a toujours une taille d'1 byte?
    (et donc, que sizeof retourne une taille en bytes)
    C'est une question de vocabulaire.
    En C, je ne sais pas comment est défini le mot "byte" (ni même si il l'est).

    Pour la définition classique (byte = octet = 8 bits), non un char ne fait pas un byte.
    Par contre, en C, char est bien l'atome d'adressage.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  17. #17
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 110
    Points
    6 110
    Par défaut
    Par définition de l'octet, 1 octet = 8 bits.
    Le byte est la plus petite unité adressable. On peut avoir 1 byte ≠ 1 octet.

    Dans les langages C et C++, la taille d'un char est toujours 1 byte.

    Extraits de ISO/IEC 9899:201x (draft de C11) :

    3.6 byte
    « addressable unit of data storage large enough to hold any member of the basic character set of the execution environment
    NOTE 1 It is possible to express the address of each individual byte of an object uniquely.
    NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined.
    The least significant bit is called the low-order bit; the most significant bit is called the high-order bit. »

    6.5.3.4 The sizeof and _Alignof operators
    « The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. »

    Extrait de N4296 (draft de C++14) :

    5.3.3 Sizeof
    The sizeof operator yields the number of bytes in the object representation of its operand.

  18. #18
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour

    Citation Envoyé par ternel Voir le message
    Et pourtant, sizeof renvoie bien un multiple de sizeof char.
    La norme exige que sizeof char == 1. Et sizeof retourne un entier.

    Pour le reste on est globalement d'accord.

    Je précisais simplement que la fonction parle d'octets, mais ce n'est pas exact.
    Si sur une architecture, le char fait 2 octets (ce qui est parfaitement légitime), sizeof char retourne quand même 1, et la fonction affichera "Un char fait 1 octets."


    Je pense qu’il ya peut être une légère confusion….; de façon très simple 1 byte = 1 octet = 8 bits et pour info sizeof n’est pas une fonction

    L’opérateur sizeof comme je l’ai déjà expliqué renvoie la taille mémoire nécessaire de stockage, en octet, pour stocker un objet du type de l'opérande ce qui veut dire également que :
    • Pour un type de données, l’opérateur sizeof renvoie la taille du type de données.
    • Pour une expression, sizeof renvoie la taille du type de variable ou de l’expression. Si par exemple vous avez une constante comme caractère littéral elle sera considère comme étant un entier int et vous obtiendrez alors comme dans mon cas sur ma machine 4 octets la taille d’un int qui correspond à un mot machine donc directement à l’architecture machine. Soit 32 bits de donnée nécessaire au stockage de l’information.

    Exemple:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        char c_str = 'a';
        (void)fprintf( stdout, "%lu\t:Constante\n", sizeof('a') );
        (void)fprintf( stdout, "%lu\t:Taille type char\n", sizeof(char) );
        (void)fprintf( stdout, "%lu\t:Taille type int\n", sizeof(int) );
        (void)fprintf( stdout, "%lu\t:Variable char\n", sizeof(c_str) );
     
        return EXIT_SUCCESS;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    4	:Constante
    1	:Taille type char
    4	:Taille type int
    1	:Variable
    Program ended with exit code: 0
    Au finale si ce n’est pas toujours vrai comme vous l’avez mentionné dans l’un de vos messages ce n'est pas du faits de sizeof c’est parce que d’une part la taille de certaines variables définies ne sont pas définis de façon définitive comme le cas du type char et varie d’une architecture à une autre (modèle de représentation différents LP32, LP64,ILP32,ILP64,LLP64)

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  19. #19
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Encore une fois, et les citations de Pyramidev le conforte, un byte n'est pas défini comme un octet.
    Généralement, ils correspondent, mais la norme ne le demande pas.

    Sur un pc "normal", c'est bien le cas, mais il ne faut pas faire l'amalgame pour autant.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  20. #20
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,
    Citation Envoyé par ternel Voir le message
    Encore une fois, et les citations de Pyramidev le conforte, un byte n'est pas défini comme un octet.
    Généralement, ils correspondent, mais la norme ne le demande pas.

    Sur un pc "normal", c'est bien le cas, mais il ne faut pas faire l'amalgame pour autant.
    D’accord, si vous le dites. Cependant ce qui est sûr la norme impose 8 bits pour un type caractère quel que soit le modèle ou l’architecture donc 1 octet ou si vous préférer 1 byte. Là où j’ai eu du mal c’est le fait d’écrire que:
    Citation Envoyé par ternel Voir le message
    En théorie, cette fonction n'est pas tout à fait exacte: sizeof retourne un multiple de la taille de char (qui a toujours un sénior de 1)
    Et comme j'ai essayer de le dire et peut être que je me trompe. Ce n’est pas l’opérande sizeof qui est en tort c’est plutôt la représentation des données si je peux dire ainsi: une constante caractère n'aura pas la même t’aille qu’une variable de type caractère qui contient cette même constante.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        char c_str = 'a';
        (void)fprintf( stdout, "%lu\t:Constante\n", sizeof('a') );
        (void)fprintf( stdout, "%lu\t:Taille type char\n", sizeof(char) )
        (void)fprintf( stdout, "%lu\t:Variable char\n", sizeof(c_str) );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    4	:Constante
    1	:Taille type char
    1	:Variable
    Ce n’est pas une question de multiple, mais d’interprétation ou mieux comment est représentée l’information et pourquoi celle-ci utilise 4 octets (type int -> 32 bits) pour une constante et non 8 bits pour le type caractère contenant la même constante? char c_str = 'a'; (je ne sais pas si vous m’avez compris). On peut se conforter avec la norme c’est très bien, mais la comprendre c’est mieux et dire que c’est marqué ainsi donc c’est ainsi ne justifie pas forcements que c’est ça (la vérité se trouve peut-être ailleurs). Attention je ne dis pas que vous avez tord sur toute la ligne "non", mais qu’il faudrait comprendre avant tout pourquoi ont obtiens des valeurs différentes avec l'opérateurs sizeof ce n'est peut être pas parce qu'il renvoie des multiples la raison peut être tout autres.
    Tout comme je peut me trompé.

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. CSS hover d'un élément qui modifie un autre élément
    Par pol2095 dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 07/01/2012, 09h20
  2. modifier un champs teste qui modifier un autre automatiquement
    Par dad72 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 27/02/2009, 16h26
  3. [Excel VBA]fonction dans une cellule qui modifie une autre cellule
    Par Invité dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 24/01/2007, 17h43
  4. Réponses: 3
    Dernier message: 13/07/2006, 00h51
  5. [Formulaire] zone de liste qui en modifie d'autres
    Par dutrannoy dans le forum Access
    Réponses: 4
    Dernier message: 09/10/2005, 20h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo