Porblème de compréhesion d'un programme en C

Résolu
Bonjour je ne comprend pas certains aspects de ce code j'aimerai des détails sur chaques lignes svp:

#include<stdio.h>

int *getByteAddress(int tab[], int i) {
char *p = (char*)tab;
int c=0;
while(c++ < i ) p++;
return (int*)p;
}

void main(void) {
int tab[] = {257, 259, 256, 0};
int *p = getByteAddress(tab, 4);
int *q = (int*)((long)p + 1);
printf("Octet de poids faible = %d\n", (char)*(q + 1) );
printf("Entier = %u\n", *(q + 1) );
}

4 réponses

  1. #include<stdio.h> //inclusion de stdio (pour printf)

    int *getByteAddress(int tab[], int i) //cette fonction retourne un pointeur
    {
    char *p = (char*)tab; //le pointeur p pointe sur tab qu'on déguise en tableau de char
    int c = 0;
    while(c < i ) //tant que c < i
    {
    c++; // on incrémente c
    p++; //on décale de 8 bit
    }
    return (int*)p; //on retourne p en précisant qu'il pointe un int
    }

    void main(void)
    {
    int tab[] = {257, 259, 256, 0}; //on déclare un tableau d'int
    int *p = getByteAddress(tab, 4); on appelle la fonction (4 est la taille du tableau)
    int *q = (int*)((long)p + 1); //on pointe l'adresse suivante (je crois...)
    printf("Octet de poids faible = %d\n", (char)*(q + 1) ); //on affiche
    printf("Entier = %u\n", *(q + 1) ); //on affiche
    }
    1. merci beacoup je peux avoir plus de précision à partir de :

      int *q = (int*)((long)p + 1); //on pointe l'adresse suivante (je crois...)
      printf("Octet de poids faible = %d\n", (char)*(q + 1) ); //on affiche
      printf("Entier = %u\n", *(q + 1) ); //on affiche
    2. à savoir aussi pourquoi int i est la taille du tableau ou se situe le pointeur p après : getByteAddress(tab, 4)
    3. le tableau int tab[] = {257, 259, 256, 0} devient un tableau de caractères(peux tu me faire une repésentation),à la fin le pointeur p se situe sur le 4 eme éléments de tab càd 0 ou sur le deuxième octet de la valeur 257
    4. ton tableau d'int est représenté en mémoire par des bits, comme ceci (les espaces n'existent pas, ils ne servent qu'à simplifier la lecture) :
      00000000000000000000000100000001 00000000000000000000000100000011 00000000000000000000000100000000 00000000000000000000000000000000

      le fait de le caster en tableau de char ne charge rien, juste la représentation :
      00000000 00000000 00000001 00000001 00000000 00000000 00000001 00000011 00000000 00000000 00000001 00000000 00000000 00000000 00000000 00000000

      ainsi, dans le premier cas, tab[1] vaut 00000000000000000000000100000011 (le 2eme bloc) alors que dans le deuxième cas, tab[1] vaut 00000000 (le 2eme bloc)

      le fait de caster idique juste à l'ordinateur comment il doit compter le décallage et le nombre de bits par bloc
  2. A noter que je ne susi pas sûr de l'utilité de ce programme, mais si c'est juste pour afficher l'octet de point faible, il suffit juste de faire du décalage de bits je pense
    1. oui je sais ce qu'est un pointeur,je comprend chaque ligne du programme mais je n'en vois pas l'utilité et le comportement d'un pointeur sur un tableau qui à la base est un tableau d'entiers puis un tableau de caractères;

      si j'ai int tab[]={1} ,(char*)tab pointe sur l'octet n°1 qui vaut 1 non(8bits,2 puissance 1)? donc il retourne le caractère dont le code ASCII vaut 1?
      1. Bonsoir
        Je me demande qu'elle est l'utilité de ta fonction ? mais avant tout quelque précision
         #include <stdio.h> 
        n'est pas fait pour printf seule . c'est plutôt en-tête standard des d'entrée/sortie ( dit Standard Input/Output d'où le studio) en d'autres termes une bibliothèque standard du C contenant les prototype ou définitions des fonctions mais aussi des macros afin d'effectuer des opérations d'entrée et sortie.

        En langage C lorsqu'un programme transmet les arguments à une fonction il place soit l'adresse soit la valeur de l'argument dans la pile mais quant il s'agit d'une chaine de caractère il va prendre l'adresse de notre tableau ou chaine de caractère et le placer dans la pile plus '\0' (fin de chaine) il faut comprendre que ce ne sont pas les caractères qui sont mis en mémoire mais l'adresse et ainsi donc la fonction ne reçoit que l'adresse de notre tableau petit rappel
        char *pStr;
        char Str[100];
         
        pStr = &Str[0];   /* est l'équivalant de */   pStr = Str;
        

        bref j'essaierais comme ceci ( je n'est pas compilé le code s'il y'a des erreures faite part de ça )

        
        int *getAddrByte(int *pTab,int iIndice){
        	
        	int i = 0;
        	char *p = ( (char*)pTab );
        	while( (i++ < iIndice) && ( (int*)(p++) ) )
        		;
        	return (p);
        }
        
        // Dans le main
        int tab[] = {257, 259, 256, 0}; 
        int *pRet = getAddrByte(&tab,4);
        
        int *pPrint_ret = (int*)((long)pRet + 1); 
        	printf(" (#)->Octet de poids faible = %d\n", (char)*(pPrint_ret  + 1) ); 
        	printf(" (#)->Entier = %u\n", *(pPrint_ret  + 1) ); 
        


        à bientôt
      2. Contributeur
        @sambia39,
        en d'autres termes une bibliothèque standard du C contenant les prototype ou définitions des fonctions
        Non, c'est pas une bibliothèque mais un header comme tu dis juste avant.

        uant il s'agit d'une chaine de caractère il va prendre l'adresse de notre tableau ou chaine de caractère et le placer dans la pile plus '\0' (fin de chaine)
        Non, il met pas le '\0'. Il prend juste l'adresse.

        Pour le code, j'ai pas regardé (il est tard :-p).
      3. leandro => non, il te retourne 0, en effet en mémoire int tab[] = {1} est représenté comme ceci :
        00000000000000000000000000000001
        quand tu le cast en char*, il devient : 00000000 00000000 00000000 00000001
        en regardant tab[0] on trouve donc 00000000

        sambia => dans le code actuel, stdio n'est inclu QUE pour printf, si on supprime les appels a printf, on peut supprimer l'inclusion du header. De plus, toutes les I/O ne sont pas définies dans stdio, write() est défini dans unistd
      4. Contributeur
        @Templier Nocturne,
        De plus, toutes les I/O ne sont pas définies dans stdio, write() est défini dans unistd
        write() n'est pas standard. Pas étonnant qu'elle ne soit pas dans stdio.h. Pour les fonctions standards I/O, elles sont bien définies dans stdio.h
      5. Contributeur
        @sambia39,
        int *pRet = getAddrByte(&tab,4);
        tab tout seul. Si tu mets &tab, le type devient int**.
    2. Contributeur
      Merci d'ouvrir un autre post.
      Tu pourras également en profiter pour poster ce code entre les balises
      </gras> et <gras>
      .

      Cdlt,