Cのポインターと配列に問題があります。コードは次のとおりです。
#include<stdio.h>
int *ap;
int a[5]={41,42,43,44,45};
int x;
int main()
{
ap = a[4];
x = *ap;
printf("%d",x);
return 0;
}
コードをコンパイルして実行すると、次の警告が表示されます。
[警告]割り当ては、キャストなしで整数からポインターを作成します[デフォルトで有効]
行番号9(ap = a [4];)の場合、端末がクラッシュします。行9を変更して位置を含めない場合(ap = a;)、警告は表示されず、機能します。なぜこうなった?答えは明白なように感じますが、私はそれを見ることができません。
この場合、_a[4]
_は配列内の_5th
_整数ですa
、ap
は整数へのポインターです。したがって、ポインターに整数を割り当てているので、それが警告です。
したがってap
は_45
_を保持するようになり、(*ap
_を実行して)参照解除しようとすると、アドレス45のメモリにアクセスしようとします。無効なアドレスなので、プログラムがクラッシュします。
ap = &(a[4]);
または_ap = a + 4;
_を実行する必要があります
c
配列名はポインターに減衰するため、a
は配列の最初の要素を指します。
このように、a
は&(a[0])
と同等です。
何をしているのですか:(読みやすくするためにinではなくバイトを使用しています)
int *ap
などで始まるため、(コンピューターの)メモリは次のようになります。
-------------- memory used by some one else --------
000: ?
001: ?
...
098: ?
099: ?
-------------- your memory --------
100: something <- here is *ap
101: 41 <- here starts a[]
102: 42
103: 43
104: 44
105: 45
106: something <- here waits x
(... print( "$ d"、...)のショートカットを印刷するときに起こることを見てみましょう
print a[0] -> 41 //no surprise
print a -> 101 // because a points to the start of the array
print *a -> 41 // again the first element of array
print a+1 -> guess? 102
print *(a+1) -> whats behind 102? 42 (we all love this number)
など、a [0]は* a、a [1] = *(a + 1)、...と同じです。
a [n]は読みやすいだけです。
さて、9行目で何が起こるでしょうか?
ap=a[4] // we know a[4]=*(a+4) somehow *105 ==> 45
// warning! converting int to pointer!
-------------- your memory --------
100: 45 <- here is *ap now 45
x = *ap; // wow ap is 45 -> where is 45 pointing to?
-------------- memory used by some one else --------
bang! // dont touch neighbours garden
したがって、「警告」は単なる警告ではなく、重大なエラーです。
int[]
およびint*
は、int []が割り当て(IIRC)を除いて、同じ方法で表されます。
ap
はポインターです。したがって、整数45.
アクセスしようとすると(x = *ap
)、アドレス45にアクセスしようとすると、アクセスできるメモリの一部ではないため、クラッシュの原因になります。