c语言之结构体

1、概念:

可以将不同种类的数据组装起来,形成一个完整的类型;

比如:
一个学生,典型地应该拥有学号(整型)、姓名(字符串)、分数(浮点型)、性别(枚举)等不同层面的属性,这些所有的属性都不应该被拆分开来,而是应该组成一个整体,代表一个完整的学生。

  • 结构体的定义:
struct 结构体标签
{
    成员1;
    成员2;
    成员3;
    ...
};
  • 语法:
  • ①、结构体标签,用来区分各个不同的结构体。
  • ②、成员,是包含在结构体内部的数据,可以是任意的数据类型。

示例:

struct student
{
    int a;
    char b;
    double c;
};

int main(void)
{
    struct student n;    //定义结构体变量
}

2、结构体的初始化:

  • 由于结构体内部拥有多个不同类型的成员,因此初始化采用与数组类似的列表方式;
  • 结构体的初始化有两种方式:1普通初始化;  2指定成员初始化;3赋值初始化。
  • 为了能适应结构体类型的升级迭代,一般建议采用指定成员初始化。

示例:

1、普通初始化
struct student n={1,'a',3.14};

2、指定成员初始化
struct student n={
                    .a=1,
                    .b='b',
                    .c=3.14};

3、成员的引用赋值
struct student n;
n.a=1;
n.b='a';
n.c=3.14;
printf("%d %c %f\n",n.a,n.b,n.c);

3、结构体指针与数组:

  • 跟普通指针无二意,可以定义指向结构体的指针,也可以定义结构体数组;
struct node  n = {100, 'x', 3.14};
struct node *p = &n;

// 以下语句都是等价的
printf("%d\n",   n.a);
printf("%d\n", (*p).a);
printf("%d\n",  p->a);  // 箭头 -> 是结构体指针的成员引用符
  • 结构体数组:
struct node n[5];
n[0].a = 300;
n[0].b = 'z';
n[0].c = 3.14;

4、结构体别名:

//结构体别名
typedef struct student   
{
    char *name;
    unsigned long number;
    char sex;
    int age;   
}student, *pstu;  //student是struct student的别名。 pstu是struct  student *的别名

5、CPU字长与地址对齐:

        字长的概念指的是处理器在一条指令中的数据处理能力,当然这个能力还需要搭配操作系统的设定,比如常见的32位系统、64位系统,指的是在此系统环境下,处理器一次存储处理的数据可以达32位或64位。

32位4字节

64位8字节

        CPU字长确定之后,相当于明确了系统每次存取内存数据时的边界,以32位系统为例,32位意味着CPU每次存取都以4字节为边界,因此每4字节可以认为是CPU存取内存数据的一个单元。

        如果存取的数据刚好落在所需单元数之内,那么我们就说这个数据的地址是对齐的,如果存取的数据跨越了边界,使用了超过所需单元的字节,那么我们就说这个数据的地址是未对齐的。

未对起的情况: 

 对起的情况:

6、求结构体的m值:

 普通变量的m值:

char c; // 由于c占1个字节,因此c不管放哪里地址都是对齐的,因此m=1

short s; // 由于s占2个字节,因此s地址只要是偶数就是对齐的,因此m=2

int i; // 由于i占4个字节,因此只要i地址满足4的倍数就是对齐的,因此m=4

double f; // 由于f占8个字节,因此只要f地址满足4的倍数就是对齐的,因此m=4

结构体的M值:

取 决于结构体中占最大内存的成员为

 struct node
 {
     short  a; // 尺寸=2,m值=2
     double b; // 尺寸=8,m值=4
     char   c; // 尺寸=1,m值=1
 };
 ​
 struct node n; // M值 = max{2, 4, 1} = 4;

7、结构体的内存大小:

struct student
{
    char name[20];
    int age;
    char sex;
};

该结构体的内存为28
首先在64位系统中,一个地址以8个字节为一个地址,这个结构体中的m值为20,8个为一行,name与age正好占完3行24个,剩下一个char型独自占新的一行地址,所以该结构体整个内存为28

在32为系统中是28
32位系统中地址为4字节为一个地址

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
引用\[1\]:C语言字节对齐问题详解中提到了C语言中的字节对齐问题。在结构体中,为了提高内存访问的效率,编译器会对结构体进行字节对齐。这意味着结构体的成员在内存中并不是紧凑排列的,而是按照一定的规则进行对齐。具体的对齐规则取决于编译器和编译选项。\[1\] 引用\[2\]:在C语言中,可以使用宏offsetof来获取结构体成员相对于结构体开头的字节偏移量。这个宏非常有用,可以帮助我们计算出每个结构体成员相对于结构体开头的偏移字节数。通过这个宏,我们可以更好地理解结构体的内存布局。\[2\] 引用\[3\]:在C语言中,指针和结构体的组合常常用于处理复杂的数据结构。指针可以指向结构体的成员,通过指针可以方便地对结构体进行操作。指针和结构体的组合可以实现更灵活的数据处理和内存管理。\[3\] 综上所述,C语言中的指针结构体组合可以用于处理复杂的数据结构,而字节对齐问题则是在结构体中为了提高内存访问效率而进行的优化。通过使用宏offsetof,我们可以更好地理解结构体的内存布局。 #### 引用[.reference_title] - *1* *3* [结构体指针,C语言结构体指针详解](https://blog.csdn.net/weixin_34069265/article/details/117110735)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C语言结构体详解](https://blog.csdn.net/m0_70749276/article/details/127061692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

biubiuboomy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值