C语言——结构体

目录

一、结构体的设计

二、结构体变量的初始化

2.1  结构体初始化

2.2  结构体指针变量

2.3  结构体嵌套结构体

三 、结构体成员访问

 3.1  结构体成员访问

3.2   结构体变量和指针

 3.3   结构体和函数

 四、 结构体与数组

 五、 计算结构体的大小

指定对齐值


一、结构体的设计

    C语言提供了基本的数据类型,例如 char 、short 、int 、float....等类型;这些称为内置类型。怎样设计出来属于自己的类型?

程序员可以使用结构体来封装一些属性,设计出新的类型,在C语言中称为结构体类型。

结构体的定义形式为:

struct 结构体名
{
   成员列表(可以是基本的数据类型,指针,数组或其他结构类型)
};

举个例子:用学生类来说,

学生拥有什么?姓名、学号、年龄、成绩....

struct Student
{
char name;
char id;
char age;
int  grade;

};

注意以下几点;

(1)、关键字struct是数据类型说明符,指出下面说的是结构体类型;

(2)、标识符Student是结构体的类型名;

(3)、最后的分号一定要写;结构体也是一个完整的c语言语句

二、结构体变量的初始化

结构体是一种数据类型,也就是说可以用它来定义变量。

结构体就像一个“模板”,定义出来的变量都具有相同的性质。可以将结构体比作“图纸”,结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的;

结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据、需要存储空间;
 

2.1  结构体初始化

#include<stdio.h>
int main() {
	struct Student {    //声明结构体类型struct Student
                        //以下4行为结构体的成员
		long int num;
		char name[20];
		char sex;
		char addr[20];
	}a = { 10101,"Li lin",'M ',"123 Beijing Road" };   //定义结构体变量a并初始化
	printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n", a.num, a.name, a.sex, a.addr);
	return 0;
}

2.2  结构体指针变量

1.  结构体指针的定义方法:

1)struct 结构体名 *指针;
2)直接在定义结构体的时候添加结构体指针的声明

//在main()方法中定义
struct student *p1;//定义结构体指针
struct student
{
	int num;
	char name[20];
	char sex;
}*p2;

 2.  利用结构体指针访问结构体变量(输出)

结构体指针访问变量方法:
1)p->结构体成员;
2)(*p).结构体成员;

//指针访问
struct student *p;//定义结构体指针
p=&st1;
printf("%d %s %c\n",p->num,p->name,p->sex);
//指针访问
struct student *p;//定义结构体指针
p=&st1;
printf("%d %s %c\n", (*p).num, (*p).name, (*p).sex);

2.3  结构体嵌套结构体

#include<stdio.h>
struct Date {
	int year;
	int month;
	int day;
};
struct Student {
	char s_name[20];
	struct Date birthday;   //结构体的嵌套
	float score;
};
int main() {
	struct Student stu = { "zs",2000,10,1,99.9 };
	return 0;
}

三 、结构体成员访问

 3.1  结构体成员访问

结构体变量使用   .   访问;

结构体变量.对象

#include<stdio.h>
#include<string.h>
struct Date
{
	int year;
	int month;
	int day;
};
struct Student
{
	char s_name[20];
	struct Date birthday;
	float score;
};
int main()
{
	struct Student stu = { "liuwen",2000,10,1,99.9 };
	printf("name=%s\nbirtyday=%d.%d.%d\nscore=%f\n", stu.s_name, stu.birthday.year, stu.birthday.month, stu.birthday.day, stu.score);
	stu.score = 77;
	printf("name=%s\nbirtyday=%d.%d.%d\nscore=%f\n", stu.s_name, stu.birthday.year, stu.birthday.month, stu.birthday.day, stu.score);
	return 0;
}

 

注意:对结构体变量整体赋值有三种情况

 (1)定义结构体变量(用{}初始化)

(2)用已定义的结构体变量初始化

(3)结构体类型相同的变量可以作为整体相互赋值;

在C语言中不存在结构体类型的强制转换

3.2   结构体变量和指针

内置类型可以定义指针变量,结构体类型也可以定义结构体类型指针;

结构体类型指针访问成员的获取和赋值形式:

(1)(*p). 成员名(.的优先级高于*,(*p)两边括号不能少)

(2)   p->成员名(->指向符)

#include<stdio.h>
#include<string.h>
//#define _CRT_SECURE_NO_WARNINGS
struct Inventory//商品
{
	char description[20];//货物名
	int quantity;//库存数据
};
int main()
{
	struct Inventory sta = { "computer",20 };
	struct Inventory* stp = &sta;
	char name[20] = { 0 };
	int num = 0;
	(*stp).quantity = 30;
	stp->quantity = 30;
	strcpy_s(name,sizeof(stp->description),stp->description);
	printf("%s %d\n", stp->description, stp->quantity);
	printf("%s %d\n", (*stp).description, (*stp).quantity);
	return 0;
}

 3.3   结构体和函数

#include<stdio.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
struct School
{
	char s_name[20];//学校
	int s_age;
};
void Print_a(struct School sx)
{
	printf("%s %d\n", sx.s_name, sx.s_age);
}
void Print_c(struct School* sp)
{
	printf("%s %d\n", sp->s_name, sp->s_age);
}
int main()
{
	struct School sx = { "xi'an",100 };
	Print_a(sx);
	Print_c(&sx);
	return 0;
}

 

 四、 结构体与数组

结构体数组,是指数组中的每一个元素都是一个结构体类型。在实际应用中,C语言结构体数组常被用来表示有相同的数据结构的群体,比如一个班的学生,一个公司的员工等;

代码功能对成绩实现冒泡排序,

#include<stdio.h>
typedef struct Student {
	const char* name;
	int  score;
	int  age;
}Student;
typedef Student ElemType;

void Swap(ElemType*a, ElemType*b) {
	ElemType temp = *a;
	*a = *b;
	*b = temp;
}

void BubbleSort(ElemType* arr, int len) {
	for (int i = 0; i < len - 1; i++) {
		for (int j = 0; j < len - 1 - i; j++) {
			if (arr[j].score > arr[j + 1].score) {
				Swap(&arr[j], &arr[j + 1]);
			}
			if (arr[j].score== arr[j + 1].score) {
				if (arr[j].name > arr[j + 1].name) {
					Swap(&arr[j], &arr[j + 1]);
			 }
			}
			
		}
	}
}
int main() {
	
	Student arr[] = {      //  结构体与数组
		{"zs",100,10},{"lisi",100,12},{"ww",99,13}
	};
	int len = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr,len);
	for (int i = 0; i < len; i++) {
		printf("%s   %d\n", arr[i].name, arr[i].score);
	}
}

 五、 计算结构体的大小

指定对齐值

预处理指令# pragma pack(n)可以改变默认对齐数。n取值是1,2, 4,8, 16。

三个规则:
(1)、结构体变量的首地址,必须是结构体变量的“最大基本数据类型成员所占字节数”的整数倍;

(2)结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍;

(3)、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节”的整数倍;

总结:

1)结构体变量的首地址,必须是MIN{"结构体最大基本数据类型成员所占字节数",指定对齐方式}大小的整数倍。
2)结构体每个成员相对于结构体首地址的偏移量,都是MIN{基本数据类型成员,指定对齐方式}大小的整数倍。
3)结构体的总大小,为MIN{结构体“最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式} 大小的整数倍。
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值