C语言关于可变参数,结构体的深度剖析

1 关于可变参数中的va_start(ap,v), va_arg(ap,t), va_end(ap)三个函数解析。    

va_start(ap,v)等价于 char *p = (char *)&format;   i=va_arg(ap,int)等价于i = *((int *)p),p = p + sizeof(int).分两个步骤完成取值,指针移动。va_end(ap)等价于p = (char *)0 .

2 关于结构体对齐的三个原则。    (在没有#pragma pack宏的情况下

原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。

•原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
•原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要齐。
struct  person{
 30         char *name;
 31         int  age;
 32         char score;
 33         int  id;
 34 };
 35 
 36 struct  person1{
 37         char *name;
 38         int  age;
 39         char score;
 40         int  id;
 41 }__attribute__ ((packed));  //告诉GCC编译器 不对结构体数据进行对齐处理
 42 
 43 struct  person2{
 44         char *name;
 45         int  age;
 46         char score;
 47         int  id;
 48 }__attribute((aligned (4)));  //告诉编译器,进行4字节对齐处理
 49 
 50 struct  person4{
 char *name;
 52         struct  person  per;
 53         int  age;
 54         char score;
 55         int  id;
 56 
 57 };
 58 int main(int argc,char **argv)
 59 {
 60         struct  person per={"www.100ask.org",10,'A',123};
 61         printf("sizeof(char   )=%d\n",sizeof(char   ));
 62         printf("sizeof(int    )=%d\n",sizeof(int    ));
 63         printf("sizeof(char  *)=%d\n",sizeof(char  *));
 64         printf("sizeof(char **)=%d\n",sizeof(char **));
 65         printf("sizeof(struct  person)=%d\n",sizeof(struct  person));
 66         printf("sizeof(struct  person1)=%d\n",sizeof(struct  person1));
 67         printf("sizeof(struct  person2)=%d\n",sizeof(struct  person2));
 68         printf("sizeof(struct  person4)=%d\n",sizeof(struct  person4));
 69 
 70         printf("&per.name  =%p,per.name  =%s\n",&per.name ,per.name);
 71         printf("&per.age   =%p,per.age   =%d\n",&per.age  ,per.age);
 72         printf("&per.score =%p,per.score =%d\n",&per.score,per.score);    
 73         printf("&per.id    =%p,per.id    =%d\n",&per.id   ,per.id);             
 74         return 0;
 75 }
 76 
 
输出结果为:
main.c  push_test  push_test.c  struct_test  struct_test.c
book@www.100ask.org:~/myFile/put_test$ ./struct_test 
sizeof(char   )=1
sizeof(int    )=4
sizeof(char  *)=8
sizeof(char **)=8
sizeof(struct  person)=24
sizeof(struct  person1)=17
sizeof(struct  person2)=24
sizeof(struct  person4)=48
&per.name  =0x7ffde2520550,per.name  =www.100ask.org
&per.age   =0x7ffde2520558,per.age   =10
&per.score =0x7ffde252055c,per.score =65
&per.id    =0x7ffde2520560,per.id    =123

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值