为什么需要结构体?
为了表示一些复杂的事物,而普通的基本类型无法满足实际要求
什么是结构体?
把一些基本类型数据组合在一起形成一个新的复合数据类型,这种新的类型叫做结构体
如何定义一个结构体?
struct Student {
int age;
float score;
char sex;
};
struct Student st1,st2;
//st1,st2都是student 里面有x和y的值
struct Student2 {
int age;
float score;
char sex;
}st2;
st2是Student2
struct {
int age;
float score;
char sex;
}st3;
st3是一种无名结构,里面有x和y
没有声明Student只是定义了一个变量st3
推荐使用第一种方式:
- 结构体名称+结构体变量名称*
结构成员
结构和数组有点像
但是可以是不同的数据类型
访问方式:
- 数组 []运算符和下标访问其成员
- 结构用 . 运算符和名字访问其成员
怎么使用结构体变量
- 赋值和初始化
初始化可以整体
赋值只能单个地进行
int main(void)
{
struct Student st = { 80,66.6,'F' };
//初始化 定义的同时赋初始值
struct Student st2;
st2 = st;
//在数组中不可以实现
st2.age = 10;
st2.score = 88;
st2.sex = 'F';
printf("%d %f %c\n", st.age, st.score, st.sex);
printf("%d %f %c\n", st2.age, st2.score, st2.sex);
}
-
如何取出结构体变量中的每一个成员
1.结构体变量名.成员名
2.指针变量名->成员名(第二种更加常用)
int main(void)
{
struct Student st = { 80,66.6,'F' };
struct Student* pst = &st;
st.age = 70;
//方式一
pst->age = 88;
//方式二
printf("%d", st.age);
pst->score = 66.6f;
/*66.6在C语言中默认是double类型
如果希望一个实数是float类型
则必须在末尾加f或F
66.6是double
66.6f是float*/
printf("%f",st.score)
/*输出结果是66.59998
浮点数不能够准确存储每一位小数
只能存一个近似值*/
}
pst->age在计算机内部会被转化成(*pst).age
(硬性规定叭)
pst所指向的那个结构体变量中的age成员
-
结构体变量和结构体变量指针作为函数参数传递的问题
结构体的输入和输出
#include<stdio.h>
#include<string.h>
struct Student {
int age;
char score;
char name[100];
};
//定义类型
int main(int argc, char const* argv[])
{
struct Student st = { 80,'F',"李四" };
InputStudent(&st);//对结构体变量输入
printf("%d %c %s\n", st.age, st.score, st.name);
}
int InputStudent(struct Student *pstu)//pstu只占四个字节
{
pstu->age = 10;
strcpy_s(pstu->name,8,"张三");//不能写成 stu.name = "张三";
pstu->score = 'F';
}
/*
示例:
发送指针还是发送内容
目的:
指针使用的优点:
可以快速传递数据
内存占据小
执行速度快
对结构体变量输入:
必须用指针
对结构体变量输出:
都可,建议指针
*/
推荐使用结构体指针变量作为函数参数传递的问题
- 结构体变量的运算
结构体变量不能相加,不能相减法,也不能乘除
但结构体变量可以相互赋值
函数题:
输入:今天的日期
输出:明天的日期
#include<stdio.h>
#include<stdbool.h>
struct date {
int month;
int day;
int year;
};
/*将输入的年份以结构体的形式存在*/
bool isLeap(struct date d);
//判断闰年与否
int numberOfDays(struct date d);
//返回每个月的天数 并借用闰年函数来检验2月的天数
int main(int argc, char const* argv[])
{
struct date today, tomorrow;
printf("Enter today's data(mm dd yyyy:)");
scanf_s("%d %d %d", &today.month, &today.day, &today.year);
if (today.day != numberOfDays(today)) {
tomorrow.day = today.day + 1 ;
tomorrow.month = today.month;
tomorrow.year = today.year;
}
else if (today.month == 12) {
tomorrow.day = 1;
tomorrow.month = 1;
tomorrow.year = today.year + 1;
}else{
tomorrow.day = 1;
tomorrow.month = today.month + 1;
tomorrow.year = today.year;
}
printf("Tomorrow's date is %d-%d-%d.\n",
tomorrow.year, tomorrow.month, tomorrow.day);
return 0;
}
int numberOfDays(struct date d)
{
int days;
const int daysPerMonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (d.month == 2 && isLeap(d)) {
days = 29;
}else {
days = daysPerMonth[d.month - 1];
}
return days;
}
bool isLeap(struct date d)
{
bool leap = false;
if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 100 == 0) {
leap = true;
}
return leap;
}
输入:12:59:59
输出:13:00:00
#include<stdio.h>
struct time {
int hour;
int minutes;
int seconds;
};
struct time timeUpdate(struct time now);
int main(void)
{
struct time testTimes;
printf("Enter time is\n");
scanf_s("%d:%d:%d",
&testTimes.hour,&testTimes.minutes,&testTimes.seconds);
testTimes = timeUpdate(testTimes);
printf("...one second later it is %.2d:%.2d:%.2d\n",
testTimes.hour, testTimes.minutes, testTimes.seconds);
return 0;
}
struct time timeUpdate(struct time now)
{
++now.seconds;
if (now.seconds == 60) {
now.seconds = 0;
++now.minutes;
if (now.minutes == 60) {
now.minutes = 0;
++now.hour;
if (now.hour == 24) {
now.hour = 0;
}
}
}
return now;
}
//结构中的结构
#include<stdio.h>
struct point {
int x;
int y;
};
struct rectangle {
struct point p1;
struct point p2;
};
void printRect(struct rectangle r)
{
printf("<%d %d> to <%d %d>\n", r.p1.x, r.p1.y, r.p2.x, r.p2.y);
}
int main(int argc, char const* argv[])
{
int i;
struct rectangle rects[] =
{
{{1,2},{3,4}},
{{5,6},{7,8}}
};
for (i = 0; i < 2; i++) {
printRect(rects[i]);
}
return 0;
}
自定义数据类型(typedef)
tyoedef int Length
Length成为了int类型的别名
Length a,b,len;
Length numbers[10];
Length这个名字就可以代替int出现在变量定义和参数声明的地方
typedef struct ADate{
int month;
int day;
int year;
}Date;
给struct ADate取了一个叫做Date的别名
Date d = { 9,1,2005 };
改善了程序的可读性
typedef struct{
int month;
int day;
int year;
}Date;
这样的struct叫做Date
用typedef说明一种新类型名
typedef 类型名 标识符
实际上并没有产生新的数据类型
原有类型名依然有效,这样做可以满足一些特殊情况的需要
联合union/ 共用体
得到一个int内部的字节
或是得到一个double内部的字节
#include<stdio.h>
typedef union {
int i;
char ch[sizeof(int)];
}CHI;
int main(int argc, char const* argv[])
{
CHI chi;
int i;
chi.i = 1234;
//十六进制0X04D2
for (i = 0; i < sizeof(int); i++) {
printf("%02hhX", chi.ch[i]);
}
printf("\n");
/*输出结果D2040000*/
return 0;
}
x86 小端 低位在前
本文深入探讨了结构体和联合体的概念与应用,讲解了结构体的定义、使用及运算,包括初始化、成员访问、作为函数参数的传递,以及结构体指针的使用。同时,介绍了联合体的基本原理,通过实例展示了如何获取整型和双精度浮点型内部的字节表示。
640

被折叠的 条评论
为什么被折叠?



