2

2 つのファイルがあるとします: file1.c-「array[10]」という名前のサイズ 10 の int 配列のグローバル定義が含まれています。file2.c-「extern int *array」という名前のintポインターが含まれています。ここでは、このポインターを配列にリンクしようとしています。

しかし、file1.c の配列のアドレスと file2.c のポインター値を確認すると、どちらも異なっています。なぜそれが起こっているのですか?

4

2 に答える 2

6

それはうまくいきません、でfile2.c、あなたが必要です

extern int array[];

配列とポインタは同じものではないためです。両方の宣言には互換性のある型が必要であり、 とint*は互換性がありませんint[N]

実際に何が起こるかは指定されていません。プログラムの形式が正しくありませんextern int *array;が、おそらく、sizeof(int*)配列の最初のバイトがアドレスとして解釈されます。

于 2012-11-25T03:15:55.380 に答える
0

extern1.c

#include <stdio.h>

extern int *array;
int test();

int main(int argc, char *argv[])
{
    printf ("in main: array address = %x\n", array);
    test();
    return 0;
}

extern2.c

int array[10] = {1, 2, 3};

int test()
{
    printf ("in test: array address = %x\n", array);
    return 0;
}

出力:

in main: array address = 1
in test: array address = 804a040

そして、アセンブル コード:

08048404 <main>:
 8048404:       55                      push   %ebp
 8048405:       89 e5                   mov    %esp,%ebp
 8048407:       83 e4 f0                and    $0xfffffff0,%esp
 804840a:       83 ec 10                sub    $0x10,%esp
 804840d:       8b 15 40 a0 04 08       mov    0x804a040,%edx    <--------- this (1)
 8048413:       b8 20 85 04 08          mov    $0x8048520,%eax
 8048418:       89 54 24 04             mov    %edx,0x4(%esp)
 804841c:       89 04 24                mov    %eax,(%esp)
 804841f:       e8 dc fe ff ff          call   8048300 <printf@plt>
 8048424:       e8 07 00 00 00          call   8048430 <test>
 8048429:       b8 00 00 00 00          mov    $0x0,%eax
 804842e:       c9                      leave  
 804842f:       c3                      ret    

08048430 <test>:
 8048430:       55                      push   %ebp
 8048431:       89 e5                   mov    %esp,%ebp
 8048433:       83 ec 18                sub    $0x18,%esp
 8048436:       c7 44 24 04 40 a0 04    movl   $0x804a040,0x4(%esp) <------- this (2)
 804843d:       08 
 804843e:       c7 04 24 3d 85 04 08    movl   $0x804853d,(%esp)
 8048445:       e8 b6 fe ff ff          call   8048300 <printf@plt>
 804844a:       b8 00 00 00 00          mov    $0x0,%eax
 804844f:       c9                      leave  
 8048450:       c3                      ret   

アセンブル コードの <--------- に注意してください。メイン関数では配列が array[0] であり、テスト関数では配列がアドレスであることがわかります。

于 2012-11-25T03:55:40.877 に答える