まず、なぜ同じ"jesus"で&"jesus"あるか:"jesus"は型の配列でありconst char[6]、最初の要素へのポインタに減衰します。配列のアドレスを取得すると、型が。である配列へのポインタがconst char (*)[6]得られます。ただし、配列へのポインターは、最初の要素へのポインターと数値的に同じです(タイプのみが異なります)。
これは、最後の行にエラーがある理由も説明しています-タイプタイプが間違っています。必要なもの:
const char (*pj)[6] = &"jesus";
最後に、問題は、繰り返される文字列リテラルが同じアドレスを持っているかどうかです。これは完全にコンパイラ次第です。非常に単純な場合は、ソースコードに文字列リテラルが出現するたびに個別のコピーを保存できます。少し賢い場合は、文字列リテラルごとに1つの一意のコピーのみを保存します。もちろん、文字列リテラルはメモリのどこかに、通常はプログラムイメージの読み取り専用データセグメントに格納されます。それらを静的に初期化されたグローバル変数と考えてください。
もう1つ、元のコードは実際には未定義の動作です。これは、引数を%p期待しているためであり、またはではありません。したがって、正しいコードは次のとおりです。void *const char *const char (*)[6]
printf("%p\n%p\n", (void const *)"jesus", (void const *)&"jesus");