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

怎么用esc服务器做网站如何做平台推广赚钱

怎么用esc服务器做网站,如何做平台推广赚钱,视频聊天软件开发,做网站行业的动态目录 1.结构体类型的声明 2.结构体变量的定义和初始化 3.结构体内存对齐 1.结构体类型的声明 之前在讲解操作符的文章中,已经学习了结构体的概念,这里稍微复习一下。 1.1结构体回顾 结构是一种集合,这些值称为成员变量,结构的…

目录

1.结构体类型的声明

2.结构体变量的定义和初始化

3.结构体内存对齐


1.结构体类型的声明

之前在讲解操作符的文章中,已经学习了结构体的概念,这里稍微复习一下。


1.1结构体回顾


结构是一种集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。

1.1.1结构体的声明

struct tag
{member-list;
}variable-list;

例如描述一个学生:

struct Stu
{char name[20];//名字int age;char sex[5];//性别char id[20];//学号
};//分号不能丢

2.结构体变量的定义和初始化

struct Stu
{char name[20];//名字int age;char sex[5];//性别char id[20];//学号
};int main()
{// 结构体变量的创建和初始化struct Stu s = {"张三", 20, "男", "2023081001"};printf("Name: %s\n", s.name);printf("Age: %d\n", s.age);printf("Sex: %s\n", s.sex);printf("Id: %s\n", s.id);struct Stu *ps = &s;printf("Name: %s\n", ps->name);printf("Age: %d\n", ps->age);printf("Sex: %s\n", ps->sex);printf("Id: %s\n", ps->id);return 0;
}

在这块代码的printf语句中, . 和 -> 都是用于访问结构体成员的操作符,但使用场景有所不同:

2.1点操作符(. )

• 用法:当你有一个结构体变量时,使用点操作符来访问它的成员。语法格式为 结构体变量名.成

员名 。

• 示例:假设有如下结构体定义:

struct Point {int x;int y;
};
struct Point p;
p.x = 10;  // 使用点操作符给结构体变量p的成员x赋值
p.y = 20;  // 使用点操作符给结构体变量p的成员y赋值


2.2箭头操作符(-> )

• 用法:当你有一个指向结构体的指针时,使用箭头操作符来访问结构体的成员。语法格式为 结构

体指针名->成员名 。它等效于 (*结构体指针名).成员名  ,本质上是先通过指针找到结构体变量,

再访问其成员。

• 示例:

struct Point {int x;int y;
};
struct Point *ptr;
struct Point p = {10, 20};
ptr = &p;
ptr->x = 30;  // 使用箭头操作符通过指针ptr给结构体成员x赋值
ptr->y = 40;  // 使用箭头操作符通过指针ptr给结构体成员y赋值

总的来说,. 用于直接通过结构体变量访问成员,而 -> 用于通过结构体指针访问成员,合理使用这

两个操作符能方便地操作结构体数据。

2.3结构的特殊声明

在声明结构的时候,可以不完全的声明

比如:

//匿名结构体类型
struct
{int a;char b;float c;
}x;
struct
{int a;char b;float c;
}*p;

上面的两个结构在声明的时候省略了结构体标签(tag)。

那么问题来了:

// 在上面代码的基础上,下面的代码合法吗?
p = &x;

警告:

编译器会把上面的两个声明当成完全不同的两个类型,所以是非法的。

匿名结构体类型,如果你有相同的结构体类型要声明的话,基本上要使用同一次。

2.4结构体的自引用

 在结构中包含一个类型为该结构本身的成员是否可以呢?

比如,定义一个链表的节点:

struct Node
{int data;struct Node next;
};

仔细分析,其实是不行的,因为一个结构体中再包含一个同类型的结构体变量,这样结构体变量的

大小就会无穷的大,是不合理的。

正确的自引用方式:

struct Node
{int data;struct Node* next;
};

在结构体自引用的过程中,夹杂了 typedef 对匿名结构体类型重命名,也容易引入问题,看看下面

的代码,可行吗?

typedef struct
{int data;Node* next;
}Node;

答案是不行的,因为 Node 是对前面的匿名结构体类型的重命名产生的,但是在匿名结构体内提前

使用 Node 类型来创建成员变量,这是不行的。

解决方案如下:定义结构体不要使用匿名结构体了

typedef struct Node
{int data;struct Node* next;
}Node;

3.结构体内存对齐

我们已经掌握了结构体的基本使用了。

现在我们深入讨论一个问题:计算结构体的大小。

这也是一个特别热门的考点:结构体内存对齐

3.1对齐规则

1. 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数 = 编译器默认的一个对齐数与该成员变量大小的较小值。
 
- VS 中默认的值为 8
- Linux中 gcc 没有默认对齐数,对齐数就是成员自身的大小
 
1. 结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大的)的

整数倍。

2. 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构

体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。

3.1.1练习

struct S1
{char c1;int i;char c2;
};
printf("%d\n", sizeof(struct S1));

结构体第一个成员 c1 是 char 类型,占1字节, 对齐到偏移量为0 的地址处, 此时已用1 字节。
 
第二个成员 i 是 int 类型 , 大小为4 字节 , 对齐数取编译器默认对齐数8 和int  类型大小4 中的较小

值,即4 。所以 i 要从4 的整数倍地址开始存储,前面 c1占了1 字节,因此要填充3字节,使得

 i  从偏移量为4 的地址开始存储 , i 存储后 , 共占用4 + 4 = 8 字节。
 
第三个成员 c2 是 char 类型,占1 字节 , 对齐数为1(char  类型大小),从当前偏移量8 处存储,占

用1 字节。
 
最大对齐数是4 (int  类型的对齐数) , 当前总占用9 字节,要满足是最大对齐数4 的整数倍,需

再填充3 字节。
 
