结构体_struct
由基本数据类型组成的复合数据类型
即先自定义想要的类型,再用该类型去申请空间
结构体声明
struct student//声明一个名称为student的数据类型,并没有分配空间
{
char name[16];
int age;
float score;
}
内存对齐
结构体内各个成员需要“对齐”地分配内存空间
为什么要内存对齐?
假设我们同时声明两个变量:
char a;
short b;
如果a地址取为0x0000 0000,那么b的地址为0x0000 0002,而不是取为0x0000 0001
这就是内存对齐。
那么,为什么b不取00000 0001地址呢?
因为如果b取0x0000 0001,那么,那么CPU就需要先从0x0000中读取一个short,取它的高8位放入b的低8位,然后再从0x0002中读取下一个short,取它的低8位放入b的高8位中,这样的话,为了获得b的值,CPU需要进行了两次读操作。
但是如果b的地址为0x0002,那么CPU只需一次读操作就可以获得b的值了。
所以编译器为了优化代码,往往会根据变量的大小,将其指定到合适的位置,即称为内存对齐(对变量b做内存对齐,a、b之间的内存被浪费,a并未多占内存)。
对齐方式
8bit字节对齐 | 任意一个8bit地址 |
16bit半字对齐: | 地址的最低位为0 |
32bit字对齐 | 地址的最低两位为0 |
64ibit多字对齐 |
各种数据类型 | 对齐方式 |
---|---|
char | 1字节对齐 |
short | 2字节对齐 |
int | 4字节对齐 |
long | 4字节对齐 |
float | 4字节对齐 |
double | 8字节对齐 |
示例
#include <stdio.h>
void show();
//结构体一般分配在堆里
/*typedef即把struct新定义的数据类型加入到类型列表内
此时直接输bookinfo就相当于int,无需重复输入 struct */
typedef struct bookinfo
{
char name[16];
int num;
int id;
double cost;
}book,book1, *pbookinfo;//前两个为该结构体类型的两个定义名,后面为结构体指针
void show()
{
book sys ={
"kitty", 18, 50, 18.99};
pbookinfo *p = &sys;//结构体指针
printf("name: %s\nname_addr: %p\n\n", sys.name, &sys.name);
printf("num: %d\nnum_addr: %p\n\n", sys.num, &sys.num);
printf("id: %d\id_addr: %p\n\n", sys.id, &sys.id);
printf("cost:%.2lf\ncost_addr: %p\n\n", sys.cost, &sys.cost);
printf("book_sys_addr: %p\n", p);
printf("size_book = %lu\n", sizeof(book));
}
int main()
{
show();
return 0;
}
打印结果如下
结构体定义
- 先声明结构类型,再定义结构体变量
struct student_info
{
char name[20];
char number[20];
char sex;
int age;
float height;
float weight;
};
struct student_info list;//定义了一个结构体变量list
- 声明类型的同时就直接定义变量
struct student_info //复合数据类型
{
char name[20];
char number[20];
char sex;
int age;
float height;
float weight;
}head,ist; //定义了两个结构体变量head,list
- 1、2配合typedef
typedef struct student
{
char name[16]
int age;
float score;
}student;/*此处为typedef定义的类型名
struct student(上面) = student(下面) ————都与int同属数据类型定义*/
//typedef为student这个类型取一个student的别名用于标识
//并将student变成一个默认类型,即加入到传统类型列表
int main()
{
/*stryct student stu;未加typedef关键字时的写法
存在struct显得臃肿,但是即便有typedef也可用这种方法定义变量
由此可以看出上面的student只是一个程序员为了便于管理代码的符号
而下面的student则通过typrdef获得了与int相同的地位*/
student stu = {
"kitty", 18, 100};//这里用的是下面的student
}
结构体初始化
方式1:
struct student_info jason = {
"jason","007";M',20,180.5,70.0};
注意:
1)个数可以少于成员数量,但总是从第一个成员开始初始化
2)列表中的参数与成员类型号一定对上
3)这种初始化方式必须要跟定义变量同时进行
方式2:
struct student_info jason;
jason.name = "jason";
jason.number = "007",
jason.sex = :'M';
jason.age=20;
jason.height =180.5; .
jason.weight= 70.0;
表示结构体成员: 变量名.成员名
如果要表示张三的学号: zhangsan.number
方式3:
struct student_info jason = {
.name = "jasoni",
.number = "007",
.sex = 'M',
.age = 20,
.height = 180.5,
.weight = 70.0};
这里要注意一点
当student结构体中存在类似
char name[16];
的内容
并且先定义后赋值时,格式为
student stu2;//定义stu2
strcpy(stu2.name, "putty");//采用strcpy赋值
//因为name在这里是一个地址而不是一个变量
结构体输入输出
输入结构体成员的值:
scanf("%s' ,jason.name);//zhangsan.name变量zhangsan成员name的地址
Scanf(^%s" ,jason->name);
scanf("%s'