C语言 结构体 案例详细解析

目录

一:什么是结构体

二:结构体 逐个赋值属性

三:结构体 定义时部分初始化

四:结构体的内存占用

五:typedef 重命名数据类型

六:结构体的定义

七:结构体数组

八:结构体作为函数参数

九:结构体作为函数返回


一:什么是结构体

结构体的定义:把不同类型的数据结合在一起,形成集合

结构体访问属性,使用点运算符

结构体,示例如下:

#include<stdio.h>

//描述一个学生 学号 姓名 年龄 密码  
struct student_t{   
     int sno;       //学号   数据成员又名属性,用分号隔开
	 char name[20]; //姓名 
	 char pwd[18];  //密码 
	 int age;       //年龄 
}; //分号不能少

int main()
{
	//结构体定义
	struct student_t stu={1001,"lily","123456",18};
    //结构体信息访问  用.点运算符  结构体名.属性名
	printf("stu:hello,%d %s %d\n",stu.sno,stu.name,stu.age);//stu:hello,1001 lily 18
	return 0;
}

若是 只定义不初始化,没有被赋值到的属性都会是随机值,因此是不提倡这样定义的:

struct student_t stu1;

二:结构体 逐个赋值属性

结构体定义[属性赋值]【一个一个地去 赋值属性】,示例如下:

#include<stdio.h>
#include<string.h>//strcpy

//描述一个学生 学号 姓名 年龄 密码     
struct student_t{   
     int sno;       //学号    
	 char name[20]; //姓名 
	 char pwd[18];  //密码 
	 int age;       //年龄 
};  

int main()
{
	//结构体定义
    struct student_t stu1;  //只定义没有初始化
	stu1.sno=1002;  //没有初始化只能一个一个赋值
	strcpy(stu1.name,"kity");//字符数组的赋值,需要注意strcpy引头文件
	stu1.age=20;
 	printf("stu1:hello,%d %s %d\n",stu1.sno,stu1.name,stu1.age);//stu1:hello,1002 kity 20
	return 0;
}

三:结构体 定义时部分初始化

结构体在定义的时候部分初始化,没有被初始化的属性是 0/空字符串,示例如下:

#include<stdio.h>
#include<string.h>

struct student_t{   
     int sno;       //学号  
	 char name[20]; //姓名 
	 char pwd[18];  //密码 
	 int age;       //年龄 
};  

int main()
{
	//结构体定义
	struct student_t stu2={1003};  //部分初始化 其他位置自动补零  字符串是空字符串
    printf("stu2:hello,%d %s %d\n",stu2.sno,stu2.name,stu2.age);//stu2:hello,1003 (空字符串) 0
	return 0;
}

结构体各个属性存储的地址是连续的

结构体的定义[主要有三种]:

定义并全部初始化

只定义不初始化

定义部分初始化

四:结构体的内存占用

使用 sizeof()函数 用来计算字节长度

1.计算内存,以最大的存储类型 【内存对齐】

示例一: 

#include<stdio.h>
#include<string.h>

struct student_t{   
     int sno;       //学号  4
	 char name[20]; //姓名  4*5
	 char pwd[18];  //密码  补充2个 4*5
	 int age;       //年龄  4           共4+20+20+4=48
}; 
//计算内存 以最大的存储类型内存对齐

int main()
{
	struct student_t stu={1001,"lily","123456",18};
    printf("stu size=%d\n",sizeof(stu));//stu size=48
	return 0;
}

示例二: 

#include<stdio.h>
#include<string.h>

struct student_t{   
  int num1;  //4
  char ch;   //1补3 为4
  int num2;  //4         总4+4+4=12
}; 
//计算内存 以最大的存储类型内存对齐

int main()
{
	struct student_t stu={4,"lily",18};
    printf("stu size=%d\n",sizeof(stu));//stu size=12
	return 0;
}

2.相邻的同类型的可以合并,数据类型越小的一起往前面放可以节省内存空间

同样的数据类型,不同的排列顺序,内存的占用也不同【学习 内存空间的节省】

数据类型小的char,统一放置于前面 

#include<stdio.h>
#include<string.h>

struct student_t{   
	char num1;     //1
	char num2;     //1  1 1合并为2 补6为8 最后是8
	double num3;   //8                    总8+8=16	
}; 
//相邻的同类型的可以合并的 数据类型越小的一起前面放可以节省空间

int main()
{
	struct student_t stu={"kity","lily",18.123};
    printf("stu size=%d\n",sizeof(stu));//stu size=16
	return 0;	
}

像以下这种,没有把数据类型小的,统一放置在前面,就相对地浪费内存占用 

#include<stdio.h>
#include<string.h>

struct student_t{   
  char num1;    //  1 补7 为8
  double num2;  //          8
  char num3;    //  1 补7 为8    总8+8+8=24
};  
//相邻的同类型的可以合并的 数据类型越小的一起前面放可以节省空间

int main()
{
	struct student_t stu={"kity",18.123,"lily"};
    printf("stu size=%d\n",sizeof(stu));//stu size=24
	return 0;
}

3.结构体内存占用的计算练习

练习一: 

#include<stdio.h>
#include<string.h>

struct student_t{   
  int NO[4];     // 4  向4看齐  4*4=16
  char Name[20]; // 1  向4看齐  4*5=20   总16+20=36
}; 

int main()
{
	struct student_t stu={18,"kity"};
    printf("stu size=%d\n",sizeof(stu));//stu size=36
	return 0;	
}

练习二: 

#include<stdio.h>
#include<string.h>

struct student_t{   
  int NO[4];     // 4  向8看齐  4*4=》 16=》  8*2    16
 double str[4];  // 8  向8看齐  8*4=》 8*4           32    总16+32=48
};  

