# Problem with Pointers

1

I'm doing a simple exercise where I have to enter two integers and calculate different operations using functions.

The question is that he asks me for these two prototypes of functions:

``````int * multi (int, int);
int * resta (int, int);
``````

I have several questions:

• What is the benefit of the function returning a pointer and not a variable of type int with the result?
• I do not understand very well how the system works to return pointers by means of functions.
• I leave the code that I did that obviously does not work for me in those two functions.

``````#include <stdio.h>

void suma (int, int, int *);
void divi (int, int, int*);
int * multi (int, int);
int * resta (int, int);

int main()
{
int num1,num2,op,results,resultd;
int *resultm;
int *resultr;

printf("Ingrese el primer numero:  ");
scanf ("%d",&num1);
printf("Ingrese el segundo numero:  ");
scanf ("%d",&num2);

printf("Elija una de las siguientes opciones: \n");
printf (" 1-Suma \n 2-Division \n 3-Multiplicacion \n 4-Resta \n 0-Salir \n");
scanf("%d",&op);

while (op>0&&op<=4)
{ switch (op)
{ case 1: suma (num1,num2,&results);
printf("El resultado es: %d \n", results);
break;
case 2: divi (num1,num2,&resultd);
printf("El resultado es: %d \n", resultd);
break;
case 3: resultm= multi(num1,num2);
printf("El resultado es: %d \n", resultm);
break;
case 4: resultr=resta(num1,num2);
printf("El resultado es: %d \n", resultr);
break; }
printf("Elija una de las siguientes opciones: \n");
printf (" 1-Suma \n 2-Division \n 3-Multiplicacion \n 4-Resta \n 0-Salir \n");
scanf("%d",&op); }

system("PAUSE");
return 0;
}

void suma (int a,int b,int *punts)
{
*punts=a+b; }

void divi (int a,int b,int *puntd)
{
*puntd=a/b; }

int * multi (int a,int b)
{
int *r;

r=(a*b);
return r; }

int * resta (int a,int b)
{
int *rr;

rr=(a-b);
return rr; }
``````

asked by Maca Igoillo 30.01.2017 в 23:15
source

1

First, what is wrong in `multi( )` , being applicable to `resta( )` :

``````int * multi (int a, int b ) {
int *r;

r = ( a * b );

return r;
}
``````

By doing `r = ( a * b )` , you are assigning to a pointer the result of a multiplication. Although force the compiler to accept it, the result will be, at least, undefined ; you are making the pointer point to an arbitrary address, which I think is not what you intend.

Note the difference between assigning to a pointer or to the targeted data ; is not the same. In other parts of your code, as `*punts = a + b` you do it right, you assign the value to the targeted data . The asterisk (*) in front of the variable marks the difference . Without it, you assign to the pointer . With it, you assign to the targeted data .

Advantages of doing so: in your code, absolutely none. In other cases, it only depends on your imagination. Think, for example, of the function `malloc( )` , which assigns memory blocks. How would you do it without returning a pointer? (OK, it's a trick question, it could be done with pointers to pointers **). A very common use is in functions that create and initialize `struct` or other TAD (Abstract Data Type), and return pointers to the created data.

From what I gather from the code, the goal of the exercise is to reuse the same variable `resultado` for all operations , and practice with the possible ways to use it using pointers: passing a pointer as an argument, or returning a pointer as a result.

My version of the same exercise. As exercise :-p, look for my changes and try to understand them according to what is said here; I see in your code that you already use everything you need (except the `do` ):

``````#include <stdio.h>

int results; // FUERA de main, para que sea accesible por todas las funciones.

void suma( int, int, int * );
void divi( int, int, int * );
int *multi( int, int );
int *resta( int, int );

int main( ) {
int num1, num2, op;

printf( "Ingrese el primer numero:  " );
scanf( "%d", &num1 );

printf( "Ingrese el segundo numero:  " );
scanf( "%d", &num2 );

do {
printf( "Elija una de las siguientes opciones: \n" );
printf( " 1-Suma \n 2-Division \n 3-Multiplicacion \n 4-Resta \n 0-Salir \n" );
scanf( "%d", &op );

switch( op ) {
case 1:
suma( num1, num2, &results );
printf( "El resultado es: %d \n", results );
break;

case 2:
divi( num1, num2, &results );
printf( "El resultado es: %d \n", results );
break;

case 3:
printf("El resultado es: %d \n", *multi( num1, num2 ) );
break;

case 4:
printf("El resultado es: %d \n", *resta( num1, num2 ) );
break;
}
} while( op );

system( "PAUSE" );
return 0;
}

void suma( int a, int b, int *punts ) {
*punts = a + b;
}

void divi( int a, int b, int *puntd ) {
*puntd = a / b;
}

int *multi( int a, int b ) {
results = a * b;
return &results;
}

int *resta( int a, int b ) {
results = a - b;
return &results;
}
``````

Pd .: I know, I'm very picky with the code format xD.

EDITO

Working with pointers is the same as working with normal data. We can only assign a value to a variable of the correct type. The main thing is to remember that pointer to int is a type in itself:

``````int a = 10; // tipo de a -> int
int *b = &a; // tipo de b -> puntero a int
char *str = "hola, mundo !!"; // tipo de str -> puntero a caracter

int c = a; // mismo tipo

int d = b; // NO. TIPOS DISTINTOS.

int *z = b; // mismo tipo

char ch1 = str; // NO. TIPOS DISTINTOS.

char ch2 = *str; // mismo tipo
``````

I add a small example; a function `swapInt( )` that exchanges the value of 2 `int` using pointers; returns `0` if the data is equal , `1` if are different .

``````#include <stdio.h>

int swapInt( int *, int * );

int main( void ) {
int dato1 = 10, dato2 = 20;
int inter;

printf( "dato1 = %d, dato2 = %d\n", dato1, dato2 );

inter = swapInt( &dato1, &dato2 );

printf( "dato1 = %d, dato2 = %d, se intercambiaron: %d\n", dato1, dato2, inter );

return 0;
}

void swapInt( int *a, int *b ) {
int tmp;

// Comparamos los punteros.
if( a == b )
return 0;

// Comparamos los valores de los datos apuntados.
if( *a == *b )
return 0;

tmp = *a; // tmp == 10.
a = *b;   // a == 20.
*b = tmp; // b == 10.

return 1;
}
``````

source
1

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.