次のプログラムを検討してください。
#include <stdio.h>
int main()
{
int a[10]={0};
printf("%p %p\n", a, &a);
printf("%d %d\n", *a, *(&a));
return 0;
}
a と &a は同じです。しかし、*a と *(&a) は違います。答えがありません。助けてください。
a[i]
と同じ*(a + i)
です。したがって、最初の要素は配列自体と同じアドレスにあります。
ここの SO に関する別の質問で、より詳細な説明を見つけることができます: How come a array's address is equal to its value in C?
配列のアドレスは、C で早い段階で学習するものの 1 つです。バッファーのアドレスは、その最初の要素のアドレスです。の場合
printf("%d %d\n", *a, *(&a));
*a
の値を取ります。
*(&a)
最初に a のアドレスを取得し、次にそれを参照します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char szBuffer[100];
char *pBufferPtr = NULL;
int main(int argc, char *argv[])
{
pBufferPtr = szBuffer;
printf("%s %i\n %s %i\n %s %i\n",
"szBuffer's address: ", (int ) szBuffer,
"&szBuffer[0]'s address: ", (int ) &szBuffer[0],
"pBufferPtr's address: ", (int ) pBufferPtr);
printf("\n%s\n", "Program ended.");
return 0;
}
私が何年も前に学んだように、ポインタを扱う最善の方法は、以前は「スタブ」コードと呼ばれていたコードを記述し、デバッガで調べるか、「印刷」(printf) ステートメントを使用することです。さらに注意が必要なのは、ポインターの内容ではなく、ポインターが指すものを変更する場合です。
「配列ベースポインター」はありません。つまり、配列を指すポインター変数はありません。配列の名前は、配列自体を指します。そのため、 のアドレスを取ることはできずa
、&a
特殊なケースとして扱われます。
式で配列の名前を使用すると、配列の最初の要素を指すポインターに分解されます。ただし、&
andsizeof
演算子は例外です。
ANSI C では、これ&a
は配列自体のアドレスを意味し、その型は「配列要素へのポインター」ではなく「配列へのポインター」と規定されています。
ANSI より前のコンパイラでは、&a は警告を引き起こします。
a
と&a
は同じ値ですが、型が異なります:int *
とint **
. コードをコンパイルしたときに警告が表示されるはずです。
*
次のようなエクストラを追加すると、2 行目が機能します。
printf("%d %d\n", *a, **(&a));
これは理にかなっています:*a
逆参照a
が配列の最初の要素を与え、 が のアドレスを取得することを&a
意味する場合、 のアドレスを取得しa
、それ*(&a)
をa
逆参照してa
、もう一度戻ってきます。