jjzjj

C语言——结构体(全)

小小圆脸 2023-04-05 原文

目录

一、结构体的设计

二、结构体变量的初始化

2.1结构体在内存表示;

2.2结构体初始化;

 2.3结构体指针变量

 2.4结构体嵌套结构体

三、结构体成员访问 

3.1、结构体成员访问

3.2、结构体变量和指针

​3.3、结构体和函数 

四、结构体与数组

五、计算结构体大小

三个规则:

例1

 例2、

指定对齐值

总结


一、结构体的设计

C语言提供了基本的数据结构,例如 char 、short 、int 、float....等类型;这些偶称为内置类型。怎样设计出来属于自己的类型?

程序员可以使用结构体来封装一些属性,设计出新的类型,在C语言中称为结构体类型。

结构体的定义形式为

struct 结构体名
{
   成员列表(可以是基本的数据类型,指针,数组或其他结构类型)
};

举个例子来说吧;

客观事务(实体)是复杂的,要描述它必须从多方面进行;也就是用不同的数据类型来描述不同的方面;用学生实体来说:

学生拥有什么? 学号、姓名、性别、年龄;

struct Student
{
  char s_id[8];
  char s_name[8];
  char s_sex[4];
  int s_age;
};

注意以下几点;

(1)、关键字struct是数据类型说明符,指出下面说的是结构体类型;

(2)、标识符Student是结构体的类型名;

(3)、最后的分号一定要写;

二、结构体变量的初始化

结构体是一种数据类型,也就是说可以用它来定义变量。

结构体就像一个“模板”,定义出来的变量都具有相同的性质。可以将结构体比作“图纸”,结构体变量比作“零件”,根据同一张图纸生产出来的零件的特性都是一样的;

结构体是一种数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据、需要存储空间;

2.1结构体在内存表示;

 C语言中  struct 不可少

2.2结构体初始化;

 2.3结构体指针变量

 2.4结构体嵌套结构体

三、结构体成员访问 

3.1、结构体成员访问

结构体变量使用   .   访问;

结构体变量.对象

#include<stdio.h>
#include<string.h>
struct Date
{
	int year;
	int month;
	int day;
};
struct Student
{
	char s_name[20];
	struct Date birthday;
	float score;
};
int main()
{
	struct Student stu = { "liuwen",2000,10,1,99.9 };
	printf("name=%s\nbirtyday=%d.%d.%d\nscore=%f\n", stu.s_name, stu.birthday.year, stu.birthday.month, stu.birthday.day, stu.score);
	stu.score = 77;
	printf("name=%s\nbirtyday=%d.%d.%d\nscore=%f\n", stu.s_name, stu.birthday.year, stu.birthday.month, stu.birthday.day, stu.score);
	return 0;

注意:对结构体变量整体赋值有三种情况

 (1)定义结构体变量(用{}初始化)

(2)用已定义的结构体变量初始化

(3)结构体类型相同的变量可以作为整体相互赋值;

在C语言中不存在结构体类型的强制转换。

3.2、结构体变量和指针

内置类型可以定义指针变量,结构体类型也可以定义结构体类型指针;

结构体类型指针访问成员的获取和赋值形式:

(1)(*p). 成员名(.的优先级高于*,(*p)两边括号不能少)

(2)   p->成员名(->指向符)

示例:

#include<stdio.h>
#include<string.h>
//#define _CRT_SECURE_NO_WARNINGS
struct Inventory//商品
{
	char description[20];//货物名
	int quantity;//库存数据
};
int main()
{
	struct Inventory sta = { "iphone",20 };
	struct Inventory* stp = &sta;
	char name[20] = { 0 };
	int num = 0;
	(*stp).quantity = 30;
	stp->quantity = 30;
	strcpy_s(name,sizeof(stp->description),stp->description);
	printf("%s %d\n", stp->description, stp->quantity);
	printf("%s %d\n", (*stp).description, (*stp).quantity);
	return 0;
}

 3.3、结构体和函数 

示例:

#include<stdio.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
struct School
{
	char s_name[20];//学校
	int s_age;
};
void Print_a(struct School sx)
{
	printf("%s %d\n", sx.s_name, sx.s_age);
}
void Print_c(struct School* sp)
{
	printf("%s %d\n", sp->s_name, sp->s_age);
}
int main()
{
	struct School sx = { "xi'an",100 };
	Print_a(sx);
	Print_c(&sx);
	return 0;
}

 内存什么的看上面;

两种传参那个更好?通过内存可以看出来;

四、结构体与数组

结构体数组,是指数组中的每一个元素都是一个结构体类型。在实际应用中,C语言结构体数组常被用来表示有相同的数据结构的群体,比如一个班的学生,一个公司的员工等;

例如:

#include<stdio.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
struct Student
{
	char s_name[20];//姓名
	int age;//年龄
	float score;//成绩
};
int main()
{
	struct Student cla[] =
	{
		{"liuwen",18,149.9},
		{"qnge",18,145},
		{"anan",19,188},
	};
	return 0;
}

五、计算结构体大小

三个规则:

(1)、结构体变量的首地址,必须是结构体变量的“最大基本数据类型成员所占字节数”的整数倍;

(2)结构体变量中的每个成员相对于结构体首地址的偏移量,都是该成员基本数据类型所占字节数的整数倍;

(3)、结构体变量的总大小,为结构体变量中“最大基本数据类型成员所占字节”的整数倍;

示例:假设总零地址开始(计算)

例1、

struct node
{
	char cha;
	int ia;
	char chb;
};
int main()
{
	int size = 0;
	struct node sd = { 'a',2,'b' };
	printf("%d\n", sizeof(struct node));//12
	return 0;
}

 例2、

struct node
{
	char cha;
	char chb;
	int ia;
};
int main()
{
	int size = 0;
	struct node sd = { 'a','b',2 };
	printf("%d\n", sizeof(struct node));//12
	return 0;
}

为什么要理解字节对齐问题?

(1)内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问变量,但是实际上, cup并非逐字节读写内存,而是以2,4,或8的倍数的字节块来读写内存,因此就会对基本数据类型的地址作出一些限制, 即它的地址必须是2, 4或8的倍数。那么就要求各种数据类型按照一定的规则在空间. 上排列,这就是对齐。

(2)有些平台每次读都是从偶地址开始,如果一个int 型(假设为32位系统)如果存放在偶地址开始的地方那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。

(3)由于不同平台对齐方式可能不同,如此一来,同样的结构在不同的平台其大小可能不同,在无意识的情况下,互相发送的数据可能出现错乱,甚至引|发严重的问题。

指定对齐值

预处理指令# pragma pack(n)可以改变默认对齐数。n取值是1,2, 4,8, 16。

总结

1)结构体变量的首地址,必须是MIN{"结构体最大基本数据类型成员所占字节数",指定对齐方式}大小的整数倍。
2)结构体每个成员相对于结构体首地址的偏移量,都是MIN{基本数据类型成员,指定对齐方式}大小的整数倍。
3)结构体的总大小,为MIN{结构体“最大基本数据类型成员所占字节数”(将嵌套结构体里的基本类型也算上,得出最大基本数据类型成员所占字节数),指定对齐方式} 大小的整数倍。
 


 

有关C语言——结构体(全)的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  4. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  5. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  6. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  7. ruby-on-rails - 一般建议和推荐的文件夹结构 - Sinatra - 2

    您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应

  8. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

  9. ruby - 如何保持我不常用的编程语言技能 - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby​​-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby​​有很大不同。由于我与ruby​​之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?

  10. ruby-on-rails - 如果特定语言环境中缺少翻译,如何配置 i18n 以使用 en 语言环境? - 2

    如果特定语言环境中缺少翻译,如何配置i18n以使用en语言环境翻译?当前已插入翻译缺失消息。我正在使用RoR3.1。 最佳答案 找到相似的question这里是答案:#application.rb#railswillfallbacktoconfig.i18n.default_localetranslationconfig.i18n.fallbacks=true#railswillfallbacktoen,nomatterwhatissetasconfig.i18n.default_localeconfig.i18n.fallback

随机推荐