int main()
{
	struct student_t stu={18,18.123};
    printf("stu size=%d\n",sizeof(stu));//stu size=48
	return 0;	
}

五:typedef 重命名数据类型

typedef:作用是 能够实现 结构体数据类型的简写,使用示例如下:

#include<stdio.h>

//重命名数据类型   struct student_t改名为STU_T
typedef struct student_t{   
     int sno;       //学号  
	 char name[20]; //姓名 
	 char pwd[18];  //密码 
	 int age;       //年龄 
}STU_T; 

int main()
{
	//结构体定义
	STU_T stu={1001,"lily","123456",18};
    //结构体信息访问  用.点运算符  结构体名.属性名
	printf("stu:hello,%d %s %d\n",stu.sno,stu.name,stu.age);//stu:hello,1001 lily 18
	return 0;
}

六:结构体的定义

结构体的定义 [3种赋值方法]

1.定义 直接赋值 

2.定义 属性赋值 [逐个赋值属性]

3.内存赋值 memcpy

具体示例如下:

1.直接赋值

#include<stdio.h>

typedef struct student_t{   
     int sno;       //学号  
	 char name[20]; //姓名 
	 char pwd[18];  //密码 
	 int age;       //年龄 
}STU_T;  

int main()
{
	//结构体定义
	STU_T stu={1001,"lily","123456",18};//全部初始化
	STU_T stu1;                         //只定义 没初始化
	stu1=stu;//直接赋值 结构体是一种数据类型
    //结构体信息访问  用.点运算符  结构体名.属性名
	printf("stu:hello,%d %s %d\n",stu.sno,stu.name,stu.age);//stu:hello,1001 lily 18
   printf("stu1:hello,%d %s %d\n",stu1.sno,stu1.name,stu1.age);//stu1:hello,1001 lily 18
	return 0;
}

2.属性赋值 示例在文章的第二标题

3.内存赋值memcpy

#include<stdio.h>

typedef struct student_t{   
     int sno;       //学号  
	 char name[20]; //姓名 
	 char pwd[18];  //密码 
	 int age;       //年龄 
}STU_T;  

int main()
{
	//结构体定义
	STU_T stu={1001,"lily","123456",18};//全部初始化
	STU_T stu2={1003};                  //部分初始化 
	
	//内存赋值法 stu2获取stu的数据
	memcpy(&stu2,&stu,sizeof(STU_T));//后面的赋值给前面
    printf("stu2:hello,%d %s %d\n",stu2.sno,stu2.name,stu2.age);//stu2:hello,1001 lily 18
	return 0;
}

七:结构体数组

结构体数组的使用,示例: 

#include<stdio.h>

typedef struct student_t{   
	int sno;       //学号  
	char name[20]; //姓名 
	char pwd[18];  //密码 
	int age;       //年龄 	
}STU_T; 

int main()
{
	int i=0;
	//结构体数组  部分初始化  int 补0  字符 补空字符串
	//数据类型 结构体名[长度]={{},{},{}};
	STU_T stuArr[38]={
		{1001,"lily","123456",18},
		{1002,"kity","123123",19},
		{1003,"tom","123489",20}
	};
	//循环访问结构体数组中每一个成员的信息
    for(i=0;i<3;i++)
	{
		printf("stu:hello,%d %s %d\n",stuArr[i].sno,stuArr[i].name,stuArr[i].age);
		//stu:hello,1001 lily 18
		//stu:hello,1002 kity 19
		//stu:hello,1003 tom 20
	}
	return 0;	
}

八:结构体作为函数参数

#include<stdio.h>

typedef struct student_t{   
	int sno;       //学号 
	char name[20]; //姓名 
	char pwd[18];  //密码 
	int age;       //年龄 
}STU_T;

void printStuInfo(STU_T stu); 

int main()
{
	int i=0;
	STU_T stuArr[38]={
		{1001,"lily","123456",18},
		{1002,"kity","123123",19},
		{1003,"tom","123489",20}
	};
	for(i=0;i<3;i++)
	{
		printStuInfo(stuArr[i]);
		//stu:hello,1001 lily 18
		//stu:hello,1002 kity 19
		//stu:hello,1003 tom 20
	}
	return 0;	
}

//打印一个学生结构体信息
//结构体作为参数传递  int char float double 按值传递
//改变函数内部值 外部不会变化   要想变化 引用 指针 寻找地址改变其值
void printStuInfo(STU_T stu)
{
  printf("stu:hello,%d %s %d\n",stu.sno,stu.name,stu.age);
}

九:结构体作为函数返回

#include<stdio.h>

typedef struct student_t{   
	int sno;       //学号 
	char name[20]; //姓名 
	char pwd[18];  //密码 
	int age;       //年龄 
}STU_T;

STU_T editStuInfo(STU_T stu);

int main()
{
	int i=0;
	STU_T stu={1001,"lily","123456",18};//全部初始化
	STU_T stu1;//只定义没初始化
    //结构体数组
	STU_T stuArr[38]={    //38个学生  部分初始化
		{1001,"lily","123456",18},
		{1002,"kity","123123",19},
		{1003,"tom","123489",20}
	};

	stu1 = editStuInfo(stuArr[0]); //改变第一个学生(学号)
	printf("stu:hello,%d %s %d\n",stu.sno,stu.name,stu.age);//stu:hello,1001 lily 18
	printf("stu1:hello,%d %s %d\n",stu1.sno,stu1.name,stu1.age);//stu1:hello,10086 lily 18
	return 0;
}

//函数内部改变 外部也变 结构体可以作为返回值
STU_T editStuInfo(STU_T stu)//改变学生学号
{
   stu.sno=10086;
   return stu;   //结构体既可以作为参数 又可以作为返回值
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

chenruhan_QAQ_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值