19-结构体声明的变异
文章目录
一、 基本结构体声明
struct TieZhu {
int num;
char *Book;
float Price;
char Name[32];
};
- 解释:声明了一个名为
TieZhu
的结构体类型,但没有定义任何变量。它仅仅是一个模板,不占用内存。
二、 变异 1:在声明结构体类型时,顺便定义变量
struct TieZhu {
int num;
char *Book;
float Price;
char Name[32];
} Even, *Jacy; // 在声明结构体类型时,顺便定义了两个变量
- 解释:在声明
TieZhu
结构体类型的同时,定义了一个名为Even
的结构体变量和一个指向TieZhu
类型的指针Jacy
。
void example1() {
Even.num = 1024;
Jacy = &Even; // 让指针Jacy指向Even的地址
Jacy->Book = "Hello";
}
- 注意事项:在这种变异中,
Even
和Jacy
直接可用,不需要单独的变量声明。
三、 变异 2:省略结构体的标签名
struct {
int num;
char *Book;
float Price;
char Name[32];
} Even2, *Jacy2; // 在声明结构体类型时,顺便定义了两个变量
- 解释:省略了结构体标签名,在这种情况下,必须在声明时定义变量
Even2
和指针Jacy2
,否则无法在后续代码中引用这种类型的结构体变量。
void example2() {
Even2.num = 1024;
Jacy2 = &Even2; // 让指针Jacy2指向Even2的地址
Jacy2->Book = "Hello";
}
- 注意事项:这种写法主要用于局部使用的结构体类型,不常见,通常用于嵌套结构体内部的成员。
四、 变异 3:使用 typedef
给结构体类型取别名
typedef struct TieZhu {
int num;
char *Book;
float Price;
char Name[32];
} Tz, *P_Tz; // Tz 相当于 struct TieZhu,P_Tz 相当于 struct TieZhu *
- 解释:使用
typedef
关键字为TieZhu
结构体类型取别名Tz
和指针类型别名P_Tz
,使代码更简洁。
void example3() {
Tz b = {
.Book = "Hello",
.Name = "Even",
.Price = 3.14
};
P_Tz p = &b;
printf("Name: %s\n", b.Name);
printf("Name: %s\n", p->Name);
}
- 注意事项:推荐使用
typedef
,它使代码更易读和维护。
五、 结构体内部包含匿名结构体成员
struct node {
int i;
char c;
float f;
struct { // 结构体内部的成员
float ff;
double d;
} info;
};
void example4() {
struct node data = {
.c = 'A',
.i = 1024,
.f = 3.489,
.info.d = 665.1234,
.info.ff = 3.444
};
struct node *p = &data;
printf("d: %lf, ff: %lf\n", data.info.d, data.info.ff);
printf("d: %lf, ff: %lf\n", p->info.d, p->info.ff);
}
- 解释:在
struct node
中包含了一个匿名结构体作为成员info
,这样可以在一个结构体中包含多个相关联的变量。 - 注意事项:在匿名结构体内的成员引用时,需通过包含该匿名结构体的成员来访问。
六、 结构体数组和指针数组
void example5() {
// 结构体数组
struct TieZhu arr[5]; // 拥有5个结构体元素的数组
// 结构体数组指针
struct TieZhu (*pArr)[5]; // 指向一个拥有5个元素的结构体数组
// 结构体指针数组
struct TieZhu *arrP[5]; // 存放5个结构体类型的指针
}
-
解释:
- 结构体数组:
struct TieZhu arr[5];
定义了一个包含5个TieZhu
结构体元素的数组。 - 结构体数组指针:
struct TieZhu (*pArr)[5];
定义了一个指向包含5个TieZhu
结构体元素的数组的指针。 - 结构体指针数组:
struct TieZhu *arrP[5];
定义了一个包含5个指向TieZhu
结构体类型的指针的数组。
- 结构体数组:
-
注意事项:
- 结构体数组:每个数组元素都是一个完整的结构体实例,占用内存。
- 结构体数组指针:指向一个包含多个结构体实例的数组,可用于传递整个结构体数组。
- 结构体指针数组:每个元素都是一个指向结构体的指针,适用于动态分配和操作多个结构体实例。
完整示例代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct TieZhu {
int num;
char *Book;
float Price;
char Name[32];
};
void example1() {
struct TieZhu Even, *Jacy;
Even.num = 1024;
Jacy = &Even;
Jacy->Book = "Hello";
}
void example2() {
struct {
int num;
char *Book;
float Price;
char Name[32];
} Even2, *Jacy2;
Even2.num = 1024;
Jacy2 = &Even2;
Jacy2->Book = "Hello";
}
typedef struct TieZhu {
int num;
char *Book;
float Price;
char Name[32];
} Tz, *P_Tz;
void example3() {
Tz b = {
.Book = "Hello",
.Name = "Even",
.Price = 3.14
};
P_Tz p = &b;
printf("Name: %s\n", b.Name);
printf("Name: %s\n", p->Name);
}
struct node {
int i;
char c;
float f;
struct {
float ff;
double d;
} info;
};
void example4() {
struct node data = {
.c = 'A',
.i = 1024,
.f = 3.489,
.info.d = 665.1234,
.info.ff = 3.444
};
struct node *p = &data;
printf("d: %lf, ff: %lf\n", data.info.d, data.info.ff);
printf("d: %lf, ff: %lf\n", p->info.d, p->info.ff);
}
void example5() {
struct TieZhu arr[5];
struct TieZhu (*pArr)[5];
struct TieZhu *arrP[5];
}
int main() {
example1();
example2();
example3();
example4();
example5();
return 0;
}
- 使用
example5
演示了结构体数组和指针数组的定义。 - 通过
example1
到example4
演示了结构体声明的几种变异及其使用方法。