Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[pointeurs] fonction renvoyant un ptr ou un tableau entier ?

9 réponses
Avatar
David Noyelle
Bonjour a tous,

je me sers d'une fonction de manipulation de bits permettant de decoder les
differents champs de type unsigned char d'une adresse IP contenue dans une
variable de type unsigned long:

***********************************************************
#define SIZE_BYTE 8;

void printIP(unsigned long ul_ip)
{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);

//affichage de l'IP
printf("IP lue = %d.%d.%d.%d", auch_ip[0], auch_ip[1], auch_ip[2],
auch_ip[3]);
}
***********************************************************
Juqu'ici tout va bien. Maintenant j'aimerai ecrire une fonction getIP(), qui
non seulement me decode l'IP contenue dans la variable de type unsigned
long, mais qui me renvoie l'addresse IP decodee.

1. Est-t'il possible d'ecrire une fonction getIP() renvoyant le tableau
auch_ip[] ?

2. Je pense que le plus simple est de faire en sorte que la fonction getIP()
renvoie un pointeur sur le premier element du tableau auch_ip[], mais j'ai
un petit peu de mal avec la syntaxe...

***********************************************************
??? getIP(unsigned long ul_ip)
{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);

return ???
}
***********************************************************

3. Utilisation de la fonction getIP() dans le main

***********************************************************
void main(...)
{
unsigned char auch_ip[4];

unsigned long ul_ip = 0xa01a8c0;

//si la fonction getIP() renvoie un tableau
memcpy(auch_ip, getIP(ul_ip), 4); // correct ?

//si la fonction getIP() renvoie un pointeur
auch_ip = getIP(ul_ip); //correct ? utilisation de l'operateur & ?
}
***********************************************************

Merci pour vos lumieres, je sais que c'est une question classique sur
l'utilisation des pointeurs mais au debut c'est un peu troublant...

David

9 réponses

Avatar
Marc Boyer
David Noyelle <david_point_noyelle_chez_yahoo_point_fr> a écrit :
je me sers d'une fonction de manipulation de bits permettant de decoder les
differents champs de type unsigned char d'une adresse IP contenue dans une
variable de type unsigned long:

***********************************************************
#define SIZE_BYTE 8;

void printIP(unsigned long ul_ip)
{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);

//affichage de l'IP
printf("IP lue = %d.%d.%d.%d", auch_ip[0], auch_ip[1], auch_ip[2],
auch_ip[3]);
}
***********************************************************
Juqu'ici tout va bien. Maintenant j'aimerai ecrire une fonction getIP(), qui
non seulement me decode l'IP contenue dans la variable de type unsigned
long, mais qui me renvoie l'addresse IP decodee.

1. Est-t'il possible d'ecrire une fonction getIP() renvoyant le tableau
auch_ip[] ?


Le C ne permet pas de renvoyer un tableau, mais on peut renvoyer
une structure contenant un tableau.

2. Je pense que le plus simple est de faire en sorte que la fonction getIP()
renvoie un pointeur sur le premier element du tableau auch_ip[], mais j'ai
un petit peu de mal avec la syntaxe...


Sauf que tu vas retourner un pointeur sur une variable locale, donc
sur une variable qui n'existera plus. Pas très utile.

La façon idiomatique en C de faire remplir un tableau par une
fonction est de passer à la fonction le dit tableau (en fait,
un pointeur sur, grace à une conversion implicite).

La signature de la fonction devient
void getIP(unsigned long ul_ip, unsigned char auch_ip[4]);

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangereux
que prendre un boulevard dans le sens légal. À qui la faute ?

Avatar
David Noyelle
Bonjour,

merci pour la reponse.

2. Je pense que le plus simple est de faire en sorte que la fonction
getIP()


renvoie un pointeur sur le premier element du tableau auch_ip[], mais
j'ai


un petit peu de mal avec la syntaxe...


Sauf que tu vas retourner un pointeur sur une variable locale, donc
sur une variable qui n'existera plus. Pas très utile.


Pourtant en ecrivant une fonction retournant un pointeur de tableau
d'elements de type unsigned char, cela semble fonctionner:

***********************************************************
unsigned char (*getIP(unsigned long ul_ip))[]
{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);

//on retourne l'adresse
return auch_ip;
}
***********************************************************

Puis dans une autre fonction du meme fichier:

***********************************************************
void maFonction()
{
unsigned short* pauch_ip;
unsigned long ul_ip = 0xa01a8c0;

//on obtient l'adresse (la variable est sensée ne plus exister...cependant
il s'agit d'un env. embarqué)
pauch_ip = getIP(ul_ip);
printf("ip = %d.%d.%d.%d", pauch_ip[0], pauch_ip[1], pauch_ip[2];
pauch_ip[3]);
}

***********************************************************
Remarque: la syntaxe suivante affiche l'IP a l'envers...

