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

Résolu
leandro95 Messages postés 67 Date d'inscription   Statut Membre Dernière intervention   -  
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   -
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

Templier Nocturne Messages postés 7734 Date d'inscription   Statut Membre Dernière intervention   1 106
 
#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
}
0
leandro95 Messages postés 67 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
leandro95 Messages postés 67 Date d'inscription   Statut Membre Dernière intervention  
 
à savoir aussi pourquoi int i est la taille du tableau ou se situe le pointeur p après : getByteAddress(tab, 4)
0
Templier Nocturne Messages postés 7734 Date d'inscription   Statut Membre Dernière intervention   1 106
 
Sais tu ce qu'est un pointeur ?

pour les printf, je t'invite à te renseigner par toi même : https://fr.wikipedia.org/wiki/Printf
0
leandro95 Messages postés 67 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
Templier Nocturne Messages postés 7734 Date d'inscription   Statut Membre Dernière intervention   1 106
 
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
0
Templier Nocturne Messages postés 7734 Date d'inscription   Statut Membre Dernière intervention   1 106
 
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
0
leandro95 Messages postés 67 Date d'inscription   Statut Membre Dernière intervention  
 
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?
0
sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   49
 
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
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
@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).
0
Templier Nocturne Messages postés 7734 Date d'inscription   Statut Membre Dernière intervention   1 106
 
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
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
@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
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
@sambia39,
int *pRet = getAddrByte(&tab,4);
tab tout seul. Si tu mets &tab, le type devient int**.
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Merci d'ouvrir un autre post.
Tu pourras également en profiter pour poster ce code entre les balises
</gras> et <gras>
.

Cdlt,
0