Home > Blockchain >  Why the scanf function is expecting a pointer type in C?
Why the scanf function is expecting a pointer type in C?

Time:11-19

I am writing the c code to implement the following state machine: enter image description here (from TI-RSLK). Here please find the code:

#include <stdio.h>
struct state{
    unsigned int output;
    unsigned int delay;
    const struct state *next[4];
};

#define center &fsm[0]
#define left &fsm[1]
#define right &fsm[2]

typedef const struct state state_t;

state_t fsm[3] = {
    {3, 50, {right, left, right, center}},
    {2, 50, {left, center, right, center}},
    {1, 50, {right, left, center, center}}
};

int main(void)
{
    state_t *spt; 
    unsigned int input;
    unsigned int output;
    spt = center;
    while(1) {
        output = spt->output;
        printf("%u \n", output);  
        scanf("%u \n", input);
        spt = spt->next[input]; 
    }
    printf("Hello World");

    return 0;
}

This piece of code will return an error:

main.c: In function ‘main’:
main.c:37:17: warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 2 has type ‘unsigned int’ [-Wformat=]
   37 |         scanf("%u \n", input);
      |                ~^      ~~~~~
      |                 |      |
      |                 |      unsigned int
      |                 unsigned int *
3 

I thought '%u' accepts an unsigned integer. Why does it refer to a pointer of unsigned int type here?

I also tried '%d'. I thought '%d' would accept an integer. The error also indicates that a pointer (of type integer) is expected.

Thank you for any discussions!

CodePudding user response:

Oh, it isn't printf that expects a pointer... It's scanf, and the reason is clear. Have you ever tried writing a function that modifies it's arguments in such a way that's visible to the caller?

void test(int fubar) {
    fubar = 42; // this doesn't work
}

To be clear, scanf needs to be able to assign to an object that is visible to the caller, and C is strictly pass-by-value (meaning arguments are copies into temporary locations), so scanf needs a reference type (such as a pointer, passed by value, because C is strictly pass-by-value) in order to modify that which is referenced.

You're missing an ampersand, and your scanf wreaks of hideous guesswork. Change this: scanf("%u \n", input);

To this:

scanf("%u", &input);
         // ^--- see?

... and pick up a copy of K&R2e so you can read it and do the exercises post-haste...

  • Related