printf("ip = %d.%d.%d.%d", pauch_ip, pauch_ip++, pauch_ip++; pauch_ip++);

La façon idiomatique en C de faire remplir un tableau par une
fonction est de passer à la fonction le dit tableau (en fait,
un pointeur sur, grace à une conversion implicite).

La signature de la fonction devient
void getIP(unsigned long ul_ip, unsigned char auch_ip[4]);


OK

David Noyelle
david noyelle chez yahoo point fr


Avatar
Marc Boyer
David Noyelle <david_point_noyelle_chez_yahoo_point_fr> a écrit :
2. Je pense que le plus simple est de faire en sorte que la fonction
getIP()


renvoie un pointeur sur le premier element du tableau auch_ip[], mais
j'ai


un petit peu de mal avec la syntaxe...


Sauf que tu vas retourner un pointeur sur une variable locale, donc
sur une variable qui n'existera plus. Pas très utile.


Pourtant en ecrivant une fonction retournant un pointeur de tableau
d'elements de type unsigned char, cela semble fonctionner:


Cela fait partie des programmes qui 'tombent en marche'.
Il marche parce que l'espace mémoire ou existait ta variable
locale n'a pas été ré-utilisé.

***********************************************************
Remarque: la syntaxe suivante affiche l'IP a l'envers...

printf("ip = %d.%d.%d.%d", pauch_ip, pauch_ip++, pauch_ip++; pauch_ip++);


Pb d'ordre d'évaluation de ++ je suppose. Essaye:
printf("ip = %d.%d.%d.%d", pauch_ip, pauch_ip+1, pauch_ip+2, pauch_ip+3);

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangereux
que prendre un boulevard dans le sens légal. À qui la faute ?



Avatar
Targeur fou
David Noyelle wrote:
Bonjour a tous,


Bonjour,

je me sers d'une fonction de manipulation de bits permettant de decoder l es
differents champs de type unsigned char d'une adresse IP contenue dans une
variable de type unsigned long:

***********************************************************
#define SIZE_BYTE 8;


Note : t'as ton byte réseau qui repose sur 8 bits, un octet, mais il
faut savoir qu'en C, un char, signed char ou unsigned char fait
CHAR_BIT bits de long (limits.h). Et les autres types intégraux ont
des longueurs en bits multiples de celle de *char.

void printIP(unsigned long ul_ip)
{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);


Les fonctions non-standard (ntoh* et hton*, network to host et vice
versa) ainsi que des masques ou macros d'extraction sont tout indiqués
pour ce genre de travail.

//affichage de l'IP
printf("IP lue = %d.%d.%d.%d", auch_ip[0], auch_ip[1], auch_ip[2],
auch_ip[3]);
}
***********************************************************
Juqu'ici tout va bien. Maintenant j'aimerai ecrire une fonction getIP(), qui
non seulement me decode l'IP contenue dans la variable de type unsigned
long, mais qui me renvoie l'addresse IP decodee.

1. Est-t'il possible d'ecrire une fonction getIP() renvoyant le tableau
auch_ip[] ?


Non.

2. Je pense que le plus simple est de faire en sorte que la fonction getI P()
renvoie un pointeur sur le premier element du tableau auch_ip[], mais j'ai
un petit peu de mal avec la syntaxe...


Pourquoi pas un pointeur en paramètre in-out plutôt qu'en retour, tu
te compliques la vie.

***********************************************************
??? getIP(unsigned long ul_ip)


int ou void getIP. Voir exemple plus bas.

{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);

return ???


return un entier ou rien du tout.

}
***********************************************************

3. Utilisation de la fonction getIP() dans le main

***********************************************************
void main(...)
{
unsigned char auch_ip[4];

unsigned long ul_ip = 0xa01a8c0;

//si la fonction getIP() renvoie un tableau
memcpy(auch_ip, getIP(ul_ip), 4); // correct ?


Possible mais crade à mon goût.

//si la fonction getIP() renvoie un pointeur
auch_ip = getIP(ul_ip); //correct ? utilisation de l'operateur & ?


Crade aussi.

Passer en paramètre in-out, c'est bien plus simple.

}
***********************************************************

Merci pour vos lumieres, je sais que c'est une question classique sur
l'utilisation des pointeurs mais au debut c'est un peu troublant...


Voilà un exemple :

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

/* macros d'extraction */
#ifdef ARCHI_GRAND_INDIEN

#define M_GetA(addr_IP) (unsigned char)( (addr_IP) >> (3*CHAR_BIT) )

#define M_GetB(addr_IP) (unsigned char)( (addr_IP) >> (2*CHAR_BIT) )
#define M_GetC(addr_IP) (unsigned char)( (addr_IP) >> CHAR_BIT )
#define M_GetD(addr_IP) (unsigned char)(addr_IP)

#else

