一.结构体

struct  Test
{int a;int b;int c;
};

关键字 struct  ,表示其是一个结构体,后面是一个可选的标记(Test)

strcut Test Code

strcut Test 的作用类似于 int 或float的 声明。

a.在定义之后跟变量名,声明结构的过程和定义结构变量的过程可以使用合并成一步

struct  Test
{int a;int b;int c;
}Code;

b.不使用标记Tag, 直接写变量名

struct
{int a;int b;int c;
}Code;

如果想多次使用一个结构模板,就需要使用带有标记的形式或者使用typedef

二.typedef 的作用

1.typedef的使用

typedef struct Simple
{int a;int b;int c;
}simple;

可以使用 simple  代替 struct Simple

//举例 用typedef 声明 初始化
typedef struct
{int a;int b;int c;
}complex;complex test = {2,4,7};

2.结构体的初始化

    struct Person  {  char *name;  int age;  double heigth;  };  

(1)定义的同时初始化

   struct Person p1 = {"luban7hao",3,100};  

(2)先定义再逐个初始化

    struct Person p2;  p2.name = "luban8hao";  p2.age = 4;  p2.heigth = 101;  

(3)定义后全部初始化

    struct Person p3;  p3 = (struct Person){"luban9hap",5,102};  

注意:

结构体和数组在这里的区别,数组不能先定义再进行一次性初始化

结构体要明确的告诉系统{}中是一个结构体

(4)将数据赋给指定的属性

 struct Person p4 = {.heigth=104, .name="luban10ha0", .age=6};  

3.结构体数组

(1)声明

struct book library[MAXBKS];

(2)示例

#include <stdio.h>#define MAXTITL 40
#define MAXAUTL 30
#define MAXBKS  100 /*最多书籍的册数*/struct book
{char title[MAXTITL];char author[MAXAUTL];float value;
};int main(int argc, char const *argv[])
{struct book library[MAXBKS]; /*结构数组*/int count = 0;int index;printf("Please enter the book title.\n");printf("Press [enter] at the start of a line to stop.\n");while(count < MAXBKS && gets(library[count].title) != NULL && library[count].title[0] != '\0'){printf("Now enter the author.\n");gets(library[count].author);printf("Now enter the value.\n");scanf("%f", &library[count++].value);while(getchar() != '\n'){continue;}if (count < MAXBKS){printf("Enter the next title.\n");}}if (count > 0){printf("Here is the list of your books: \n");for (index = 0; index < count; index++){printf("%s by %s: $%.2f\n", library[index].title, library[index].author, library[index].value);}}else{printf("No books?Too bad.\n");}return 0;
}

4.结构体指针

(1)声明

struct guy *him; // 指向结构体的指针

(2)示例

#include <stdio.h>#define LEN 20struct names {char first[LEN];char last[LEN];
};struct guy {struct names handle;char favfood[LEN];char job[LEN];float income;
};int main(int argc, char const *argv[])
{struct guy fellows[2] = {   {{"Ewen", "Villard"},"grilled salmon","personality coach",58112.00},{{"Rodney", "Swillbelly"},"tripe","tabloid editor",2344422.00}};struct guy *him; // 指向结构体的指针printf("address #1: %p #2: %p\n", &fellows[0], &fellows[1]);him = &fellows[0];printf("pointer #1: %p #2: %p\n", him, him + 1);printf("him->income is $%.2f: (*him).income is $%.2f\n", him->income, (*him).income);printf("him->favfood is %s: him->handle.last is %s\n", him->favfood, him->handle.last);return 0;
}

5.访问结构体成员

访问成员,2种方式:

使用->,如him->favfood
使用(*him).income,注意必须用圆括号,因为.运算符比*的优先级更高

三.位段

1.定义与声明:

位段的声明与结构体类似,但是其成员是一个或者多个位的字段。这些不长度的字段实际上存储在一个或者多个的整形变量中。

2.位段的使用

struct Test
{unsigned int f1 :1; unsigned int f2 :1; unsigned int f3 :1; unsigned int type :4;unsigned int index :9;
};

我们定义了一个结构 Test

该结构定义了五个成员。

第一个成员叫做 f1, 是 unsigned int 类型的。 规定了它以 1 位存放。

