数组允许定义可存储相同类型数据项的变量,
结构是另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
一、解释
C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型)
引:
在实际问题中,一组数据往往有很多种不同的数据类型。例如,登记学生的信息,可能需要用到 char型的姓名,int型或 char型的学号,int型的年龄,char型的性别,float型的成绩。
结构体(类似“记录”),则可以有效的解决这个问题。
概念
结构体本质上是一种数据类型,但它可以包括若干个“成员”,每个成员的类型可以相同也可以不同,也可以是基本数据类型或者又是一个构造类型。
优点
结构体不仅可以记录不同类型的数据,而且使得数据结构是“高内聚,低耦合”的,更利于程序的阅读理解和移植,而且结构体的存储方式可以提高CPU对内存的访问速度。
struct tag
{
member-list
member-list
member-list
...
} variable-list ; //不要忘记大括号后有一个分号
分析:
struct关键词表示接下来是一个结构。
tag 是结构体标签。
member-list 成员列表,是标准的变量定义,比如 int i; 或者 float f,或者其他有效的变量定义。
variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。
结构声明可以放在函数外(此时为全局结构体,类似全局变量,在它之后声明的所有函数都可以使用)
也可以放在函数内(此时为局部结构体,类似局部变量,只能放在该函数内使用,如果与全局结构体同名,则会暂时屏蔽全局结构体)。
此声明只定义了结构体类型(结构体里有什么 int char float),并没有定义变量(std1 std2)
例
//如声明一个学生的结构:
struct Student
{
char name[20]; //姓名
int num; //学号
float score; //成绩
}; //注意分号
三、结构变量
结构体的定义不分配存储空间,结构体变量按其数据结构分配相应的存储
struct 结构体名 结构体变量名;
例
struct Student
{
char name[20]; //姓名
int num; //学号
float score; //成绩
};
struct Student stu1; //定义结构体变量
struct Student
{
char name[20];
int num;
float score;
}stu1;
//在定义之后跟变量名
定义结构体变量以后,系统就会为其分配内存单元,所占长度为结构体中变量的所占字节之和,具体的长度可以在编译器中使用sizeof关键字分别求出来。
四、结构体的不同形式tag、member-list、variable-list 这 3 部分至少要出现 2 个。
结构体并没有标明其标签
struct
{
int a;
char b;
double c;
} s1;
此种方法不能再次定义新的结构体变量(s2,s3…)了。
结构体没有声明变量
struct example
{
int a;
char b;
double c;
};
有标签的结构体,声明了变量t1、t2、t3
struct SIMPLE t1, t2[20], *t3;
用typedef创建新类型
typedef struct
{
int a;
char b;
double c;
} Simple2;
//现在可以用Simple2作为类型声明新的结构体变量
Simple2 u1, u2[20], *u3;
用结构成员运算符点(.)
访问成员的一般形式:
结构变量名 . 成员名
如 stu1 . name 表示学生stu1的姓名。
结构体中的成员又是一个结构体的访问形式:
结构变量名 . 结构变量名(…) . 成员名
如 stu1.birthday.year 访问出生的年份
struct Birthday
{
int year;
int month;
int day;
};
struct Student
{
char name[20];
int num;
float score;
struct Birthday birthday; //生日
}stu1;
struct Student
{
char name[20];
int num;
float score;
struct Birthday{
int year;
int month;
int day;
} bir1;
}stu1;
具体操作
实例
#include#include struct Books { char title[50]; char author[50]; char subject[100]; int book_id; }; int main( ) { struct Books Book1; struct Books Book2; strcpy( Book1.title, "C Programming"); strcpy( Book1.author, "Nuha Ali"); strcpy( Book1.subject, "C Programming Tutorial"); Book1.book_id = 6495407; strcpy( Book2.title, "Telecom Billing"); strcpy( Book2.author, "Zara Ali"); strcpy( Book2.subject, "Telecom Billing Tutorial"); Book2.book_id = 6495700; printf( "Book 1 title : %sn", Book1.title); printf( "Book 1 author : %sn", Book1.author); printf( "Book 1 subject : %sn", Book1.subject); printf( "Book 1 book_id : %dn", Book1.book_id); printf( "Book 2 title : %sn", Book2.title); printf( "Book 2 author : %sn", Book2.author); printf( "Book 2 subject : %sn", Book2.subject); printf( "Book 2 book_id : %dn", Book2.book_id); return 0; }
- 定义时直接赋值
struct Student
{
char name[20];
char sex;
int number;
}stu1 = {"zhaozixuan",'M',12345}; //注意初始化值的类型和顺序要与结构体声明时成员的类型和顺序一致*
struct Student
{
char name[20];
char sex;
int number;
};
struct Student stu1 = {"zhaozixuan",'M',12345};
定义结构体之后逐个赋值strcpy(stu1.name, "王伟"); stu1.sex = 'M'; stu1.number = 12305;定义之后任意顺序赋值
struct Student stu1 =
{
.name = "Wang",
.number = 12345,
.sex = 'W',
};
部分初始化struct Student stu4 = {.name = "Lisa"};
用一个已经存在的结构体去初始化一个新的相同类型的结构体变量,整体的拷贝(每一个成员都一一赋值给新的结构体变量)stu3 = stu1;
注意
在对结构体变量初始化时,要对结构体成员一一赋值,不能跳过前面成员变量,而直接给后面成员赋初值,但是可以只赋值前面几个,对与后面未赋值的变量,如果是数值型,则会自动赋值为0,对于字符型,会自动赋初值为NULL,即‘ ’。
.是运算符,在所有运算符优先级中最高
printf("%d",stu1.name);
scanf("%d",&stu2.birthday.month);
如果结构体的成员本身是一个结构体,则需要继续用.运算符,直到最低一级的成员。(stu2.birthday.month)正确 (stu1.birthday)错误



