C语言中位段内存的探讨研究

目录

1.char->int

2.char->long long

3.int->char

4.long long->char

5.int->long long

6.long long->int 

7.char->int->long long

8.char->long long->int

9.int->char->long long

10.int->long long->char

11.long long->int->char

12.long long->char->int

 13.结论罗列

14.总结

结论一:

结论二:


由于位段的特殊性,本文用的是VS编译器,其他编译器的结果可能是不同的。以在同一个位段中分别定义int,char,long long为例,这是因为三者所占大小具有一定的代表性,是不同的。经过几次测试,我发现同一个类型如果相邻且有多个的话,会占据同一快新开辟的内存,所以这里只以一个char或者int或者long long类型为例。

所有的测试前一个是代码内容,后面的图片是内存测试结果以及结论。

1.char->int

struct S
{
	char a : 2;
	int b : 2;
};
int main()
{

	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	return 0;
}

当定义顺序为char->int时,先为char开辟四个字节的空间,然后再重新为下面的int开辟四个字节的空间。再强调一下,如果char类型前面还有char类型,或者int类型后面还有int类型,则为它们开辟的空间仍然在为char开辟,或者为int开辟的空间中。 

2.char->long long

struct S
{
	char a : 2;
	long long b : 2;
};
int main()
{

	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	return 0;
}

当顺序为char->long long时,先为char开辟8个字节的空间,再为long long重新开辟8个字节的空间。

3.int->char

struct S
{
	int a : 2;
	char b : 2;
};
int main()
{

	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	return 0;
}

当定义顺序为int->char时,会先为int开辟四个字节的空间,然后再为char开辟四个字节的空间。 

4.long long->char

struct S
{
	long long a : 2;
	char b : 2;
};
int main()
{

	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	return 0;
}

当顺序为long long->char时,会先为long long开辟8个字节的空间,然后为char 开辟8个字节的空间。

5.int->long long

#include<stdio.h>
struct S
{
	int a : 2;
	long long b : 2;
};
int main()
{

	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	return 0;
}

 当顺序为int->long long时,会先为int开辟8个字节,然后再为long long开辟8个字节。

6.long long->int 

#include<stdio.h>
struct S
{
	long long a : 2;
	int b : 2;
};
int main()
{

	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	return 0;
}

 当定义顺序为long long->int 时,先为long long开辟8个字节,再为int 开辟8个字节。

7.char->int->long long

#include<stdio.h>
struct S
{
	char a : 2;
	int b : 2;
	long long c : 2;
};
int main()
{
	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	s.c = 2;
	return 0;
}

 先为char分配4个字节,然后为int分配4个字节,最后为long long分配8个字节。

8.char->long long->int

#include<stdio.h>
struct S
{
	char a : 2;
	long long b : 2;
	int c : 2;
};
int main()
{
	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	s.c = 2;
	return 0;
}

 当顺序为char->long long->int时,先为char分配8个字节,再为long long分配8个字节,最后为int分配8个字节。

9.int->char->long long

#include<stdio.h>
struct S
{
	int a : 2;
	char  b : 2;
	long long c : 2;
};
int main()
{
	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	s.c = 2;
	return 0;
}

当顺序为int->char->long long时,先为int分配4个字节,再为char分配4个字节,最后为long long分配8个字节。

10.int->long long->char

#include<stdio.h>
struct S
{
	int a : 2;
	long long  b : 2;
	char c : 2;
};
int main()
{
	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	s.c = 2;
	return 0;
}

 当顺序为int->long long->char时,先为int分配8个字节,再为long long分配8个字节,最后为char分配8个字节。

11.long long->int->char

#include<stdio.h>
struct S
{
	long long a : 2;
	int  b : 2;
	char c : 2;
};
int main()
{
	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	s.c = 2;
	return 0;
}

 当顺序为long long->int->char,会先为long long分配8个字节的内存,然后为int分配4个字节,最后为char分配4个字节。

12.long long->char->int

#include<stdio.h>
struct S
{
	long long a : 2;
	char  b : 2;
	int c : 2;
};
int main()
{
	struct S s= { 0 };
	s.a = 2;
	s.b = 2;
	s.c = 2;
	return 0;
}

 当顺序为long long->char->int时,先为long long分配8个字节的内存,然后为char开辟4个字节的空间,最后为int开辟4个字节的空间。

 13.结论罗列

char->int,先为char开辟四个字节的空间,然后再重新为下面的int开辟四个字节的空间。

char->long long,先为char开辟8个字节的空间,再为long long重新开辟8个字节的空间。

int->char,会先为int开辟四个字节的空间,然后再为char开辟四个字节的空间。

long long->char,会先为long long开辟8个字节的空间,然后为char 开辟8个字节的空间。

int->long long,会先为int开辟8个字节,然后再为long long开辟8个字节。

long long->int ,先为long long开辟8个字节,再为int 开辟8个字节


char->int->long long,先为char分配4个字节,然后为int分配4个字节,最后为long long分配8个字节。

char->long long->int,先为char分配8个字节,再为long long分配8个字节,最后为int分配8个字节。

int->char->long long,先为int分配4个字节,再为char分配4个字节,最后为long long分配8个字节。

int->long long->char,先为int分配8个字节,再为long long分配8个字节,最后为char分配8个字节。

long long->int->char,会先为long long分配8个字节的内存,然后为int分配4个字节,最后为char分配4个字节。

long long->char->int,先为long long分配8个字节的内存,然后为char开辟4个字节的空间,最后为int开辟4个字节的空间。

14.总结

我们把数据分为按类型顺序分为两组,得出结论:

结论一:

当一个位段中只有两种类型的时候,每次对类型变量进行空间分配时,分配空间大小为最大类型的大小,且每换一个类型就要重新分配一段空间。

结论二:

当一个位段中定义了三种类型的时候,每次对类型进行空间分配时,

当最大的类型定义在两种中间的时候,为三个类型分配的空间均为第三个类型所占空间。

其他情况中,最大的类型占其应占的最大空间,剩下两个类型占两者之间最大的类型所占的空间。

同时博主用char,short,int和short,int,long long均做了检验结论是相同的。

当位段中有四个类型时,我尝试过总结,情况更为复杂,但毕竟位段的性质和编译器是分不开的,这里只是在VS编译器发现的结果,所以没有再进行四个类型的研究。感兴趣的大佬们可以尝试总结一下呀,然后可以分享一下。

posted @ 2022-09-24 20:29  卖寂寞的小男孩  阅读(49)  评论(0)    收藏  举报