文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言的struct结构体怎么创建

2023-06-30 00:39

关注

本篇内容主要讲解“C语言的struct结构体怎么创建”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言的struct结构体怎么创建”吧!

一、本章重点

二、创建结构体

先来个简单的结构体创建

这就是一个比较标准的结构体

struct people{int age;int id;char address[10];char sex[5];};//不要少了分号。

需要注意的是不要少了分号。

那么这样创建结构体呢?

struct phone{char brand[10];//品牌int price;//价格}; struct people{int age;int id;char address[10];char sex[5];struct phone;};

很显然,一个结构体是能够嵌套另一个结构体的。

没有这样的设计,这样做也行

struct people{int age;int id;char address[10];char sex[5];char phone_brand[10];int phone_price;};

但结构体中成员太多了是不利于我们后期的维护的,试问:假设有1000个成员,你能快速的找出你需要的成员吗?当有了分块的结构体,我们是能够迅速的定位和查看的。

????结构体能够嵌套另一结构体,那么结构体能否嵌套自己呢?

struct phone{char brand[10];int price;struct phone;};

这样做之后编译器会给你一个报错

C语言的struct结构体怎么创建

原因是什么呢?

因为这个结构体的大小是未定义的,你能算出这个结构体的大小吗?这是不可能的!

既然大小不能确定,那么当你用这个结构体去创建变量,编译器该为这个变量开辟多大的空间呢?所有编译器在设计之初便杜绝了这种可能。

在提一个问题,结构体是否可以嵌套自己的结构体指针呢?

struct people{int age;int id;char address[10];char sex[5];struct people* son[2];};

答案是:可以

这里并不存在空间该分配多少的问题,因为struct people*是指针类型,它的大小是确定的,在32位机器下是4字节,64为机器是8字节。

三、typedef与结构体的渊源

先上一段代码

struct people{int age;int id;}a;//a代表什么?  int main(){a.age = 20;printf("%d\n", a.age);return 0;}

提问:a代表什么?

其实我们可以这样去看这个问题

struct people{int age;int id;} a;  int main(){a.age = 20;printf("%d\n", a.age);return 0;}

对比int b呢?

int b;struct people{int age;int id;} a;  int main(){a.age = 20;printf("%d\n", a.age);return 0;}

显然,struct people{int age;int id;}代表的是结构体类型,就像整形类型一样去创建变量。

那么这里的a就是结构体创建的变量。

这里也能明白结构体创建的最后为什么要保留分号。

那我们再看一段代码:

typedef struct people{int age;int id;}a;  int main(){a.age = 20;printf("%d\n", a.age);return 0;}

此时加上typedef,a还能当结构体创建的变量吗?

显然不行,此时编译器会报错。

C语言的struct结构体怎么创建

 理解方式以上述一致。

typedef struct people{int age;int id;} a;

类似于

typedef struct people{int age;int id;} a;typedef int b;

此时的a就是struct people{int age;int id;}

typedef的作用是把struct people{int age;int id;}这一类型重命名为a。

不知道你有没有见过这样的代码

typedef struct people{int age;int id;}b,a,*c; int main(){a a1;b b1;c c1 = &a1;a1.age = 5;b1.age = 6;c1->age = 10;printf("%d %d %d\n", a1.age, b1.age, c1->age);return 0;}

你知道运行结果吗?

这里的b、a、c是什么呢?

这里我就不啰嗦了,a和b都是struct people{int age;int id;}结构体类型,c是struct people{int age;int id;}*  结构体指针类型。

运行结果:

C语言的struct结构体怎么创建

那么再次提升一下

typedef struct people{int age;int id;}b, a, c[20];这里的b、a、c代表什么呢?

期待着你动手解决这一问题。

四、匿名结构体

这就是一个匿名的结构体

struct{int age;int id;}; int main(){struct p1;p1.age = 10;printf("%d\n", p1.age);return 0;}

匿名结构体能这样创建结构体变量吗?

此时编译器会报错

C语言的struct结构体怎么创建

这样的匿名结构体只能在创建结构体的时候定义好变量。

比如这样

struct{int age;int id;}p1; int main(){p1.age = 10;printf("%d\n", p1.age);return 0;}

C语言的struct结构体怎么创建

 接下来我们看下这段代码

typedef struct{int age;int id;}people; int main(){people p1;p1.age = 10;printf("%d\n", p1.age);return 0;}

这里我们重命名这个匿名结构体,即把这个结构体类型重命名为people。

那么我们自然可以用people类型来创建p1。也可创建p2、p3等等。

运行结果:

C语言的struct结构体怎么创建

以下代码合法吗?

//匿名结构体类型struct{ int a; char b; float c; }x; struct{ int a; char b; float c; }a[20], *p; int main(){    //在上面代码的基础上,下面的代码合法吗?    p = &x;    return 0;}

警告: 编译器会把上面的两个声明当成完全不同的两个类型。 所以是非法的。

五、结构体大小

如何求结构体类型的大小?

这需要了解结构体成员在内存是怎么存储的。

你知道下面这段代码的运行结果吗?

struct people{char a;int b;char c;}; int main(){struct people p1;printf("%d\n", sizeof(p1));//大小是6吗?return 0;}

char是一字节大小

int是四字节大小

char是一字节大小

直接相加等于6

那么这个结构体的大小是6吗?

但我们发现答案是12

C语言的struct结构体怎么创建

这是为什么呢?

简单来说编译器为了读取内存时提升效率和避免读取出错,它做了内存对齐的操作。

什么是内存对齐?

就是让数据安排在合适的位置上所进行的对齐操作。

为什么要内存对齐?

不是所有的硬件平台都能访问任意地址上的任意数据的;

某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

对齐规则:

Windows中默认对齐数为8,Linux中默认对齐数为4

最大对齐数:即所有成员对齐数中最大的对齐数。

struct people{char a;int b;char c;};

C语言的struct结构体怎么创建

解析:

第一个为char,直接放在偏移地址为0的位置处。

第二个为int,它的自身大小为4,比默认对齐数小,所以它的对齐数是4。

4是4的整数倍,所以在偏移地址为4处开始放数据。

第三个为char,自身大小为1,比默认对齐数小,它的对齐数是1。

8是1的整数倍,从偏移地址为8的位置开始放。

总大小为9,不是最大对齐数的整数倍

要浪费3个空间,调整后为12。

我们再看看下面这段代码:

将char 和 int成员变量交换位置后,这结构体的大小还是12吗?

struct people{char a;char c;int b;}; int main(){struct people p1;printf("%d\n", sizeof(p1));//大小是多少呢?return 0;}

C语言的struct结构体怎么创建

解析:

第一个:直接从0处开始放

第二个是char:对齐数是1,1是1的整数倍,从偏移地址为1的位置开始放。

第二个是int:对齐数是4,4是4的整数倍,从偏移地址为4的位置开始放。

放好各个成员变量后,总大小是8,是最大对齐数(4)的整数倍,不需要调整。

因此这个结构体的大小是8.

C语言的struct结构体怎么创建

再来看看下面这个如何?

struct people{char a;int b;short c[2];char d;}; int main(){struct people p1;printf("%d\n", sizeof(p1));//大小是6吗?return 0;}

C语言的struct结构体怎么创建

解析:

第一个成员是char,直接放再0地址处。

第二个成员是int,对齐数是4,从偏移地址为4的位置处开始存放。

第三个成员是short[2],关于数组,它的对齐数是首元素的大小与默认对齐数的较小值,这里它的对齐数是2,然后从偏移地址为8处开始存放4个字节。

第四个成员是char,对齐数是1,直接放开12位置处。

总大小是13,最大对齐数是4,不是最大对齐数的整数倍,需要对齐到最大对齐数的整数倍,浪费3字节大小,对齐到16.

所以这个结构体的大小是16.

六、结构体指针

先创建一个结构体

struct people{char a;int b;};

然后用该结构体创建变量,再用结构体指针指向该变量。

int main(){struct people p1;struct people* p = &p1;return 0;}

所谓结构体指针,即指向结构体的指针。

正如整形指针,即指向整形的指针。

访问变量方式1:

int main(){struct people p1;struct people* p = &p1;p1.a = 'a';p1.b = 10;printf("%c %d\n", p1.a, p1.b);return 0;}

访问变量方式2:

int main(){struct people p1;struct people* p = &p1;p->a = 'a';p->b = 10;printf("%c %d\n", p->a, p->b);return 0;}

访问变量方式3:

int main(){struct people p1;struct people* p = &p1;(*p).a = 'a';(*p).b = 10;printf("%c %d\n", (*p).a, (*p).b);return 0;}

到此,相信大家对“C语言的struct结构体怎么创建”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