An array decays into a pointer to its first element in many contexts, including its use in a function call.  It doesn't decay when it's the operand of the unary & (address-of) operator.  That means d and &d yield the same address in your example, but have different types.  char * and char (*)[100], respectively, in your case.
In contrast, c is a pointer.  When you take its address with &, you're getting the address of the pointer variable, as opposed to using c directly, which gives you the address it's pointing to.  c is a char *, and &c is a char **.
Editorial note:  Use %p to print pointer types.  %x is for an unsigned int, and unsigned int might be a different size from a pointer.  Corrected code might look like:
printf("%p\n", (void *)c);