第三周周报
不知不觉已经到了第三周了,本周由于返校之类的杂事,学习上的事情有一点点耽误了,下周要好好补上了,本次想把结构体有关的内容整理一下,然后有一次每日一练涉及到了一点信息论的内容,这次也写上一点分享。
结构体总结
c语言中已经有了float、int、double等数据类型存放某一个数据,有了数组来存放一堆相同类型的数据,如果想存储一堆不同类型的数据就需要使用到结构体类型
结构体与数组的主要区别就在于数组是存放同一种类型的数据,而结构体可以存放不同类型的数据。
结构体的一般形式
struct Student{
char name[20]; //姓名
int age; //年龄
char sex[5]; //性别
char id[10]; //学号
}; //分号不能省略 很重要
匿名结构体的声明
在声明的时候可以省略结构体的名字
struct {
int a;
char b;
double c;
}x;
结构体的自引用
结构体虽然不能存放自己的结构体,但是可以存放指向自己类型结构体的指针。
例子:
//错误例子1:
struct Node{
int data;
struct Node nextNode;
};
//错误例子2:
struct Node{
int data;
Node nextNode;
}x;
//正确例子:
struct Node{
int data;
struct Node* nextNode; //用于存放其他结构体变量的地址
};
结构体的定义域与初始化
结构体变量的定义:
struct Point{
int x;
int y;
}p1; //定义结构体变量p1
struct Point p2; //定义结构体变量p2
结构体变量的初始化
int x = 10,y = 10;
p1 = {x,y}; //初始化p1
p2 = {20,20}; //初始化p2
struct Node{
int data;
struct Node* nextNode;
}p3 = {10,NULL}; //定义并初始化p3
结构体传参
形参是结构体变量时,该形参仅仅只是实参的拷贝,对形参的操作并不会影响到实参
形参是结构体指针变量时,将实参结构体变量的地址传入函数中,操作指针间接对实参进行修改
struct Point{
int x;
int y;
};
void initial(struct Point n){
int x = 10;
int y = 10;
n = { x, y };
}
int main(){
struct Point p = { 15, 15 };
initial(p);
printf("%d %d\n", p.x, p.y); //15 15
return 0;
}
struct Point{
int x;
int y;
};
void initial(struct Point* n){
int x = 10;
int y = 10;
*n = { x, y };
}
int main(){
struct Point p = { 15, 15 };
initial(&p);
printf("%d %d\n", p.x, p.y); //10 10
return 0;
}
内对齐规则
我们这周做了许多每日一练都是和内对齐相关的
内存对齐规则:
1.对齐数字:结构体中所占内存最大的成员变量 和 编译器默认的对齐数字 中 较小值。
2.编译器默认的对齐数字是8字节,则对齐数字就是较小的int所占的字节数4)
3.每一个成员变量的起始地址必须是对齐数字的整数倍
4.结构体总大小为最大对齐数的整数倍
5.如果结构体的成员变量有结构体变量,这种情况下,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍
位段
位段的特性:
1.位段的成员必须是int、unsigned int、signed int、char
2.位段的成员名后面有一个冒号和一个数字
3.位段的空间是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的
4.位段是不跨平台的,可移植的程序尽量少使用位段
5.当一个结构体中第一个位段的剩余空间无法容纳下第二个位段时,需要重新开辟一个sizeof(type)大小的空间来容纳第二个位段,这里的type是第二个位段的数据类型
1000桶水,其中一桶有毒,猪喝毒水后会在15分钟内死去,想用一个小时找到这桶毒水,至少需要几头猪?
这里找了一篇写的很好的知乎
简要的介绍了信息论和这类问题