结构体是一种结构类型,是由若干个数据项组合而成的复合对象,这些数据项称为结构体的成员,每一个成员可以是一个基本数据类型或者一个构造数据类型。在定义结构体类型的变量之前首先声明一个结构体类型。
声明结构体类型的一般形式如下:
struct 结构体名
{ 类型说明符 成员1;
类型说明符 成员2;
···
类型说明符 成员n;
};
struct是声明结构体类型的关键字,“结构体名”由用户自己命名,应遵循标识符的命名规则。
分号是结构体类型说明的结束标志,不能省略。
定义结构体类型的变量有以下三种方式:
(1)先声明结构体类型,再定义结构体类型的变量。
struct student {
int num;
char name[20];
int score;
};
struct student x, y;
(2)声明结构体类型的同时,定义结构体变量。
struct student {
int num;
char name[20];
int score;
} x, y;
(3)省略类型名,直接定义结构体类型的变量。
struct {
int num;
char name[20];
int score;
} x, y;
为了提高内存寻址效率,处理器系统结构对基本数据类型在内存中存放有限制,要求这些数据的首地址是对齐模数k的整数倍,系统默认的对齐模数为8字节。
结构体变量所占存储存储空间总大小是最宽结构体成员所占字节数和对齐模数之间取最小数值的整数倍,可表示为min(max(Li),k)的整数倍。
访问结构体变量的成员的一般形式是:
结构变量名.成员名
“.”在结构体成员运算符,在所有运算符中优先级最高。
写一个简单的例子。
#include <stdio.h>
struct student {
int num;
char name[20];
float score;
} class2023[10], x;
int main() {
struct student class2023[10] = {
{10001, "Moks", 88.8},
{10002, "", 90.12}
};
printf("请输入第2位同学的姓名:");
gets(class2023[1].name);
x = class2023[0];
printf("学号\t姓名\t成绩\n");
printf("%d\t%s\t%.2f\n", class2023[0].num, class2023[0].name, class2023[0].score);
printf("%d\t%s\t%.2f\n", class2023[1].num, class2023[1].name, class2023[1].score);
printf("\n");
printf("复制的信息是%d\t%s\t%.2f\n", x.num, x.name, x.score);
printf("\n");
printf("结构体数组class2023所占存储空间大小是:%d\n", sizeof(class2023));
printf("结构体x所占存储空间大小是:%d", sizeof(x));
}
输入和输出的结果。
只能对结构体变量具体成员进行输入输出操作。
同类型的结构体变量可以整体赋值。
结构体的成员可以像普通变量一样,进行赋值、算术运算等操作。
两个结构体变量不能用运算符“==”或"!="进行比较操作。
结构体指针变量定义的一般形式是:
结构体类型说明符 *结构体指针变量名;
定义一个结构体指针变量滞后,C编译系统只给这个指针变量分配一个用于存放其他结构体变量地址的空间,它并没有具体指向,必须将一个结构体变量的地址赋给该指针变量,结构体变量的地址通过取地址符“&”取得。
写一个简单的例子。
struct student *p;
p = &x;
此时在前面例子中的变量x的存储地址存放在了变量p中,也就是说,指针p指向了变量x。
结构体指针变量访问结构体成员的一般形式如下:
(*结构体指针变量名) .成员名 //第一种:圆点运算符
结构体指针变量名->成员名 //第二种:指向运算符,也称箭头运算符
“->”是“*”运算符和“.”运算符的组合,它先定位所指向的结构体变量,然后选择结构体成员。
“->”是由一个减号和一个大于号组成,且运算优先级最高。
p->num; //得到所指结构体变量成员num的值
p->num++; //得到num的值之后使该值加1
++p->num; //先使num的值加1,再使用它
typedef是C语言中的关键字,它的主要作用是为类型重命名,一般形式如下:
typedef 原类型名 新类型名
使用例子:
1.类型名替换
typedef float REAL;
REAL a,b; //等同于float a,b;
2.定义一个类型名代表一个结构体类型
typedef struct student {
int num;
char name[20];
float score;
} STU;
STU stu1,stu2; //等同于struct student stu1,stu2;
3.定义一个类型名代表一个数组类型
typedef int ARR[10];
ARR a,b,c; //等同于int a[10],b[10],c[10];
4.定义一个类型名代表一个指针
typedef int* zhizhen;
zhizhen p; //等同于 int *p;
写一个简单的例子。
#include <stdio.h>
struct student {
int num;
char name[20];
float score;
};
typedef struct student s1; //重命名结构体student为s1
int main() {
s1 class2023[10] = {
{10001, "Moks", 88.8},
{10002, "", 90.12}
};
s1 *p = NULL; //设置结构体指针p
p = class2023; //将结构体数组的起始地址赋值p
printf("请输入第2位同学的姓名:");
gets(class2023[1].name);
printf("学号\t姓名\t成绩\n");
printf("%d\t%s\t%.2f\n", p->num, p->name, p->score);
p++; //p指向的数组下标加1
printf("%d\t%s\t%.2f", (*p).num, (*p).name, (*p).score);
}
重命名还可以这样表达。
typedef struct {
int num;
char name[20];
float score;
} s1;
输入和输出的结果。