本博客涉及的结构体知识有:
1.0:结构体的创建和使用
2.0: typedef 关键字与#define 关键字的区别
3.0: 结构体成员的访问【地址访问与成员访问】
4.0: 结构体嵌套调用
5.0 数组访问赋值结构体成员
......
1.0:结构体的创建和使用
结构体类型和枚举类型一样,是一种用户自定义的数据类型,它可以使用一个变量来描述事物的多种属性,便于数据的管理,数据类型声明的语法格式:或者说->【结构是一些值的集合,这些值被称为成员变量,结构体中的成员可以是不同的变量类型 】,和数组相比结构体的数据类型更为的灵活,数组指的是一组相同类型的值的集合,数组的下标是从0开始的。
格式1:
// 结构体的声明格式
typedef struct
{
成员列表
}structName_t;
注:成员列表中的成员并不是变量在什么的时候并不会开辟内存空间
内存空间的开辟要在创建结构体变量之后
***********************************
* 结构体: 创建结构体案例
* 参数 : 结构体成员 char name[20]; char tel[12];
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
typedef struct
{
char name[20];
char tel[12];
char sex[5];
int high;
}People_t;
格式2:
结构体变量的声明
struct Person
{
// 成员列表
char name[20];
int age;
}struct_name_t;
上面的结构体是一个结构体数据类型,并不是一个变量,创建结构体类型的时候并不会开辟内存空间
struct Stu
{
// 成员列表
char name[20];
int age;
}s1,s2;
s1 与 s2 是 struct Stu 类型的变量(s1 s2 是结构体成员的全局变量)
格式3:
// 结构体成员变量声明
struct Point
{
int x;
int y;
}p1 = {2,3};
struct score
{
int n;
char ch;
};
struct Stu
{
char name[20];
int age;
struct score s;
};
成员变量的初始化
int main()
{
struct Stu s1 = {"8888",20,{100,'q'}};
printf(%s %d %d %c,s1.name,s1.age,s1.n,s1.s.ch);
}
结构体变量的定义
/**
***********************************
* 结构体: 结构体变量定义后同时进行赋值
* 参数 : 无参数
* 返回值: 无返回值
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
People_t peo = { "张三","15863310892","男",181 };
2.0 typedef 关键字的使用
typedef关键关键字:用于定义一个已有关键字的别名,具体创建格式如下所示
/**
***********************************
* 结构体: typedef 关键字的用法
* 参数 : 无参数
* 返回值: 无返回值
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
typedef 数据类 名字
typedef uint8_t uint;
typedef unsigned char uchar;
typedef 关键字和define关键字的区别,两者都是给对象取一个别名增强程序的可读性【尽量防止程序中魔鬼数字的出现】,两者有如下的区别
1: 使用场景不同
- typedef 关键字用于给数据类型定义别名
- #define关键字又称为(宏定义) 用于给数字,表达式(写表达式时注意带上括号防止异常问题的出现),代码语句定义别名。
2:执行时机不同
- typedef在编译阶段执行;
- #define在预编译阶段执行;
3:定义方法不同
- #define别名在替换对象的前面,并且定义后面不用加分号;
#define PI 3.14
#define MAX_NUM_LIST 9
typedef的别名在替换对象的后面,并且定义后面需要加分号;
typedef unsigned char uchar;
3.0: 结构体成员的访问
注:有指针访问和圆点运算符访问两种访问方式
使用圆点运算符并打印输出
/**
***********************************
* 结构体: 结构体成员变量访问
* 参数 : 结构体成员访问
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
// peo 是结构体变量,结构体变量创建后才会开辟内存控制,结构体变量初始化
People_t peo = { "张三","15863310892","男",181 };
// 浮点数在内存中不能精确的存储,结构体嵌套初始化
recallStruct_t recal = { {"李四","15863310892","男",181},100, 88.8f };
printf("%s %s %s %d\n", peo.name, peo.tel, peo.sex, peo.high);
printf("%s %s %s %d %d %f\n",
recal.p.name,
recal.p.tel,
recal.p.sex,
recal.p.high,
recal.num,
recal.f);
使用指针访问【地址访问】
/**
***********************************
* 结构体: 结构体传递地址调用
* 参数 : *p 指针地址
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
void Print(People_t *p)
{
// 左边的是结构体指针 “结构体指针->成员变量”
printf("%s %s %s %d\n", p->name, p->tel, p->sex, p->high);
}
注:以上的这种写法需要在主函数中进行调用
4.0: 结构体嵌套调用
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
/**
***********************************
* 结构体: 创建结构体
* 参数 : 结构体成员 char name[20]; char tel[12];
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
typedef struct
{
char name[20];
char tel[12];
char sex[5];
int high;
}People_t;
/**
***********************************
* 结构体: 创建结构体
* 参数 : 结构体成员,内部包含结构体【顺带变量初始化,结构体初始化】
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
typedef struct
{
People_t p;
int num;
float f;
}recallStruct_t;
/**
***********************************
* 结构体: 结构体传递地址调用
* 参数 : *p 指针地址
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
void Print(People_t *p)
{
// 左边的是结构体指针 “结构体指针->成员变量”
printf("%s %s %s %d\n", p->name, p->tel, p->sex, p->high);
}
/**
***********************************
* 结构体: 结构体成员变量访问
* 参数 : 结构体成员访问
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
void PrintTwo(People_t input)
{
// 左边的是结构体变量 “结构体变量.成员变量”
printf("%s %s %s %d\n", input.name, input.tel, input.sex, input.high);
}
int main()
{
// peo 是结构体变量,结构体变量创建后才会开辟内存控制,结构体变量初始化
People_t peo = { "张三","15863310892","男",181 };
// 浮点数在内存中不能精确的存储,结构体嵌套初始化
recallStruct_t recal = { {"李四","15863310892","男",181},100, 88.8f };
printf("%s %s %s %d\n", peo.name, peo.tel, peo.sex, peo.high);
printf("%s %s %s %d %d %f\n", recal.p.name, recal.p.tel, recal.p.sex, recal.p.high, recal.num, recal.f);
Print(&peo);
PrintTwo(peo);
return 0;
}
注:以上的注释编写方式仅限于更好的理解知识,实际的开发过程会更为规范,推荐书籍《高质量 C C++ 编程指南 》。
注:上面的两种打印输出方式哪一种打印方式更好,结构体传递参数吧 “对象” 进行结构体传参的时PrintTwo() 这种参数传递方式方式时PrintTwo(peo),peo实际是一个对象已经在内存中开辟了一块内存空间,如果把对象作为实际参数传递给形参的时候“形参里面的内容实际上是实际参数的一份拷贝” 打印peo的时候打印输出的数据是一样的,空间和时间的浪费会降低程序的性能。【推荐使用地址传递的方式把参数的地址传递进去(地址的大小就是4-8字节)通过地址找到数据】参数传递的时候会压栈,结构体传递参数的时候尽量传递结构体的地址节省时间和空间。
5.0 数组方式给结构体成员赋值
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
#define MAX_LIST_NUM (sizeof(arrList) / sizeof(arrList[0]))
/**
***********************************
* 结构体: 创建结构体
* 参数 : 结构体成员 char name[20]; char tel[12];
* 返回值: 无
* 时间 : 2024/7/13
* 作者 : _沧浪之水_
************************************
**/
typedef struct
{
char name[20];
char tel[12];
char sex[5];
int high;
}People_t;
static People_t arrList[] =
{
{"Keil","122345625","男",180},
{"Ling","122345625","女",185}
};
int main()
{
uint8_t i = 0;
for (i = 0; i < MAX_LIST_NUM; i++)
{
printf("%s %s %s %d\n",
arrList[i].name,
arrList[i].tel,
arrList[i].sex,
arrList[i].high);
}
return 0;
}
6.0 结构体内存对齐
......