scanf needs to know where to put the data it is scanning from input. If you simply pass a variable instead of a pointer to a location/variable then that value (the variable you are passing in) will only be a copy of the variable because that's how such things are passed into functions. Any changes to such a copied value only affects that copy and when the function ends you'll find that nothing in the original (passed-in) variable has changed. A pointer/address, even if it is a copy, is still a copy of the actual address and so writing to that location via a pointer (copied pointer) will still put the data in the correct location such that when the function ends the parsed information winds up where it's supposed to be. So, in order to actually save data, scanf needs an address.
The printf function on the other hand does not need to get anything and therefore does not need to know about the address of the passed in variable, just the value. So, using a pointer, you must dereference said pointer by use of the '*' in front of the pointer variable name to get the value pointed to by that pointer, otherwise the printf function would essentially be operating on the assumption that it was the value of the pointer (the address) that you wanted to print and not the value stored at that address.
Then any of the following read operations would work to load data into x:
int * p = &x; /* Store address of x into pointer p */
Also, any of following write operations would output the value stored in x
scanf("%d",&x); /* Store into where ever x is located in memory */
scanf("%d",p); /* Store into location pointed to by p (p holds address of x) */
printf("%d\n",x); /* Output the value stored in x */
printf("%d\n",*p); /* Output value of what's stored at where p points to (same location as x) */