浅析C语言中的结构体

结构体:是一系列有相同类型或不同类型构的数据构成的数据集合。

结构体的学习可以从以下几个方面开始:


一.结构体类型的声明。

struct tag{

member-list;

} vaeriable-list;

注:tag 要做到见名知义,可以省略但是不建议省略

      member-list 不能为空

     veriable-list 建议省略(在需要的时候在声明)

例如建造一个学生的结构体

struct s{
    int math; 
    int chinese;
};
struct stu{
    char name[20];
    int age;
    struct s score;//结构体的嵌套
};

匿名结构体:声明结构体的时候可以省略tag,即为匿名结构体。
struct{
int a;
int b;
char c;
} x;

注:即使两个结构体的数据类型完全相同,他们也是两个结构体。

二.结构体的成员。

结构体成员的访问:

1.  stu.name;

    stu.age;

2.struct stu stu1;

struct stu* p=&stu;

(*p).name;

(*p).age;

p->name;

p->age;

三.结构体的自引用。

在结构体中不可以包含一个类型为他自身的结构体。

但结构体中可以包含自身类型的指针类型。

如:

struct Node{
    int data;
    struct Node* next;
};

四.结构体的不完整声明。

struct A{
	int _a;
	struct B*p1;
};
struct B {
	int _b;
	struct A*p2;
};

四.结构体变量的定义和初始化。

定义:struct s score1;

初始化 struct s score2={88,90};4

结构体的嵌套初始化:struct stu stu1={"zhang",18,{88,90}};

结构体的赋值只能访问成员变量逐个赋值,不可以一起赋值。

六.结构体的内存对齐。

现象:

#include<stdio.h>
#include<Windows.h>
struct s1{
	int a;
	char c;
	double d;
};
struct s2{
	char c;
	double d;
	int a;
};
int main(){
	printf("%d\n", sizeof(struct s1));
	printf("%d\n", sizeof(struct s2));
	system("pause");
	return 0;
}
上面一段简单的代码我们希望的打印结果是:13 13 

但实际确实如下:


为什么会出现以上现象呢?这就是结构体的内存对齐。

结构体内存对齐的原因:主要有平台和性能两个原因,简而言之,就是拿空间换取时间。

对齐规则:

1.第一个成员在与结构体变量的偏移量为0的地指出;

2.下一个成员变量对齐到该成员变量的对齐数的整数倍地址处。对齐数=min(默认对齐数(vs:8,liunux:4),该成员字节数);

3.结构体的总大小为所有成员变量的最大的对齐数的整数倍;

4.如果结构体嵌套,嵌套的结构体对齐到自己最大对齐数的整数倍除,结构体的整体大小就是所有成员变量最大的对齐数的整数倍。

例子:

#include<stdio.h>
#include<Windows.h>
struct s1{
	int a;//4
	char c;//4+1=5;
	double d;5+3+8=16
};//16可以整除最大对齐数8,故s1=16
struct s2{
	char c;// 1
	struct s1 s;1+7+16=24
	double d;//24+8=32
	int a;//32+4=36
};大于36的最小的整除最大对齐数8的是40,所以运算结果应该是40
int main(){
	printf("%d\n", sizeof(struct s2));
	system("pause");
	return 0;
}

七.传参。

结构体传参有传值和传址两种,均会形成临时变量,在结构体成员很多时传址的效率高于传值。

void print1(struct s2 s){
//传值
	printf("%d\n", s.a);
}
void print2(struct s2*p){
//传址
	printf("%d\n", p->a);
	printf("%d\n", (*p).c);
}

猜你喜欢

转载自blog.csdn.net/weixin_41891854/article/details/80460987