この章の内容
親切なヒント
皆さんこんにちは、Cbiltpsです 私のブログでは、わかりにくい文章や言葉で表現しにくい要点などがある場合は、画像を載せています。なので、写真付きのブログはとても重要です!!!
私に興味があれば、私の最初のブログをご覧ください。
この章の要点
- 構造体の型の宣言
- 構造体の初期化
- 構造体メンバーへのアクセス
- 構造体のパラメータの受け渡し
1. 構造の宣言
1.1 構造を理解する
その構造はどのようにして生まれたのでしょうか?
複雑なオブジェクトを記述する場合、変数の値(型)だけでなく、多くの属性の組み合わせによっても記述することができ、このとき、この複雑なオブジェクトを表現するための構造が導入される。
構造体とはメンバー変数と呼ばれる値の集合です。
構造体の各メンバーは、異なる型の変数にすることができます。
1.2 構造体型の宣言(作成)
struct tag
{
member_list;
}variable_list;
//sturct 是结构体关键字
//tag 是结构体的名字(标签)
//member_list 是成员变量
//variable_list 是变量列表
//注意:这里的变量列表可以写,也可以不写。
//如果写了:相当于拿前面的结构体类型创建了全局变量
たとえば、本について説明するには、次のようにします。
#include <stdio.h>
//结构体类型——因为不是在创建变量,所以不会占用内存
struct Book
{
char name[20];//下面的三个属性就是成员变量,每个成员可以是不同类型的
char author[15];
float price;
}b1,b2;//b1和b2是全局变量,相当于拿前面结构体类型所创建的变量——放在内存的静态区
//这里的变量列表也可以省略
int main()
{
struct Book b;//这里的b虽然是结构体变量,但是是局部变量——放在内存的栈区
return 0;
}
構造体型を作成する別の方法もあります。
typedef struct Stu
{
char name[20];
int age;
char id[10];
}Stu;//在使用typedef的时候,对这个结构体类型重新起名字叫Stu
//注意:在没有typedef的时候,分号前面的是结构体变量。
// 有typedef的时候,分号前面的是结构体类型(重新起名字的)。
int main()
{
//那么对这个结构体类型有两种写法:
struct Stu B;//用的是没有重新起名字的结构体类型
Stu N;//用的是重新起名字的结构体类型,这种写法更加简洁一些
return 0;
}
1.3 構造体メンバの種類
構造体のメンバーは、変数、配列、ポインター、またはその他の構造体にすることができます。
1.4 構造体変数の定義と初期化
前のコードのコメントでは、実際には構造体変数の定義が 2 つあることがわかります。
1. ローカル変数
2. グローバル変数
それでは、初期化について直接話しましょう。
typedef struct Stu
{
char name[20];
int age;
char id[10];
}Stu;
int main()
{
struct Stu B = {
"张三", 20, "123456" };//就是这样初始化的
Stu N = {
"李四", 23, "7654323" };
return 0;
}
場合によっては、構造体に次の構造体が含まれることがあります。
struct S
{
int a;
char c;
double d;
};
struct T
{
struct S s;
char name[20];
int num;
};
int main()
{
struct T t = {
{
100,'c', 3.14}, "lisi", 30 };//结构体中的结构体这样初始化
return 0;
}
2. 構造体メンバーへのアクセス
- 構造体変数のメンバーへのアクセス
構造体変数のメンバーには、2 つのオペランドを受け入れるドット演算子を介してアクセスします.
。 - 変数のメンバーへの構造体ポインター アクセス
取得するのが構造体変数ではなく、構造体へのポインターである場合があります。
struct S
{
int a;
char c;
double d;
};
struct T
{
struct S s;
char name[20];
int num;
};
int main()
{
//结构体变量访问成员
struct T t = {
{
100, 'w', 3.14}, "zhangsan", 200 };
printf("%d %c %f %s %d\n", t.s.a, t.s.c, t.s.d, t.name, t.num);
//结构体指针访问指向变量的成员
struct T* pt = &t;
printf("%d %c %f %s %d\n", pt->s.a, pt->s.c, pt->s.d, pt->name, pt->num);
return 0;
}
3. 構造体パラメータの受け渡し
#include <stdio.h>
struct S
{
int arr[100];
int num;
char ch;
double d;
};
void print1(struct S ss)
{
printf("%d %d %d %d %c %lf\n", ss.arr[0], ss.arr[1], ss.arr[2], ss.num, ss.ch, ss.d);
}
int main()
{
struct S s = {
{
1,2,3,4,5}, 100, 'w', 3.14};
print1(s);
return 0;
}
#include <stdio.h>
struct S
{
int arr[100];
int num;
char ch;
double d;
};
void print2(struct S* ps)
{
printf("%d %d %d %d %c %lf\n", ps->arr[0], ps->arr[1], ps->arr[2], ps->num, ps->ch, ps->d);
}
int main()
{
struct S s = {
{
1,2,3,4,5}, 100, 'w', 3.14 };
print2(&s);//4个字节
return 0;
}
上記のprint1
合計print2
関数のうちどれがより優れていますか?
答えは「優先print2
関数」です。
関数が推奨される理由print2
:
関数がパラメータを渡すとき、パラメータをスタックにプッシュする必要があります。構造体オブジェクトを渡す場合、その構造体が大きすぎると、パラメータをスタックにプッシュするシステムのオーバーヘッドが比較的大きくなり、パフォーマンスの低下
につながります。
理解するために絵を描いてみましょう。
上記のstack Push が理解できない場合は、例を使って説明しましょう。
//以这段代码为例:
#include <stdio.h>
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = Add(a, b);
return 0;
}
結論: パラメータを構造体に渡すときは、構造体のアドレスを渡すのが最善です。