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

有域名就可以做网站么项目管理软件模块

有域名就可以做网站么,项目管理软件模块,陕icp网站建设,乐辰网站建设Hi~#xff01;这里是奋斗的小羊#xff0c;很荣幸各位能阅读我的文章#xff0c;诚请评论指点#xff0c;欢迎欢迎~~ #x1f4a5;个人主页#xff1a;小羊在奋斗 #x1f4a5;所属专栏#xff1a;C语言 本系列文章为个人学习笔记#xff0c;在这里撰写成文一…       Hi~这里是奋斗的小羊很荣幸各位能阅读我的文章诚请评论指点欢迎欢迎~~                                                      个人主页小羊在奋斗                                                 所属专栏C语言    本系列文章为个人学习笔记在这里撰写成文一为巩固知识二为一些学友们展示一下我的学习过程及理解。文笔、排版拙劣望见谅。  1、结构体类型的声明 2、结构体内存对齐 3、结构体传参 4、结构体实现位段 1、结构体类型的声明 1.1结构体变量的创建和初始化 其实之前在C语言操作符2中我们已经比较详细地介绍过结构体变量的创建和初始化这里再补充一个特殊的初始化方法——按照指定的顺序初始化。 前面我们学到的初始化方法是按结构体成员的顺序初始化就像下面这样 除了按顺序初始化我们也可以按指定的顺序初始化 这两种初始化方法得到的效果是一样的。 1.2结构体的特殊声明 我们之前学过的结构声明常规形式是这样的 但在声明结构的时候还可以不完全声明就是省略掉自定义名。 但是这种不完全的结构体声明必须在声明的同时直接创建变量并且这个类型只能使用一次也就是创建一次变量但是一次可以创建多个。 下面这个代码的问题在哪儿呢用这个不完全的结构类型创建一个指针p将p1的地址赋给p。 当我们运行起来就会发现编译器报警告说两个指针类型不兼容。 这是因为我们创建的结构体类型是没有名字的虽然两个成员一样但编译器认为它们两个的地址类型是不一样的。 1.3结构的自引用 什么是结构的自引用呢说白了就是结构自己引用自己有点递归的意思。举个例子当我们想将一个数据存到内存中时可以按顺序存也可以随机地存只要能找到就行。那当我们随机存的时候找到第一个数怎么找到第二个数就是一个问题。 这时候我们可以定义一个结构体类型有两个成员名一个存数据另一个存下一个数据的地址这样的话当我们找到第一个数就能找到第二个数以此类推。 在结构体的自引用过程中夹杂了 typedef 对不完全结构体类型声明的重命名也容易引出问题。 上面的代码是否正确呢我们重命名了结构体类型名并且在结构体成员中也用了重命名后的类型名。这样做是不对的因为我们是要重定义这个结构体类型的类型名上面的代码是在没有重定义之前就使用了打破了顺序的问题。 2、结构体内存对齐 2.1对齐现象  在介绍之前我们可以先猜一下结构体类型是怎么计算大小的呢 上面两个结构体类型成员变量相同都是两个char类型和一个int类型那两个结构体类型的大小会是6个字节吗 可以看到结果并不是我们猜测的而且上面两个结构体类型只是改变了成员变量的顺序它们的大小就发生了变化。那我们可以得到的结论是结构体类型的大小并不是单纯的成员变量类型大小之和而且结构体类型的大小还跟成员顺序有关系。这是为什么呢 其实结构体的成员在内存中是存在对齐现象的。 接着我们就来探讨一下上面两个结构体类型的大小为什么是8个字节和12个字节。假设上面是一块内存一小格表示一个字节第一个字节相较于起始位置偏移量为1第二个字节相较于起始位置偏移量为2以此类推这就是偏移量的概念。 用结构体类型 struct S1 创建一个结构体变量s假设s从第0个字节开始我们知道s的大小是8个字节那其成员n、c1、c2分别在哪个位置呢这里再介绍一个宏 offsetof 它的作用是计算结构体成员相较于结构体变量起始位置的偏移量。 可以看到n的偏移量为0c1的偏移量为4c2的偏移量为5。也就是说这三个结构体成员在内存是像下面这样存的。 但是这也不够8个字节啊难道说结构体变量s即使用不到第6、7个字节但还是将这两个字节霸占了吗是的这两个字节就相当于浪费掉了。 那用结构体类型 struct S2 创建的结构体变量所占的12个字节里n、c1、c2三个成员变量是存在哪些位置呢  可以看到c2的偏移量为0n的偏移量为4c1的偏移量为8。也就是说这三个结构体成员在内存中是像下面这样存的。 可以看到上面也没有12个字节并且把第1、2、3、9、10、11个字节都浪费了。那这又是为什么呢 通过上面的内容我们可以得到的结论是结构体成员在内存中存的时候并不是一个挨着一个存的而是按一定的规则存储的这个规则就是结构内存对齐。  2.2对齐规则 如果我们想要计算结构体类型的大小就必须要先了解结构体的内存对齐才能知道结构体类型在内存中究竟是如何开辟空间的。具体的对齐规则如下 1结构体的第一个成员不管是什么类型对齐到和结构体变量起始位置偏移量为0的地址处 2其他成员变量要对齐到某个数字对齐数的整数倍的地址处 对齐数 编译器默认的一个对齐数 与 该成员变量大小的较小值VS中默认的值为8Linux中gcc没有默认对齐数对齐数就是成员自身的大小. 3结构体总大小为最大对齐数结构体中每个成员变量都有一个对齐数所有对齐数中最大的的整数倍 4如果嵌套了结构体的情况嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体中成员的对齐数的整数倍。 了解了对齐规则我们就来解释一下上面两个结构体类型的大小为什么是8个字节和12个字节。 先看结构体类型 struct S1根据规则1我们知道n存在第0、1、2、3这四个字节中。根据规则2VS默认对齐数是8c1的大小为1小于默认对齐数c1要对齐到1的整数倍的地址处所以c1存到了第4个字节中再看c2c2的大小也是1小于默认对齐数c2要对齐到1的整数倍的地址处所以c2存到了第5个字节中。根据规则3结构体成员中最大对齐数为4此时结构体成员所占6个字节不是4的倍数所以还要再额外占用两个字节的空间那这两个字节的空间就被浪费掉了。所以最终这个结构体类型的大小就是8个字节。 再看结构体类型 struct S2根据规则1我们知道c2存在第0个字节中。根据规则2VS默认对齐数是8n的大小为4小于默认对齐数n要对齐到4的整数倍的地址处所以n存到了第4、5、6、7个字节中那第1、2、3个字节就被浪费掉了再看c1c1的大小是1小于默认对齐数c1要对齐到1的整数倍的地址处所以c1存到了第8个字节中。根据规则3结构体成员中最大对齐数为4此时结构体成员所占9个字节不是4的倍数所以还要再额外占用三个字节的空间那这三个字节的空间也被浪费掉了。所以最终这个结构体类型的大小就是12个字节。 再来通过下面这个练习理解规则4 可以看到结构体类型 struct S2 的大小是24个字节三个结构体成员的偏移量分别为0、4和16。那么其成员变量在内存中的存储就应该是这样 其中结构体变量s的大小是8个字节其结构体类型中成员变量最大对齐数为4而对于结构体类型 struct S2 其成员变量中最大对齐数为8所以最终结构体类型的大小就是24。  2.3为什么存在内存对齐 通过上面的学习我们知道内存对齐的时候很容易就浪费了内存空间那为什么还要存在内存对齐呢 大部分的参考资料都是这样说的 1平台原因移植原因 不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定类型的数据比如只能取int类型那就只能访问4的倍数的内存空间否则抛出硬件异常。 2性能原因 数据结构尤其是栈应该尽可能地在自然边界上对齐。原因在于为了访问未对齐的内存处理器需要做两次内存访问而对齐的内存访问仅需要一次访问。假设一个处理器总是从内存中取8个字节则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数那么就可以用一个内存操作来读或写了。否则我们可能需要执行两次内存访问因为对象可能被分在两个8字节内存块中。 什么意思呢假设创建一个结构体类型其中成员变量为char类型的c和int类型的n。 下面是不考虑对齐的情况直接在c后面存n 下面是考虑对齐的情况 因为n为int类型考虑对齐的话c后面三个字节的空间就浪费掉了。 假设我们现在要用一个32位的机器去访问这个结构体的成员变量n32位的机器一次能访问4个字节的内存那在开始位置访问不考虑对齐的情况时需要访问两次才能读取完整的n但是在访问考虑对齐的情况时只需要访问一次就行了因为n前面刚好是4个字节可以跳过就没有必要访问前面的内存了这样的话效率就会提高。 总的来说结构体的内存对齐是拿空间来换取时间的做法。 那在设计结构体的时候我们既要满足对齐又要节省空间如何做到呢 有一个小技巧让占用空间小的成员尽量集中在一起。就像前面我们创建的 struct S1 和 struct S2 一样虽然两个成员一样但是成员顺序不一样最终两个结构体类型的大小也就不一样了。 2.4修改默认对齐数 #pragma 这个预处理指令可以改变编译器的默认对齐数。 上面结构体类型 struct S 的大小在默认对齐数下是12个字节。 当我们将默认对齐数改为1时结构体类型 struct S 的大小就变成了6个字节。因为结构体成员c1、n、c2的大小分别为1、4、1而默认对齐数是1的时候其每个成员的对齐数都为1就相当于没有对齐是紧挨着存储的。 默认对齐数一般修改的都是2的次方数。 3、结构体传参 来看下面的代码 #include stdio.hstruct S {int arr[1000];char ch;int n; };void print1(struct S tmp) {int i 0;for (i 0; i 10; i){printf(%d , tmp.arr[i]);}printf(\n);printf(ch %c\n, tmp.ch);printf(n %d\n, tmp.n); }void print2(struct S* tmp) {int i 0;for (i 0; i 10; i){printf(%d , tmp-arr[i]);}printf(\n);printf(ch %c\n, tmp-ch);printf(n %d\n, tmp-n); }int main() {struct S s { {1,2,3,4,5,6,7,8,9,10}, a, 8 };print1(s);print2(s);return 0; } 上面写了两个函数print1和print2打印结构体变量s的内容print1用的是传值调用print2用的是传址调用哪个更好呢 答案是传址调用更好。传值调用时形参tmp是拷贝了一份结构体变量s需要压栈要开辟一块和s大小相等的内存空间而且拷贝的过程也是需要时间的所以时间和空间上都要消耗而传址调用指针tmp只需要接收一个4个字节或8个字节的地址就行并不需要额外开辟新的空间并且还没有拷贝过程中时间的消耗。 另外传值调用能做到的传址调用都能做到但是传址调用能做到的传值调用未必都能做到比如间接修改内存中的值。要是我们不想指针指向的对象被修改也可以加上const修饰这样就没什么后顾之忧了。 所以结构体传参的时候要传结构体的地址。 4、结构体实现位段 4.1什么是位段 位段的声明和结构体是类似的有两个不同 1位段的成员必须是 int、unsigned int 或 signed int在c99中位段成员的类型也可以选择其他类型。 2位段的成员名后边有一个冒号和一个数字。 来看结构体和位段声明的比较 位段中的位指的是二进制位也就是比特位所以能想到的是位段中冒号后面的数字指的就是比特位其中_a占2个比特位_b占5个比特位_c占10个比特位_d占30个比特位。成员名前面的_只是编程习惯没有特殊意思。而int型大小是4个字节最大32位所以不能超过这个数。 为什么要有位段呢 以前我们在写代码的时候有没有想过这样一个问题。就是说我们创建了一个整型变量_a它占4个字节但是这个_a我们只是想让它表示0、1、2、3这四个值而这四个值二进制表示为00、01、10、11只需要2个比特位就行了那我们还给它开辟一个32位的空间是不是太浪费了。同样的如果_b只需要5个比特位就够了_c只需要10个比特位就够了_d只需要30个比特位就够了那我们就没有必要给它们都开辟4个字节的内存空间了。 为了实现这种比较精准的内存大小的开辟位段就出现了。我们只需要按它们的需求开辟相应大小的内存空间就能避免很多不必要的浪费。我们用上面声明的结构体和位段来做个验证结构体的大小是16个字节位段是不是真的变小了呢 可以看到位段所占内存是结构体的一半。但是_a_b_c_d加起来一共是47个比特位按道理来说6个字节就够了为什么是8个字节呢这跟位段的内存分配有关。 4.2位段的内存分配 1位段的成员可以是 int、unsigned int、signed int 或者是 char 类型 2位段的空间上是按照需要以4个字节int或1个字节char的方式来开辟的 3位段涉及很多不确定的因素位段是不跨平台的注重可移植的程序应避免使用位段。 那位段到底是如何分配内存的呢 以上面这个位段为例char类型一次开辟8个比特位而a只需要占用3个比特位就行但是这时候就有个问题a是从左往右存呢还是从右往左存呢左右或上下都是一样的这里以左右为例这是不确定的不妨假设是从右向左存的。a存好占用了3个比特位剩下的5个比特位还足够存b存好b后只剩下1个比特位不够存c了还需要再开辟8个比特位那这时候又有个问题剩下的那一个比特位是浪费掉呢还是存一部分c呢这也是不确定的不妨我们再假设不够存下一个数据的话就浪费掉。在开辟的第二个字节中存好c后还剩3个比特位不足以存d还需要再开辟一个字节存d按我们的假设需要开辟3个字节的空间。 开辟好内存空间后就需要给相应的成员变量赋值10的二进制表示是1010但是a只有3个比特位所以a中只存了01012的二进制表示是1100所以b中存了11003的二进制表示是11所以c中存了000114的二进制表示是100所以d中存了0100。 如果真按如上我们假设的存储方式存储那在内存中应该是下面这样 可以看到在当前VS环境下我们的分析是正确的。了解了位段的内存分配我们再回到上面的问题为什么下面这个位段是8个字节而不是6个字节。 一个int类型是32位存好_a_b_c需要17个比特位剩下15个比特位显然不足以存_d所以还需要再开辟4个字节的空间存_d所以总共需要8个字节而不是6个字节。 4.3位段的跨平台问题 1int 位段被当成有符号数还是无符号数是不确定的 2位段中最大位的数目不能确定16位机器最大1632位机器最大32写成27在16位机器中会出问题 3位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义 4当一个结构包含两个位段第二个位段成员比较大无法容纳于第一个位段剩余的位时是舍弃剩余位还是利用这是不确定的。 总结跟结构相比位段可以达到同样的效果并且可以很好的节省空间但是有夸平台的问题。 4.4位段使用的注意事项 位段的几个成员可能共有同一个字节的地址这样有些成员的起始位置并不是某个字节的起始位置那么这些位置处是没有地址的。内存中每个字节分配一个地址一个字节内部的比特位是没有地址的。 所以不能对位段的成员使用操作符这样就不能使用scanf直接给位段的成员输入值只能是先输入放在一个变量中然后赋值给位段的成员。 如果觉得我的文章还不错请点赞、收藏 关注支持一下我会持续更新更好的文章。
http://www.sczhlp.com/news/167416/