成员f2 和 f3 被定义为长度只有 1 位的。定义成员 type 占有 4 位。定义成员 index 占有 9 位。

C 编译器自动地把上面的位段定义压缩在一起。位段的划分如图所示。Test总共使用了 16 位。

这种方法的好处是, 定义成 Test类型的变量的位段, 可以如引用一般的结构成员一样方便地引用。同时, 使用了更少的内存单元数。

3.特殊情况

在包含位段的结构中, 也可以包括 "通常的" 数据类型。因此, 如果我们想定义一个结构, 它包含一个 int, 一个 char, 和二个 1 位的标志:

 struct Test{int a;int b;unsigned f1:1;unsigned f2:1;};

当位段出现在结构体中,被压缩成一个字,如果某个位段无法放入一个字中,则该字的剩余部分不用,直接跳入下一个字中。

举例:利用位段和联合体 完成Float To Int 转换

//参考博客 https://blog.csdn.net/huai1693838234/article/details/44804459  用C++实现
//float型数据在计算机中以IEEE754标准存储  
//32位长度,1位实数符号位(原码表示),1位指数符号位,7位指数位(此八位为移码表示)以及23位数据位(补码表示)

union  Bit
{float val;//将要强转的值struct H{//由于机器是小端//小端简单地说 就是高地址存高位 低地址存低位 结构体成员是向高地址增长的//所以用如下方式获取unsigned int tail:23;//获取val的最后23位 即尾码unsigned int offset:8;//获取val的中间8位 即阶码+偏移量unsigned int flag:1;//获取val的第一位 即符号位}H;
};
//abs()函数:求绝对值(整数)
//exp()函数:e的次幂函数(以e为底的x次方值)  在另一种方法求float to int 会使用到,此次作业暂时不涉及。
int FloatToInt2(float val)
{if(abs(val) < 0.000001)//如果为0值 直接返回{return 0;}int res;//保存返回值Bit temp;temp.val = val;int offset = temp.H.offset - 127;//获得偏移量res = temp.H.tail;res |= 0x00800000;//将丢弃的1填充回来res = res >> (23-offset);//移位操作 舍弃小数点后的数字if(temp.H.flag == 1)//负数{res = -res;}return res;
}
int main()
{printf("%d\n",FloatToInt2(-12.7));getchar();return 0;
}

使用位段时, 必须注意下列事项:
1.在某些机器上, 位段总是作为 unsigned 处理, 而不管它们是否被说明成 unsigned 的。
2.大多数C 编译器都不支持超过一个字长的位段。
3.位段不可标明维数; 即, 不能说明位段数组, 例如 flag:l[2]。
4.最后, 不可以取位段地址。原因是, 在这种情况不, 显然没有称作为 "位段指针" 类型的变量。

四.联合体

联合的声明与结构体类似,但是联合的所有成员 引用的是内存中相同的位置

不同时刻把不同的东西存储在同一个位置时,可以使用联合。

union (联合体)
{}
sizeof(union)  //最大的一个元素的大小

五.枚举类型

enum abc { a,b,c,}
//如果给中间的值 例如:b 赋值 b=4 ,则再输出的时候只能给后面的值 c+1, 则c =5,而前面的a不能-1;
//就是一个常量和限制

六.关于内存对齐的使用规则

(1)前面的地址必须是后面的地址的整数倍,不是就补齐

(2)整个struct的长度必须是最长字节的正数倍!~~

(3)如程序中有#pragma pack(n)预编译指令,则所有成员对齐以n字节为准(即偏移量是n的整数倍),

不再考虑当前类型以及最大结构体内类型

注意:关于pragma pack(n)的使用

(1)n必须是已有的大小 ,如:1,2,4,8 等

(2)如果指定的大小>默认的大小,是以默认的为准

(3)如果指定的大小<默认的大小,以指定的为准

