"%d" is a placeholder telling printf() of the type of the variable and whatever type this variable is it will be treated as what the placeholder describes it to be. Giving a value of type pointer while specifying the value as type integer would still make printf() behave as though it was given an integer despite the truth being it is of type pointer.
printf() cannot know of the type of the arguments you are passing to it except through this placeholder mechanism.
should work with any valid l-value as far as I know. If you can assign to it through the assignment operator, you can invoke cin >> using it. But I'm much more noob on C++ so I'm not sure.
If x is a float or double printf() will think its an int because of the %d and try to print it accordingly. On 32-bit compilers the size of an int is 4 bytes while the size of a float is 6 bytes. You might even get strange results for all the other parameters because the float will screw up the order of the parameters on the stack. So if you have "%d%f" printf() will attempt to use some of the float as part of the string, which of course is wrong.
The main thing is to make sure the data types of the parameters match the items in the format. If x is an int then passing either x or &x might depend on the compiler you are using, because &x is a pointer. On some compilers pointers and ints are the same size, while on others, like Turbo C, they are different sizes.