得出结果:所以  sizeof(struct S1)  的结果是12 字节。

struct S2
{char c1;char c2;int i;
};
printf("%d\n", sizeof(struct S2));

 第一步:根据规则1,第一个成员c1为 char 类型,占1 字节,对齐到偏移量为0 的地址处,此时占

用1 字节。

第二步:第二个成员 c2 也是 char 类型,占1 字节,对齐数为1 ( char  类型自身大小 ),紧接在

 c1  后面存储,从偏移量为1 的地址开始,此时共占用2 字节。

第三步:第三个成员 i 是 int 类型,大小为4 字节,对齐数取编译器默认对齐数8 和  int  类型大小4

中的较小值,即4 。所以 i 要从4 的整数倍地址开始存储,前面已占用2 字节,因此需填充2 字

节,使得  i  从偏移量为4 的地址开始存储,  i  存储后共占用4 + 4 = 8 字节。

第四步:依据规则3,最大对齐数是4( int  类型的对齐数)  , 当前总占用8 字节,8 是4 的整数倍,

无需额外填充。
 
结论:

所以  sizeof(struct S2)  的结果是8 字节。若运行包含上述结构体定义和  printf("%d\n",sizeof(struct

S2));  语句的C 语言程序,会输出  8  。

3.2为什么存在内存对齐?

1. 平台原因 (移植原因):

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2. 性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。假设一个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对齐成8的倍数,那么就可以用一个内存操作来读或者写值了。否则,我们可能需要执行两次内存访问,因为对象可能被分放在两个8字节内存块中。


 总体来说:结构体的内存对齐是拿空间来换取时间的做法。
 
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:

让占用空间小的成员尽量集中在一起

//例如:
struct S1
{char c1;int i;char c2;
};struct S2
{char c1;char c2;int i;
};S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别。
输出结果:12
8

1. 分析struct S1大小

在常见编译器(如VS , 默认对齐数为8)下,依据结构体内存对齐规则:

- 第一个成员c1是 char 类型,占1 字节,对齐到偏移量为0 的地址处 ,此时占用1 字节。

- 第二个成员 i是 int 类型,大小为4 字节 ,对齐数取编译器默认对齐数8 和 int 类型大小4 中的较

小值,即4 。所以  i  要从4 的整数倍地址开始存储,前面  c1  占了1 字节,因此要填充3 字节,使

得 i 从偏移量为4 的地址开始存储, i 存储后,共占用4 + 4 = 8 字节。

- 第三个成员 c2 是 char 类型,占1 字节,对齐数为1( char  类型大小 ),从当前偏移量8 处存

储,占用1 字节。

- 最大对齐数是4 ( int  类型的对齐数 ),当前总占用9 字节,要满足是最大对齐数4 的整数倍,

需再填充3 字节。所以  sizeof(struct S1)  为12 字节。
 
2. 分析  struct S2 大小
 
- 第一个成员 c1 为 char 类型,占1 字节,对齐到偏移量为0 的地址处,占用1 字节。

- 第二个成员 c2 也是 char 类型,占1 字节,对齐数为1 ,紧接在  c1  后面存储,从偏移量为1

的地址开始,此时共占用2 字节

- 第三个成员 i是 int 类型,大小为4 字节,对齐数为4 。前面已占用2 字节,需填充2 字节,使

得  i  从偏移量为4 的地址开始存储,  i  存储后共占用4 + 4 = 8 字节。最大对齐数是4 ,8 是4 的

整数倍,无需额外填充 。所以  sizeof(struct S2)  为8 字节。
 
可见,虽然 S1 和 S2 成员相同,但成员顺序不同,导致内存对齐方式有别,所占空间大小也就

不同 。

所以在设计结构体的时候,我们既要满足对齐,又要节省空间,应该:

让占用空间小的成员尽量集中在一起

在之前关于操作符的文章中,我们只是粗略的介绍了解了结构体,今天正式认识了结构体,包括结构体的声明,初始化,以及内存对齐,希望大家能理解,感谢大家的观看!

http://www.cadmedia.cn/news/15248.html

相关文章:

  • web前端框架有哪些搜索引擎优化师工资
  • 东莞国药官网网上商城百度优化软件
  • 网站建设运行环境搜索百度指数
  • 建设法律法规文本查询网站阿里云盘资源搜索引擎
  • 上海专业的网站建杭州网站设计制作
  • 富锦建设局网站北京百度关键词推广
  • 网站开发论文文献书籍武汉seo推广
  • 海外营销网站建设刷赞网站推广免费链接
  • 郑州网站推广哪家好论坛seo教程
  • 西安到北京高铁几小时优化seo公司哪家好
  • 广州市手机网站建设公司深圳seo优化方案
  • 外贸独立站建站哪家好网络服务器的功能
  • 大连大连建设工程信息网站优秀网站设计欣赏
  • 网站建设后怎么爱廷玖达泊西汀
  • qq业务代理网站建设十大广告公司
  • 长春自助建站软件百度营销推广登录
  • 厦门房产网seo研究中心怎么样
  • 河南省建设工程人力资源小璇seo优化网站
  • 租号网站怎么做自己个人怎样做电商
  • 动漫网站模板代码优化
  • 服装网站建设教程软文网站推广
  • 菏泽网站建设便宜臻动传媒淘宝店铺如何推广
  • 佛山企业网站开发公司线上营销平台
  • 光谷软件园 网站建设全国新冠疫情最新消息
  • 成都十大建筑设计公司seo优化方案项目策划书
  • 301网站目录全网推广平台
  • 西安北郊做网站公司微信推广方案
  • 南联网站建设哪家好百度电商平台
  • 遵化网站建设电商营销推广有哪些?
  • 长春哪家网站做的好宁波网站推广