当前位置: 首页 > news >正文

宁波网站推广方式怎么样上海交通大学文科建设处网站

宁波网站推广方式怎么样,上海交通大学文科建设处网站,中国智慧城市建设门户网站,html代码在线萌新的学习笔记#xff0c;写错了恳请斧正。 目录 在定义结构体时起别名 匿名结构体 结构体的自引用 结构体的内存对齐 offsetof 内存对齐练习 为什么要内存对齐 平台原因 性能原因 书写规范 修改默认对齐数 结构体传参 位段#xff08;位域#xff09; 位段的…萌新的学习笔记写错了恳请斧正。 目录 在定义结构体时起别名 匿名结构体 结构体的自引用 结构体的内存对齐 offsetof 内存对齐练习 为什么要内存对齐 平台原因 性能原因 书写规范 修改默认对齐数 结构体传参 位段位域 位段的概念 位段的声明 位段的内存分配 位段的特殊声明 位段的跨平台性 位段注意事项 关于结构体的基本内容包括结构体的声明、创建、初始化、结构成员访问已经在笔记#15中讲述不再赘述。 在定义结构体时起别名 在定义结构体时前面直接加typedef进行起别名的操作不会影响结构体的创建。 typedef struct a {int a;float b;char c; } sta; 这就是定义了一个结构体类型struct a然后给它起别名为类型sta 但是这样就不能在定义结构体类型的时候直接创建结构体变量了 注意相关内容看下面 匿名结构体可以起别名这样就能正常使用了自引用同时起别名不能用别名自引用创建的优先顺序高于起别名 匿名结构体 结构体在声明时其实可以省略结构体标签名称。如下 struct {int a;float b;char c; } a; 这就是匿名的创建了一个结构体并声明了一个该类型的结构体变量。 注意在不起别名的情况下 匿名创建结构体如果没有直接声明几个对应的结构体变量之后就再也不能申请了。匿名创建结构体之后也再也无法找到这个结构体类型了。两个成员相同的匿名结构体不会被认为是同一种结构体比方说 struct {int a;float b;char c; } a;struct {int a;float b;char c; } b, *p; 在上面这种情况下如果令p等于a就是非法的因为两个匿名结构体类型不一样。 但是我们可以在创建匿名结构体的时候起别名这样就能通过别名正常使用结构体了 typedef struct {int a;float b;char c; } st; 比方说上面这段代码就能继续通过st这个类型名继续进行创建变量等操作 结构体的自引用 结构体可以自引用常用于链表以后讲 当然这不是说结构体的成员可以是该结构体本身 如果这样就无限套娃了大小无穷大 结构体的自引用指的是结构体的成员变量可以是该结构体的指针类型 比方说 struct chain {int data;struct chain* next; }; 如果起别名和自引用同时进行的话自引用的地方不能用别名 比方说这样是不行的 typedef struct chain {int data;st* next; } st; 应该写成这样这边顺便把指针起别名了 typedef struct chain {int data;struct chain* next; } st;typedef st* pst; 结构体的内存对齐 我们现在研究一下结构体的内存大小 结构体类型占内存的大小是不是等于所有成员变量占内存的和呢 我们写一段程序验证一下 #include stdio.hstruct S1 {char c1;int i;char c2; };int main() {printf(%d\n, sizeof(struct S1));return 0; } 这段代码在Win11 VS2022 x64 Debug的环境下输出12 而我们知道如果单纯的成员变量大小相加答案应该为6 所以结构体内存究竟是如何排布的呢 其实结构体在内存中的排布遵循内存对齐规则 1. 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处 2. 其他成员变量要对齐到某个数字对齐数的整数倍的地址处        对齐数 编译器默认的对齐数 与 该成员变量大小 的 较小值         VS2022 的默认对齐数为8Linux gcc没有默认对齐数 3. 结构体总大小为结构体成员中最大的对齐数的整数倍 4. 如果结构体嵌套了结构体嵌套的结构体成员对齐到自己成员中最大对齐数的整数倍处并且占据单独计算自身大小那么大的空间因为内存对齐浪费的空间不会被下一个成员利用。结构体总大小就是所有对齐数包括嵌套结构体中的成员中最大对齐数的整数倍 offsetof //定义于头文件 stddef.h #define offsetof(type, member) /*implementation-defined*/ 在stddef.h头文件中有一个宏offsetof可以返回一个成员在结构体中的偏移量 其第一个参数是结构体类型名第二个参数是成员变量名 其返回值可以用%zd、%zu接收 内存对齐练习 #include stdio.hstruct S1 {char c1;int i;char c2; };struct S2 {char c1;char c2;int i; };struct S3 {double d;char c;char i; };struct S4 {char c1;struct S3 s3;char d; };int main() {printf(%d\n, sizeof(struct S1));printf(%d\n, sizeof(struct S2));printf(%d\n, sizeof(struct S3));printf(%d\n, sizeof(struct S4));return 0; } 在Win11 VS2022 x64 Debug的环境下4段输出为12、8、16、32 为什么要内存对齐 其实这是一种空间换时间的做法 平台原因 不是所有的硬件平台都能访问任意地址上的任意数据某些平台只能在某些地址处对齐的位置取对应类型的数据否则硬件异常。 性能原因 内存对齐的情况下访问速度一般会更快 访问未对齐内存的数据处理器可能需要作两次内存访问内存是一段一段访问的数据不对齐可能存放在两个内存的访问段内而对齐的内存访问仅需要一次访问 书写规范 所以为了节省空间我们创建结构体应该尽量使较小的成员变量在前面较大的放在后面 修改默认对齐数 我们可以使用预处理指令#pragma来修改编译器默认的对齐数 #include stdio.h#pragma pack(1) //设置默认对⻬数为1struct S {char c1;int i;char c2; };#pragma pack() //取消设置的对⻬数还原为默认int main() {printf(%d\n, sizeof(struct S));return 0; } 上面这段代码的输出结果就为6 结构体传参 与其他数据类型类似结构体传参也分为直接传参与传地址两种 #include stdio.hstruct S {int data[3];int num; } s { {1,2,3}, 1000 };void print1(struct S s) {printf(%d\n, s.num); }void print2(struct S* ps) {printf(%d\n, ps-num); }int main() {print1(s); //传结构体print2(s); //传地址return 0; } 两种方式作用相同但是我们优先使用传地址的方式 因为函数传参时需要拷贝实参作为形参压栈如果传递结构体本身会占用较多的内存 位段位域 位段的概念 位段是一种特殊的结构体类型其成员的内存宽度可以被我们规定 位段成员必须是int、signed、unsigned之间的一种C99以前 C99标准开始位段成员也可以使用布尔类型 位段的声明 位段的声明与结构体类似但是成员名可以省略代表直接浪费一段空间后有一个冒号和数字 #include stdio.hstruct A {int _a : 2;signed _b : 5;unsigned _c : 10;int _d : 30; };int main() {printf(%d\n, sizeof(struct A));return 0; } 这段程序在Win11 VS2022 x64 Debug的环境下的输出结果为8 为什么呢这与位段的内存分配有关 位段的内存分配 位段声明中冒号后面的数字就代表了其被规定占据多少个比特位 而整个位段总大小是按4个字节int类或者1个字节_Bool逐步分配的 上述代码中位段A内存申请了一次4个字节32位。这32位填充了_a、_b、_c后只剩下15位了发现不够继续填充_d就再次申请了4个字节用来填充数据_d所以总共占据了8个字节。 位段的特殊声明 相邻的几段如果类型占据的空间大小一致可以打包起来写在一起通常可以比方说 struct B {int _a : 2, _b : 5, _c : 10;int _d : 30; }; //宽8 规定空间可以省略代表占据一整个类型的空间比方说 struct B {int _a : 2, _b : 5, _c : 10;int _d; }; //宽8 这里_d就占据了整个4字节32位的空间 成员名可以省略用来占据一定不被使用的空间 struct C {unsigned _a : 2;signed _b : 5;int _c : 30, _d : 1, _e : 3;int _f : 3, :2, _g : 4; }; //宽12 这里_f和_g直接有两个比特是被占位的 如果宽度规定为0即零位域必须未命名代表直接开始下一个分配单元这边剩下来的丢掉 struct D {unsigned _a : 2, :0;signed _b : 5, :0;int _c : 30, _d : 1, _e : 3;int _f : 3, : 2, _g : 4; }; //宽16 位段的跨平台性 位段跨平台性很差原因如下 int位段被当做有符号还是无符号是不确定的机器的位数不一样导致类型宽度不一样位段在每个分配单元中数据从左往右填还是从右往左填不确定还有很多其他原因 所以虽然位段很省空间没事还是不要用位段 位段注意事项 位段不能取地址不能有指针变量会报错 因为位段的成员的起始位置可以不在整字节处没有地址
http://www.pierceye.com/news/675634/

相关文章:

  • 营销型网站网站设计免费域名注册 国外
  • 杭州网站制作公司网站厦门网站建设 首选猴子网络
  • 公司如何建站合肥网站设计
  • wordpress单页导出wordpress head 优化
  • 建筑模版东莞网站建设技术支持北京网页制作服务商
  • 网站html地图怎么做的wordpress 国内视频网站
  • 哪个网站做的简历比较好龙岗做网站公司icxun
  • 海外网站开发网站打开慢怎么回事
  • 外贸导向企业网站搜索引擎大全排名
  • 网站域名怎么做变更企业查询系统
  • 12306网站多少钱做的怎么研发软件app
  • 手机端建站井冈山保育院网站建设
  • 服装设计网站怎么做wordpress网站商务通
  • 重庆建设医院官方网站医疗网站源码
  • 大学生想做网站天元建设集团有限公司商业承兑汇票拒付最新消息
  • 怎么区分营销型网站文章类型的网站模版
  • 网站充值接口怎么做国家企业官网查询系统
  • 厦门网站建设工程网站备案幕布大小
  • 做家教去什么网站滕州做网站哪家好
  • 深圳市涂能装饰设计公司网站网站建设活动策划方案
  • 建设三合一网站找设计公司上哪个网站
  • 代理ip做网站流量饭店网站模板
  • 保险网站查询软件开发工程师和程序员的区别
  • 江都区城乡建设局网站马局下载app下载安卓免费
  • 网站做后台kuler 网站
  • 北京建网站公司飞沐扬中信息网
  • 商河网站建设公司南县网站建设推荐
  • 湛江企业网站建站模板网站开发 平台
  • c做的网站app开发制作专业吗
  • 杭州做网站公司做网站的文章