The two structs are different. When you initialize the first struct, about 40 bytes of memory are allocated. When you initialize the second struct, about 10 bytesof memory are allocated. (Actual amount is architecture dependent)
You can use the string literals (string constants) to initalize character arrays. This is why
person p = {"John", "Doe",30};
works in the first example.
You cannot assign (in the conventional sense) a string in C.
The string literals you have ("John") are loaded into memory when your code executes. When you initialize an array with one of these literals, then the string is copied into a new memory location. In your second example, you are merely copying the pointer to (location of) the string literal. Doing something like:
char* string = "Hello";
*string = 'C'
might cause compile or runtime errors (I am not sure.) It is a bad idea because you are modifying the literal string "Hello" which, for example on a microcontroler, could be located in read-only memory.