1. ホーム
  2. arrays

[解決済み] int (*p)[10]=s と int (*o)[5]=&s の違いは何ですか?

2022-02-15 21:46:52

質問

int (*o)[5]=&s; という規則に基づいて、ポインタoが5つの要素を持つ配列を指すのは正しい方法ですか?

また、このsは次のように記述することもできます。

int (*p)[10]=s; 

が、なぜ

&s at int (*o)[5]=&s; 

のように、どちらも同じ出力を返します。

#include <stdio.h>
int main()
{
        int s[5]={10,1,2,3,4};
        int (*p)[10]=s;
        printf("%d\n",*p);
        printf("%d\n",**p);
        printf("%d\n",&s);
        
        printf("\n");

        int (*o)[5]=&s;
        printf("%d\n",*o);
        printf("%d\n",**o);
        printf("%d",&s);
    
        return 0;
}

このプログラムの出力は

-593812272
10
-593812272

-593812272
10
-593812272

解決方法は?

この行

int (*p)[10]=s;

は不正解です。イニシャライザの型は int * を暗黙のうちに変換するため、配列指定子 s をその最初の要素へのポインタに変換します。そして、左手と右手の2つのポインタは互換性がありません。だから、コンパイラはメッセージを出すべきだ。

この行

int (*o)[5]=&s;

が正しいです。イニシャライザーの型は int ( * )[5] これは、初期化されたポインタ o .

ポインタの値を出力するには、変換指定子を使用しなければならないことに注意してください。 %p . そうでない場合は、変換指定子 %d を使用してポインタを出力すると、未定義の動作が発生します。

そのため、例えば以下のような呼び出しの代わりに

printf("%d\n",*o);
//...
printf("%d",&s);

を書く必要があります。

printf("%p\n", ( void *)*o);
//...
printf("%p\n", ( void * )&s);

式は *o は、配列 s は暗黙のうちに最初の要素へのポインタに変換されます。

式の値は *o という式と &s は、配列が占めるメモリ領域のアドレスなので、同じです。しかし、その型は異なっている。の呼び出しの引数として使用される最初の式は,配列が占めるメモリ領域のアドレスであるため,同じである。 printf は、型が int * 一方、2番目の式は int ( * )[5] .