中国专门做生鲜的网站网站佣金怎么做分录

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

中国专门做生鲜的网站,网站佣金怎么做分录,公司名称免费起名,网站开发包含上线吗在我们使用C语言进行编写代码时#xff0c;常常会使用已经给定的类型来创建变量#xff0c;比如int型#xff0c;char型#xff0c;double型等#xff0c;而当我们想创建一些较为复杂的东西时#xff0c;单单用一个类型变量是没办法做到的#xff0c;比如我们想创建一个…在我们使用C语言进行编写代码时常常会使用已经给定的类型来创建变量比如int型char型double型等而当我们想创建一些较为复杂的东西时单单用一个类型变量是没办法做到的比如我们想创建一个学生学生拥有的属性繁多有年龄有姓名有性别有成绩等等等等…那么此时我们应该如何创建一个学生类型变量呢这就涉及到我们今天要学习的新知识结构体类型。 一、结构体类型的声明 当我们要统计很多同类型数据的时候我们可以使用数组而通常定义复杂的类需要多种不同的类型数据而结构体就是用来存放这些不同类数据的。 struct tag {member - list; }variable - list; 这段代码中tag代表的意思是要创建结构体的名字member-list代表结构体中的各种成员变量variable-list可以不写写的时候可以代表创建结构体类型时顺带创建的结构体变量。 比如此时我们想定义一个学生变量 struct Stu {int age;//年龄char name[20];//名字double score;//成绩char sex[5];//性别 };//分号一定不能忘记 二、结构体变量的定义和初始化 ① 结构体变量的定义 对于结构体变量的定义我们可以像上面提到的在创建结构体类型时直接创建出结构体变量 struct Stu {int age;//年龄char name[20];//名字double score;//成绩char sex[5];//性别 }s1;//分号一定不能忘记 这样就成功定义了结构体变量s1当然除了这种方法还可以在声明结构体之后再定义 struct Stu {int age;//年龄char name[20];//名字double score;//成绩char sex[5];//性别 }; int main() {struct Stu s1;return 0; } ② 结构体变量的初始化 而对于结构体变量的初始化也可以根据上面两种定义方式分成两种初始化的方法 在创建结构体类型时直接创建出结构体变量的情况下结构体变量初始化 struct Stu {int age;//年龄char name[20];//名字double score;//成绩char sex[5];//性别 }s1 { 18,zhangsan,99.5,男 }; int main() {printf(%d %s %.1f %s\n, s1.age, s1.name, s1.score, s1.sex);return 0; } 在声明结构体之后再定义的情况下对结构体变量初始化 struct Stu {int age;//年龄char name[20];//名字double score;//成绩char sex[5];//性别 }; int main() {Stu s1 { 18,zhangsan,99.5,男 };//struct Stu s1 { 18,zhangsan,99.5,男 };//两种方法都是可以的printf(%d %s %.1f %s\n, s1.age, s1.name, s1.score, s1.sex);return 0; } (注:如果定义的结构体名和变量名不冲突那么在定义结构体变量时可以省略掉struct关键字。) ③ 结构的特殊声明 在声明结构的时候可以不完全的声明也就是说在声明结构体时并不为此结构体命名此声明被称为匿名结构体类型。 struct {int age;char name[20];double score;char sex[5]; }s1; struct {int age;char name[20];double score;char sex[5]; }*sp; int main() {sp s1;return 0; } 那么如果我们分别声明两个成员变量类型相同的匿名结构体一个定义s1结构体变量另一个定义指针sp那么再对s1取地址s1与sp会是相等的嘛答案是此行为是非法的 编译器会把上面的两个声明当成完全不同的两个类型所以是非法的。 匿名的结构体类型如果没有对结构体类型重命名的话基本上只能使用一次。 ④ 结构的自引用 结构体能够存储各种成员变量那我们是否能在结构中包含一个类型为该结构本身的成员呢 正常来说在结构中包含整形变量就是int a字符型变量就是char a那同样的我们要包含同类型结构变量是写成struct …吗例如 struct Node {int date;struct Node next; } 这样看似是代表了该结构本身成员date但实际上操作起来比如我们此时计算sizeof(struct Node)会发生套娃的情况一直循环的进入Node结构体而每一次进入都多了一个占四字节的date最后变成无穷大所以这样写是错误的。 而其实我们想做到的就是找到同类型成员变量那其实我们直接使用指针去指向下一个变量就好了~所以其实正确的方法很简单只需要我们取next地址像这样写就好了 struct Node {int date;struct Node next; } 而后我们再来了解一下typedef的用法它的作用很多主要作用于 ① 定义一种类型的别名而不只是简单的宏替换。可以用作同时声明指针型的多个对象。 意思就是说我们正常来定义整形变量就是int num而我们可以通过typedef来创建一个独特的新词来代表int比如此时我们输入typedef int Int;那么此时我们再写入int a和INT a其实是一样的。(需要注意的是后面那句话!!!可以用作同时声明指针型的多个对象) 多说无益我们来看一道例题 #define INT_PTR int* typedef int* int_ptr; INT_PTR i, j; int_ptr x, y; 在上面代码中ijx,y四个常量的数组类型哪一个是int数据类型 答案为j是int型i,x,y这个常量为int类型为什么 在#define这个宏在预处理阶段将会转化为int i j而typedef不会出现这种情况新定义的名称所代表的类型是什么对应创造的变量就是什么。 ② 声明struct新对象时可以使用。 我们来看这段代码是否可行呢 typedef struct{int data;Node* next;}Node; 答案是不行的因为Node是对前面的匿名结构体类型的重命名产生的但是在匿名结构体内部提前使用Node类型来创建成员变量这是不行的。解决方案 typedef struct Node{int data;struct Node* next;}Node; 三、结构体的内存对齐 结构体内存对齐非常重要!!!故需要讲解的内容也较多!!!所以我单独分出一篇文章来对结构体的内存对齐进行透彻深入的讲解,需要的小伙伴们请进入这个博客进行进一步学习~ ⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇ C语言结构体内存对齐-CSDN博客 ⬆⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆​​​​​​​⬆ ① 结构体内存对齐的规则 结构体中存放的数据各种各样它们的存储是否能做到在内存中紧密排列呢又或者说结构体的内存应该怎样去计算呢让我们来举个例子 struct Stu1 {int age;char name;int id;char sex; }; struct Stu2 {char sex;char name;int age;int id; }; int main() {int num1 sizeof(struct Stu1);int num2 sizeof(struct Stu2);printf(num1长度为:%d\nnum2长度为:%d\n, num1, num2);return 0; } 如果按照之前计算整型数组和字符数组大小的常规思路来判断这两个结构体的大小应该是相等的一个int型变量占4个字节一个char型变量占1个字节那么Stu1有两个int型变量和两个char型变量大小理应为441110同样的Stu2也应为10。那让我们将代码运行一下看看是不是这样的欸奇怪了不仅两个结构体的大小不为10甚至两个结构体的大小都不相等这是怎么一回事呢其实结构体Stu1在内存中的存址形式是这样的 为什么会是这样的存储形式呢这就是结构体内存对齐所造成的。 结构体内存对齐的规则 ① 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处。 ② 其他成员变量要对齐一个叫对齐数的数字的整倍数的地址。 对齐数的概念

  • 在不同的编译器中默认的对齐数也有所不同Visual Studio Code的编译器的对齐数是8Linux的编译器的对齐数是4。 * 在结构体存址时对齐数取(编译器默认的对齐数)和(该成员变量大小)中较小的数。③ 结构体所占内存大小等于最大对齐数结构体中每个成员变量都有一个对齐数各成员变量中最大的对齐数的整数倍。 ④ 如果结构体有嵌套那么嵌套的结构体存储在自己成员的最大对齐数的整数倍地址处嵌套结构体大小为所有成员包括嵌套的结构体的成员的最大对齐数的整数倍。 ② 结构体内存对齐运算 比如此时我们创建一个结构体变量 struct Stu1 {char name;int id;char sex; }; 用图片来表示我们发现结构体的大小一下子从1变成了8并且其中出现了三个浪费的空间那么造成这种情况的原因是什么呢让我们来一起计算一下它现在的对齐数当我们只存放一个char型变量name时对齐数为1所以此时内存大小仅仅为1。但当我们存入int型变量id时对齐数变成4所以结果的内存大小必须被4整除故浪费三个空间使内存大小变成8。最后也浪费三个空间与上面是同理的。 四、结构体实现位段 ① 位段的定义与初始化 既然讲了结构体就不得不提到结构体的位段了。那么什么是结构体的位段呢有些数据在存储时并不需要占用一个完整的字节只需要占用一个或几个二进制位即可。为了充分利用好内存空间就出现了位段~ 位段的声明 ① 位段的成员必须是intunsigned int或signed int在C99中位段成员的类型也可以选择其他类型。 ② 段位的成员名后面有一个冒号和一个数字。 ③ 后面的数字用来限定成员变量占用的位数。 让我们来用代码来进行一下举例 struct A {int _a : 2;int _b : 5;int _c : 10;int _d : 30; }; 这就是位段的初始化四个成员变量是int型但使用位段将它们的内存大小进行了定义。而这种内存的定义应该从何体现呢我们对着这段代码进行一些增加 struct A {int _a : 2;int _b : 5;int _c : 10;int _d : 30; }; int main() {struct A arr { 1,15,511,536870911 };printf(%d\n%d\n%d\n%d\n, arr._a, arr._b, arr._c, arr._d);return 0; } 此时我们定义的四个成员变量所占用的内存分别为2bit5bit10bit30bit相应的因为int型变量是有正负之分的所以还需要有一个符号位那么此时真正储存大小的bit位就分别是14929。而此时我输入的115511536870911恰好就是除符号位以外其他位全部为1的情况所以此情况是能够正常输出的现在我们将这四个数全部都加一就会变成这是因为此时所有位进1使符号位从0变成了1所以数字都变成了负数。而符号位一般都是最后一位这也就证明初始化位段冒号后的数字是bit个数 那么位段A所占的内存大小又是多少呢 struct A {int _a : 2;int _b : 5;int _c : 10;int _d : 30; }; int main() {struct A arr {};printf(%d\n,sizeof(arr));return 0; } 答案是8。那么这是为什么呢接下来让我们学习一下位段的内存分配。 ② 位段的内存分配 Ⅰ 位段的成员可以是 int unsigned int signed int 或者是 char 属于整形家族类型 Ⅱ 位段的空间上是按照需要以4个字节 int 或者1个字节 char 的方式来开辟的。 Ⅲ 位段涉及很多不确定因素位段是不跨平台的注重可移植的程序应该避免使用位段。 让我们看一段代码结构体中存放了四个char型变量并且都通过位段改变了内存大小那么这个结构体的大小是多少呢 struct S {char a : 3;char b : 4;char c : 5;char d : 4; }; int main() {struct S s {};s.a 10;s.b 12;s.c 3;s.d 4;printf(%d, sizeof(s));return 0; } 答案是3。那么接下来让我们通过这张图来深入的了解一下结构体内存分配这就是结构体S的大小为3的原因啦~ 接下来再让我们对数据s.as.bs.cs.d四个成员变量所占用的地址进行一下分析最后得到的地址是62 03 04 xx。结果是否是这样呢让我们证实一下~没错~我们的答案是正确的。使用位段能够有效的节省大量不必要的空间而需要注意的是地址的存储是从右往左使用的并且当一个字节中剩余空间不足时会浪费一段空间在新的空间中存储所以使用位段时也需要精心计算否则或许反而会使占用内存变多 然而位段的好处如此多也就相应的证明它也有坏处!!! ③ 位段的跨平台问题 ①. int 位段被当成有符号数还是无符号数是不确定的。 ②. 位段中最大位的数目不能确定。(16位机器最大1632位机器最大32写成27在16位机器会 出问题) ③. 位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义。 ④. 当一个结构包含两个位段第二个位段成员比较大无法容纳于第一个位段剩余的位时是舍弃剩余的位还是利用这是不确定的。 总结
    跟结构相比位段可以达到同样的效果并且可以很好的节省空间但是有跨平台的问题存在。 那么关于结构体的相关知识这次就为大家分享到这里啦~值得关注的是结构体属于自定义类型中的一种而自定义类型还有联合与枚举而联合与枚举的相关知识就要留到下一篇文章给大家讲解啦~还请大家多多期待如果这篇文章有讲得不细致的地方或者有出现错误的地方还请大家多多指出我也会虚心学习的那么我们下一篇再见啦