Problem with recursiveness and pointers

Asked

Viewed 841 times

1

I am struggling to resolve the following issue:

Make a recursive function that allows you to sum the even elements of an integer vector, you must use pointers to traverse the vector

My code is not performing the correct condition calculations if of function somarpar, he got like this:

#include <stdio.h>
#include <stdlib.h>

int somarpar (int vet[], int n){
    int i=0, h=0, *pont=vet;


    for(i=0; i<n; i++){  

    if((pont[i]%2) == 0){

             h = pont[i] + somarpar(pont, n-1);

             }
        } return h;  
}

int main(int argc, char *argv[])
{   
    int somarpar(int vet[], int n);

    int vetor[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *p=vetor, z;

    z = somarpar(p, 10);

printf("a soma dos numeros pares eh: %i\n", z);

    system ("pause");

}

2 answers

1

First before going for the answer I would like to say that your program had several "little mistakes", so first of all I would like to point them out just so you know where you went wrong.

#include <stdio.h>
#include <stdlib.h> /*  Você não utilizou nenhuma função desta biblioteca, não precisava
                        ter incluido-a  */

int somarpar ( int vet[], int n )
{
    int i = 0, h = 0, *pont = vet;  /*  seu exercico diz para usar ponteiro, logo não deve
                                        usar o i para controlar o indice do vetor, e sim
                                        aritimética de ponteiro */

    for ( i = 0; i < n; i++ )   {   /*  Você esta utilizando uma chamada recursiva, o que por si
                                        só já é um loop, for desnecessario, é aqui que faz o seu resultado
                                        sair maior do que o esperado.  */
        if((pont[i]%2) == 0)
        {
            h = pont[i] + somarpar(pont, n-1);
        }
    }

    return h;
}

int main (int argc, char *argv[])   /* você não utilizou nenhuma das duas variaveis, logo não deveria te-las aqui   */
{
    int somarpar(int vet[], int n); /*  declarou a função novamente, e além de tudo dentro da função main
                                        NÃO FAÇA ISSO!.  */

    int vetor[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *p=vetor, z;    /* não precisava fazer este ponteiro para o vetor   */

    z = somarpar(p, 10);

    printf("a soma dos numeros pares eh: %i\n", z);

    system ("pause");
                        /* esqueceu do return 0;    */
}

Taking into account the statement that asks to do a recursive function and also use pointer to walk on the vector index.

First we must understand what the exercise means by "you must use pointers to traverse the vector", you should understand that, what this exercise wants of you, is that you use pointer arithmetic to traverse the vector, ie without using a variable i for example, only with pointer. To do this is simple, just know that a common vector is somehow a pointer, and also you just need to understand how a vector works, and how is the calculation that the computer does to traverse the vector.

So come on, when you declare a vector of any type for example and you want to go through it, what you do so far is a loop where you start any variable (e.g.: i) at zero and then at the end increment it with one, but in the middle of the code you would do something like vet[i], right, so what really happens when you do that is this, vet[i] is equivalent to (tipo*)(vet + i), note that you do a casting for the pointer type of your vector, and then sum your vector with the index you want to access.

Example, let’s assume that you want to sum up a vector of any integers, you have two ways to do:

normal:

for ( i = 0, somatorio = 0; i < tam; ++i )
        somatorio += vet[i];

or

Using Pointer Arithmetic:

for ( ptrVet = (int*)(vetor), somatorio = 0; tam > 0; --tam, ptrVet = (int*)(ptrVet + 1) )
    somatorio += *ptrVet;

Both as I think you can notice are the same thing, the difference is that one omits the pointer arithmetic that the computer does.

Good in the other piece of the question it asks you to do a recursive function, IE, in this case it is not for you to use for, while or do while to loop, and yes recursiveness.

As you used in your function I will consider that you already know how a recursive function works, but even so I will give a very brief explanation.

A recursive function is a function that calls itself or another function in order to make a "loop", to make one you just put an output condition inside a function and then call it recursively until the condition is reached. For example, let’s assume that you want to do a recursive multiplication function, then it would look in such a way.

int multiplicaNumero ( int x, int y )
{
    if ( y <= 1)        /*  Condição de saída   */
        return x;

    return x + multiplicaNumero(x, y - 1);
}

That being explained, if you have understood what I have explained, it will be easy to understand how to do your exercise, so without further ado, here is the final result of your question, that would be the answer I would consider right, given the question, remembering that there are thousands of ways to do the same thing in C, so anything close would be correct.

#include <stdio.h>

int somarPar ( int vet[], int tam )
{
    int* ptrVet = (int*)(vet), soma = 0;

    if ( tam <= 0 )
        return 0;

    if ( *ptrVet % 2 == 0 )
        soma = *ptrVet;

    return soma + somarPar((int*)(ptrVet + 1), tam - 1);
}

int main ()
{
    int vetor[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int tam = sizeof(vetor) / sizeof(vetor[0]);

    printf("a soma dos numeros pares eh: %i\n", somarPar(vetor, tam));

    system ("pause");

    return 0;
}

I hope I helped ;), good luck with the C language studies.

  • 1

    I think it gets more beautiful and direct to the subject of pointers if in the signature of somaPar you by as first argument int *vet in place of int vet[]

  • 1

    And I totally agree with you, the point is that this is her code and not mine, so I kind of tried to do it the way she would, which consequently would be the best way for her to understand, then you can notice that I leave the function the way it was the one she passed on to us.

1

The code has several problems, some of syntax.

I actually consider exercise bad for recursion. It looks better with iteration.

So much so that it looks like it was putting a loop inside the recursive function.

I saw no need to use pointers in this algorithm.

Need to have a recursive termination condition (n > 0) and the simple condition whether it is par and should take this value or not.

#include <stdio.h>

int somarpar(int vet[], int n) {
    return n > 0  ? somarpar(vet, n - 1) + (vet[n] % 2 == 0 ? vet[n] : 0) : 0;
}

int main(void) {   
    int vetor[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    printf("a soma dos numeros pares eh: %i\n", somarpar(vetor, 10));
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.