C语言学习笔记——组合数据类型

目录

 

一、结构体

二、枚举与共用体


一、结构体

结构体:(类似我们经常使用的基本数据类型,但是可以根据我们的需求来定义)

  • 是一种由用户自己定义的数据类型(定义的类型集合,必须是由基本数据类型、数组、指针等构成)
  • 结构体的定义:(定义在函数外部)
  • struct  结构体名
  • {
  •        成员列表;(用所学的类型)
  • };
  •  如:
  • struct student
  • {
  •         char name[100];
  •         char sex;
  •         char ate;
  •         int    id;
  • };

结构体的赋值方法:

  • 结构体变量:
  • 在定义变量的时候依次赋值:struct student a={"a",'m',18,12345};
  • 在{}内进行赋值,不依照顺序:struct student a={.id = 123456, .name = "a",.age = 18, .sex = 'm'};
  • 对结构体变量的每一个成员赋值:(推荐使用
  • struct student a={0}//定义一个结构体变量并清空
  • strcpy(a.name,"a");//注意在给数组赋值的时候不能直接赋值,要通过strcpy或者一个一个字符赋值(a.name[0] = 'a')
  • a.sex = 'm';             //因为a.name 相当于数组的首地址!!!
  • a.age = 18;
  • a.id = 123456;
  •  
  • 结构体指针:
  • 使用      ->    指向符
  • 如:
  • struct student a = {0};//定义一个结构体变量,并且清空
  • struct student *p =  &a;//结构体指针指向 a (结构体变量)
  • 使用 指向符 进行赋值
  • strcpy(p->name,"a");//此时p指向name 的地址,一定要用strcpy或者一个一个赋值(p->name[0] = 'a')
  • p->sex = 'm';
  • p->age = 18;
  • p->id = 123456;

结构体的空间分配:

  • 结构体的空间分配的影响因素
  • 结构体在分配空间的时候,按照最大的数据类型进行字节对齐的原则:2字节对齐、4字节对齐
  • 在定义结构体的时候,相同的数据尽量放一起,这样可以使定义的结构体的占用最少的空间
  • 下面示例3,会具体演示,什么叫2字节对齐、4字节对齐。

 

  • 例1:
  • 结构体变量的几种赋值方式:
  • 测试代码如下:
#include<stdio.h>
#include<string.h>
struct student 
{
	char name[20];
	char sex;
	int age;
};

void main(int argc, char const *argv[])
{
	//定义并且依次赋值
	struct student a={"xiaoming",'m',18};

	//定义并且不按顺序赋值
	struct student b={.age = 20,.name = "xiaobai",.sex = 'f'};

	//对结构体成员里面每一个成员赋值
	struct student c = {0};//定义一个结构体变量,并且清空
	strcpy(c.name,"xiaohua");
	c.sex = 'm';
	c.age = 18;

	//打印查看结果
	printf("a.name = %s , a.sex = %c ,a.age = %d\n",a.name,a.sex,a.age);
	printf("b.name = %s , b.sex = %c ,b.age = %d\n",b.name,b.sex,b.age);
	printf("c.name = %s , c.sex = %c ,c.age = %d\n",c.name,c.sex,c.age);

	return ;
}

输出结果,如图所示:

 

  • 例2:
  • 通过结构体指针赋值:
  • 为一个结构体指针分配一块堆空间再利用该指针往堆空间中进行赋值
  • 测试代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/*
为一个结构体指针分配一块堆空间
再利用该指针往堆空间中进行赋值
 */
struct student
{
	char name[20];
	char sex;
	int age;
};

void main(int argc, char const *argv[])
{
	//定义一个结构体指针
	struct student *p = NULL;
	
	//将结构体指针指向 堆空间
	p = (struct student *)malloc(2*sizeof(struct student));

	//用指针往堆空间中进行赋值
	strcpy(p->name,"xiaobai");
	p->sex = 'm';
	p->age = 21;

	strcpy((p+1)->name,"zhanghua");
	(p+1)->sex = 'f';
	(p+1)->age = 20;

	//打印
	printf("p.name = %s , p.sex = %c , p.age = %d\n",p->name,p->sex,p->age);
	printf("(p+1).name = %s , (p+1).sex = %c , (p+1).age = %d\n",(p+1)->name,(p+1)->sex,(p+1)->age);	
	
	return ;
}

输出结果,如图所示:

 

  • 例3:
  • 结构体的空间分配:
  • 与类型的摆放顺序有关
  • 与结构体中需要空间最大的基本类型有关
  • 测试代码如下:
#include<stdio.h>
#include<string.h>
//按占用空间最大的基本类型来分
struct test
{
	char a;
};
struct test1
{
	char a;
	short b;
};
struct test2
{
	char a;
	int b;
};

//结构体所用空间与,类型顺序有关
struct test3
{
	char a;
	int b;
	short c;
};
struct test4
{
	char a;
	short c;
	int b;
};
struct test5
{
	char a;
	short b;	
};
struct test6
{
	short b;
	char a;
};

void main(int argc, char const *argv[])
{
	printf("按占用空间最大的基本类型来分:\n");
	printf("struct test ={char a} ----> = %d\n",sizeof(struct test));
	printf("struct test1 ={char a;short b;} ----> = %d\n",sizeof(struct test1));
	printf("struct test2 ={char a;int b} ----> = %d\n",sizeof(struct test2));
	printf("====================================================\n");
	printf("结构体所用空间,与类型的顺序有关:\n");
	printf("4字节对齐:\n");
	printf("struct test3 ={char a;int b;short c;} ----> = %d\n",sizeof(struct test3));
	printf("struct test4 ={char a;short c;int b;} ----> = %d\n",sizeof(struct test4));
	printf("2字节对齐:\n");
	printf("struct test5 ={char a;short b;} ----> %d\n",sizeof(struct test5));
	printf("struct test6 ={short b;char a;} ----> %d\n",sizeof(struct test6));

	return;
}

输出结果,如图所示:

4字节对齐:

2字节对齐:

 

二、枚举与共用体

共用体:

  • 也是由用户定义的一种数据类型(与结构体相似),但是它里面的成员共用最大的数据类型空间
  • 较少使用

枚举:

  • 把一个类型中的所有可能情况都列举出来,用一定的范围值来表示
  • 主要用于提升 代码的可读性。

 

  • 例1:
  • 共用体 共用 最大的数据空间,并且 变量成员 首地址都相同
  • 测试代码:
#include<stdio.h>
union test//共用int型的空间
{
	char a;
	short b;
	int c;
};


void main(int argc, char const *argv[])
{
	union test a;

	printf("a = %p \n",&a);
	printf("a.a = %p\n",&a.a);
	printf("a.b = %p \n",&a.b);
	printf("a.c = %p \n",&a.c);
	printf("==================\n");
	a.c = 10000;
	printf("a.c = %d\n",a.c);
	printf("a.a = %d\n",a.a);

	return ;
}

输出结果,如图所示:

可以发现,共用体中的变量中成员的首地址都是相同的,而当给a.c赋值的时候,a.a也可以打印出数据,这说明共用体变量中的成员是共用一个空间的。

 

  • 例2:
  • 枚举
  • 测试代码:
#include<stdio.h>
//枚举
enum test
{
	apple,//apple = 20
	orange,
	water
};

void main(int argc, char const *argv[])
{
	printf("apple = %d\n",apple);
	printf("orange = %d\n",orange);
	printf("water = %d\n",water);
	
	return ;
}

输出结果,如图所示:

若是在枚举中,给apple赋值20,后面的成员的值都会从apple的值,开始往下递增,如:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃鱼的猫丿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值