C语言 结构体

发布于:2025-08-10 ⋅ 阅读:(19) ⋅ 点赞:(0)

结构体

  • 结构体
    • 结构体中元素的类型可以不一样,且只能包含元素,没有函数,称之为成员
    • 所有成员变量内存地址连续,符合字节对齐规则
    • 创建的结构体相当于一个新的类型
数组和结构体
数组 结构体
存储的数据类型 数据类型一致 数据类型可以不一致
访问方式 通过下标或指针移动相应的数据类型大小
储存地址方式及规则 地址连续 地址连续但遵循字节对齐
struct name							struct man
{								   {
    数据类型 成员;  						char name[20];
};								   };

struct node no;  //错误,n是一个变量类型,没有实际数据类型
访问方式
  • . : 结构体变量
  • ->:指针变量,非指针类型不可使用
struct node
{
	int x;
	char c;
};
int main()
{
	struct node  no;
	no.c = 'a';
	no.x = 10;
    printf("%c %d",no.c,no.x);
	return 0;
}

struct node
{
	int x;
	char c;
}no = {10,'a'},n1={20,'b'};  //全局变量
int main()
{
    printf("%c %d",no.c,no.x);   //一样
    printf("%c %d",n1.c,n1.x);   //一样
	return 0;
}

typedef struct node   //此处的node可以省略
{
	int x;
	char c[255];
}NODE;    //加上typedef后node是类型名
int main()
{
	NODE  no;     //此时不用写struct    
    //struct node no  == NODE no
	strcpy(no.c,"ssss");
	no.x = 10;
	printf("%s %d",no.c,no.x);
	return 0;
}

  • 结构体在未使用时,不会开辟内存空间,在声明一个结构体变量后会按照字节排序分配空间
struct node
{
	int x;
	char c;
	int *p;
};
int main()
{
	struct node  no;
	char ch = 'a';	
	no.p = (int *) malloc (sizeof(int) * 8);
    
	for(int i=0;i<=8;i++)
		*(no.p + i) = i;		
	for(int i=0;i<=8;i++)
		printf("%d",*(no.p + i));
    
    free(no.p);
    no.p = NULL;
	return 0;
}
  • 如果是结构体指针变量,先开辟内存,指向有效内存,再这个基础上申请成员的内存;结束时先释放成员,再释放节点
typedef struct 
{
	char c;
	int *p;
}node;
int main()
{
	node*  no = NULL;	
	no = (node*) malloc (sizeof(node));
	if(no == NULL) 
		return -1;
	
	no->p = (int*) malloc (sizeof(int) * 22);
	if(no->p == NULL)
	{
		free(no->p);   //把申请过的放掉
		no -> p = NULL;	
		return -1;
	}
			
	if(no -> p  != NULL)
	{
		free(no->p);   //先释放成员的内存
		no -> p = NULL;	
	}	
	if(no -> p  != NULL)
	{
		free(no);      //在释放节点内存
		no = NULL;
	}		
	return 0;
}

结构体空间

  • 空结构体占 0 字节
  • 结构体指针变量占指针字节
字节对齐
  • 结构体地址大小是最大成员类型的整数倍
  • 小类型占位 = 相近大类型占位
  • 已经对齐的元素看成整体,与后一个对齐
typedef struct 
{
	char 
     double
    int
        char
}stu;
int main()
{
	stu man;
	printf("%d\n",sizeof(man));

	return 0;	
}

在这里插入图片描述

#pragma pack(n) //设定变量以n字节对齐,、
//n为8时,char类型不变
//n越小,节省空间
#pragma pack(2)
typedef struct 
{
	char
     int
     char
}stu;
//大小为8

位域

  • 将多个位域成员存储在同一个类型内存中
  • 位域取值不能超过位数的最大值
  • 位域用于unsigned整数数据类型,浮点数不行
typedef struct 
{
	char 	 a :  5;   //只用5比特位
    double 	  b : 3;   //不能超过 0b111
    int		  c  : 4;
	char	 d  : 7;
}stu;
int main()
{
	stu man;
	printf("%d\n",sizeof(man));
	return 0;	
}

与结构体的区别

  • 所占大小不一样
  • 取值范围
    • 结构体大小取值依赖数据类型
    • 位域仅通过字节数取值范围
  • 位域不能使用&

共用体

  • union : 所有成员共用一段内存,同时刻只有一个成员有效,这个空间的值只能是最新的一个赋值
  • 内存大小:最大成员所占内存,遵循内存对齐,
  • 如果结构体套联合体,内存是整个结构体的最大类型的整数倍
union name 
{
    int a;
    double d;
    char str[17];
};      //size = 8
int main()
{
    union name na;
    sizeof(na);   //17 -> double(8) -> 24   
 	na.d  = 2.1;
    na.a = 10;
    na.c =  'a'; 
	printf("%d,%c",na.a,na.c); //97,a
}
//float 因为存储方式不一样,输出可能不对

枚举

  • 枚举存放的数据是整数常量,可以重复,
enum name
{
    data0;
    data1;
    data2;
    datan;
};
  • 枚举常量默认从0开始依次递增
  • 可以手动指定枚举常量的值,未指定则在前一个基础上加一
  • 不能引出枚举体中的量,只能被赋值
enum weekday
{
  MON = 1,TUE,WED,THU,FRI,SAT,SUN  
};

网站公告

今日签到

点亮在社区的每一天
去签到