详细介绍:C语言 结构体

结构体

  • 结构体
    • 结构体中元素的类型可以不一样,且只能包含元素,没有函数,称之为成员
    • 所有成员变量内存地址连续,符合字节对齐规则
    • 创建的结构体相当于一个新的类型
数组和结构体
数组结构体
存储的数据类型数据类型一致数据类型可以不一致
访问方式通过下标或指针移动相应的数据类型大小
储存地址方式及规则地址连续地址连续但遵循字节对齐
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
};
posted @ 2025-08-11 13:40  yfceshi  阅读(39)  评论(0)    收藏  举报