0

多くのプログラミング言語 ( JavaScriptJava、およびRubyを含む) では、配列をそれ自体の中に入れることができます。ここでは、C 整数配列をその 3 番目のインデックスに配置しようとしていますが、これが C プログラミング言語でサポートされているかどうかはわかりません。

#include <stdio.h>

int main(void) {
    int arr[] = {1, 1, 2};
    arr[2] = arr; //now I'm trying to put arr into itself.
    printf("%i", arr[2]); //this prints a negative number each time I run the program
    printf("%i", arr[2][0]); //prog.c:7:24: error: subscripted value is neither array nor pointer nor vector

    return 0;
}

C配列をそれ自体の中に入れることは可能ですか、それともまったく不可能ですか?

4

2 に答える 2

5

いいえ、配列にintそれ自体を含めることはできません。

配列の要素の 1 つを配列への変換されたポインターにするなど、いくつかの (おそらく移植性のない) トリックがあります。

int arr[10];
arr[5] = (int)arr;

しかし、これは配列にそれ自体が含まれるようにはなりません。式arrは配列型であるため、これを含むほとんどのコンテキストで最初の要素へのポインターに暗黙的に変換 (「減衰」) されます。arrしたがって、変換によって情報が失われないと仮定すると、arr[5]type に戻すことで の最初の要素へのポインターを取得できますint*arrこれはの最初の要素へのポインターのみを提供することに注意してください。の長さに関する情報が失われますarrint*また、ポインタの値が に収まらず、情報の損失が生じることは非常に一般的ですint(64 ビット システムでは、int*64 ビットとint32 ビットが一般的です)。

整数、ポインター、および配列は、3 つのまったく異なるものです。それらは単に交換可能ではありません。

読むことをお勧めします: comp.lang.c FAQのセクション 6 。これは、C における配列とポインターの間のしばしば混乱を招く関係を非常にうまく説明しています。

Java や Ruby などの言語でさえ、配列は実際にはそれ自体を含むことはできません。それ自体への参照を含めることができますが、言語はそれが参照であることを隠す構文糖衣を提供する場合があります。C では、そのような参照は一般に明示的です。

できることは、独自の型のオブジェクトへのポインターを含むデータ構造を定義することです。これは通常、構造体で行われます。例えば:

struct tree_node {
    int data;
    struct tree_node *left;
    struct tree_node *right;
};

これはCであるため、ツリーノードのメモリを明示的に管理しmalloc()、割り当てとfree()解放を使用する必要があります-または、それを行う既存のライブラリを使用できます。

于 2013-05-22T03:09:31.077 に答える
0

システムの int の長さがポインターの長さと同じかそれ以上で、ポインターを int にキャストして格納できる場合、実際には可能です。ポインターとして逆参照してみてください。後者を怠ったことが、エラー メッセージの原因でした。

このような単純なスキームでは、どの要素が値で、どの要素がポインターであるかを別々に追跡する必要があることに注意してください。ポインターの長さが要素の長さよりも短いことを保証できる場合 (またはユーザー空間ポインターの有効範囲がさらに制限されている場合) にのみ、要素がリテラル値かポインターかを示すためにいくつかのビットを予約できます。 .

これがその要素に適しているという事前の知識に基づいて、明示的にキャストバックする方法の例を次に示します。

printf("%i", ((int *)arr[2])[0]);

これをより明確に行うには、配列を int ではなく共用体にすることをお勧めします。これにより、各要素はunionint とポインターになります。つまり、同じメモリに対して 2 つの正式に認識されるビューが存在するということです。ただし、各要素の該当する型を追跡するためのスキームが必要です。

于 2013-05-22T02:50:43.737 に答える