For each conversion specifier, scanf() expects the corresponding argument to be a pointer to the proper type: %d expects an argument of type int *, %f expects an argument of type double *, %c and %s both expect an argument of type char *, etc.  
The difference between %c and %s is that the former tells scanf() to read a single character and store it in the location specified by the corresponding argument, while the latter tells scanf() to read multiple characters until it sees a 0-valued character and store all those characters in the buffer starting at the location specified by the argument.  
You need to use the & operator on your arguments if they are not already of pointer type.  For example:
int x;
int *px = some_valid_memory_location_such_as_&x;
char c;
char *pc = some_valid_memory_location_such_as_&c;
...
scanf("%d", &x); // x is not a pointer type, so we must use the & operator
scanf("%d", px); // px is a pointer type, so we don't need the & operator
scanf("%c", &c); // etc.
scanf("%c", pc); // etc.
Where things get confusing is reading strings of characters (using the %s conversion specifier):
char buf[SIZE];
scanf("%s", buf);    // expression 'buf' *implicitly* converted to pointer type
Why don't we need the & operator in this case?  It has to do with how C treats array expressions.  When the compiler sees an expression of array type (such as buf in the scanf() call), it will implicitly convert the expression from type N-element array of T to pointer to T, and set its value to the address of the first element in the array.  This value is not an lvalue -- it cannot be assigned to (so you can't write something like buf = foo).  The only exceptions to this rule are when the array expression is an operand of either the sizeof or & operators, or if the array expression is a string literal being used to initialize another array:
char *p = "This is a test";  // string literal implicitly converted to char *,
                             // string *address* written to p
char a[] = "This is a test"; // string literal not implicitly converted,
                             // string *contents* copied to a
In short, the expression buf is implicitly converted from type char [SIZE] to char *, so we don't need to use the & operator, and in fact the type of the expression &buf would be pointer to SIZE-element array of char, or (*)[SIZE], which is not what scanf() expects for the %s conversion specifier.