IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 从C语言基础到高级C语言 (结构体和位域) -> 正文阅读

[C++知识库]从C语言基础到高级C语言 (结构体和位域)

结构体

1、概念

自己定义的类型

2、姿势

1、struct{结构成员;结构成员;};

例如:

struct{
int len;
int h;
int w;
};

struct{
int len;
int h;
int w;
} xx;

xx.len = 20;
xx.h = 160;
xx.w = 160;

2、truct 结构标记{结构成员;结构成员;};

*结构标记 结构成员 及变量名字可以相同

例如

struct x{int x;}; struct x x; ---> 没有问题

struct x{int x;} xx;

struct x xx; //等同于上面

3、定义

1、struct{成员;成员;} x,y,z;

2、struct 结构标记{结构成员;结构成员;}x,y,z;

4、赋值

例如:

struct point{
int x;
int y;
};
struct point sp;
sp.x = 10; //结构体变量,用点(.)去获取成员
sp.y = 20;
struct point *psp = (struct point *)malloc(sizeof(struct point));
psp->x = 10; //结构体指针变量,用->去获取成员
psp->y = 20;

看例子

#include <stdio.h>
#include <string.h>

int main(void)
{
	struct{
		char name[20];
		char addr[50];
		int h;
		int w;
		int xw;
		int yw;
		int tw;
	} mm;
	strcpy(mm.name,"Ricci");
	strcpy(mm.addr,"xxx");
	mm.h = 159;
	mm.w = 180;
	mm.xw = 36;
	mm.yw = 60;
	mm.tw = 60;
	
	printf("%s\n",mm.name);
	
	return 0;
}

/**
  ***********
  *  运行结果
  *  Ricci
  **********
  */

5、初始化

struct{成员;成员;} x = {成员值,成员值};

struct 结构标记 x = {成员值,成员值};

例如:

struct point{int x;int y};

struct point x = {10,20};

看例子

#include <stdio.h>
#include <string.h>

struct mm{
	char name[20];
	char addr[50];
	int h;
	int w;
	int xw;
	int yw;
	int tw;
};

int main(void)
{
	struct mm sm;
	strcpy(sm.name,"Ricci");
	strcpy(sm.addr,"xxx");
	sm.h = 159;
	sm.w = 180;
	sm.xw = 36;
	sm.yw = 60;
	sm.tw = 60;

	printf("%s\n",sm.name);
	
	struct mm *psm = &sm;
	printf("%s\n",psm->addr);
	
	struct mm smm = {"xx","hqyj",170,150,10,10,10};
	printf("%s\n",smm.name);
	printf("%s\n",(&smm)->addr);
	
	return 0;
}

/**
  ***********
  *  运行结果
  *  Ricci
  *  xxx
  *  xx
  *  hqyj
  **********
  */

6、取别名

typedef struct{成员;成员;} 别名;

typedef struct 结构标记{结构成员;结构成员;} 别名;

例如:

typedef struct point sp_t;

sp_t xx = {10,20};

7、使用

struct point{int x;int y};
main{
struct point sp; // int a;
sp.x = 10; //结构体变量,用点(.)去获取成员
sp.y = 20

struct point *psp = (struct point *)malloc(sizeof(struct point));
psp->x = 10; //结构体指针变量,用->去获取成员
psp->y = 20;
}

8、结构体算字节数

1、32位操作系统最大按照4字节对其

2、64位操作系统最大按照8字节对其

3、每个数据成员存储的起始位置是自身大小的整数倍

4、结构体总大小(也就是sizeof的结果),必须是该结构体成员中最大的对齐模数的整数倍

例子:在32操作系统中

struct xx{
char sx[23];
int sex; //0 1
double d;
short b;
char xs[21];
int *p;
char c;
short s;
int xx;
}; ---> 72

9、手动修改结构体的对其方式

#pragma pack(n) n为 2的次方数 1 2 4 8 16 32

#include <stdio.h>
#pragma pack(4)

struct person{
	char name[18];
	int sex;
	int age;
	char wh[20];
	char *hobby[20];
	float sc;
};

int main(void)
{
	printf("%lu\n",sizeof(struct person));
	
	struct person sp;
	printf("%d\n",(int)((char *)&sp.sex-(char *)&sp));
	
	return 0;
}

/**
  ***********
  *  运行结果
  *  212
  *  20
  **********
  */

位域

1、概念

带有预定宽度的变量称为位域

2、姿势

struct 标签{
位域类型 位域变量名:位域宽度;
位域类型 位域变量名:位域宽度;
};

例子:

struct xx{
int a:2; //占2位 00 01 10 11
unsigned b:4; //占4个位
};

3、位域类型

位域类型为整型,例:char、short、int 、unsigned int(简写为unsigned)

4、位域宽度

1、不能超过该类型的的大小

例子:int a:33 //错误

2、赋值时不能超过该类型的承受范围

例子:

unsigned char a:2 // 00 01 10 11那么a只能存 0 1 2 3这几个数字

a = 5; //错误

5、位域对齐

位域类似结构体,按照最大类型对齐,但是Linux中类型与类型之间挨着

6、空域

位域宽度为0的位域称为空域,其作用是:该次对齐空间剩余部分全部补0

例子:?

struct xx{
int b:1 ;
int :0 ; // 32位对齐,所以该处共有31个0
int c:3 ; // 新的对齐行
}

7、无名位域

位域没有名字,仅仅占用空间,无名位域不能调用,其作用是隔开两个位域

例子:

struct xx{
unsigned a:2
unsigned: 3 //无名位域,将a和c隔开3个位,该3个位不能使用
unsigned c:2
}

8、位域大小计算(存储规则)

1、如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止

2、如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍

3、如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++,GCC采取压缩方式

4、如果位域字段之间穿插着非位域字段,则不进行压缩

9、使用的测试

#include <stdio.h>
#include <string.h>

//无名位域
struct xx{
	int a:5;
	int :3;
	int c:4;
};

int main(void)
{
	printf("%lu\n",sizeof(struct xx));
	
	struct xx sx;
	bzero(&sx,4);
	sx.a = 0x1a;    
	//sx.b = 0xa;
	sx.c = 0xb;
	
	printf("%#hhx\n",*((unsigned char *)&sx+0));  //
	printf("%#hhx\n",*((unsigned char *)&sx+1));  //
	printf("%#hhx\n",*((unsigned char *)&sx+2));  //
	printf("%#hhx\n",*((unsigned char *)&sx+3));  //
//	printf("%#hhx\n",*((unsigned char *)&sx+4));  //
	
	return 0;
}

/**
  ***********
  *  运行结果
  *  4
  *  1x1a
  *  0xb
  *  0
  *  0
  **********
  */

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:08:17  更:2022-09-21 00:09:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 14:52:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码