小女不会,求大神过来相教

若能使程序运行后的输出结果如下:
201501
201502
201503
则空白处填写的表达式或语句应该是
#include 
struct student
 { 
     int age;
     char num[8];
  };
   
int main()
{
    struct student stu[3]={{20,"201501"},{21,"201502"},{19,"201503"}};
    struct student *p=stu;
    
    ____________________
     
    return 0;
}

A.
    printf("%s\n",(p++).num);
    printf("%s\n",(p++).num);
    printf("%s\n",(p++).num);

B.
    printf("%s\n",(++p)->num);
    printf("%s\n",(++p)->num);
    printf("%s\n",(*p).num);

C.
    printf("%s\n",stu[0]->num);
    printf("%s\n",stu[1]->num);
    printf("%s\n",stu[2]->num);

D.
    printf("%s\n",(*p).num);
    printf("%s\n",(++p)->num);
    printf("%s\n",stu[2].num);
我感觉好像都对啊!!!好纠结。可否挨个讲一下?
还有这题:
若有以下说明,则下面哪个叙述是正确的(已知short占2个字节,float占4个字节)。
struct 
{   
    short a;
    float b;
} v1;

union 
{   
    short a;
    float b;
} v2;

A.
执行sizeof(v1)获得的结果是8个字节,对结构体变量v1中的任何一个成员都可以进行初始化。

B.
执行sizeof(v2)获得的结果是6个字节,对共用体变量v2中的任何一个成员都可以进行初始化。

C.
执行sizeof(v2)获得的结果是6个字节,只能对共用体变量v2中的第一个成员进行初始化。

D.
执行sizeof(v1)获得的结果是4个字节,对结构体变量v1中的任何一个成员都可以进行初始化。
我感觉v1是六个字节,而v2是四个字节……

应该选D。
A和C,p是指针,因此取成员值时应该为(p++)->num, stu[N]是实体,取成员值时应该是 stu[0].num;
B选项,考察++p和p++的区别,p++先取值后自加,因此(p++)的值还是p;++p先自加再取值,所以(++p)的值是(p+1),
所以B选项第一行打印的是201502.

粗看一下是D
指针操作么。P是指针,所以P取值用->,stu是数组实例,所以stu取值用.。
A 首先P指针用.取值错误
B ++P和P++的区别在于,++ P是先执行++操作,后取值,P++是先取值,后执行++操作,所以第一次—(++p)->num应该显示的是201502
C 应该用.
D *p 指取指针p的实例,因此用.

选D,因为p是指针,所以不是使用p.num的使用方式,指针的使用时:p->num,同理,C也是错的,至于B的错误在于第一个选项的地址是stu[1]而不是stu[0]的,因为他是先对p进行操作了

第二题选A,由于发生了结构体的对齐,导致short后面留了2个字节的空白,后面才跟的是float,所以加起来总共是8字节,而v2确实占用4字节

第二题是结构体内存对齐,以及联合体大小问题。
不明白的话可以自己写程序,用sizeof看一下就知道了。

v1 8个字节,结构体按照最长的成员对齐
v2 4个字节,联合按所有类型的基本长度的最小公倍数

第二题选A,BC答案错在与共用体占用的内存为最大的一个成员所占的内存,则为4. D答案错的很明显,结构体内存是成员内存相加,同时考虑对齐方式。A答案是对的,结构体发生了对齐,short后面有两个空字节。