When your compiler sees
char *n1 = "John";
What it's doing behind your back is this.
Code:
static const char compiler_generated_name[] = { 'J', 'o', 'h', 'n', '\0' };
char *n1 = compiler_generated_name;
In other words, it's an initialised char array with a name you don't get to see.
The (dis)-advantage of using "string" is that the compiler usually quietly drops complaints about const.
And because nobody's got time for this level of micro-management, BK/KT decided that when the compiler saw a "string", it would do all the work for you.
Code:
const char m1[] = { 'H', 'e', 'l', 'l', 'o', ',', ' ',
'w', 'o', 'r', 'l', 'd', '\n', '\0' };
printf(m1);
String constants normally end up in .rodata, not .data (that's why they're constants).