学习C语言与反汇编之间的角色扮演

C语言主要是记录一下,在学习过程中认为容易忘记且重要的东西,方便以后忘了再来学习一下。 集中于结构体部分以及结构体对齐的知识。

结构体的使用练习

**1、定义一个结构体Gamer用来存储一个游戏中的角色的信息,包括血值、等级、坐标等信息 。
要求:

(1) 具体包含哪些信息自由设计

(2) 但这些包含的类型中,必须要有一个成员是结构体类型。

2、定义一个函数,用来给这个结构体变量赋值.

3、定义一个函数,用来显示这个结构体变量的所有成员信息.**
#include
#include <stdio.h>
#include <string.h>
struct point
{
int x;
int y;
int z;
};
struct Gamer
{
char name[20];
int level;
float HP;
point a;
}No1;
void Function()
{
char a[]=“xiaozhi”;
for (int i = 0; i <strlen(a) ; ++i) {
No1.name[i]=a[i];
}
No1.level = 99;
No1.HP = 99.9;
No1.a.x=6;
No1.a.y=5;
No1.a.z=9;
}
void Display()
{
printf("name:%s level:%d HP:%f point:%d %d %d ",No1.name,No1.level,No1.HP,No1.a.x,No1.a.y,No1.a.z);
}
int main() {
Function();
Display();
return 0;
}

sizeof的使用
基本类型的sizeof

可以使用类型,也可以使用变量
例子:
printf("%d\n",sizeof(char));
printf("%d\n",sizeof(int));
printf("%d\n",sizeof(float));
printf("%d\n",sizeof(double));

int x = 10; //变量
printf("%d\n",sizeof(x));


### 数组类型的sizeof


例子:


char arr1[10] = {0};
short arr2[10] = {0};
int arr3[10] = {0};
printf(“%d\n”,sizeof(arr1)); //10
printf(“%d\n”,sizeof(arr2)); // 20
printf(“%d\n”,sizeof(arr3)); // 40
printf(“%d\n”,sizeof(arr1[10])); // 1
printf(“%d\n”,sizeof(arr2[10])); // 2
printf(“%d\n”,sizeof(arr3[10])); //4

注意其中的不同。

![C语言](https://img-blog.csdnimg.cn/20191121114446436.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3MyMjY5MTYyNDA=,size_16,color_FFFFFF,t_70)## 结构体(内存)对齐
### 为什么要有内存对齐?
本质:是要效率还是空间,二选一的结果.统称是性能,还有台移植等因素,编译器对数据结构进行了内存对齐。
### pragma pack的基本用法
在vc6.0++中默认值是8字节对齐。

#pragma pack( n )
结构体。
#pragma pack(  )
该操作会改变一个结构体的字节对齐数,这是针对编译器的。
对齐参数:n为字节对齐数,其取值为1、2、4、8,默认是8。
如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,**即是说,结构体成员的偏移量应该取二者的最小值.**


#pragma pack(n)
struct Test
{
int a ;
__int64 b ;
char c ;
};
#pragma pack()

以下是各种情况的内存对齐分析:

1:1字节对齐
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4jqKG8MD-1574307676266)(/images/15735626712023.jpg)]

2:2字节对齐时:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L71tGDp1-1574307676267)(/images/15735626990588.jpg)]

3:4个字节对齐
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jSQdocRL-1574307676267)(/images/15735627321430.jpg)]

4、8个字节对齐

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3MWbwXny-1574307676268)(/images/15735627463362.jpg)]
### 对齐原则:

原则一:数据成员对齐规则:结构的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储).									
									
原则二:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。																	

原则三:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。									**(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储.)**									
									
原则四:对齐参数如果比结构体成员的sizeof值小,该成员的偏移量应该以此值为准.									
	也就是说,结构体成员的偏移量应该取二者的最小值.								


**由浅入深,分析内存对齐原则后内存到底是怎么分配的**
#### 案例分析一:


struct Test
{
char a;
int b ;
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KUnHQ8Xn-1574307676268)(/images/15735632219948.jpg)]
**sizeof(Test) =1+3(补齐的)+4=8(其中最大的4的整倍数)**

#### 案例二分析:


struct Test
{
int a ;
__int64 b ;
char c ;
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TgVdwhLL-1574307676269)(/images/15735634186981.jpg)]
**sizeof(Test) =4+4(补齐的)+8+1+7(补齐的)=24(其中最大的8的整倍数)**


#### 案例三分析:


struct Test
{
int a ;
__int64 b ;
char c ;
char d ;
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pdLSQiI9-1574307676270)(/images/15735635119907.jpg)]

**sizeof(Test) =4+4(补齐的)+8+1+1+6(补齐的)=24(其中最大的8的整倍数)**

#### 案例四分析:


struct S1
{
char c;
double i;
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NTmPuUdc-1574307676270)(/images/15735636051365.jpg)]

**sizeof(S1) =1+7(补齐的)+8=16(其中最大的8的整倍数)**

####  案例五分析:


struct S2
{
int c1;
char c2[10];
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pNC29rRz-1574307676271)(/images/15735636961393.jpg)]

**sizeof(S2) =4+10+2(补齐的)=16(其中最大的8的整倍数)**

#### 案例六分析:


struct S3
{
char c1;
S1 s;
char c2;
char c3;
};

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XWb9SHGQ-1574307676272)(/images/15735637638057.jpg)]

**sizeof(S3) =1+7+1(s中的char c)+7(补齐的)+8(s中的double)+1+1+6(补齐的)=32(其中最大的8的整倍数)**

#### 案例七分析:


struct S4
{
char c1;
S1 s;
char c2;
double c3;
};、

{% image /images/15735639114324.jpg '-w558' '' %}

**sizeof(S4) =1+7+1(s中的char c)+7(补齐的)+8(s中的double)+1+7(补齐的)+8=40(其中最大的8

![C语言](https://img-blog.csdnimg.cn/20191121114432557.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3MyMjY5MTYyNDA=,size_16,color_FFFFFF,t_70)
关注微信公众号:C程序开发 免费获取进阶指导和学习资料!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值