文字列定数の実体

" " で囲む表現をしている情報は、 文字列定数と呼ばれますが、
この実体は、 " " で囲む文字に対応するコードをメモリー上に並べ、 その並べた先頭文字のアドレスを表現しているデータで、つまりポインタです。
この並ぶ一つ一つは、文字のコード番号でchar型になっています。
よって、その先頭文字のアドレスということは、(char *)型のポインタ変数に 記憶でき、それで管理できることになります。

例えば、 char * s; のポインタ変数が用意されている場合、

s = "AB\n12"; と記憶させることができるわけです。

この時、sは、(char *)型なので、[]演算子や*演算子を使って希望の位置にあるchar型記憶領域を表現できます。
例えば、 *s や、 s[0] と表現すれば、並ぶ先頭文字の 'A' を表現すること ことになり、次の位置にある 'B' は、 *(s+1) や、 s[1] で表現できます。

なお、 " " で囲む表現がメモリに並べられる時、並べられた領域の最後に、 追加でヌルコード( '\0' が埋め込まれる規則になっています。
例えば、 "AB\n12\n" の表現があるとすると、次のようなメモリへの割り当てが行われます。

'A' 'B' '\n' '1' '2' '\n' '\0'

"AB\n12\n" は、上記のように割り当てられた メモリの先頭文字 'A' のアドレスを表現しているので、このようなポインタを 引数にして、表示関数が作られます。
以下に、そのようなmy_printf関数のプログラム例と動作を示します。



#include <stdio.h>

/* sが指し示す文字列を表示する */
void my_printf(char * s )
{
	int i;
	for(i = 0; s[i] != '\0'; i++){
		putchar( s[i] );	/* ← putchar( *(s+i) ); と同じ */
	}
}

main()
{
	char * p = "AB\n12\n";
	
	my_printf( p );
	printf( p );
	my_printf( "pの指し示す次の文字から表示する。\n" );
	my_printf( p+1 );
	printf( p+1 );
}
AB
12
AB
12
pの指し示す次の文字から表示する。
B
12
B
12