#define M_GetD(addr_IP) (unsigned char)( (addr_IP) >> (3*CHAR_BIT) )

#define M_GetC(addr_IP) (unsigned char)( (addr_IP) >> (2*CHAR_BIT) )
#define M_GetB(addr_IP) (unsigned char)( (addr_IP) >> CHAR_BIT )
#define M_GetA(addr_IP) (unsigned char)(addr_IP)

#endif /* ARCHI_GRAND_INDIEN */

int GetIP(unsigned long ul_ip, unsigned char * pAddrIPabcd_arr, int
size)
{

/* Un petit ntoh ici ne pourrait éventuellment pas faire de mal */

if (pAddrIPabcd_arr == NULL || size <4) { return -1; }

/* decodage de l'IP */
pAddrIPabcd_arr[0] = M_GetA(ul_ip);
pAddrIPabcd_arr[1] = M_GetB(ul_ip);
pAddrIPabcd_arr[2] = M_GetC(ul_ip);
pAddrIPabcd_arr[3] = M_GetD(ul_ip);

return 0;
}

int main(void)
{
unsigned char ip[4];
unsigned long ul_ip = 0xa01a8c0;

/* on fait les porcs, on regarde pas ce que renvoie GetIP() */
(void)GetIP(ul_ip, ip, 4);

/* affichage IP */
printf("IP: %u.%u.%u.%un", ip[0], ip[1], ip[2], ip[3] );

return 0;
}

Ce qui donne 192.168.1.10, j'ai bon ;-)

A+
Regis

Avatar
Emmanuel Delahaye
1. Est-t'il possible d'ecrire une fonction getIP() renvoyant le tableau
auch_ip[] ?


Non. Tout ce qu'on sait faire, c'est retourner une adresse. Celle-ci
doit être valide après l'exécution de la fonction :

- Adresse d'un tableau statique (simple, mais peu conseillé)
- Adresse d'un tableau alloué (penser à libérer après usage)
- Adresse d'un tableau dont l'adresse a été passé en paramètre.

--
C is a sharp tool

Avatar
Emmanuel Delahaye
Pourtant en ecrivant une fonction retournant un pointeur de tableau
d'elements de type unsigned char, cela semble fonctionner:

***********************************************************
unsigned char (*getIP(unsigned long ul_ip))[]
{
unsigned char auch_ip[4];

//decodage de l'IP
auch_ip[0] = readBits(ul_ip, 7, SIZE_BYTE);
auch_ip[1] = readBits(ul_ip, 15, SIZE_BYTE);
auch_ip[2] = readBits(ul_ip, 23, SIZE_BYTE);
auch_ip[3] = readBits(ul_ip, 31, SIZE_BYTE);

//on retourne l'adresse
return auch_ip;
}


Comportement indéfini. L'adresse n'est plus valide (variable
automatique) après avoir quitté la fonction.

--
C is a sharp tool

Avatar
Harpo
Emmanuel Delahaye wrote:

1. Est-t'il possible d'ecrire une fonction getIP() renvoyant le
tableau auch_ip[] ?


Non. Tout ce qu'on sait faire, c'est retourner une adresse. Celle-ci
doit être valide après l'exécution de la fonction :


Pas nécessairement, il me semble correct qu'une fonction qui
généralement retourne une adresse retourne NULL lorsqu'elle n'a pas
réussi à allouer le tableau ou le remplir ou que sais-je.


Avatar
David Noyelle
"Emmanuel Delahaye" wrote in message
news:436a57ef$0$19918$

Non. Tout ce qu'on sait faire, c'est retourner une adresse. Celle-ci doit
être valide après l'exécution de la fonction :

- Adresse d'un tableau statique (simple, mais peu conseillé)
- Adresse d'un tableau alloué (penser à libérer après usage)
- Adresse d'un tableau dont l'adresse a été passé en paramètre.


OK merci,

Avatar
Pierre Maurette
Emmanuel Delahaye wrote:

1. Est-t'il possible d'ecrire une fonction getIP() renvoyant le
tableau auch_ip[] ?


Non. Tout ce qu'on sait faire, c'est retourner une adresse. Celle-ci
doit être valide après l'exécution de la fonction :


Pas nécessairement, il me semble correct qu'une fonction qui
généralement retourne une adresse retourne NULL lorsqu'elle n'a pas
réussi à allouer le tableau ou le remplir ou que sais-je.
C'est le problème déjà évoqué de façon sanglante ici-même de confondre

adresse et pointeur. NULL est une valeur valide de pointeur. Le
pointeur NULL n'est jamais déréférençable, puisqu'on est *certain*
qu'il n'est égal à aucune adresse valide d'objet.
Si la fonction renvoie l'adresse d'un objet local et que cette valeur
est affectée à un pointeur, au moment de l'affectation, l'objet est
mort. Donc ce n'est pas une valeur valide pour le pointeur.

--
Pierre Maurette