構造体は複合データ型です。つまり、他の変数を含む変数です。あなたはObjectiveCに精通しているので、それを「データのみ」のクラスのような小さなものと考えるかもしれません。つまり、メソッドのないクラスです。これは、関連情報をまとめて保存し、1つのユニットとして渡すことができる方法です。
Typedefは、Cの組み込み型の同義語として独自のデータ型に名前を付ける方法です。これにより、コードが読みやすくなり、コンパイラーがより多くのエラーをキャッチできるようになります(プログラムの意図についてコンパイラーに効果的に教えます。 )典型的な例は
typedef int BOOL;
(古いANSI Cには組み込みのBOOL型はありません。)
これは、次のようなことができることを意味します。
BOOL state = 1;
そして、パラメーターを受け取る関数を宣言してから、コンパイラーに、実際にはsだけであってもsをBOOL
渡していることを確認させます。BOOL
int
void flipSwitch(BOOL isOn); /* function declaration */
...
int value = 0;
BOOL boolValue = 1;
flipSwitch(value); /* Compiler will error here */
flipSwitch(boolValue); /* But this is OK */
struct StudentRecord
したがって、上記のtypedefは、学生レコード構造体の同義語を作成しているため、学生レコードを毎回呼び出すことなく渡すことができます。これにより、コードがよりクリーンで読みやすくなります。あなたの例では、ここにそれ以上のものがあることを除いて。私が今説明したのは:
typedef struct {
char * firstName;
char * lastName;
int id;
float mark;
} StudentRecord;
これで、次のようなことができます。
StudentRecord aStudent = { "Angus\n", "Young\n", 1, 4.0 };
また
void writeToParents(StudentRecord student) {
...
}
しかし*
、typedefの後にはあります。これは、StudentRecord自体をtypedefするのではなく、StudentRecordへのポインターを保持するデータ型をtypedefするためです。え?読む...
StudentRecordを渡し、メンバー変数を変更できるようにする場合は、変数自体ではなく、ポインターを渡す必要があるため、StudentRecordへのこのポインターが必要です。typedefはこれに最適です。これも、コンパイラが微妙なエラーをキャッチできるためです。上記でwriteToParents
は、StudentRecordの内容を読み取るだけで作成しました。グレードを変更したいとします。メンバーを直接変更できないため、単純なStudentRecordパラメーターを使用して関数を設定することはできません。したがって、ポインタが必要です。
void changeGrade(StudentRecord *student, float newGrade) {
student->mark = newGrade;
}
*を見逃す可能性があることは簡単にわかります。そのため、代わりに、StudentRecordのポインター型をtypedefすると、コンパイラーが役立ちます。
typedef struct { /* as above */ } *PStudentRecord;
今:
void changeGrade(PStudentRecord student, float newGrade) {
student->mark = newGrade;
}
両方を同時に宣言するのがより一般的です。
typedef struct {
/* Members */
} StudentRecord, *PStudentRecord;
これにより、プレーンな構造体typedefとポインターtypedefの両方が得られます。
では、ポインタとは何ですか?別の変数のメモリにアドレスを保持する変数。シンプルに聞こえます。表面的にはそうですが、非常に微妙になり、非常に迅速に関与します。このチュートリアルをお試しください