Buscar..


Observaciones

En C, es común usar valores de retorno para denotar errores que ocurren; y para devolver datos mediante el uso de punteros pasados. Esto se puede hacer por múltiples razones; incluyendo no tener que asignar memoria en el montón o usar una asignación estática en el punto donde se llama la función.

Usando parámetros de puntero para devolver múltiples valores

Un patrón común en C, para imitar fácilmente la devolución de múltiples valores de una función, es usar punteros.

#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;
}

Pasando en Arrays a Funciones

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;
  }
}

Aquí, la static dentro de [] del parámetro de función, solicita que la matriz de argumentos tenga al menos la cantidad de elementos especificados (es decir, elementos de size ). Para poder usar esa función, debemos asegurarnos de que el parámetro de size aparezca antes del parámetro de matriz en la lista.

Utilice getListOfFriends() esta manera:

#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;
}

Ver también

Pasar matrices multidimensionales a una función.

Los parámetros se pasan por valor

En C, todos los parámetros de función se pasan por valor, por lo que la modificación de lo que se pasa en funciones de llamada no afectará las variables locales de las funciones de llamada.

#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;
}

Puede usar punteros para permitir que las funciones de los destinatarios modifiquen las variables locales de las funciones de los que llaman. Tenga en cuenta que esto no se pasa por referencia, sino que se pasan los valores de puntero que apuntan a las variables locales.

#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;
}

Sin embargo, devolver la dirección de una variable local a los resultados del llamante en un comportamiento indefinido. Consulte Desreferenciación de un puntero a una variable más allá de su duración .

Orden de ejecución de parámetros de función

El orden de ejecución de los parámetros no está definido en la programación en C. Aquí puede ejecutarse de izquierda a derecha o de derecha a izquierda. El orden depende de la implementación.

#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;
}

Ejemplo de función que devuelve la estructura que contiene valores con códigos de error

La mayoría de los ejemplos de una función que devuelve un valor implican proporcionar un puntero como uno de los argumentos para permitir que la función modifique el valor apuntado, similar al siguiente. El valor de retorno real de la función suele ser algún tipo, como un int para indicar el estado del resultado, ya sea que haya funcionado o no.

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 */
}

Sin embargo, también puede usar una struct como valor de retorno que le permite devolver tanto un estado de error como otros valores. Por ejemplo.

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;
}

Esta función podría ser utilizada como la siguiente muestra.

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

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

O podría ser utilizado como el siguiente.

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow