结构体学习笔记

最近在网上做笔试题时发现蛮多公司对于结构体这方面比较重视,所以第一篇博客就用来记载我个人对于结构体的学习吧。

在C语言中,结构体应该占据了一定分量,基本是作为基本功吧,学习C语言的程序员对结构体应该都有自己的了解。

一、结构体是一系列数据的集合,可能这些数据是用来描述一个物体,也可能是用来对一个问题的抽象描述,列如链表,结构体里面包含了每个节点的数据以及指向下一个节点的地址。结构体里所有的数据从本质上来讲应该是作为一个物体的各个基本属性。

ex:    

struct     person  //定义一个结构体

 {        

    char name[100];// 人名

    int age;//年龄

    char sex[100];//性别

};//分号不能少,作为结构体定义的结束标志

这个声明里面包含了两个字符数组,一个整型变量,但是并没有创建对象并传入实际数据。

二、对于结构体的赋值

对于结构体的赋值我们可以在定义变量的时候初始化,比如说:

struct person p1={“小明",19,"男" };

但是在定义之后如果想要对变量进行赋值只能进行单个赋值,比如:

struct person p1;

p1.name="小明";

p1.age=18;

p1.sex="男";


好了,以上就是结构体的基本知识,但是在面试中我们可不会考这么基础的知识点。

三、结构体经典面试题

1、什么是结构体?

C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。结构体可以被声明为变量指针数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员(member),且这些成员可以为不同的类型,成员一般用名字访问。

2、在什么情况下能使用结构体,使用结构体有什么好处?

存储复合型数据类型的时候,有时候基本数据类型无法满足现实中的变量描述,比如一个人有年龄int、身高float、姓名string/char*等等属性,所以你在描述一个人的属性时就不能用单一的基本数据类型来描述,于是便使用结构体。
类似于封装,具有安全性。

3、什么是结构体内存对齐,为什么要对齐?有什么好处?

结构体内存对齐是按照结构体内元素定义顺序一个一个放入内存,但是并不是一个接一个,从结构体存储的首地址开始,每个放入内存的数据都是按照自己定义的数据类型所占字节来对内存进行划分,所以所以元素放置的位置一定是在自己宽度的整数倍上开始。

例:

#include<stdio.h>

struct a

{

    char a;

    int b;

    double c

};

int main()

{

    struct a test;

    printf("%d",sizeof(test));

    return 0;

}

但是程序运行显示的是 16,而不是我们以为的13,这就是结构体内存对齐之后产生的结果;

这时候就牵扯到一个补齐原则: 

在经过对齐原则分析后,检查计算出的存储单元是否为所有元素中所占内存最大的元素的长度的整数倍,是,则结束;若不是,则补齐为它的整数倍。在这例题中我们可以看到我们预期的结果是13但是在内存对齐下,13不是最大元素长度的整数倍,所以当达到16满足了内存对齐,所以结果显示的是16。

当char a时,以char自身大小(一字节)划分,a占有了首地址0一个字节。但是当int b时,以int自身大小(四字节)划分,所以b从四字节的非负整数倍开始存储占用四个字节,由于首地址0已被占用,所以b从第四个地址开始占用四个字节。同理,当double c时,double也以自身大小(八字节)划分内存,而前八个(0——7)已被占用,故c从第八个地址开始占用八个字节。


4、怎么自定义对齐参数?有没有什么限制?

在widows中默认对齐数是8;在linux中默认对齐数是4

自定义结构体对齐参数可以在结构体之前加宏#pragma pack(int),最后在struct定义之后加#pragma pack就可以自定义设置对齐参数。且对齐参数要根据结构体内元素来进行设置。

5、如何知道结构体某个成员相对于结构体起始位置的偏移量?

使用offsetof宏来判断结构体中成员的偏移地址。使用offsetof宏需要包含stddef.h头文件,该宏定义如下:
#define offsetof( type , menber ) ( size_t)&((( type *)0)-> member )
1
2
巧妙之处在于将地址0强制转换为type类型的指针,从而定位到member在结构体中偏移位置,编译器认为0是一个有效的地址,从而认为0是type指针的起始地址。
借鉴了前辈的总结,希望可以慢慢转化成自己的知识储备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值