结构体(struct)
结构体
结构体是将不同类型的数据按照一定的功能需求进行整体封装,封装的数据类型与大小均可以由用户指定。
1 结构体的声明、定义及初始化
1.1 声明结构体类型
struct 结构体名
{
成员列表;
};
struct STUDENT
{
char name[]; //名字
int age; //年龄
char sex; //性别
int num; //学号
char add[]; //家庭住址
float score; //分数
};
1)结构体类型是由基本数据类型组合而成的新的数据类型。结构体类型的成员是由程序员自己定义的,所以结构体类型是由我们人为定义的数据类型。
2)struct STUDENT是定义的数据类型名字(与系统提供的int,char,float,double等提供的标准类型名一样,都是数据类型,具有相同的作用,都是用来定义变量的),它向编译系统声明这是一个结构体类型。
3)声明结构体类型仅仅是声明了一个类型,系统并不为之分配内存,好比系统不会类型为int分配内存一样。只有当使用这个类型定义了的变量时,系统才会为变量分配内存。所以在声明结构体类型的时候,不可以对里面的变量进行初始化。
1.2 定义结构体变量
定义结构体变量有两种方法:
1)先声明结"构体类型",再定义"结构体类型变量"
struct STUDENT stud1,stud2;
stud1,stud2就是我们定义的结构体变量名。定义了结构体变量之后,系统就会为之分配内存单元。
2)声明结构体类型的同时定义结构体变量
struct STUDENT
{
char name[]; //名字
int age; //年龄
char sex; //性别
int num; //学号
char add[]; //家庭住址
float score; //分数
}stud;
声明了一个结构体类型(struct STUDENT),并用这个类型定义了一个结构体变量stud。
注:结构体变量不能相加、不能相减、不能相乘、不能相除。但结构体变量可以相互赋值,可以将一个结构体变量赋值给另一个结构体变量,前提是这两个结构体变量的结构体类型必须相同。
1.3 结构体变量的引用
由于结构体变量中有多个不同类型的成员,所以结构体变量成员不能整体引用,只能一个成员一个成员的引用。
1)引用方式:
结构体变量名.成员名
2)可以引用"结构体变量成员"的地址,也可以引用"结构体变量的"地址
&stud1.name //stud1.name成员在内存中的首地址
&stud1 //stud1在内存中的首地址
结构体变量的首地址,就是结构体第一个成员的首地址。&stud1等价于第一个成员name的首地址,而name是一个数组,数组名表示数组的首地址,所以&stud1与stud1.name是等价的。等价仅仅指的是它们表示"同一个内存空间的地址"但它们的类型是不同的,&stud1是结构体变量地址,是struct STUDENT*型的,而stud1.name是数组名,是char*型的,类型不同所以在程序中不能互换。
2 结构体字节对齐
2.1 例一
#include <stdio.h>
struct DATA
{
int m;
char n;
}DATA; int main()
{
printf("%p,%p\n",&DATA.m,&DATA.n);
printf("%d\n",sizeof(DATA));
} /***********************************
输出:
001A7560,001A7564
8
************************************/
我们看到DATA不是占5字节,而是占8字节。变量m的地址是从001A7560到001A7563占4字节;变量n的地址是从001A7564到 001A7567,也占4字节。m占4字节我们能理解,但n是char型,char型不是占1字节吗,这里为什么占4字节?其实不是它占了4字节,它占的还是1字节,只不过结构体中有一个字节对齐的概念。
字节对齐:结构体是一种构造数据类型,里面可以有不同数据类型的成员。这些成员中,不同数据类型所占的内存空间不同。通过例子可以看出结构体变量成员分配内存不是顺序存储,而是按字节对齐的方式存储。即结构体成员中占内存最多的数据类型所占的字节数为标准,所有成员在分配内存是都要与这个长度对齐。
m | |||
n | 空 | 空 | 空 |
所谓的空并不是里面什么都没有,它就同定义了一个变量没有初始化一样,里面是一个很小的负的填充字,在此只是为了便于表达。
2.2 例二
#include <stdio.h>
struct DATA
{
int m;
char n;
char i;
}DATA; int main()
{
printf("%p,%p,&p\n",&DATA.m,&DATA.n,&DATA.i);
printf("%d\n",sizeof(DATA));
} /***********************************
输出:
001A7560,001A7564,001A7565
8
************************************/
m | |||
n | i | 空 | 空 |
3 结构体数组
结构体数组的每一个元素都是一个结构体类型的变量,都包含结构体中的所有成员。
1)定义结构体数组(同定义结构体变量一样,只不过将变量改为数组)
struct STUDENT stud[];//定义了一个结构体数组,里面包含5个元素,每个元素都是一个结构体变量,包含结构体所有成员 for(i=;i<;i++)
{
printf("%s%d %c%d",stud[i].name,stud[i].age,sutd[i].sex,stud[i].num);
}
结构体数组的引用与引用一个结构体变量在原理上是一样的。只不过结构体数组中有多个结构体变量,只需利用for循 环一个一个地使用结构体数组中的元素。
4 结构体指针
4.1 指向结构体变量的指针
指向什么结构体类型的结构体变量,就要定义成什么样的结构体类型。比如指向 struct STUDENT 类型的结构体变量,那么指针变量就一定要定义成 struct STUDENT* 类型。
struct STUDENT *p //定义一个结构体指针变量
(*p).name //
指针引用结构体变量成员方式:
(*指针变量名).结构体成员名 或者 指针变量名->结构体成员名
注:只有指针变量名后面才能加"->"
4.2 指向结构体数组的指针
结构体数组的每一个元素都是一个结构体变量。如果定义一个结构体指针变量并把结构体数组的数组名赋给这个指针变量的话,就意味着将结构体数组的第一个元素,即第一个结构体变量的地址,也即第一个结构变量中的第一个成员的地址赋给了这个指针变量。
5 结构体类型的定义
结构类型无法将自己的类型作为其成员的类型,因为自己的类型定义尚不完整,要在结束的大括号(})后才算定义完整。然而,结构类型可以包含指向自己类型的指针,这样的应用很常见。例如,在实现链表(linked list)和二叉树(binary tree)时,就会用到这种自引用结构(self-referential structure)。
struct Cell
{
struct Song song; // 这条记录的数据
struct Cell *pNext; // 指向下一条记录的指针
};
结构体(struct)的更多相关文章
- C语言结构体-struct
知识点: 1)结构体的定义. 2)结构体的sizeof. 3) 结构体的指针. 1) 结构体的定义: 在逻辑上有一定关联的多个数据类型做为一整体进行操作的数据结构,它的关键字是struct.下面我将 ...
- 内核中用于数据接收的结构体struct msghdr(转)
内核中用于数据接收的结构体struct msghdr(转) 我们从一个实际的数据包发送的例子入手,来看看其发送的具体流程,以及过程中涉及到的相关数据结构.在我们的虚拟机上发送icmp回显请求包,pin ...
- Swift中元组(Tuples),结构体(Struct),枚举(Enums)之间的区别
Swift有许多种存储数据方式,你可以用枚举(enums),元组(tuples),结构体(structs),类(classes),在这篇文章中我们将比较枚举.元组.结构体之间区别,首先从最简单的开始- ...
- C语言 - 结构体(struct)比特字段(:) 详细解释
结构体(struct)比特字段(:) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26722511 结构体(struc ...
- Go语言学习笔记(四)结构体struct & 接口Interface & 反射
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struc ...
- 结构体(struct)大小
结构体(struct)大小 本文参考链接:C语言结构体(struct)常见使用方法,链接中的实例代码经实践有几处不准确,本文在引用时已做更改 注意:在结构体定义时不能申请空间(除非是结构体变量),不可 ...
- 结构体struct sockaddr_in, struct sockaddr,struct in_addr
一.结构体 struct sockaddr_in, struct sockaddr, struct in_addr struct sockaddr_in, struct sockaddr,str ...
- GO开发[五]:golang结构体struct
Go结构体struct Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性 ...
- 结构体struct、联合体union、枚举类型enum
1.c语言中的类型 1)内置类型——char,short,int,float,double: 2)用户自定义类型(UDT)——struct结构体,union联合体,enum枚举类型 2.内存对齐 2. ...
- C++/C#:类Class与结构体Struct的区别
C++中: 默认的访问控制.继承访问权限不同:struct时public的,class时 private的: 其它基本一样. C#中: struct是值类型,class是引用类型的: struct S ...
随机推荐
- centos 安装python PIL模块
转载:https://www.cnblogs.com/ccdc/p/4069112.html 1.安装 使用yum安装缺少类库: #尤其重要,否则会报错 yum install python-deve ...
- 算法提高 新建Microsoft Word文档
算法提高 新建Microsoft Word文档 时间限制:1.0s 内存限制:256.0MB 问题描述 L正在出题,新建了一个word文档,想不好取什么名字,身旁一人惊问:“你出 ...
- 14 CSS题目附答案
转载自公众号:web前端开发 原文题目:45道CSS基础面试题(附答案) 1. 介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的? 标准盒子模型:宽度=内容的宽度(content) ...
- 【MySQL】锁——查看当前数据库锁请求的三种方法 20
MySQL提供了查看当前数据库锁请求的三种方法:1. show full processlist命令 观察state和info列 2. show engine innodb status\G ...
- 限时免费 | 12月6日,广州保利洲际酒店,ABC Summit 2018云智峰会来了!
随着科技的迅猛发展,人工智能技术也逐渐取得了各个突破.自20世纪70年代以来,作为计算机学科的一个分支,人工智能就被列为世界三大尖端技术之一.近年来,阿尔法狗战胜世界第一柯洁,使人工智能再度迎来新的热 ...
- centos7更改网卡名称
1.编辑/etc/sysconfig/grub文件,加入net.ifnames=0 biosdevname=0 2.执行命令grub2-mkconfig -o /boot/grub2/grub.cfg ...
- python摸爬滚打之day20--多继承,MRO和C3算法
1.新式类和经典类 在python2.2之前, 基类如果不写(), 则表示为经典类; 在python2.2之后, 经典类不复存在, 只存在新式类. 如果基类谁都不继承的话, 则默认继承object. ...
- etcd集群的搭建
由于最近在学习kubernetes,etcd作为kubernetes集群的主数据库,必须先启动. etcds实例名称 IP地址 Hostname etcd 1 192.168.142.161 kube ...
- input type = file 上传图片转为base64
项目背景是做图片识别,接口需要上传图片格式为base64格式的,react项目的相关代码: let reader = new FileReader();reader.readAsDataURL(e.t ...
- 使用JavaScript实现在页面上所有内容加载完之前一直显示loading...页面
Html <body class="is-loading"> <div class="curtain"> <div class=& ...