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

Résolu/Fermé
leandro95 Messages postés 67 Date d'inscription vendredi 25 avril 2014 Statut Membre Dernière intervention 5 juin 2016 - 25 avril 2014 à 16:14
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 - 27 avril 2014 à 14:11
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 jeudi 22 janvier 2009 Statut Membre Dernière intervention 21 mai 2016 1 104
25 avril 2014 à 16:30
#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 vendredi 25 avril 2014 Statut Membre Dernière intervention 5 juin 2016
25 avril 2014 à 16:35
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 vendredi 25 avril 2014 Statut Membre Dernière intervention 5 juin 2016
25 avril 2014 à 16:37
à 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 jeudi 22 janvier 2009 Statut Membre Dernière intervention 21 mai 2016 1 104
25 avril 2014 à 16:38
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 vendredi 25 avril 2014 Statut Membre Dernière intervention 5 juin 2016
25 avril 2014 à 16:43
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 jeudi 22 janvier 2009 Statut Membre Dernière intervention 21 mai 2016 1 104
26 avril 2014 à 03:54
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 jeudi 22 janvier 2009 Statut Membre Dernière intervention 21 mai 2016 1 104
25 avril 2014 à 16:36
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 vendredi 25 avril 2014 Statut Membre Dernière intervention 5 juin 2016
25 avril 2014 à 16:51
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 vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
25 avril 2014 à 23:51
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
26 avril 2014 à 02:15
@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 jeudi 22 janvier 2009 Statut Membre Dernière intervention 21 mai 2016 1 104
26 avril 2014 à 04:24
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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
26 avril 2014 à 14:58
@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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
26 avril 2014 à 14:59
@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 samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 844
27 avril 2014 à 14:11
Merci d'ouvrir un autre post.
Tu pourras également en profiter pour poster ce code entre les balises
</gras> et <gras>
.

Cdlt,
0