web-dev-qa-db-ja.com

Cポインターと配列:[警告]割り当ては、キャストなしで整数からポインターを作成します

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;)、警告は表示されず、機能します。なぜこうなった?答えは明白なように感じますが、私はそれを見ることができません。

16
user2274889

この場合、_a[4]_は配列内の_5th_整数ですaapは整数へのポインターです。したがって、ポインターに整数を割り当てているので、それが警告です。
したがってapは_45_を保持するようになり、(*ap_を実行して)参照解除しようとすると、アドレス45のメモリにアクセスしようとします。無効なアドレスなので、プログラムがクラッシュします。

ap = &(a[4]);または_ap = a + 4;_を実行する必要があります

c配列名はポインターに減衰するため、aは配列の最初の要素を指します。
このように、a&(a[0])と同等です。

23
Dipto

何をしているのですか:(読みやすくするために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

したがって、「警告」は単なる警告ではなく、重大なエラーです。

7
halfbit

int[]およびint*は、int []が割り当て(IIRC)を除いて、同じ方法で表されます。

apはポインターです。したがって、整数45.

アクセスしようとすると(x = *ap)、アドレス45にアクセスしようとすると、アクセスできるメモリの一部ではないため、クラッシュの原因になります。

0
njzk2