相关文章:

  • 舟山建设企业网站做资讯网站要什么手续
  • 南京专业做网站公司网站制作联盟
  • 网站注册信息查询3建设营销型网站流程图
  • 乌兰察布做网站怎么打开网站
  • 网站建设行业2017做网站做系统一样么
  • 江门网站建设推荐软件开发外包费用评估
  • 万网怎样做网站调试城市建设与管理局网站
  • UnicodeEncodeError: locale codec cant encode character \u5e74 in position 2: encoding error
  • 2025 年生物除臭设备厂家最新推荐排行榜:覆盖污水处理厂 / 垃圾中转站等多场景,助力企业精准挑选优质设备
  • python语法记录
  • 免费自己做网站软件红色php企业网站模板
  • 做视频网站注意事项湟中网站建设
  • 如何找网站做推广sentos上部署.net网站
  • 做外贸网站应该关注哪些地方前端开发工程师是干嘛的
  • 巩义网站推广商城网站一般建设的宽度
  • 徐州做网站的公司有几家企业 网站 客户留言怎么做
  • 网站专栏建设方案便捷的邢台做网站
  • wp网站怎么用插件做html网页保定seo排名外包
  • 金坛区建设工程质量监督网站专业网站建设哪家效果好
  • 做公司企业网站标准尺寸做便民网站都需要提供什么
  • 广告公司起名字大全郑州网站seo顾问
  • 哪个门户网站做推广好wordpress更改静态
  • 炫富做图网站html5可以做交互网站吗
  • 网站制做公司淘宝页面设计模板
  • 360网站排名优化站长之家 网站模板
  • 淄博企业网站建设价格能发布自做的视频网站
  • 高端网站设计公司有wordpress文章迁移
  • 微网站可以做商城吗企业服务局
  • 网站地图在首页做链接网站开发过程 知乎
  • 巩义网站建设价格wordpress文件填写