Mohican_4/22 结构体 typedef 枚举 联合 位段 内存对齐相关推荐

  1. C语言自定义类型的介绍(结构体,枚举,联合体,位段)

    ⭐️前面的话⭐️ 大家好!在C语言中,有个叫"自定义类型"玩意,它究竟是什么呢?其实,就是字面意思,可以自己定义的类型就是自定义类型.具体说就是我们熟知的结构体,枚举,位段,联合体 ...

  2. 结构体,枚举类型与联合体

    目录 ​编辑 一.结构体的基本使用 1.什么是结构体 2.结构体的一般声明 3.结构体的特殊声明 4.结构体的自引用 5.结构体变量的定义和初始化 二.结构体内存对齐 1.内存对齐规则 3.为什么会存 ...

  3. 自定义类型: 结构体,枚举,联合

       1.结构体    个人认为结构体和数组特别相似,只不过结构体和数组的区别在于结构体的成员可以是不同类型,而数组成员类型是相同的.    (1)结构体的声明 struct tag {成员列表//至 ...

  4. 关于结构体,枚举,联合的一些知识

    关于结构体,枚举,联合的一些知识 首先我们来看一下什么是结构体 通俗来说,结构体便是各种类型的集合. 接下来便是各处所代表的含义了 例如,我们现在来描述一个人. 其中name,age,sex,addr ...

  5. 一文道破 结构体,枚举,联合

    自定义类型:结构体,枚举,联合 结构体 结构体类型的声明 1. 结构的基础知识 2.特殊的声明 3.结构体的自引用 4.结构体的定义和初始化 5.结构体内存对齐 6.修改默认对齐数 7.结构体传参 位 ...

  6. 自定义类型:结构体,枚举,联合

    结构体: 描述一个学生: struct Stu {char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号 }://分号不能丢 特殊 ...

  7. 结构体、枚举类型和联合体

    文章目录 一:结构体的基本使用 1.什么是结构体 2.结构体的声明 (1):一般声明 (2):特殊声明 3.结构体的自引用 4.结构体变量的定义和初始化 二:结构体的内存对齐 1.内存对齐规则 2.练 ...

  8. SV学习笔记—结构体及枚举类型及字符串

    目录 1.结构体 1.1 压缩结构体 1.2 非压缩结构体 1.3联合结构体 2.枚举类型 3.字符串 1.结构体 Verilog的最大缺陷之一是没有数据结构,SV中可以使用struct语句创建结构, ...

  9. 液晶OCM12864,结构体,枚举,指针,规范化和模块化编程

    来自:http://www.eeworld.com.cn/mcu/2011/0804/article_4786.html 1.首先来看看枚举和结构体的使用吧 /******************** ...

最新文章

  1. 零基础入门--中文命名实体识别(BiLSTM+CRF模型,含代码)
  2. 微软收购社交监控分析公司Netbreeze
  3. ubuntu连有线网 无法连接外网
  4. 产品经理如何高效的做用户调研?
  5. 盘点十个超级实用的 JS 特性
  6. mysql json 创建索引_MySQL · 最佳实践 · 如何索引JSON字段
  7. Mysql 数据库水平分表 存储过程
  8. mysql2005本地连接_sql2005连接配置详细图解
  9. hive退出命令_从零开始学习大数据系列(五十五)使用Hive命令行及内置服务
  10. 2.2 BubbleSort
  11. 浙江利捷分析报告(0612)
  12. 高校/中职大数据实验室建设方案
  13. Unity UGUI坐标和世界坐标转化
  14. 计算机bios所以的英文翻译,bios界面翻译对照 主板BIOS界面全英文翻译介绍
  15. android 自动语音提醒,Android 语音播报实现方案
  16. linux系统编程实训总结,linux实训总结与体会
  17. PADS如何导入DXF文件
  18. js实现表格列的位置拖拽
  19. 引力波,你果真懂了吗?
  20. 计算机毕业设计之java+springcloud基于vue的智慧养老平台-老人信息管理-敬老院管理系统

热门文章

  1. Deity is on the struggling road too!
  2. python绘制地图的第三方库,geopandas,用python画地图原来这么简单!
  3. ie11兼容问题汇总及解决方案
  4. vue中播放flv流视频
  5. 微信小程序存在的风险_警惕,你的微信小程序可能面临着风险!
  6. 个推解读 | 各厂商推送消息分类新规出台,APP开发者必看
  7. 一些名片上最常用的中英文称呼:
  8. 开发简单Android聊天软件(1)
  9. 三个小故事让你一次记住双拼输入法口诀
  10. 机器学习 | 台大林轩田机器学习基石课程笔记12 --- Nonlinear Transformation