做ic什么网站好,网站上的qq咨询怎么做,wordpress my02visitors,站长seo推广前言
从0开始记录我的学习历程#xff0c;我会尽我所能#xff0c;写出最最大白话的文章#xff0c;希望能够帮到你#xff0c;谢谢。 1.结构体类型的概念及定义
1.1、概念#xff1a; 结构体是一种构造类型的数据结构#xff0c; 是一种或多种基本类型或构造类型的数…前言
从0开始记录我的学习历程我会尽我所能写出最最大白话的文章希望能够帮到你谢谢。 1.结构体类型的概念及定义
1.1、概念 结构体是一种构造类型的数据结构 是一种或多种基本类型或构造类型的数据的集合。 它允许我们组合多个基本数据类型如整数、浮点数、字符等来创建一个新的复合数据类型。这个新的数据类型就像一个小包裹里面装着了我们需要的不同类型的数据。 1.2、 结构体类型的定义方法
咱们在使用结构体之前必须先有类型然后用类型定义数据结构这个类型相当于一个模具
(1).先定义结构体类型再去定义结构体变量 struct 结构体类型名{ 成员列表允许我们组合多个基本数据类型如整数、浮点数、字符等 } 例1 struct stu{
int num;
char name[20];
char sex;
}; 我们看这个例子。 我们定义了一个名为stu的结构体类型。这个结构体类型包含了三个成员一个整数num一个字符数组name和一个字符sex。这些成员代表了学生的学号、姓名和性别。 struct stu lucy, bob, lilei; 一旦我们定义了这个结构体类型就可以创建变量来存储实际的学生信息了。在这个例子中我们创建了三个变量lucy、bob和lilei。每个变量都是一个结构体类型的实例它们都有三个成员num、name和sex。 在定义结构体类型的时候顺便定义结构体变量以后还可以定义结构体变量 struct 结构体类型名 { 成员列表 ; } 结构体变量 1, 变量 2; struct 结构体类型名 变量 3 变量 4 例如看下面这个例子实际上是和上面的例子是一个意思的。
struct stu{
int num;
char name[20];
char sex;
}lucy;
struct stu bob, lilei; 在定义结构体类型的时候没有结构体类型名顺便定义结构体变量 因为没有类型名所以以后不能再定义相关类型的数据了。也就是不可以往成员列表里面添加东西了。 struct { 成员列表 ; } 变量 1 变量 2; 2 结构体变量的定义初始化及使用 1、结构体变量的定义和初始化 结构体变量是个变量这个变量是若干个数据的集合 注 (1): 在定义结构体变量之前首先得有结构体类型然后在定义变量 (2): 在定义结构体变量的时候可以顺便给结构体变量赋初值被称为结构体的初始化 (3): 结构体变量初始化的时候各个成员顺序初始化 struct stu{
int num;
char name[20];
char sex;
};
struct stu boy;
struct stu lucy{101,lucy,f};我们创建了两个变量来存储实际的学生信息。第一个变量boy它是一个未初始化的结构体变量它没有任何成员的值被赋定。第二个变量lucy是一个已经初始化的结构体变量。在声明时我们直接给它赋初值。这里我们给了学号、姓名和性别的值。
在这个初始化中我们按照成员的顺序给了值
101 是 num 成员的值。lucy 是 name 成员的值。由于 name 是一个字符数组我们使用引号括起来来表示字符串。f 是 sex 成员的值。 1、结构体变量的使用 定义了结构体变量后要使用变量 (1). 结构体变量成员的引用方法 结构体变量. 成员名 struct stu{
int num;
char name[20];
int age;
}bob;
int main(int argc, char *argv[])
{
lihua{10,bob,10};
printf(%d\n,bob.num);
printf(%s\n,bob.name);
printf(%d\n,bob.age);
return 0;
}可以看到 通过.操作符我们可以访问结构体变量的各个成员。上面的代码分别打印出了bob的学号、姓名和年龄。
2、结构体成员多级引用 首先我们有一个名为date的结构体它包含了三个整数字段year、month和day。这些字段代表了一个特定的日期。
struct date{int year;int month;int day;
};接下来我们有一个名为stu的结构体它包含了四个字段一个整数num、一个字符数组name、一个字符sex和一个子结构体birthday。子结构体birthday是我们之前定义的date结构体。
struct stu{int num;char name[20];char sex;struct date birthday;
};现在我们在主函数中创建了一个名为lilei的变量它是一个stu类型的变量。我们通过赋值来初始化这个变量的字段。
struct stu lilei{101,lilei,m};
lilei.birthday.year1986;
lilei.birthday.month1;
lilei.birthday.day8;在这里我们通过.birthday.year, .birthday.month, 和 .birthday.day来访问和设置子结构体中的日期字段。
最后我们使用printf函数来打印出变量
printf(%d %s %c\n,lilei.num,lilei.name,lilei.sex);
printf(%d %d %d\n,lilei.birthday.year,lilei.birthday.month,lilei.birthday.day);这里我们通过多级结构体成员的引用来访问和打印出各个字段的值。可以看到就是通过点来访问的 嘎嘎简单哈。
3.结构体数组 结构体数组是个数组由 若干个相同类型的结构体变量构成的集合 1 、结构体数组的定义方法 struct 结构体类型名 数组名 [ 元素个数 ]; 结构体数组是一种数据结构它允许我们存储多个相同类型的结构体变量。这是非常有用的因为它可以帮助我们组织和管理大量的相关数据。 让我们来看看一个例子以便更好地理解结构体数组 首先我们有一个名为stu的结构体它包含了三个字段一个整数num、一个字符数组name和一个字符sex。 struct stu{int num;char name[20];char sex;
};接下来我们定义了一个名为edu的结构体数组它包含了三个元素edu[0]、edu[1]和edu[2]。 struct stu edu[3];这个数组 edu 可以被视为三个 stu 类型的结构体变量的集合。我们可以通过数组的下标来访问每个元素并对它们进行操作。 例如我们可以将值 101 给 edu[0] 数组中的第一个结构体变量的 num 字段赋值 edu[0].num 101;这里.num 是指 edu[0] 结构体变量中的 num 字段。 同样我们可以使用 strcpy 函数将字符串 “lucy” 给 edu[1] 数组中的第一个结构体变量的 name 字段赋值 strcpy(edu[1].name, lucy);这里.name 是指 edu[1] 结构体变量中的 name 字段。 4.结构体指针 结构体指针是一种在C语言中用于存储和操作结构体变量的特殊类型的指针。它允许我们通过指针来访问和修改结构体变量的字段而无需直接使用变量的名称。 让我们来看看一个例子以便更好地理解结构体指针 首先我们有一个名为stu的结构体它包含了两个字段一个整数num和一个字符数组name。 struct stu{int num;char name[20];
};接下来我们定义了一个名为p的结构体指针变量它可以存储 stu 类型的结构体变量的地址。 struct stu * p;这个指针变量 p 可以被视为一个存储结构体变量地址的“指针”它占用了相同数量的内存空间用于保存这个地址。 现在我们创建了一个名为boy的结构体变量并使用 指针运算符将其地址赋值给指针变量 p。 struct stu boy;
p boy;这里boy 是 boy 结构体变量的地址我们将其赋值给指针变量 p。 接下来我们可以通过以下方式访问和修改 boy 结构体变量的字段 直接访问 boy.num 101; // 直接访问并修改 boy 的 num 字段通过指针访问 (*p).num 101; // 使用指针来访问并修改 boy 的 num 字段使用指针运算符 p-num 101; // 使用指针运算符来访问并修改 boy 的 num 字段在这三种方法中最后两种都是通过指针来访问和修改结构体变量的字段。前提是指针必须先指向一个结构体变量。如果指针没有正确地指向一个结构体变量那么尝试访问或修改其字段可能会导致程序出错。 结构体指针经常用到的地方 (1)保存结构体变量的地址 typedef struct stu{
int num;
char name[20];
float score;
}STU;
int main()
{
STU *p,lucy;
plucy;
p-num101;
strcpy(p-name,baby);
//p-namebaby;//错误因为 p-name 相当于 lucy.name 是个字符数组的名字是个常量
} (2)传结构体变量的地址 #includestdio.h
#includestring.h
typedef struct stu{
int num;
char name[20];
float score;
}STU;
void fun(STU *p)
{
p-num101;
(*p).score87.6;
strcpy(p-name,lucy);
}
int main()
{
STU girl;
fun(girl);
printf(%d %s %f\n,girl.num,girl.name,girl.score);
return 0;
} (3): 传结构体数组的地址 结构体数组是由多个相同类型的结构体变量构成的。存放在内存里 也有起始地址其实就是第 0 个结构体的地址。 #includestdio.h
#includestring.h
typedef struct stu{
int num;
char name[20];
float score;
}STU;
void fun(STU *p)
{
p[1].num101;
(*(p1)).score88.6;
}
int main()
{
STU edu[3];
fun(edu);
printf(%d %f\n,edu[1].num,edu[1].score);
return 0;
}
注意 结构体变量的地址编号和结构体第一个成员的地址编号相同但指针的类型不同 #include stdio.h
struct stu{
int num;
char name[20];
int score;
};
int main(int argc, char *argv[])
{
struct stu bob;
printf(%p\n,bob);
printf(%p\n,(bob.num));
return 0;
} 注意结构体数组的地址就是结构体数组中第 0 个元素的地址. #include stdio.h
struct stu{
int num;
char name[20];
int score;
};
int main(int argc, char *argv[])
{
struct stu edu[3];
printf(%p\n,edu);//struct stu *
printf(%p\n,(edu[0]));//struct stu *
printf(%p\n,(edu[0].num));//int *
return 0;
} 原本不想把这个代码放上来的 但是我觉得虽然废话多 但是如果光看话的话感觉总是有点离谱。 5、结构体内存分配 内存分配与对齐规则 分配单位 定义结构体中最大成员变量的长度。 例如如果结构体中最大成员是int占4字节则分配单位为4字节如果最大成员是double占8字节则分配单位为8字节。 成员变量偏移 定义成员变量的起始地址必须是其自身长度的整数倍。 例如一个int类型变量4字节必须放在一个地址是4的倍数的位置上。一个short类型变量2字节必须放在一个地址是2的倍数的位置上。 结构体总大小 定义结构体总大小必须是分配单位的整数倍。 如果最终计算出的结构体大小不是分配单位的整数倍需要填充padding到分配单位的整数倍。 内存分配与对齐示例 假设我们有以下结构体 struct Example {char a; // 1字节偏移0short b; // 2字节偏移21 1对齐到2int c; // 4字节偏移4double d; // 8字节偏移8
};1. 确定分配单位 char1字节short2字节int4字节double8字节 最大成员变量是double占8字节因此分配单位是8字节。 2. 计算每个成员变量的偏移量 按照结构体中成员变量的顺序并根据它们自身长度的整数倍来计算偏移 char a 起始地址0分配结构体的起始地址长度1字节偏移量00是1的倍数short b 上一个成员a结束地址1为满足2字节对齐b的起始地址2长度2字节偏移量22是2的倍数int c 上一个成员b结束地址4为满足4字节对齐c的起始地址4长度4字节偏移量44是4的倍数double d 上一个成员c结束地址8为满足8字节对齐d的起始地址8长度8字节偏移量88是8的倍数 3. 计算结构体总大小 最后一个成员d结束地址168 8结构体总大小必须是分配单位8字节的整数倍。 最终大小为16字节已经是8的整数倍无需额外填充。 成员类型偏移量achar0bshort2cint4ddouble8 结构体总大小为16字节满足对齐规则。 就是这样存的。