Es seguro reemplazar el paso de parametros por valor, utilizando punteros a constantes ?

Iniciado por Locura_23, 27 Julio 2021, 23:37 PM

0 Miembros y 2 Visitantes están viendo este tema.

Locura_23

Quiero decir, se podría reemplazar completamente paso por valor, para solo utilizar punteros? Por ejemplo, la siguiente función no necesita punteros pero pienso que actuaría mejor (dado un programa más grande)
(Aunque esta función sería mejor hacerla en linea pero sirve como ejemplo)


#include <stdio.h>

int sumaEnteros(const int *pNum,const int *pOtroNum);

int main()
{
   char buffer[5] = { 0 };
   int num = 0, otroNum = 0, res = 0;

   printf("Ingrese un numero: ");
   fgets(buffer, 4 , stdin);

   sscanf(buffer,"%d",&num);

   printf("Ingrese otro numero: ");
   fgets(buffer, 4 , stdin);
   sscanf(buffer, "%d" , &otroNum);

   res = sumaEnteros(&num,&otroNum);

   printf("\n\n %d + %d = %d\n",num,otroNum,res);

   return 0;
}

int sumaEnteros(const int *pNum, const int *pOtroNum)
{
   return *pNum + *pOtroNum;
}


ivancea96

Reemplazar los tipos de los parametros por punteros a esos tipos, poder se puede, y por lo general, no debería fallar, pero tiene algunas complicaciones:
1. En la función habría que asegurarse (o dejar claro), que no puede recibir un nullptr o un puntero inválido. Para asegurar esto suele ser más visual pasar parámetros por referencia en vez de un puntero.
2. Pasar un puntero a int es tan costoso o más que pasar un int. Copiar un int o copiar un puntero, suele ser idéntico (ambos son tipos de dato entero, y el tamaño suele ser el mismo). Con lo cual, rara vez se gana nada, es raro ver un puntero a const int como parámetro, la verdad (lo mismo con cualquier otro tipo entero o float/double).
3. La norma general: usar cada cosa en su momento. Por muy grande que sea un programa, sus funciones son pequeñas, y cuanto más precisas sean sus definiciones, mejor. Es decir, si una funcion sum(a, b) necesita 2 enteros, pide 2 enteros, no 2 punteros, porque pedir punteros complica el uso de la función, y puede dar a pensar que la función haga otras cosas (¿Por qué pediría un puntero si no?). En caso de clases que no queramos copiar, por el motivo que sea (rendimiento, no se pueda copiar, etc etc), entonces pasar por referencia (const Class&) suele ser más efectivo.

Nota: Lo de paso por referencia es un tema de C++, no C. Si estás trabajando con C, ignora lo del paso por referencia: es poco más que una "utilidad" para facilitar el uso de punteros

srWhiteSkull

Estarías haciendo lo mismo, internamente toma el puntero de las variables y por supuesto trabajar con punteros nunca es seguro así que prescinde de los punteros siempre que sea necesario

Locura_23

@ivancea96 , @srWhiteSkull  gracias por sus respuestas!

Sí sobre esta forma lo leí en un libro, el cual argumenta que de esta manera se combina la seguridad que ofrece el paso de parámetros por valor, pues al ser constantes los punteros, los valores están protegidos, y también la eficiencia al rendimiento de los punteros.

Sin embargo si es posible que haga un poco torpe la lectura de las funciones

RayR

Aunque se puede, no tiene caso hacerlo con tipos básicos, como te dijo ivancea96. De hecho, aparte de los inconvenientes que él te menciona, también está el hecho de que ya no podrías pasarle constantes literales; además de que lo que leíste en el libro sólo aplica si los parámetros son objetos grandes, como estructuras. Ahí se justifica pasar por puntero porque es más eficiente copiar un único valor de 32 o 64 bits, que todos los campos de una estructura o clase, (por no hablar de las llamadas a constructores que se llevarían a cabo si hablamos de C++), por más que el compilador pueda hacer optimizaciones que lo hagan menos ineficiente.

Pero si hablamos de tipos simples, como int, el paso por puntero es de hecho menos eficiente. Dado que el parámero que la función recibe es sólo una dirección, antes de acceder al valor en sí, hay que ir a buscarlo a la memoria, lo cual no sucede con el paso por valor.

En resumen, a menos que se trate de objetos grandes, no tiene sentido pasar punteros a funciones que no necesitan modificar los parámetros. Eso sólo hace tus funciones menos legibles, menos seguras, menos flexibles y menos eficientes.

Locura_23

@RayR gracias por tu respuesta

Ya veo,ahora quedó más claro. Saludos  :)