c语言输出狐狸图形,c语言中的结构体

结构体是 C 语言主要的自定义类型方案,这篇就来认识一下结构体。

一、结构体的形态

C源程序(struct.c):

#include

typedef struct{

unsigned short int a;

unsigned short int b;

}Data;

int main()

{

Data c, d;

c.a = 1;

c.b = 2;

d = c;

printf("d.a:%d\nd.b:%d\n", d.a, d.b);

return 0;

}

赋值部分翻译后:

movw $1, 28(%esp) # c.a = 1

movw $2, 30(%esp) # c.b = 2

movl 28(%esp), %eax #

movl %eax, 24(%esp) # d = c

可以看出:

c.a 是在 28(%esp) 之后的2个字节

c.b 是在 30(%esp) 之后的2个字节

c 是 28(%esp) 之后的4个字节

d 是 24(%esp) 之后的4个字节

不得不感叹名字(结构体名字、子元素名字)再一次被抛弃了,子元素名代表的是相对于结构体的偏移。

二、结构体的复制

大一的时候,老师千叮咛万嘱咐:数组不能复制!但是当发现下面这个程序正常运行后,我困惑了(block.c):

#include

typedef struct{

char data[1000];

}Block;

Block a={{'a','b','c',}};

int main()

{

Block b;

b=a;

puts(b.data);

return 0;

}

Block a={{'a','b','c',}} 是对 a 的部分初始化,'c' 后面自动填 0,写成 Block a={{"abc"}} 也一样,C 语言对初始化还是很宽容的。

上面这个程序居然正常的编译、运行了,这究竟是怎样的逆天?

看看汇编部分:

leal 24(%esp), %edx

movl $a, %ebx

movl $250, %eax

movl %edx, %edi # edi = &b

movl %ebx, %esi # esi = &a

movl %eax, %ecx # ecx = 250

rep movsl

我们发现程序确实通过 250 次 movsl 复制了一个"数组"。其原因是:结构体是可以复制的,结构体又可以包括任意类型的子元素,数组也行,所以"数组"也被复制了。

那为什么纯粹的数组就不能复制呢?

我们可以这样去理解:一个变量能被复制的必要条件是我们知道它的大小。结构体做为自定义类型,在编译的时候编译器必然存储了它的子元素类型、个数等相关信息,结构体的大小也就知道了;而数组一般只在乎它的类型和起始地址,元素个数总是被忽视的(例如:void func(char s[]) 可接受任何长度的字符数组做参数),而且元素个数也没有被当做数组的一部分存入内存,所以数组的复制是不好实现的。

小结

如果给结构体下一个实在点的定义话,那就是:有格式的字节数组。有了结构体后 C 语言的变量类型就丰富多了,但是同时也要注意:

超过 4 字节的结构体不宜做参数(参数传递浪费时间、空间),换做指针更好。

超过 4 字节的结构体不宜做返回值类型(话说一般返回值都用 eax 来存,那么超过 4 字节的时候怎么存呢?自己去探索吧!)。

出差必备

买火车票、高铁票、机票,订酒店都打9折的出行工具TRIP,点击注册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值