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);