EDIT: "BIG MISTAKE"セクションを更新しました。
Cスタイル(C++とは異なります)のtypedefのクイックレッスンと、それがどのようなものなのか、そしてその使い方です。
まず、基本的なtypedefトリック。あなたがIP1の宣言に*を入れていなかったにもかかわらず、ポインタ・ツー・タイプ-INT:
typedef int* int_pointer;
int_pointer ip1;
int *ip2;
int a; // Just a variable
ip1 = &a; // Sets the pointer to a
ip2 = &a; // Sets the pointer to a
*ip1 = 4; // Sets a to 4
*ip2 = 4; // Sets a to 4
IP1とIP2は同じタイプです。それは宣言の中に*ありました。
トピックを切り替える。 あなたは、実行時に動的にこれを行うには
int array1[4];
として配列を宣言するの話、あなたが行う可能性があります:今
int *array2 = malloc(sizeof(int) * 4);
int a = 4;
array1[0] = a;
array2[0] = a; // The [] implicitly dereferences the pointer
、我々はポインタの配列をしたい場合は何?
int *array1[4];
int a;
array1[0] = &a; // Sets array[0] to point to variable a
*array1[0] = 4; // Sets a to 4
この配列を動的に割り当てましょう。
int **array2 = malloc(sizeof(int *) * 4);
array2[0] = &a; // [] implicitly dereferences
*array2[0] = 4; // Sets a to 4
int **に注目してください。つまり、ポインタからintへのポインタへのポインタです。私たちが選択すれば、ポインタtypedefを使うことができます。
typedef int* array_of_ints;
array_of_ints *array3 = malloc(sizeof(array_of_ints) * 4);
array3[0] = &a; // [] implicitly dereferences
*array3[0] = 4; // Sets a to 4
最後の宣言には*が1つしかありません。それは、そのうちの1つが「typedefの中に」あるからです。その最後の宣言で、ints(int *)への4つのポインタからなるサイズ4の配列ができました。
ここではオペレータの優先度を指摘することが重要です。逆参照演算子[]は*より優先されます。 SO私たちがやっていること、絶対的に明確になるこのです:
今
*(array3[0]) = 4;
、のは、構造体とのtypedefに話題を変えてみましょう。
struct foo { int a; }; // Declares a struct named foo
typedef struct { int a; } bar; // Typedefs an "ANONYMOUS STRUCTURE" referred to by 'bar'
なぜ匿名の構造体をtypedefしますか?まあ、読みやすいように!
struct foo a; // Declares a variable a of type struct foo
bar b; // Notice how you don't have to put 'struct' first
機能を宣言...
funca(struct foo* arg1, bar *arg2);
我々はARG2の前で '構造体' を置く必要はありませんでしたどのように参照してください?
今、私たちは、あなたが使用する必要があり、コードは、このように構造を定義することを参照してください。
typedef int* array_of_ints;
が比較:我々の前にポインタの配列をしたかに似ている
typedef struct { } * foo_pointers;
side-by-side
typedef struct { } * foo_pointers;
typedef int* array_of_ints;
唯一の違いは、struct {}とintの違いです。私たちのfoo_pointersで
、我々のようなfooへのポインタの配列を宣言することができます。
foo_pointers fooptrs[4];
今、私たちは私たちがアクセスすることはできません匿名の構造体へのポインタ店4その配列を持っています。
トピックスイッチ!
UNFORTUNATELY FOR YOU、あなたの先生は間違いを犯しました。上記のfoo_pointers型のsizeof()を見ると、構造体のサイズではなく、その構造体へのポインタのサイズを返します。 32ビットプラットフォームの場合は4バイト、64ビットプラットフォームの場合は8バイトです。これは、構造体そのものではなく、構造体へのポインタをtypedefするためです。 sizeof(pStudentRecord)は4を返します。
したがって、構造自体にスペースを割り当てることはできません。しかし、コンパイラはこの愚かさを許します。 pStudentRecordは、メモリを有効に割り当てるために使用できる名前/型ではなく、匿名の「概念」構造体へのポインタですが、そのサイズをコンパイラに渡すことができます。
pStudnetRecord g_ppRecords [2]; pStudentRecord * record = malloc(sizeof(* g_ppRecords [1]));
より良い練習はこれを行うことです。
typedef struct { ... } StudentRecord; // Struct
typedef StudentRecord* pStudentRecord; // Pointer-to struct
今は明確な方法で、構造体StudentRecord年代を作る能力だけでなく、pStudentRecordさんとそれらへのポインタを持っていると思います。
あなたが強制する方法は非常に悪い習慣ですが、現時点ではまったく問題ではありません。 intを使った簡単な例に戻りましょう。
私の人生を複雑にするtypedefを作成したいが、ここで起こっているコンセプトについて説明したいのですが?古いintコードに戻りましょう。あなたが見ることができるように
typedef int* array_of_ints;
int *array1[4];
int **array2 = malloc(sizeof(int *) * 4); // Equivalent-ish to the line above
array_of_ints *array3 = malloc(sizeof(array_of_ints) * 4);
int a, b, c, d;
*array1[0] = &a; *array1[1] = &b; *array1[2] = &c; *array1[3] = &d;
*array2[0] = &a; *array2[1] = &b; *array2[2] = &c; *array2[3] = &d;
*array3[0] = &a; *array3[1] = &b; *array3[2] = &c; *array3[3] = &d;
、我々はpStudentRecordでこれを使用することができます。
pStudentRecord array1[4];
pStudentRecord *array2 = malloc(sizeof(pStudentRecord) * 4);
一緒にすべてを入れて、それがその論理的に次の:
array1[0]->firstName = "Christopher";
*array2[0]->firstName = "Christopher";
は等価です。 (注意:上記のように正確に行うのではなく、実行時に文字列にchar *ポインタを割り当てることは、既に十分なスペースが割り当てられていることがわかっている場合にのみOKです)。
これは実際に最後のビットを1つだけ表示します。私たちがこのすべての記憶で何をしているのか?どのようにそれを解放するのですか?
free(array1);
free(array2);
とポインタ、匿名の構造体の型定義、および他のものの深夜レッスンの終わりがあります。
ポインタは単にアドレスを指しています。あなたは、あなたが望むように(スペースを使い果たすまで)、そのアドレスから始まるように多くのメモリを予約することができます。 – chris
私はそれが貧しい問題だと思う、あなたはそれのためのスペースを割り当ててみるので、配列がそのような方法で定義できることを理解しているので、あなたは何を求めているのですか?ポインタのスペースを割り当てるのに十分ではありませんbtw pStudentRecordであり、pSt ... ord *ではないstructには、それを使用するために、struct自身のための場所を割り当てる必要があります! – Michael