C语言 | 复合型数据结构——自定义数据类型

结构体_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;
}

打印结果如下

结构体定义

  1. 先声明结构类型,再定义结构体变量
struct student_info
{
   
	char name[20];
	char number[20];
	char sex;
	int age;
	float height;
	float weight;
};

struct student_info list;//定义了一个结构体变量list
  1. 声明类型的同时就直接定义变量
struct student_info //复合数据类型
{
   
	char name[20];
	char number[20];
	char sex;
	int age;
	float height;
	float weight;
}head,ist; //定义了两个结构体变量head,list

  1. 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在这里是一个地址而不是一个变量

结构体输入输出

C 语言中,「.」与「->」有什么区别?

输入结构体成员的值:
scanf("%s' ,jason.name);//zhangsan.name变量zhangsan成员name的地址

Scanf(^%s" ,jason->name); 

scanf("%s'
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值