c++学习9 结构体
一 结构体赋值
结构体赋值的方法有三种,逐个成员赋值,整体赋值和拷贝赋值。
设一个结构体有struck student{ int age;char ch[32]; };
逐个成员赋值:student tony={16,"tony"};
整体赋值:student lucy;lucy=tony。//相同类型的结构体才可以这么做。
拷贝赋值:#include<string.h>;memcpy(&lucy,&tony,sizeof(student));
二 结构体数组
本质是数组,只是数组的每个元素为以结构体。
struck student{ int age;char ch[32]; };
student arr[5]={{12,"wbh"},{14,"lyq"},{16,"sh"},{18,"sb"},{19,"kk"}}.
三 结构体指针变量
结构体指针变量的本质是一个变量,只不过该变量保存的内容是结构体的地址。
结构体输出:cout<<结构体成员 . 数据类型<<endl;
指针输出:cout<<(*p).数据类型<<endl;cout<<p->数据类型<<endl;cout<<(&结构体成员)->数据类型<<endl;
四 结构体数组元素的指针变量
指针变量,保存结构体数组元素的地址。
通过指针变量,可以用->来访问结构体元素内容;
五 结构体的指针成员
浅拷贝和深拷贝的区别:
浅拷贝:就是直接带入相等,很死板的机械复制同一个维度空间的内容。
void test08()
{
student wbh;
wbh.age = 19;
wbh.name = new char[32];
strcpy(wbh.name, "wangbohan");
cout << "姓名:" << (&wbh)->name << endl << "年龄:" << (&wbh)->age;
student lyq;
lyq = wbh;//这就是浅拷贝。
delete[]lyq.name;//第一次释放new char[32];
delete[]wbh.name;//第二次释放new char[32],重复释放内存空间,这就是在有指针变量的前提下浅拷贝带来的缺点。
}
深拷贝:深拷贝可以避免浅拷贝里的内存空间重复释放的问题,解决方法也很直接,就是在第二个结构体里重新申请一个内存空间,然后利用strcpy()函数来拷贝内存空间内容。
1 void test08()
2 {
3 student wbh;
4 wbh.age = 19;
5 wbh.name = new char[32];
6 strcpy(wbh.name, "wangbohan");
7 cout << "姓名:" << (&wbh)->name << endl << "年龄:" << (&wbh)->age;
8 student lyq;
9 lyq = wbh;//这就是浅拷贝。
10 delete[]lyq.name;//第一次释放new char[32];
11 delete[]wbh.name;//第二次释放new char[32],重复释放内存空间,这就是在有指针变量的前提下浅拷贝带来的缺点。
12 student ljj;
13 ljj.age = 26;
14 ljj.name = new char[32];//ljj这个指针成员,我们专门为了她重新申请了一个堆区内存空间。
15 strcpy(ljj.name, wbh.name);//所以我们没有直接用等号赋值法,而是运用了函数strcpy()来赋值。
16 delete[]ljj.name;//释放 另 一 个 内存空间,而不是重复调用导致的反复释放。
17 }
六 结构体变量在堆区,结构体的指针成员也指向堆区
其实就是把结构体本身存储在文字常量区里,然后通过指针去申请内存空间,把结构体这个变量本身放在堆区里。
废话不多说,上代码:
1 void test09()
2 {
3 student* p;//结构体在指针。
4 p = new student;//在堆区里申请一个结构体的空间,注意哦!必须要前后结构实体一致,不然会分配失败
5 //错误示范:
6 //p = new massage;
7 p->name = new char[32];
8 strcpy(p->name, "wangbohan");
9 }
七 结构体的对齐规则
结构体有一个自己的、默认的对齐规则,用来提高读取速率和处理速度的,但是会浪费空间。
(也就是典型的用空间换取时间的例子)
ps:上图中“CPU一次性提取4字节”是一个假设。
自动对齐规则:
1.确定分配单位(一行分配多少字节)由结构体中最大的基本类型的长度决定;
2.确定成员的偏移量——成员偏移量==成员自身类型的整数倍;
3.收尾工作——结构体的总大小==分配单位的整数倍。
强制对齐规则:
#pragma pack(value) 时指定对齐值为value。value的值分为:1,2,4,8,16。
1.确定分配单位(一行分配多少字节)
分配单位=min(结构体中最大的基本类型,value);
2.确定成员的偏移量
成员偏移量==成员自身类型的整数倍;
3.收尾工作:结构体的总大小==value的整数倍。
八 结构体的位域
在结构体中,以位为单位的成员,称之为位域。
本来应该是至少三个字节的,压缩后测量sizeof只有一个字节,这就是字节位域的压缩(a占2个,b占2个,c占4个,正好8bite一个字节)。
以及不能对位域取地址。为什么呢?因为地址是相对于字节来说的,你一个位域都成二进制了,哪还有地址可言?所以一取地址就报错了。
1 struct op
2 {
3 unsigned char a : 2;
4 unsigned char b : 2;
5 unsigned char c : 4;//这些总共就一个字节,8bite内容
6 };
7 void test10()
8 {
9 op sd;
10 sd.a = 5;//0101,但是只有后两个二进制,从右往左读取,只读取到01。
11 cout << (int)(sd.a) << endl;//结果是1,乐了
12
13 }
另起一个存储单元:来一点小小的位操作震撼
无意义位段:我占了,但是我不给你用
运用案例:
九 共用体union
共用体和结构体的区别:
结构体的每一个成员都分配单独的空间;而共用体的所有成员都在同一空间内,对某一成员操作就是对整个空间操作。
1 union gyt
2 {
3 int a;
4 int b;
5 int c;
6 };
7 void test11()
8 {
9 gyt cc;
10 cc.a = 10;
11 cc.b = 20;
12 cc.c = 30;
13 cout << cc.a + cc.b + cc.c << endl;//结果是30+30+30=90,对我们的认知来说应该是10+20+30才对。
14 }
个人理解:共用体之所以是可以一起操作是因为他们的空间是彼此覆盖的,大的数据类型覆盖了小的数据空间(相当于他们的所占空间叠在一起了)那么大改小好理解,小改大是什么原因呢?我的推测是因为小的在大的空间里面,如果小的改了大的不改,那么就会造成读取大空间的数据变量时发现里面牛头不对马嘴的情况,所以大的也一起改变了。
十 枚举enum
1 enum pocker_color {heitao,hongtao,fangkuai,meihua};
2 void test12()
3 {
4 pocker_color op = meihua;
5 cout << op << endl;//结果是0,枚举的数据开头都是从0开始排序的。
6 //如果需要修改枚举值,应该去把pocker_color的里面的值去重新用“=”来关联起来
7 //enum pocker_color {heitao=10,hongtao,fangkuai,meihua}这种
8 }
Tips:
1.指针变量只有8B,所以它只存地址,而正因为如此,内容物都存放在文字常量区(无法直接操作,只能读不能写),所以我们要在堆区申请一个new的空间,将内容放进去以便于操作。
c++学习9 结构体的更多相关文章
- C语言学习之结构体
前言 一直以来,C语言的学习都在入门阶段,只用到数组.函数.循环.选择.位运算这些基本的知识,较少用到指针.预处理.结构体.枚举类型.文件操作等这些C语言的精髓内容,现在想想真不敢说自己熟练掌握C语言 ...
- c语言学习笔记 - 结构体位域
在学习结构体的时候遇到了位域这个概念,位域主要是为了节省内存空间,比如用一个32位,4个字节的int存储一个开关变量时,会造成空间浪费,于是干脆就考虑在这个32划分不同的区域来存储数据,例如划出1位存 ...
- C语言学习1——结构体剖析
一、定义结构体变量的方法 1.1先声明结构体类型在定义变量名 例如: a.声明结构体类型 struct student { int num; char name[20]; char sex; int ...
- C语言学习笔记--结构体
结构体定义三种方式: #include<stdio.h> //第一种定义方法 struct point { int x; int y; }; struct point p1,p2; //第 ...
- C学习之结构体
结构体(struct) 结构体是由基本数据类型构成的.并用一个标识符来命名的各种变量的组合,结构体中可以使用不同的数据类型. 1. 结构体说明和结构体变量定义 在Turbo C中, 结构体也是一种数据 ...
- SNMP学习之结构体snmp_secmod_def
此结构体中定义了各个回调函数,在函数init_ksm(E:\code\net-snmp-5.4.2.1\snmplib)中进行了初始化. void init_ksm(void) { struct sn ...
- 【CUDA学习】结构体指针复制
内核函数中要用data结构作用参数 typedef struct { int* value; int* num; } data; //host端 data* h_input; h_input=(dat ...
- go学习笔记-结构体
结构体 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 定义 格式 type struct_variable_type struct { member definition; member ...
- iOS开发-Object-C学习之结构体使用
前言:定义结构体并不是定义一个变量,而是定义了种数据类型. 结构体作用: 结构体和其他类型基础数据类型一样,例如int类型,char类型 只不过结构体可以做成你想要的数据类型.以方便日后的使用. 在实 ...
- libevent源码学习_event结构体
在libevent中最重要的结构体莫过于event和event_base了,下面对于这2个结构体进行分析. 1.结构体event,位于:event.h struct event { /* * 双向链表 ...
随机推荐
- 超棒的良心工具-OCR工具集
使用平台:Windows 虽然是OCR工具,但多了一个"集"字,原因在于该软件内置了搜狗网络OCR.本地离线OCR,不用key,还原天若OCR操作. 一句话:免去申请注册key登录 ...
- 直播平台制作,Android 悬浮窗延时5秒返回APP问题
直播平台制作,Android 悬浮窗延时5秒返回APP问题 案例需求分析:在APP界面,点击Home键后,APP退出后台,同时会打开一个悬浮窗,当用户点击悬浮窗上的按键会返回APP. 出现的问题是:点 ...
- VC如何创建C编译器能使用的动态库
方法 使用extern "C"修饰 设置统一的调用约定 举例 例1--使用__cdecl,一般C编译器使用此约定,如LabWidnows/CVI. cpp代码 extern &qu ...
- windows远程桌面之前用于连接到xxx的凭据无法工作
使用windows远程桌面连接时报错提示: 之前用于连接到xxx的凭据无法工作 确认输入的用户名密码没有问题 解决方法: 打开gpedit.msc组策略管理,依次找到 计算机配置 > windo ...
- 配置Centos8网络绑定
配置Centos8网络绑定 原理: 在物理网卡两块之上创建一块虚拟主卡, 逻辑上是一主双从, 按不同的模式负载运行,常用模式如主备或并行提供双倍带宽等.模式: 可选参数"mode=act ...
- atx
https://github.com/openatx/atx-agent/releases/download/0.9.4/atx-agent_0.9.4_linux_386.tar.gz
- office365启动突然提示注册表错误,无法打开“规则”配置的解决方案
感觉目前网上的资料,暂无清晰的解答,根据现象分析是outlook的原始邮件文件即psd文件中的规则相关字段存在问题,导致outlook无法打开. 因此网上的各种答疑如重装,调整注册表等等措施都是无效的 ...
- C# 调用c库
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runti ...
- Day21 21.2:CrawlSpider-redis分布式爬虫
CrawlSpider-redis分布式 分布式在日常开发中并不常用,只是一个噱头! 概念: 可以使用多台电脑搭建一个分布式机群,使得多台对电脑可以对同一个网站的数据进行联合且分布的数据爬取. 声明: ...
- 项目启动报错:关于modals以及node版本相关
programme1: 1.代码用master分支的. 2. 删除node_module , yarn lock 文件,package-lock文件. 3. 用 npm install 或者 yar ...