What is the benefit of the function returning a pointer and not a variable of type int with the result?
In a final program, it does not benefit you at all. Using variables by value is much simpler and faster than using them via pointer. In addition, dynamic memory usually comes into play with pointers and this is often a source of considerable problems.
However, we must not forget that right now you are learning and during the learning you have to internalize how the language works and that includes the use of pointers and dynamic memory management and that is precisely the purpose of these exercises.
I do not understand very well how the system works to return pointers by means of functions
The pointers are still variable. A pointer is just that, instead of storing a direct value it does the same with memory addresses ... in fact you could do the following:
int* ptr;
ptr = 5;
printf("%d",ptr); // 5
It is certainly neither the cleanest nor the most recommended use for the case of pointers but it serves to demonstrate that they do not cease to be variables of use.
Since pointers store memory addresses instead of values or results, their main utility is that they allow information to be shared between different processes. As we see in the following example, this is not possible without pointers:
void Incrementa(int var)
{ var++; }
void Decrementa(int var)
{ var--; }
void IncrementaPtr(int* var)
{ *var++; }
void DecrementaPtr(int* var)
{ *var--; }
int main()
{
int variable = 0;
Incrementa(variable);
Incrementa(variable);
printf("%d\n",variable); // 0
Decrementa(variable);
printf("%d\n",variable); // 0
IncrementaPtr(&variable);
IncrementaPtr(&variable);
printf("%d\n",variable); // 2
DecrementaPtr(&variable);
printf("%d\n",variable); // 1
}
As you can see, the functions that do not use pointers do not allow modifying the value stored in the variable, while those that use pointers are able to modify the value of the variable located in the function main()
.
Another advantage of the pointers is that they are able to store lists of elements:
int lista[100];
The previous variable is, really, a pointer. It is worth mentioning that, due to how it is declared, it has certain limitations with respect to normal pointers, but it is still a pointer. What is happening in the previous line is that the system reserves 100 consecutive positions of type int
and makes the pointer lista
point to the first of them. Thus, to access any item in the list, it is sufficient to apply a determined displacement. Thus, the following operations are equivalent:
int valor;
valor = lista[5]; // Acceso por índice
valor = *(lista+5); // Aritmética de punteros
valor = *(5+lista); // Aritmética de punteros
valor = 5[lista]; // Acceso por índice, funciona pero no te la recomiendo ;)
Why do I tell you this pain in the ass?
Because it is necessary to know the different utilities of the pointers before understanding what happens when returning a pointer.
If you have a variable and return it with a return ... what happens? That said value is copied to the variable that captures the return
:
int func()
{ return 5; }
int main()
{
int var = func(); // var captura el return
printf("%d",var);
}
If instead of a variable you return a pointer, what happens? The memory address is copied:
int* func()
{ return 5; } // Aquí puede que aparezca un warning
int main()
{
int* var = func();
printf("%d",var);
}
Now, returning pointers has certain limitations and complications:
Unable to return an array of fixed size:
int* func()
{
int lista[100];
return lista; // ERROR!!!!
}
Beware of dereferenced variables:
int* func()
{
int valor = 10;
return &valor;
}
int main()
{
int* var = func();
printf("%d",*var); // Cuidado!!! la variable valor ya no existe!!!
}
Beware of memory leaks (dynamic memory that is created and not destroyed)
int* func()
{
int* ptr = (int*)malloc(5*sizeof(int));
return ptr;
}
int main()
{
int* var = func();
var = func(); // La primera reserva de memoria la has perdido!!!!
free(var);
}
The question is that he asks me for these two prototypes of functions: int * multi (int, int); int * subtraction (int, int);
In this case, it tells me that you are being asked to work with dynamic memory:
int* multi(int a, int b)
{
int* ptr = (int*)malloc(sizeof(int)); // Reservamos espacio para un único elemento
*ptr = a*b;
return ptr;
}
int main()
{
int* ptr = multi(3,4);
printf("%d",*ptr);
free(ptr);
}
As I said at the beginning is not the most elegant or the most recommended way to address this problem in a real solution ... but we must not forget that now you are learning and this is one more phase of this process.