数据结构day2

一、结构体大小的求取

结构体字节大小的计算需要满足字节对齐原则。

64位操作系统默认8字节对齐32位操作系统默认4字节对齐

字节对齐原则

        1.结构体成员变量的自身对齐量=本身的数据类型大小>操作系统默认对齐量?操作系统默认对齐量:本身的数据类型大小

        2.结构体中每一个成员变量的起始位置,都在其自身对齐量的整数倍上(0除外)

        3.结构体的整体大小是最大成员变量对齐量的整数倍

示例:

1.无嵌套结构体无数组

struct data
{    
    char t1;  //t1的自身对齐量是1,偏移地址0是其整数倍,故直接存储1字节     
    char t2;  //t2的自身对齐量是1,偏移地址1是其整数倍,故直接存储1字节      
    unsigned short t3;//t3的自身对齐量是2,偏移地址2是其整数倍,故直接存储2字节   
    unsigned long t4; //t4的自身对齐量是8,偏移地址4不是其整数倍,故需空四个偏移地址,再存储8字节
}; //共16个字节是最大对齐量8的倍数,故该结构体大小为16个字节
struct data
{
    char t1; //t1的自身对齐量是1,偏移地址0是其整数倍,故直接存储1个字节
    int t2; //t2的自身对齐量是4,偏移地址1不是其整数倍,故需空3个偏移地址,再存储4个字节  
    short t3;//t3的自身对齐量是2,偏移地址8是其整数倍,故直接存储2个字节
}; //总共10个字节不是最大对齐量4的整数倍,故需空2个偏移地址,则该结构体共12个字节
struct s1
{
    char c1; //c1的自身对齐量是1,偏移地址0是其整数倍,故直接存储1个字节 
    int i; //i的自身对齐量是4,偏移地址1不是其整数倍,故需空3个偏移地址,再存储4个字节 
    char c2;//c2的自身对齐量是1,偏移地址8是其整数倍,故直接存储1个字节 
};//总共9个字节不是最大对齐量4的整数倍,故需空3个偏移地址,则该结构体共12个字节
struct s2
{
   char c1; //c1的自身对齐量是1,偏移地址0是其整数倍,故直接存储1个字节
   char c2; //c2的自身对齐量是1,偏移地址1是其整数倍,故直接存储1个字节
   int i; //i的自身对齐量是4,偏移地址2不是其整数倍,故需空2个偏移地址,再存储4个字节    
}; //总共8个字节是最大对齐量4的整数倍,故该结构体共8个字节
typedef struct
{
    int b;//b的自身对齐量是4,偏移地址0是其整数倍,故直接存储4个字节     
    char a;//a的自身对齐量是1,偏移地址4是其整数倍,故直接存储1个字节    
    long e;//e的自身对齐量是8,偏移地址5不是其整数倍,故需空3个偏移地址,再存储8个字节    
    char c;//c的自身对齐量是1,偏移地址16是其整数倍,故直接存储1个字节     
    float d;//d的自身对齐量是4,偏移地址17不是其整数倍,故需空3个偏移地址,再存储4个字节   
    double t;//t的自身对齐量是8,偏移地址24是其整数倍,故直接存储8个字节   
}node;//总共32个字节是最大对齐量8的整数倍,故该结构体共32个字节 

2.无嵌套结构体有数组

struct C 
{  
    char a;//a的自身对齐量是1,偏移地址0是其整数倍,故直接存储1个字节   
    char b[3];//b的自身对齐量是1,偏移地址1是其整数倍,故直接存储3个字节   
    char c; //c的自身对齐量是1,偏移地址4是其整数倍,故直接存储1个字节
}; //总共5个字节是最大对齐量1的整数倍,故该结构体共5个字节

 3.有嵌套结构体变量无数组

         每个结构体都是一个独立的单位,需要分开算。嵌套结构体变量的总字节数算出来后再算其自身对齐量。

typedef struct Test
{
    short a;//a的自身对齐量是2,偏移地址0是其整数倍,故直接存储2个字节 
    struct//拿出来单独算其总字节数
    {
        int b;//b的自身对齐量是4,偏移地址0是其整数倍,故直接存储4个字节    
        double c;//c的自身对齐量是8,偏移地址4不是其整数倍,故需空4个偏移地址,再存储8个字节   
        char d;//d的自身对齐量是1,偏移地址16是其整数倍,故直接存储1个字节   
    }p;/*总共17个字节不是最大对齐量8的整数倍,故需空7个偏移地址,则该结构体共24个字节
         p的自身对齐量是8,偏移地址2不是其整数倍,故需空6个偏移地址,再存储24个字节*/ 
    int e;//b的自身对齐量是4,偏移地址32是其整数倍,故直接存储4个字节 
}Test;//总共36个字节不是最大对齐量8的整数倍,故需空4个偏移地址,则该结构体共40个字节

 4.有嵌套结构体变量有数组

typedef struct Test
{
    short a;//a的自身对齐量是2,偏移地址0是其整数倍,故直接存储2个字节 
    struct//拿出来单独算其总字节数
    {
        int b;//a的自身对齐量是4,偏移地址0是其整数倍,故直接存储4个字节 
        double c[10];//c的自身对齐量是8,偏移地址4不是其整数倍,故需空4个偏移地址,再存储80个字节   
        char d;//d的自身对齐量是1,偏移地址88是其整数倍,故直接存储1个字节 
    }p;/*总共89个字节不是最大对齐量8的整数倍,故需空7个偏移地址,则该结构体共96个字节
         p的自身对齐量是8,偏移地址2不是其整数倍,故需空6个偏移地址,再存储96个字节*/
    int e;//e的自身对齐量是4,偏移地址104是其整数倍,故直接存储4个字节  
}Test;//总共108个字节不是最大对齐量8的整数倍,故需空4个偏移地址,则该结构体共112个字节

 二、验证大小端存储

 1.强制转换数据类型验证

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
	int a=0x12345678;
	char b=(char)a;
	if(b==0x78)
	{
		printf("小端存储\n");
	}
	else if(b==0x12)
	{
		printf("大端存储\n");
	}
	return 0;
}

2.指针验证

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
	int a=0x12345678;
	char* p=&a;
	if(*p==0x78)
	{
		printf("小端存储\n");
	}
	else if(*p==0x12)
	{
		printf("大端存储\n");
	}
	return 0;
}

      出现警告是因为指针的数据类型和变量的数据类型不一致,会发生强制转换,按指针的数据类型字节大小取地址。

      故指针的数据类型一般要和变量保持一致

3.共同体验证

        共用体中的所有成员,共用同一片内存。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef union
{
	int a;
	char b;
}A;

int main(int argc, const char *argv[])
{
	A P;
	P.a=0x12345678;
	if(P.b==0x78)
	{
		printf("小端存储\n");
	}
	else if(P.b==0x12)
	{
		printf("大端存储\n");
	}
	return 0;
}

 

三、枚举

        枚举有和结构体相同的地方,故可以将其类似于结构体进行记忆。但枚举也有和结构体明显不同的地方,故不能简单的用结构体的知识去认知。 

        枚举和结构体的声明基本一致,不同之处在于枚举的成员是一个整型常量,每个成员之间需要用逗号(,)隔开,且最后一个成员可以省略逗号;结构体的成员是一个需要加上数据类型的变量,每个成员之间需要用分号(;)隔开,且最后一个成员不可以省略分号。

        枚举和结构体的变量定义完全一致 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值