valores valor una retornar retornan retorna que multiples metodo funciones funcion devolver devolución con como c return-value

una - funciones que retornan valores en c++



¿Cómo devuelvo múltiples valores desde una función en C? (9)

Si tengo una función que produce un resultado int y una string resultados, ¿cómo los devuelvo a ambos desde una función?

Por lo que puedo decir, solo puedo devolver una cosa, según lo determinado por el tipo que precede al nombre de la función.


Como uno de los tipos de resultado es una cadena (y está utilizando C, no C ++), recomiendo pasar punteros como parámetros de salida. Utilizar:

void foo(int *a, char *s, int size);

y llámalo así:

int a; char *s = (char *)malloc(100); /* I never know how much to allocate :) */ foo(&a, s, 100);

En general, prefiere hacer la asignación en la función de llamada , no dentro de la función en sí, de modo que pueda estar lo más abierto posible para las diferentes estrategias de asignación.


Cree una estructura y establezca dos valores dentro y devuelva la variable struct.

struct result { int a; char *string; }

Tiene que asignar espacio para el char * en su programa.


Dos enfoques diferentes:

  1. Pase los valores de retorno por el puntero y modifíquelos dentro de la función. Usted declara su función como nula, pero regresa a través de los valores pasados ​​como punteros.
  2. Defina una estructura que agregue sus valores de retorno.

Creo que el # 1 es un poco más obvio sobre lo que está pasando, aunque puede ser tedioso si tienes demasiados valores de retorno. En ese caso, la opción n. ° 2 funciona bastante bien, aunque hay algunos gastos generales involucrados en la fabricación de estructuras especializadas para este fin.


Hola, Peter, creo que puedes devolver 2 valores con la ayuda de punteros en C.


No sé cuál es tu string , pero supongo que administra su propia memoria.

Tienes dos soluciones:

1: Devuelve una struct que contiene todos los tipos que necesitas.

struct Tuple { int a; string b; }; struct Tuple getPair() { Tuple r = { 1, getString() }; return r; } void foo() { struct Tuple t = getPair(); }

2: Usa punteros para repartir valores.

void getPair(int* a, string* b) { // Check that these are not pointing to NULL assert(a); assert(b); *a = 1; *b = getString(); } void foo() { int a, b; getPair(&a, &b); }

El que elija usar depende en gran medida de las preferencias personales en cuanto a cualquier semántica que le guste más.


Pasando parámetros por referencia a la función.

Ejemplos:

void incInt(int *y) { (*y)++; // Increase the value of ''x'', in main, by one. }

También al usar variables globales, pero no es recomendable.

Ejemplo:

int a=0; void main(void) { //Anything you want to code. }


Un enfoque es usar macros. Coloque esto en un archivo de encabezado multitype.h

#include <stdlib.h> /* ============================= HELPER MACROS ============================= */ /* __typeof__(V) abbreviation */ #define TOF(V) __typeof__(V) /* Expand variables list to list of typeof and variable names */ #define TO3(_0,_1,_2,_3) TOF(_0) v0; TOF(_1) v1; TOF(_2) v2; TOF(_3) v3; #define TO2(_0,_1,_2) TOF(_0) v0; TOF(_1) v1; TOF(_2) v2; #define TO1(_0,_1) TOF(_0) v0; TOF(_1) v1; #define TO0(_0) TOF(_0) v0; #define TO_(_0,_1,_2,_3,TO_MACRO,...) TO_MACRO #define TO(...) TO_(__VA_ARGS__,TO3,TO2,TO1,TO0)(__VA_ARGS__) /* Assign to multitype */ #define MTA3(_0,_1,_2,_3) _0 = mtr.v0; _1 = mtr.v1; _2 = mtr.v2; _3 = mtr.v3; #define MTA2(_0,_1,_2) _0 = mtr.v0; _1 = mtr.v1; _2 = mtr.v2; #define MTA1(_0,_1) _0 = mtr.v0; _1 = mtr.v1; #define MTA0(_0) _0 = mtr.v0; #define MTA_(_0,_1,_2,_3,MTA_MACRO,...) MTA_MACRO #define MTA(...) MTA_(__VA_ARGS__,MTA3,MTA2,MTA1,MTA0)(__VA_ARGS__) /* Return multitype if multiple arguments, return normally if only one */ #define MTR1(...) { / typedef struct mtr_s { / TO(__VA_ARGS__) / } mtr_t; / mtr_t *mtr = malloc(sizeof(mtr_t)); / *mtr = (mtr_t){__VA_ARGS__}; / return mtr; / } #define MTR0(_0) return(_0) #define MTR_(_0,_1,_2,_3,MTR_MACRO,...) MTR_MACRO /* ============================== API MACROS =============================== */ /* Declare return type before function */ typedef void* multitype; #define multitype(...) multitype /* Assign return values to variables */ #define let(...) / for(int mti = 0; !mti;) / for(multitype mt; mti < 2; mti++) / if(mti) { / typedef struct mtr_s { / TO(__VA_ARGS__) / } mtr_t; / mtr_t mtr = *(mtr_t*)mt; / MTA(__VA_ARGS__) / free(mt); / } else / mt /* Return */ #define RETURN(...) MTR_(__VA_ARGS__,MTR1,MTR1,MTR1,MTR0)(__VA_ARGS__)

Esto permite devolver hasta cuatro variables de una función y asignarlas a hasta cuatro variables. Como ejemplo, puede usarlos así:

multitype (int,float,double) fun() { int a = 55; float b = 3.9; double c = 24.15; RETURN (a,b,c); } int main(int argc, char *argv[]) { int x; float y; double z; let (x,y,z) = fun(); printf("(%d, %f, %g/n)", x, y, z); return 0; }

Esto es lo que imprime:

(55, 3.9, 24.15)

La solución puede no ser tan portátil porque requiere C99 o posterior para macros variadas y declaraciones variables de enunciado. Pero creo que fue lo suficientemente interesante para publicar aquí. Otro problema es que el compilador no le advertirá si les asigna los valores incorrectos, por lo que debe tener cuidado.

Ejemplos adicionales, y una versión basada en pila del código que usa uniones, están disponibles en mi repositorio github .


Use punteros como sus parámetros de función. Luego utilícelos para devolver múltiples valores.


Option 1 : declare una estructura con un int y una cadena y devuelva una variable struct.

struct foo { int bar1; char bar2[MAX]; }; struct foo fun() { struct foo fooObj; ... return fooObj; }

Option 2 : puede pasar uno de los dos vía puntero y hacer cambios en el parámetro real a través del puntero y devolver el otro como de costumbre:

int fun(char **param) { int bar; ... strcpy(*param,"...."); return bar; }

o

char* fun(int *param) { char *str = /* malloc suitably.*/ ... strcpy(str,"...."); *param = /* some value */ return str; }

Option 3 : Similar a la opción 2. Puede pasar ambos a través del puntero y no devolver nada de la función:

void fun(char **param1,int *param2) { strcpy(*param1,"...."); *param2 = /* some calculated value */ }