%x
is a format specifier indicates you want to print in lower-case hexadecimal.
So when you don't specify data in the first printf
the result is undefined. Even though the code compiles - it is incomplete!
So let us fix the code first- here is the revised code
#include <stdio.h>
void foo(char *str);
int main(int argc, char* argv[])
{
foo("%x");
return 0;
}
void foo(char *str)
{
char c='c';
printf(str,c);
printf("\n%x",&c);
}
Now to answer your questions "how variables are stored in the memory stack"
The stack pointer registers the top of the stack,every time a value is pushed on to or popped out of the stack - the stack pointer is adjusted to point to the free memory. And then there is the stack frame, it corresponds to a call to the function which has not yet terminated with a return.

the other part was "what the printf statements are printing."
The first parameter in the printf is a format specifier, the second parameter onwards are the data that are to be used for those format specifier(s). When you did not have the c in your first original printf - it just picked up the adjacent int and printed that for %x that was specified. In the revised first printf I made it print he cvalue of c in hexadecimal. In your second printf you make it print the address of C variable that is in the stack.
Check these links for further details -
https://en.wikipedia.org/wiki/Call_stack#Structure
Also other Stackoverflow Q&As that show up on the right pane.