Function with reference passage

Asked

Viewed 677 times

3

I’m trying to make a simple function that counts diamonds, each diamond is given by a pair of '<' and '>'. But I’m trying to do it with pointers, but it’s not giving me the right result. I followed the "Simple teaching for pointers", and according to him I believe I am doing it correctly. Where is my mistake? Instead of showing the result, the number of diamonds, it always prints the same memory address.

They shall carry out the relevant tasks:

int main(int argc, char** argv) {
    int casos; // número de casos de teste
    int n;
    int *diamantes; // aponta para número de diamantes
    char vetor[1000]; //variável para armazenar a entrada

    scanf("%d", &casos);

    for (n = 0; n < casos; n++) {
        limparBuffer();
        ler(vetor);
        contador(vetor, diamantes);
        printf("%d\n", diamantes);
    }
    return (EXIT_SUCCESS);
}

int contador(char vetor[], int *d) {
    int i, contEsq = 0, contDir = 0;
    int n = 1;
    for (i = 0; vetor[i] != '\0'; i++) {
        if (vetor[i] == '<')
            contEsq++;
        else if (vetor[i] == '>')
            contDir++;
    }


    if (contEsq > contDir)
        d = &contDir;
    else
        d = &contEsq;

}
  • 1

    I ask what the problem is? Something can be easy to understand but it would be better for you to say what is happening with your code that shouldn’t. There’s something I’m not sure is wrong because it might be that you wanted what’s going on. When to the pointer I strongly advise to avoid it. Even if it’s just an example, I don’t think it makes sense to complicate a program to do something unnecessary. If you want to use the pointer, get something that needs a pointer.

  • Edited question, I agree that could make everything easier using just returns, but the intention is not only to understand, but rather to dominate this content. So I’m applying to the most diverse tasks where it wouldn’t be necessary, or even there are ways to do the same thing more easily. Grateful for the tip.

3 answers

5


Mastering content is just never doing something where you don’t need to. Doing it where you don’t need to is learning wrong.

And it doesn’t really make any sense to do what you’re doing. I can answer you this: don’t do this, you have a basic misconception of variable scope understanding. You are pointing to one of the two variables created in contador and then out of this function will try to access that address when it should no longer be available.

So what is the solution to this? It’s very simple, return the value as any plausible code does. Trying to do the wrong thing will result wrong.

And worse, there’s another problem. Good. Because if it didn’t, it would work by coincidence and you would think you were doing it right.

When you do d = &contDir is saying "take the address of the variable contDir and play in d". Which will then be accessed outside the function by diamantes and print it. In other words, you’re having the address printed. And this address should not be accessed in any way, because it may not have what you expect anymore.

So one possible solution is to get the operator out of d = contDir. What is technically wrong and some compilers may signal problem.

Another way is to access diamantes melting: printf("%d\n", diamantes);. But you’ll keep making a mistake doing this because of the scope.

You probably made that mistake because you want to use something at any cost. It doesn’t work that way.

There is still the solution: *d = contDir;. The most correct but totally unnecessary.

Take this parameter d and make a return which you should do even though you’ve declared the type of this function as int.

Don’t define a solution and look for a problem where it fits. This doesn’t teach anyone. If you insist that you are learning something by doing this I will not say what it is called because some people would consider it aggressive. I’ll just say it’s stubborn.

I don’t know if this is the only problem because the current code is not compileable, parts are missing.

  • I understood the errors, and especially the most serious and that makes the code unfeasible (scope error), and now I know why not do what I am doing is unnecessary and incorrect. I don’t take away your right to think this is stupid, and your answer showed me why it really would be. Thank you.

3

First, the solution to your problem:

1a) exchange the declaration int *diamantes for int diamantes

1b) Or else, do int *diamantes = (int*) malloc(sizeof(int))

2) If you have done 1a, change contador(vetor, diamantes) for contador(vetor, &diamantes). If you’ve done 1b, change printf("%d\n", diamantes) for printf("%d\n", *diamantes)

3) exchange d = &contDir and d = &contEsq for *d = contDir and *d = contDir

4) If you did 1b, then before the return (EXIT_SUCCESS) do free(diamantes)

Now, the explanation:

There is no reference in C. Only, and exclusively, passage by value. Turns out, when you pass a pointer, the value past is a memory address. With it, you can access the contents of that memory address using the * operator and change it.

What were you doing while writing d = &contDir was to change the value past and not the contents. Therefore, when the function returned, nothing had changed and your printf was printing an arbitrary address value because you had not initialized the pointer.

  • The problem was solved following the tips of the first solution, but I found the explanation satisfactory too, grateful.

0

Change the code to:

if (contEsq > contDir)
    d* = contDir;
else
    d* = contEsq;

and tell me if it worked.

  • Didn’t work ...

  • what happened this time ?

  • as the bigown spoke up, as the function was used and in main she is "lost". At least this I understood ...

  • C can put the rest of code and test data in Pastebin for me to compile here ?

  • Of course, here the link of the old (http://pastebin.com/JY9bKx8m), and here the new and working (http://pastebin.com/E2Y6jpjb)

Browser other questions tagged

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