2

ご存知のようint (*p)[10]に、int [10]配列を指すポインターを定義するために使用できます。したがって、とがあれば、p=0コンパイラーはコンパイル時にpが何であるかを知っているため、これは機能します。sizeof(int)==4p+10+10*4 = 40

そして、このようにするとどうなりますか?

int main()
{
    int sz = 10;
    int (*p)[sz];
}

言い換えれば、szプログラムがそこで実行されるまで、誰も知りません。これは機能しないはずですが、機能します。

だから私の質問は、それがどのように機能するのかということです。つまり、実行時に値の型をcに格納する場所はありますか?そうでない場合、これはどのように機能しますか?このうち、コンパイラに関連しているだけですか?

私はを使用しgcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)ていますが、次のコードでテストできます。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    int COL ;
    int ROW ;
    scanf("%d %d", &COL, &ROW);
    int (*p)[COL];
    int *mem = (int*)malloc(sizeof(int)*COL*ROW);
    memset(mem,0,sizeof(int)*COL*ROW);
    p = (int (*)[10])mem;

    printf("0x%p\n", p);
    printf("COL=%d\n", p+1, (((int)(p+1))-((int)p))/sizeof(int));

    mem[2*COL+0] = 1;
    printf("%d\n", p[2][0]);
    mem[2*COL+5] = 2;
    printf("%d\n", p[2][5]);
    mem[6*COL+7] = 3;
    printf("%d\n", p[6][7]);

    p[1][2] = 4;
    printf("%d\n", mem[1*COL+2]);

    free(p);

    return 0;
}

私は愚かな質問をしたり、愚かな間違いを犯したりしないことを願っています...

4

1 に答える 1

2

可変長配列タイプのポインター演算は、6.5.6:10に従って明確に定義されており、サンプルコードはあなたのものと非常によく似ています。6.5.3.4:2に従って、sizeofが可変長配列に適用されると、オペランドは実行時にサイズを決定するために評価されるため、可変長配列ポインターの演算も同様に進行します。

可変長配列(6.7.6.2:4)は、第2版(修正されたISO / IEC 9899:1999)以降の標準の一部です。ただし、これらは、準拠実装がサポートする必要のないオプション機能です(6.10.8.3)。

于 2012-09-28T09:10:20.153 に答える