Recherche…


Remarques

En C, il est courant d'utiliser des valeurs de retour pour indiquer des erreurs qui se produisent; et pour retourner des données en utilisant des pointeurs passés. Cela peut être fait pour plusieurs raisons; y compris ne pas avoir à allouer de la mémoire sur le tas ou à l'aide d'allocation statique au point où la fonction est appelée.

Utilisation de paramètres de pointeur pour renvoyer plusieurs valeurs

Un modèle courant en C, pour imiter facilement le retour de plusieurs valeurs d'une fonction, consiste à utiliser des pointeurs.

#include <stdio.h>

void Get( int* c , double* d )
{
    *c = 72; 
    *d = 175.0;
}

int main(void)
{
    int a = 0;
    double b = 0.0;

    Get( &a , &b );

    printf("a: %d, b: %f\n", a , b ); 

    return 0;
}

Passer des tableaux à des fonctions

int getListOfFriends(size_t size, int friend_indexes[]) {
  size_t i = 0;
  for (; i < size; i++) {
    friend_indexes[i] = i;
  }
}
C99 C11
/* Type "void" and VLAs ("int friend_indexes[static size]") require C99 at least. 
   In C11 VLAs are optional. */
void getListOfFriends(size_t size, int friend_indexes[static size]) {    
  size_t i = 0;
  for (; i < size; i++) {
    friend_indexes[i] = 1;
  }
}

Ici, le static à l'intérieur du paramètre [] du paramètre function demande que le tableau d'arguments ait au moins autant d'éléments que spécifié (éléments de size ). Pour pouvoir utiliser cette fonctionnalité, nous devons nous assurer que le paramètre size est placé avant le paramètre array dans la liste.

Utilisez getListOfFriends() comme ceci:

#define LIST_SIZE (50)

int main(void) {
  size_t size_of_list = LIST_SIZE;
  int friends_indexes[size_of_list];

  getListOfFriends(size_of_list, friend_indexes); /* friend_indexes decays to a pointer to the
                                                     address of its 1st element: 
                                                                      &friend_indexes[0] */

  /* Here friend_indexes carries: {0, 1, 2, ..., 49}; */

  return 0;
}

Voir également

Passer des tableaux multidimensionnels à une fonction

Les paramètres sont passés par valeur

En C, tous les paramètres de fonction sont passés par valeur, donc la modification de ce qui est passé dans les fonctions appelées n'affectera pas les variables locales des fonctions appelantes.

#include <stdio.h>

void modify(int v) {
    printf("modify 1: %d\n", v); /* 0 is printed */
    v = 42;
    printf("modify 2: %d\n", v); /* 42 is printed */
}

int main(void) {
    int v = 0;
    printf("main 1: %d\n", v); /* 0 is printed */
    modify(v);
    printf("main 2: %d\n", v); /* 0 is printed, not 42 */
    return 0;
}

Vous pouvez utiliser des pointeurs pour laisser les fonctions appelées modifier les variables locales des fonctions appelantes. Notez que ce n'est pas une référence par référence, mais que les valeurs des pointeurs pointant vers les variables locales sont transmises.

#include <stdio.h>

void modify(int* v) {
    printf("modify 1: %d\n", *v); /* 0 is printed */
    *v = 42;
    printf("modify 2: %d\n", *v); /* 42 is printed */
}

int main(void) {
    int v = 0;
    printf("main 1: %d\n", v); /* 0 is printed */
    modify(&v);
    printf("main 2: %d\n", v); /* 42 is printed */
    return 0;
}

Cependant, le renvoi de l'adresse d'une variable locale à l'appelé entraîne un comportement indéfini. Voir Déréférencement d'un pointeur sur variable au-delà de sa durée de vie .

Ordre d'exécution des paramètres de la fonction

L'ordre d'exécution des paramètres n'est pas défini dans la programmation en C. Ici, il peut être exécuté de gauche à droite ou de droite à gauche. La commande dépend de l'implémentation.

#include <stdio.h>

void function(int a, int b) 
{
    printf("%d %d\n", a, b);
}

int main(void)
{
    int a = 1;
    function(a++, ++a);
    return 0;
}

Exemple de fonction renvoyant une structure contenant des valeurs avec des codes d'erreur

La plupart des exemples de fonctions renvoyant une valeur impliquent de fournir un pointeur comme argument pour permettre à la fonction de modifier la valeur pointée, comme ci-dessous. La valeur de retour réelle de la fonction est généralement un type tel que int pour indiquer le statut du résultat, qu'il fonctionne ou non.

int func (int *pIvalue)
{
    int iRetStatus = 0;             /* Default status is no change */

    if (*pIvalue > 10) {
        *pIvalue = *pIvalue * 45;   /* Modify the value pointed to */
        iRetStatus = 1;             /* indicate value was changed */
    }

    return iRetStatus;              /* Return an error code */
}

Cependant, vous pouvez également utiliser une struct comme valeur de retour, ce qui vous permet de renvoyer à la fois un statut d'erreur et d'autres valeurs. Par exemple.

typedef struct {
    int    iStat;      /* Return status */
    int    iValue;     /* Return value */
}  RetValue;

RetValue func (int iValue)
{
    RetValue iRetStatus = {0, iValue};

    if (iValue > 10) {
        iRetStatus.iValue = iValue * 45;
        iRetStatus.iStat = 1;
    }

    return iRetStatus;
}

Cette fonction pourrait alors être utilisée comme l'exemple suivant.

int usingFunc (int iValue)
{
    RetValue iRet = func (iValue);

    if (iRet.iStat == 1) {
        /* do things with iRet.iValue, the returned value */
    }
    return 0;
}

Ou il pourrait être utilisé comme suit.

int usingFunc (int iValue)
{
    RetValue iRet;

    if ( (iRet = func (iValue)).iStat == 1 ) {
        /* do things with iRet.iValue, the returned value */
    }
    return 0;
}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow