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

网站开发工作周记求职网站

网站开发工作周记,求职网站,广州的百度推广公司,新企业在哪里做网站好自定义类型 其实C语言有内置类型 也有自定义的类型 内置类型#xff08;C语言本身支持的现成的类型#xff09; 如#xff1a;char short int long float double.... 但仅仅有这些类型是不够的 比如说 我们想表示一个人#xff08;复杂对象#xff09; 对于人的描述那…自定义类型 其实C语言有内置类型 也有自定义的类型 内置类型C语言本身支持的现成的类型 如char short int long float double.... 但仅仅有这些类型是不够的 比如说 我们想表示一个人复杂对象 对于人的描述那就很多了 比如性别 年龄 身高........ 所以C语言就有了自定义类型 自定义类型结构体  其实我们之前有说过结构体的一些知识点 现在我们再进行复习一遍 以加深印象 结构体回顾 结构是⼀些值的集合这些值称为成员变量。结构的每个成员可以是不同类型的变量。 结构体类型的声明 例如描述一个学生 我们这里定义了一个struct Stu的结构体类型 它的成员变量有三个 字符数组name 整形变量age 字符数组gender 注意最后的分号不能丢 结构体变量的创建和初始化 结构的特殊声明 在声明结构的时候可以不完全的声明。 ⽐如匿名结构体类型 这里我们在声明的时候 省略掉了结构体标签 即struct后面为空 正常是struct x   x为结构体标签 如何在上述代码的基础上 我们让 px; 警告 编译器会把上面的两个声明当成完全不同的两个类型 所以是非法的 匿名的结构体类型 如果没有对结构体类型重命名的话typedef 基本上只能使用一次 我们给匿名结构体类型重命名为X  然后定义了一个名为i的结构体变量 结构的⾃引⽤  在讲之前 我们还得先讲一下数据结构中的链表 当然  还是希望大家自行去搜索 因为这里我只能讲个大概 数据结构--其实是数据在内存中的存储和组织各个数据之间的关系的结构 那我们开始讲链表了 这里我们讲下链表 假设要在内存中存储1 2 3 4 5 我们当然可以用数组来存储连续空间---在数据结构也称为顺序表 但我们的链表可不是连续的哦 是靠各个结点存储数值和下一结点的地址连接起来 当然我们也需要有一个头结点来找到我们存储的数据 在最后一个结点存放地址的位置 我们置为空 说明之后无结点了 我们只要找到1就可以找到其余数 每个结点分成两部分data域存储数值   指针域存储下一结点的地址 指针域使得当前结点可以指向下一结点 在结构体中包含⼀个类型为该结构本⾝的成员是否可以呢 ⽐如定义⼀个链表的结点 上述代码正确吗如果正确那 sizeof(struct Node) 是多少 仔细分析其实是不⾏的因为⼀个结构体中再包含⼀个同类型的结构体变量这样结构体变量的⼤ ⼩就会⽆穷的⼤是不合理的。想象成套娃一样 正确的⾃引⽤⽅式 我们让next成为一个指针 指向下一个结构体的地址 这样就可以实现结构体间的连接 在结构体⾃引⽤使⽤的过程中夹杂了 typedef 对匿名结构体类型重命名也容易引⼊问题看看 下⾯的代码可⾏吗 答案是不行的 这里的struct Node* next中的struct Node此时还不能省 我们是先定义结构体类型 再重命名 不能在定义结构体类型的时候 直接使用重命名后的名字 当然匿名的结构体类型是不能实现这种结构体自引用的效果的 正确形式应该为 用typedef给结构体类型struct Node)重命名为Node 当然下面代码也能实现重命名 结构体内存对⻬ 我们已经掌握了结构体的基本使⽤了。 现在我们深⼊讨论⼀个问题计算结构体的⼤⼩。 这也是⼀个特别热⻔的考点 结构体内存对⻬ 那我们先上一段代码来看看你是否能计算出来结构体大小 我刚开始看到这题的时候 我给出的答案是4  我当时认为结构体变量s初始化为数字0 以为这个0会赋给i  又因为i为int类型 所以得出结果为4 但是答案为12 对齐规则 ⾸先得掌握结构体的对⻬规则 1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处 //这里就意味着我们的c1存放在偏移量为0的地址处 2.其他成员变量要对⻬到某个数字对⻬数的整数倍的地址处。 //这里我们的i就从偏移量为4的地址起始向下取4个字节4--7 //我们的c2的对齐数为1  8是1的倍数 所以我们的c2存在偏移量为8的地址处 对⻬数 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。 VS 中默认的值为 8 //这里i的大小为4字节  所以这里我们i的对齐数为448) 注意Linux中 gcc 没有默认对⻬数对⻬数就是成员⾃⾝的⼤⼩ 3. 结构体总⼤⼩为最⼤对⻬数结构体中每个成员变量都有⼀个对⻬数所有对⻬数中最⼤的的 整数倍。 //我们本题的最大对齐数为4  结构体的总大小为最大对齐数的整数倍 //结构体的总大小9 10 11都不是4的整数倍 12是4的倍数 所以本题输出的是12偏移量为0-11 x表示空间被浪费了 不存放数据 4. 如果嵌套了结构体的情况嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处结构体的整体⼤⼩就是所有最⼤对⻬数含嵌套结构体中成员的对⻬数的整数倍。 练习1 c1 c2分别放在偏移量为0 1的地址处 因为i的最大对齐数为4在VS中 默认为8  这里48) 所以i占据偏移量为4--7的空间 结构体的总大小为4的倍数 刚好8是4的倍数 所以答案为8 练习2 double类型占8个字节--最大对齐数 所以其占据偏移量0-7的地址 c放在偏移量为8的地址处 i的对齐数为4 找到一个4的倍数 即为12  所以偏移量12-15的地址处存放i 16是最大对齐数8的倍数 所以16是最终结果 练习3 嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处 所以我们嵌套的s3最大对齐数为8从偏移量为8的位置向后占据16个字节 然后变量d的对齐数为8  刚好24是8的倍数  d便占据偏移量24-31的地址 刚好0-31  这里的结构体的整体大小为32 是最大对齐数8的倍数 所以结果为32 为什么存在内存对⻬? ⼤部分的参考资料都是这样说的 1. 平台原因 (移植原因) 不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定类型的数据否则抛出硬件异常。 2. 性能原因 数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于为了访问未对⻬的内存处理器需要作两次内存访问⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数那么就可以⽤⼀个内存操作来读或者写值了。否则我们可能需要执⾏两次内存访问因为对象可能被分放在两个8字节内存块中。 总体来说结构体的内存对⻬是拿空间来换取时间的做法。 举例 假设我们给一个结构体 struct S { char c;//1 int i;//4 }; 在这里我们应该需要8个字节来存放该结构体 假设我们32位系统每次读取4个字节 第一种情况 一次即可读取到i 第二种情况 则需要两次才能读取出来 第一次读取不全 第二次补全 那在设计结构体的时候我们既要满⾜对⻬⼜要节省空间如何做到 让占⽤空间⼩的成员尽量集中在⼀起 修改默认对齐数 我们在上面知道了VS的默认对齐数为8 #pragma这个预处理指令 可以改变编译器的默认对齐数 结构体在对齐方式不合适的时候 我们可以自己更改默认对齐数 结构体传参 我们的arr很大 所以我们的结构体s也很大 我们的函数print1 的tmp也会创建一个很大的空间 这会很浪费空间但不会修改s 所以不建议这样 我们现在给出另一种方式来传参 我们这里直接给print2传结构体s的地址 这就避免了空间的浪费但可能改变s 所以我们可以在这里用const限制 这里的原因是 函数传参的时候 参数是需要压栈 会有时间和空间的系统开销 如果传递一个结构体对象的时候 结构体过大 参数压栈的系统开销比较大 所以会导致性能的下降 结论结构体传参的时候 要传结构体的地址 结构体实现位段 结构体讲完就得讲讲结构体实现 位段 的能⼒。 什么是位段? 位段的声明和结构是类似的有两个不同 1. 位段的成员必须是 int、unsigned int 或signed int 在C99中位段成员的类型也可以选择其他类型。 2. 位段的成员名后边有⼀个冒号和⼀个数字。 ⽐如 位段的位其实是二进制位 在结构体S1   int类型占4个字节--32个bit位 假如我的_a是0或1  二进制表示即为00  01 两个bit位即可 所以32bit位会浪费 而我的位段S2  _a占2个bit位  _b占5个bit位  _c占10个bit位 _d占30个bit位 所以位段是专门用来节省内存的 我们知道上面的结构体S1占16个字节 那我们的位段S2占几个字节呢 结果为什么是8呢 我们在位段的内存分配来讲解 位段的内存分配 1. 位段的成员可以是 int unsigned int signed int 或者是 char 等类型 2. 位段的空间上是按照需要以4个字节 int 或者1个字节 char 的⽅式来开辟的。 3. 位段涉及很多不确定因素位段是不跨平台的注重可移植的程序应该避免使⽤位段。 在第三点中 不同的编译器对位段的实现可能是不同的 现在我们再举个例子 做这题前 我先告诉大家几个注意点 1.申请到的一块内存中 从左向右使用 还是从右向左使用 是不确定的 在VS中 是从右向左使用的 2.剩余的空间不足下一个成员使用的时候 是浪费呢 还是继续使用呢 那我们的各个数又是如何存储的呢 a二进制数为1010 但因为a只占3个bit位 存后三个 二进制数 则存的是010 当然当我们输出a的值发现a不是10 而是2 就是因为这个原因 我们调试一下 看下是否如此 位段的跨平台问题  1. int 位段被当成有符号数还是⽆符号数是不确定的。 2. 位段中最⼤位的数⽬不能确定。16位机器最⼤1632位机器最⼤32写成27在16位机器会出问题。 3. 位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义。 4. 当⼀个结构包含两个位段第⼆个位段成员⽐较⼤⽆法容纳于第⼀个位段剩余的位时是舍弃剩余的位还是利⽤这是不确定的。 总结跟结构体相⽐位段可以达到同样的效果并且可以很好的节省空间但是有跨平台的问题存在。 所以我们根据不同的平台写不同的代码--解决跨平台的问题 位段的应⽤ 下图是⽹络协议中IP数据报的格式我们可以看到其中很多的属性只需要⼏个bit位就能描述这⾥使⽤位段能够实现想要的效果也节省了空间这样⽹络传输的数据报⼤⼩也会较⼩⼀些对⽹络的畅通是有帮助的。 假如我们A要给B发送“呵呵”这条消息 我们现在用 送快递的方式来大概理解一下 我们知道在寄包裹时 需要在包裹上写 寄件人 收件人 这里的寄件人就如同源IP地址 收件人就如同目的IP地址 我们看到第一行4位版本号 假如我们用char1个字节-8bit位我们发现就浪费了一半的空间 这时候用位段就完美的节省了空间 而且我们看到它一共占20个字节 其实它对空间的把握特别好 位段使⽤的注意事项 位段的⼏个成员共有同⼀个字节这样有些成员的起始位置并不是某个字节的起始位置那么这些位置处是没有地址的。内存中每个字节分配⼀个地址⼀个字节内部的bit位是没有地址的。 所以不能对位段的成员使⽤操作符这样就不能使⽤scanf直接给位段的成员输⼊值只能是先输⼊放在⼀个变量中然后赋值给位段的成员
http://www.pierceye.com/news/14151/

相关文章:

  • 搭建视频网站常熟公司网站建设电话
  • 淘宝网站建设的目标是什么意思wordpress 设置站点地址
  • 电商网站建设的目的跟意义建设网站多久到账
  • 苏州企业网站推广兼职做诚信网站认证
  • 给公司做网站多钱汽车报价大全网页版
  • 网站建设的书籍做微网站公司
  • ip查询网站备案查询自己开发一个网站应该怎么做
  • 广州营销型网站建设怎么样界面十分好看的网站
  • 教如何做帐哪个网站好销售的产品是帮别人做网站
  • 化妆品网站建设可行性报告wordpress 机械 主题
  • 哈尔滨自助模板建站网站推广注册
  • 郑州外贸网站建设公司价格什么叫网站建设
  • 网站备案内容网页设计案例大全
  • 高端网站 设计做电子手抄报的网站
  • 上传自己做的网站深圳集团网站建设案例
  • 多用户商城网站建设公司做网站淘宝条形码
  • 省工程建设信息网郑州优化网站公司有哪些
  • 高端网站设计哪个好seo模拟点击软件源码
  • 网站公司利润杭州注册公司有什么优惠政策
  • 南宁市建设工程质量监督站网站分销系统搭建
  • 海南最新通知今天重要消息seo关键词使用
  • 锦州网站建设资讯制作图片教程
  • wordpress 限时 插件页面seo优化
  • 怀化网站优化联系方式网站前端开发语言
  • 网站备案到哪里个人网站流程
  • 做网站需要许可证吗网站设计是怎么设计的
  • 网站网站建设费进什么科目高级软件开发培训班
  • 怎样做视频网站网站宣传推广
  • 洛阳做网站汉狮网络品质最好的购物平台
  • 做新网站推广的活动建筑资料软件