異なる翻訳単位で宣言されたオブジェクトには、一貫した型を使用する必要があります。
が与えられint a[] = {2, 3};
た場合、宣言extern int a[];
またはextern int a[2]
; extern int *a;
互換性がありますが、ポインターと配列は完全に別の型であるため互換性はありません。
&
配列に関する特別な点の 1 つは、配列の名前が「アドレス」(単項) またはのオペランドとして以外の式のコンテキストに表示される場合sizeof
、最初の要素へのポインターに自動的に変換されることです。これにより、配列とポインター間の構文の互換性が提供されますが、それらは同じ型ではありません。
コメント付きの例として、これら 2 つの関数を検討してください。a
式は、最初の関数の 2 番目 (技術的には 3 番目) で最初の要素へのポインターに変換されますが、それが のオペランドでprintf
ある最初の関数では変換されないことに注意してください。printf
&
#include <stdio.h>
void print_array_info(void)
{
extern int a[];
printf("address of a: %p\n", (void*) &a); // prints address of a
printf(" converted a: %p\n", (void*) a); // prints address of a[0]
printf("value of a[0]: %x\n", a[0]); // prints value of a
}
void print_pointer_info(void) {
extern int a[];
int *b = a; // == &a[0]
printf("address of b: %p\n", (void*) &b); // prints address of b
printf(" value of b: %p\n", (void*) b); // prints value of b (== &a[0])
printf("value of b[0]: %x\n", b[0]); // prints value of b[0] (== a[0])
}
%p
ポインターを出力し、明示的に にキャストするために使用することに注意してくださいvoid*
。