Oracle

Oracle

oracle, 非常oracle.

データ構造ノート 01 - C基礎

この学習ノートは 2021 年 11 月に作成されました。当時、私が受講していた教材は C 言語で実装されていると主張していましたが、実際には C++ の構文がいくつか使用されていました。これは初心者にとって非常に使いにくいものでしたので、私はデータ構造に関する一連の学習ノートを作成しました。これらのノートはすべて純粋な C 言語で実装されています。Redis のソースコードを参考にした部分も多くあります。例えば、双方向リストやハッシュテーブルなどです。もし間違いを見つけた場合は、いつでも指摘していただければ修正します。このノートがコンピュータの初心者の友人たちにとって参考になれば幸いです。

カバー

ポインタについて#

ポインタは C 言語の中核であり、リンク構造を表すための重要な要素です。ポインタの基本的な概念を理解し、単方向リストなどのリンク構造を理解することはもはや難しい問題ではありません。

ポインタとポインタ変数の理解#

変数はデータを格納するためのものであり、ポインタはメモリアドレスです。ポインタ変数はメモリアドレスを格納するための変数です。

    // 整数型の変数ageを宣言し、値を17に設定します
    int age = 17;
    // 整数型のポインタを宣言し、変数ageのアドレスを指すようにします。&記号は「アドレスを取得する記号」と考えることができます。
    int *p = &age;
    printf("ageの値:%d\n", age);
    printf("*pの値:%d\n", *p);
    printf("変数ageのアドレス:%p\n", &age);
    printf("ポインタpが指すアドレス:%p\n", p);
    printf("ポインタp自体のアドレス:%p\n", &p);

出力結果は次のようになります:

    ageの値:17
    *pの値:17
    変数ageのアドレス:000000000062FE1C
    ポインタpが指すアドレス:000000000062FE1C
    ポインタp自体のアドレス:000000000062FE10

ポインタの図解#

C 言語ポインタ

メモリについて#

メモリアドレスについて疑問が生じるかもしれませんが、次のように大まかに理解することができます。

変数名メモリアドレス
age000000000062FE1C17
p000000000062FE10000000000062FE1C

整数型のポインタ変数 p は、整数型の変数 age のメモリアドレスを格納しています。
記号&はアドレスを取得する記号ですので、&age = 000000000062FE1C です。ポインタ変数自体も変数ですので、p には自分自身のアドレスがあります。アドレスを取得する操作は & p = 000000000062FE10 です。そして、*pはポインタ変数 p が格納している値に対応するメモリアドレスに格納されている値を取得します。

struct の宣言#

構造体(struct)は、C プログラミングでよく使用されるもので、オブジェクトのような属性だけでなく、メソッドのないものとして理解できます。構造体の宣言は、オブジェクトの構成レイアウトを記述します。

学生を表す struct を宣言してみましょう:

struct student {
    char name[64];
    int age;
    int class;
}

ここでstudent構造体タグと呼ばれます。struct studentintのような変数の型のように考えることができます。その後、この構造体を使用することができます:

struct の初期化#

すべての属性を一度に初期化できます#

struct student stu = {"austin", 19, 3};

注意:
中括弧内の値の順序は、構造体の属性の順序と一致している必要があります。

宣言後に個別に初期化することもできます#

struct student stu;
strcpy(stu.name, "austin");
stu.age = 19;
stu.class = 3;

strcpy 関数について
strcpy 関数は C 標準ライブラリ <string.h> から提供されており、使用する際にはincludeを忘れないでください。C 言語にはStringのような変数型はないため、通常は文字配列を使用して文字列を表現しますが、文字配列には直接文字列を代入することはできません。しかし、strcpy関数を使用することでこの問題を解決することができます。

構造体の属性宣言と変数宣言を組み合わせることもできます#

struct student {
    char name[64];
    int age;
    int class;
}stu;
/* その後、この構造体を初期化することができます
strcpy(stu.name, "austin");
stu.age = 19;
stu.class = 3; */

初期化を一緒に書くこともできます#

struct student {
    char name[64];
    int age;
    int class;
}stu = {"austin", 19, 3};

複数の変数を一緒に初期化することもできます:

struct student {
    char name[64];
    int age;
    int class;
}stu = {"austin", 19, 3},
stu2 = {"tim", 78, 100};

構造体のタグを省略することもできます#

struct studentの変数stuだけが必要な場合、構造体のタグstudentを省略することができます:

struct {
    char name[64];
    int age;
    int class;
}stu;

これにより、struct student stuのように他の変数を宣言することはできなくなります。

struct の使用#

構造体変数を定義する場合は、. を使用してメンバにアクセスします。
構造体ポインタを定義する場合は、-> を使用してメンバにアクセスします。

struct student {
    char name[64];
    int age;
    int class;
}stu;

// 構造体変数の初期化
strcpy(stu.name, "austin");
stu.age = 19;
stu.class = 3;

struct student *stu_ptr = &stu;

// .を使用して構造体変数のメンバにアクセスする
printf("age: %d\n", stu.age);
// ->を使用してアクセスする
printf("age: %d\n", stu_ptr->age);

typedef の使用#

たとえば、次のような構造体があるとします:

struct student {
    char name[64];
    int age;
    int class;
}

上記のように、この構造体を使用する場合、struct student stuのように変数を宣言します。
typedefキーワードを使用してstruct studentに別名を指定できます:

typedef struct student s;

上記のコードでは、struct studentsという別名に指定しています。したがって、s stu;の文はstruct student stu;と等価です。より簡潔で便利です。
構造体を定義する際にtypedefキーワードを使用することもできます。上記のコードを次のように統合できます:

typedef struct student {
    char name[64];
    int age;
    int class;
}s;

まとめ#

structの使用方法はさまざまですが、理解するのは難しくありません。structの使用方法を熟練させることをお勧めします。これはデータ構造の基本的な構文です。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。