这个struct file 结构体score *next;定义在结构体中是怎么使用的,我怎么看不明白???

博客访问: 215416
博文数量: 108
博客积分: 3265
博客等级: 中校
技术积分: 1197
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
//对指向结构体类型变量的正确使用。输入一个结构体类型变量的成员,并输出。
/*使用malloc()需要* /
struct data / *定义结构体* /
&& int day,month,
struct stu /*定义结构体* /
&&& char name[20];
/嵌*套的结构体类型成员*/
main() /*定义m a i n ( ) 函数* /
&&&& struct stu * 定/*义结构体类型指针*/
& & &student=malloc(sizeof(struct stu)); 为/指* 针变量分配安全的地址*/
&&&& printf("Input name,number,year,month,day:\n");
&&&& scanf("%s",student->name); 输/*入学生姓名、学号、出生年月日*/
&&&& scanf("%ld",&student->num);
&&&& scanf("%d%d%d",&student->birthday.year,&student->birthday.month,
&&&& &student->birthday.day);
&&&& printf("\nOutputname,number,year,month,day\n");
&&&& /*打印输出各成员项的值*/
&&&& printf("%20s%10ld%10d//%d//%d\n",student->name,student->num,
&&&& student->birthday.year,student->birthday.month,
&&&& student->birthday.day);
程序中使用结构体类型指针引用结构体变量的成员,需要通过C提供的函数malloc()来为指针分配安全的地址。函数sizeof()返回值是计算给定数据类型所占内存的字节数。指针所指各成员形式为:
student->name
student->num
student->birthday.year
student->birthday.month
student->birthday.day
===============================
struct data
&&& intday,month,
struct stu/*定义结构体*/
&&& char name[20];
&&& /嵌*套的结构体类型成员*/
struct stu student[4],*p;定/*义结构体数组及指向结构体类型的指针*/
作p=student,此时指针p就指向了结构体数组student。
p是指向一维结构体数组的指针,对数组元素的引用可采用三种方法。
student+i和p+i均表示数组第i个元素的地址,数组元素各成员的引用形式为:
(student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i
与&student[i]意义相同。
若p指向数组的某一个元素,则p++就指向其后续元素。
3)指针的数组表示法
若p=student,我们说指针p指向数组student,p[i]表示数组的第i个元素,其效果与
student[i]等同。对数组成员的引用描述为:p[i].name、p[i].num等。
//程序示例:
structdata/*定义结构体类型*/
&&&& intday,month,
structstu/*定义结构体类型*/
&&&& char name[20];
&&&& structstu*p,student[4]=
&&&&&&&& {"liying",1,},
&&&&&&&& {"wangping",2,},
&&&&&&&& {"libo",3,},
&&&&&&&& {"xuyan",4,}
/*定义结构体数组并初始化*/
&&&& p=/*将数组的首地址赋值给指针p,p指向了一维数组student*/
&&&& printf("\n1----Outputname,number,year,month,day\n");
&&&& for(i=0;i<4;i++)/*采用指针法输出数组元素的各成员*/
&&&& printf("%20s%10ld%10d//%d//%d\n",(p+i)->name,(p+i)->num,
&&&& (p+i)->birthday.year,(p+i)->birthday.month,
&&&& (p+i)->birthday.day);
//结构指针变量作函数参数
struct stu
&&&& char *
&&&& char ***;
&&&&&{101,"Li ping",'M',45},
&&&& {102,"Zhang ping",'M',62.5},
&&&& {103,"He fang",'F',92.5},
&&&& {104,"Cheng ling",'F',87},
&&&& {105,"Wang ming",'M',58},
&&&& struct stu *
&&&& void ave(struct stu *ps);
&&&& ave(ps);
void ave(struct stu *ps)
&&&& int c=0,i;
&&&& float ave,s=0;
&&&& for(i=0;i<5;i++,ps++)
&&&&&&&&&& s+=ps->
&&&&&&&&&& if(ps->score<60) c+=1;
&&&& printf("s=%f\n",s);
&&&& ave=s/5;
&&&& printf("average=%f\ncount=%d\n",ave,c);
测试环境:VC++6.0
输出结果:
s=345.000000
average=69.000000
Press any key to continue
阅读(16458) | 评论(1) | 转发(3) |
相关热门文章
给主人留下些什么吧!~~
为什么不给malloc强制转化为stu?struct&stu&*&定/*义结构体类型指针*/&&&&&&student=malloc(sizeof(struct&stu));&为/指*&针变量分配安全的地址*/
请登录后评论。如何计算结构体大小?
我先定义了一个结构体&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&k&&struct&/span& &span class=&n&&X&/span&
&span class=&p&&{&/span&
&span class=&kt&&char&/span& &span class=&n&&a&/span&&span class=&p&&;&/span&
&span class=&kt&&float&/span& &span class=&n&&b&/span&&span class=&p&&;&/span&
&span class=&kt&&int&/span& &span class=&n&&c&/span&&span class=&p&&;&/span&
&span class=&kt&&double&/span& &span class=&n&&d&/span&&span class=&p&&;&/span&
&span class=&kt&&unsigned&/span& &span class=&n&&e&/span&&span class=&p&&;&/span&
&span class=&p&&};&/span&
&/code&&/pre&&/div&由于存储变量时地址对齐的要求,所以这个结构体大小应该是32。&br&&img src=&/8c297c6c9d9a9bfde20417_b.jpg& data-rawwidth=&516& data-rawheight=&325& class=&origin_image zh-lightbox-thumb& width=&516& data-original=&/8c297c6c9d9a9bfde20417_r.jpg&&&br&如果我多定义一个任意型的指针&br&&div class=&highlight&&&pre&&code class=&language-text&&struct X
&/code&&/pre&&/div&按照地址对齐的要求,这样结构体大小应该是40,但它仍然是32。&br&&img src=&/f0f4b5bbc8be42249acdd_b.jpg& data-rawwidth=&504& data-rawheight=&330& class=&origin_image zh-lightbox-thumb& width=&504& data-original=&/f0f4b5bbc8be42249acdd_r.jpg&&&br&我再加一个任意型的指针&br&&div class=&highlight&&&pre&&code class=&language-text&&struct X
double *g;
&/code&&/pre&&/div&结果这样结构体大小就直接变成40了。如果指针大小是地址总线大小的话,2个指针就是8字节,加上原来的32字节也刚好等于40字节,并且也满足存储变量时地址对齐的要求。但是为什么刚才加一个指针不变,两个就变了。&br&&img src=&/24af33d79cdd0b352efbd_b.jpg& data-rawwidth=&590& data-rawheight=&336& class=&origin_image zh-lightbox-thumb& width=&590& data-original=&/24af33d79cdd0b352efbd_r.jpg&&所以请问一下各位结构体大小应该如何计算。
我先定义了一个结构体struct X
unsigned e;
由于存储变量时地址对齐的要求,所以这个结构体大小应该是32。…
我来补充一下匿名用户的答案。第一个图是这样的struct X {
// 1 bytes
char padding1[3]; // 3 bytes
// 4 bytes
// 4 bytes
char padding2[4]; // 4 bytes
// 8 bytes
unsigned e;
// 4 bytes
char padding3[4]; // 4 bytes
padding1的存在是因为,offset(b)必须能够被align(b)整除,所以塞三个charpadding2的存在是因为,offset(d)必须能够被align(d)整除,所以塞4个char对于所有基本类型,align(T)==sizeof(T),所以有了上面两条,那align(X)是多少呢?当然就是所有成员里面align最大的那个,是align(d)==8好了,因此sizeof(X)必须能够被align(X)整除,就有了padding3。
一开始的时候是这样的struct X {
// 1 bytes
char padding1[3]; // 3 bytes
// 4 bytes
// 4 bytes
char padding2[4]; // 4 bytes
// 8 bytes
unsigned e;
// 4 bytes
char padding3[4]; // 4 bytes
加了一个指针以后是这样的struct X {
// 1 bytes
char padding1[3]; // 3 bytes
// 4 bytes
// 4 bytes
char padding2[4]; // 4 bytes
// 8 bytes
unsigned e;
// 4 bytes
// 4 bytes
再加一个指针以后是这样的struct X {
// 1 bytes
char padding1[3]; // 3 bytes
// 4 bytes
// 4 bytes
char padding2[4]; // 4 bytes
// 8 bytes
unsigned e;
// 4 bytes
// 4 bytes
double *g;
// 4 bytes
char padding3[4]; // 4 bytes
这样就好懂多了吧?
Woo,最后一个应该是被编译器当成柔性数组了。1)什么是柔性数组?struct array
嗯,上面的int x[0]就是柔性数组,一般数组长度定义为0,不能被编译器编译通过,但是,这里用在结构体最后一个元素,且长度为0,就是柔性数组,这里也是特列。一般柔性数组占用结构体大小为0,也就是说,他就是用来做偏移量标记的。关于楼主的问题,下面的结构体strut array
//这里的相当于int p[0],然后被编译器当做柔性数组来优化了。所以,size为0
这里,再次强调一下,柔性数组必须是结构体的最后一个成员。
直观点说明一下,我觉得应该是这个样子。说的不对的,请大家指正。三种结构体分别如图所示。
首先来点直观的:
16 |dddddddd| 23
16 |dddddddd| 23
24 |eeeeffff| 31
16 |dddddddd| 23
24 |eeeeffff| 31
不过具体的对齐方式实际上是可调的,比如在gcc下对结构体使用 __attribute__ ((packed)) 就会变成这个样子:
16 |dddddddd| 23
24 |eeeeffff| 31
32 |gggg|???
话到这里还没说完,上面说的都是针对x86而言的,如果在arm上,你将会看到这个:
|abbbbccc| 7
|cddddddd| 15
16 |deeeefff| 23
24 |fgggg|??
但这样似乎又太丑了,那么让我们再给b和c加上 __attribute__ ((aligned(4))) 这回看起来是这个样子的——
12 |dddd| 15
16 |dddd| 19
20 |eeee| 23
24 |ffff| 27
28 |gggg| 31
看题主用vs,那应该就是windows下了。windows下是强制K字节基本对象必须按照K字节对齐,也就是double必须按8字节对齐。Linux下没windows严格,对于double类型只需要按4字节边界对齐即可,所以在Linux下可能结果就不一样了。
标准没有硬性规定怎样对齐,不同架构下int和指针的大小也不一样,相同架构下编译器不同,对齐策略也可能不同,而且编译器不会有确定的规则,除非源码里显式指定(例如#pragma pack n)。这三个struct在64bit gcc和clang下的结果是32、40、48。所以这个问题的答案是,你不告诉编译器怎么对齐,那它爱怎么对齐就怎么对齐,也不保证永远这么对齐。依赖未定义行为就是作死……
对齐模数的计算方法:一种数据类型的对齐模数,等于一个该数据类型的变量在内存中占用的字节数。一个结构体变量在内存中占用的字节数的计算方法:1. 结构体变量的各成员是按顺序存储的,但不一定是连续存储的。2. 每个成员在结构体变量中的存储位置(相对于结构体变量的首地址的地址),必须是其对齐模数的整数倍。3. 整个结构体变量在内存中占用的字节数,必须是所有成员的对齐模数的最大值的整数倍。
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 lua struct c 结构体 的文章

 

随机推荐