结构体名问题

本文详细解析了C语言中结构体中字符数组在输出时的特殊处理方式,包括内存对齐原理及如何正确输出完整内容。

问题:

#include <stdio.h>
struct {char a[3];
int b;}data={"he",10};
int main(void)
{printf("%c %d",data);
return 0;} 
输出结果是 h 10


然后我改变代码
#include <stdio.h>
struct {char a[3];
char b[3];
int c;}data={"he","hf",10};
int main(void)
{printf("%c %c %d",data);
return 0;} 
输出结果是 h f 10

在输出时 它只输出第一个数组的第一个字符 第二数组的第二个字符

我也试过三个字符数组 输出时是第三个数组的第三个字符

但是假如不是字符数组 我改成整数数组
如下
#include <stdio.h>
struct {int a[3];
int b[3];
}data={{10,11,12},{13,14,15}};
int main(void)
{printf("%d %d %d %d %d %d",data);
return 0;} 
输出结果 10 11 12 13 14 15
但是如果是字符数组
是不能输出全部的结果的
如这样
#include <stdio.h>
struct {char a[3];
char b[3];}data={"he","hf"};
int main(void)
{printf("%c %c %c %c",data);
return 0;} 

输出结果 h f ? 乱码


既然在输出时对字符数组有这么特殊的处理
为什么我在结构体之间赋值不会了
如下

#include <stdio.h>
struct book {char a[3];
char b[3];}data={"he","hf"};
int main(void)
{struct book ndata;
ndata=data;
printf("%s %s",ndata.a,ndata.b);
return 0;} 
结果完全无误 he hf
为什么这里结构体名就代表全部的内容了?

解答:

在 结构体中 和 传递参数 的时候都要进行 内存对齐。一般讨论内存对齐都是讨论跟结构体有关的情况下,不过传参数的时候也有内存对齐存在。内存对齐在不同编译器下表现略有不同,不同体系结构的计算机上自然也不一样,不过先假设一种简单情况:在我们常用的x86上,变量的大小小于等于8字节。这个时候一般这样对齐:char型对齐到1的倍数地址(不用对齐^_^),short对齐到2的倍数,int及更大的对齐到4的倍数。这个时候传参数一般就是对齐到4的倍数,lz的程序

就是这种情况。

先看看这个程序:

#include <stdio.h>
struct
{
     char x[10];
}temp={"0123456789"};
int main(void)
{
     printf("%c%c%c",temp);
     return 0;
} 

以上程序结果为048,原因就是进行了对齐。尽管参数表里的3个参数都指明是char,但是因为是传递参数,所以应该对齐到4的倍数(每个参数的其实地址都是4的倍数)。
printf是可变参数的函数,可变参数的函数在c语言中规定必须有一个固定参数,printf的固定参数就是参数表。printf函数调用之后,根据固定参数的地址和大小计算出下一个参数的起始地址,然后再根据这个参数的起始地址和大小计算下一个参数,依次进行,对于每个参数的处理按照参数表的指示进行。注意,以上的每一步计算都考虑内存对齐,遵照参数起始地址为4的倍数来的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值