如何计算结构体大小

如何计算结构体大小
如何计算结构体大小

运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof(char) = 1; sizeof(int) = 4。基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。

C语言中的构造数据类型有三种:数组、结构体和共用体。

数组是相同类型的元素的集合,只要会计算单个元素的大小,整个数组所占空间等于基础元素大小乘上元素的个数。

结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐问题。看下面这样的一个结构体:

ST ruct stu1

{

int i;

char c;

int j;

};

先介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。因此,第一个成员i的偏移量为0。第二个成员c的偏移量是第一个成员的偏移量加上第一个成员的大小(0+4),其值为4;第三个成员j的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1),其值为5。

实际上,由于存储变量时地址对齐的要求,编译器在编译程序时会遵循两条原则:一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)二、结构体大小必须是所有成员大小的整数倍。

对照第一条,上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成8。

对照第二条,结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足要求。

再看一个满足第一条,不满足第二条的情况

struct stu2

{

int k;

short t;

};

成员k的偏移量为0;成员t的偏移量为4,都不需要调整。但计算出来的大小为6,显然不是成员k 大小的整数倍。因此,编译器会在成员t后面补上2个字节,使得结构体的大小变成8从而满足第二个要求。由此可见,大家在定义结构体类型时需要考虑到字节对齐的情况,不同的顺序会影响到结构体的大小。对比下面两种定义顺序

struct stu3

{

char c1;

int i;

char c2;

}

struct stu4

{

char c1;

char c2;

int i;

}

虽然结构体stu3和stu4中成员都一样,但sizeof(struct stu3)的值为12而sizeof(struct stu4)的值为8。

如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。看下面的例子:

struct stu5

{

short i;

struct

{

char c;

int j;

} ss;

int k;

}

结构体stu5的成员ss.c的偏移量应该是4,而不是2。整个结构体大小应该是16。

如何给结构体变量分配空间由编译器决定,以上情况针对的是Linux下的GCC。其他平台的C编译器可能会有不同的处理。

内存对齐节约内存

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格),而称T比S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数

地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上

三个原则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)

另外还可以用

#prgam pack(n)来指定偏移量的大小,n为字节对齐数,其取值为1、2、4、8、16,默认是8,如果这个值比结构体成员的sizeof值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值。

比如:对32位机器,指针大小为4

struct P1 { int a; char b; int c; char d; }; //16

struct P2 { int a; char b; char c; int d; }; //12

struct P3 { short a[3]; char b[3]; }; //10

struct P4 { short a[3]; char *b[3]; }; //20

struct P5 { struct P2 *a; char b; struct P1 c[2]; }; // 40

而:

struct P6 { int a; int b; char c; char d; }; //12

struct P7 { int a; char b; char c; int d; }; //12

struct P8 { short a[3]; char b[3]; }; //10

struct P9 { char *b[3]; short a[3]; }; //20

struct P10 { struct P2 *a;struct P6 c[2]; char b; }; // 32

所以为了节约内存,一个简单的解决方法是:结构体的成员排序应该是从大到小

结构体练习题

算并输出每个人的学号和平均成绩。 2.已知链表结点结构如下,假设动态链表已经建立,请编写删除给定学号的结点的函 数。(只编写删除子函数即可) 3.编写函数实现动态链表的建立。链表结点结构如下,要求在主函数中将你所建立的链 表输出到屏幕上。 4.有10个学生,每个学生的信息包括学号、姓名、3门课的成绩,从键盘输入10个学 生数据存入结构体数组中,要求输出个人总分最高的学生的信息(包括学号、姓名、3门课成绩、总分)。 5.链表的结点数据类型如下: struct node{ int data; struct node *next; }; 链表的建立和输出函数如下,编写将第i个结点删除的函数,并完善主函数,调试运行整个程序。 struct node *creat() { int x; struct node *h,*s,*r; h=(struct node *)malloc(sizeof(struct node)); r=h; scanf("%d",&x); while(x!=-1) { s=(struct node*)malloc(sizeof(struct node)); s->data=x; r->next=s; r=s; scanf("%d",&x); } r->next=NULL; return h; } void print(struct node *h) //打印函数 { struct node *p; p=h->next; if(p==NULL) printf("list is empty!"); else { while(p!=NULL) { printf("%4d",p->data); p=p->next; } } }

类和结构体的区别

类和结构体的区别 1. class和structure很相似,从技术层面讲,class是引用,而 structure则是数值.有人很形象的说 class里有行动,方法,成员,是有机体的结合,而structure则是活生生的有机体, 2. 通俗的理解,class包涵structure, class里有方法拉,成员 拉,什么滴, 而structure只有数据, 二 .类与结构的差别 %%%类成员默认是private,而结构体默认是 public。 1.值类型与引用类型 结构是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,string 对 应 system.string 结构,通过使用结构可以创建更多的值类 型 类是引用类型:引用类型在堆上分配地址 堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑 因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用 注: 1.虽然结构与类的类型不一样,可是他们的基类型都是对象 (object),c#中所有类型的基类型都是object 2.虽然结构的初始化也使用了New 操作符可是结构对象依然分 配在堆栈上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用 2.继承性 结构:不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed . 类:完全可扩展的,除非显示的声明sealed 否则类可以继承其

结构体的指针应用

什么是结构体? 简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以作为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。 定义结构体使用struct修饰符,例如: struct test { float a; int b; }; 上面的代码就定义了一个名为test的结构体,它的数据类型就是test,它包含两个成员a和b,成员a的数据类型为浮点型,成员b的数据类型为整型。由于结构体本身就是自定义的数据类型,定义结构体变量的方法和定义普通变量的方法一样。 test pn1; 这样就定义了一个test结构体数据类型的结构体变量pn1,结构体成员的访问通过点操作符进行,pn1.a=10 就对结构体变量pn1的成员a进行了赋值操作。注意:结构体生命的时候本身不占用任何内存空间,只有当你用你定义的结构体类型定义结构体变量的时候计算机才会分配内存。 结构体,同样是可以定义指针的,那么结构体指针就叫做结构指针。 结构指针通过->符号来访问成员,下面我们就以上所说的看一个完整的例子: #include #include using namespace std; struct test//定义一个名为test的结构体 { int a;//定义结构体成员a int b;//定义结构体成员b }; void main() { test pn1;//定义结构体变量pn1 test pn2;//定义结构体变量pn2 pn2.a=10;//通过成员操作符.给结构体变量pn2中的成员a赋值 pn2.b=3;//通过成员操作符.给结构体变量pn2中的成员b赋值

结构体与共用体相关题目练习

结构体与共用体 1.说明一个结构体变量时系统分配给它的内存是 A)各成员所需要内存量的总和 B)结构体中第一个成员所需内存量 C)成员中占内存量最大者所需的容量 D)结构中最后一个成员所需内存量 2.C语言结构体类型变量在程序执行期间 A)所有成员一直驻留在内存中 B)只有一个成员驻留在内存中 C)部分成员驻留在在内存中 D)没有成员驻留在内存中 3.设有以下说明语句 struct stu { int a ; float b ; } stutype ; 则下面的叙述不正确的是 A) struct 是结构体类型的关键字 B) struct stu 是用户定义的结构体类型 C) stutype 是用户定义的结构体类型名 D) a和b都是结构体成员名 4.设有以下结构类型说明和变量定义,则变量a在内存所占字节数是【】。 struct stud { char num[6]; int s[4]; double ave; } a,*p; 5.程序中有下面的说明和定义 struct abc { int x;char y;} struct abc s1,s2; 则会发生的情况是 A)编译出错B)程序将顺利编译、连接、执行 C)能顺利通过编译、连接、但不能执行 D)能顺利通过编译、但连接出错 6.有如下定义 struct person { char name[9]; int age;}; struct person class[10]={ " Johu", 17,"Paul", 19,"Mary", 18,"Adam", 16}; 根据上述定义,能输出字母M的语句是 A) prinft(" %c\n",class[3].name); B) printf(" %c\n",class[3].name[1]); C) prinft(" %c\n",class[2].name[1]); D) printf(" %c\n",class[2].name[0]);7.下面程序的输出是 A)0 B)1 C)3 D)6 main() { struct cmplx { int x; int y;} cnum[2]={1,3,2,7}; printf("%d\n",cnum[0].y/cnum[0].x*cnum[1].x);} 8.下列程序的输出结果是 A)5 B)6 C)7 D)8 struct abc { int a, b, c; }; main() { struct abc s[2]={{1,2,3},{4,5,6}}; int t; t=s[0].a+s[1].b; printf("%d \n",t);} 9.有以下程序 struct stu { int num;char name[10];int age;}; void fun(struct stu *p) { printf("%s\n" ,(*p).name); } main() { struct stu students[3]={{9801,"Zhang",20} ,{9802,"Wang", 19} , {9803,"Zhao",18} }; fun(students+2);} 输出结果是 A)Zhang B)Zhao C)Wang D)18 10.设有如下定义: struct sk {int a ;float b ;}data ,*p ; 若有p=&data ;,则对data中的a域的正确引用是 A)(*p).data.a B)(*p).a C)p->data.a D)p.data.a 11.下面程序的输出结果为

C语言中不同的结构体类型的指针间的强制转换详解

C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险。只要理解了其内部机制,你会发现C是非常灵活的。 一. 结构体声明如何内存的分布, 结构体指针声明结构体的首地址, 结构体成员声明该成员在结构体中的偏移地址。 变量的值是以二进制形式存储在内存中的,每个内存字节对应一个内存地址,而内存存储的值本身是没有整型,指针,字符等的区别的,区别的存在是因为我们对它们有不同的解读,param的值就是一个32位值,并且存储在某个内存单元中,通过这个32位值就能找到param所指向的结构的起始地址,通过这个起始地址和各个结构所包含变量离起始地址的偏移对这些变量进行引用, param->bIsDisable只是这种引用更易读的写法,只要param是指向 PAINT_PARAM的指针,那么param的值就肯定存在,param存在,偏移量已知,那么param->bIsDisable就肯定存在,只是要记住,param->bIsDisable只是代表了对param一定偏移地址的值。 不是说某个地址有那个结构体你才能引用,即使没有,你也能引用,因为你已经告诉了编译器param变量就是指向一个PAINT_PARAM结构体的变量并且指明了param的值,机器码的眼中是没有数据结构一说的,它只是机械的按照 指令的要求从内存地址取值,那刚才的例子来说,peg->x,peg->y的引用无论 0x30000000是否存在一个eg结构体都是合法的,如果0x30000000开始的8 个字节存在eg结构体,那么引用的就是这个结构体的值,如果这个位置是未定义的值,那么引用的结果就是这8个字节中的未定义值,内存位置总是存在的,而对内存中值的引用就是从这些内存位置对应的内存单元取值。 举个例子: typedefstruct_eg { int x; int y; }eg;

关于返回结构体的函数

(一)不超过8 bytes 的小结构体可以通过EDX:EAX 返回。 本文的范例代码取材于《汇编中函数返回结构体的方法》一文,并在此基础上进行修改和试验。要研究的第一份代码如下,定义一个不超过8 bytes 的小结构体,不超过8 bytes 是因为这个结构体能够用EDX:EAX 容纳,我们之后将看到在release 编译时,编译器能够向返回普通基础类型那样进行返回。 #include //不超过 8 bytes 的“小结构体” struct A { int a; int b; }; //返回结构体的函数 struct A add(int x, int y) { struct A t; t.a = x * y; return t; } int main() { struct A t = add(3, 4); printf("t.a = %ld\n", t.a); return0; } 首先,我们需要解决一个常见困惑,就是要明确这段代码和下面的典型错误代码的区别:char* get_buffer() { char buf[8];

return buf; } 上面的get_buffer 返回的是栈上的临时变量空间,在函数返回后,其所在的空间也就被“回收/释放”了,也就是说函数返回的地址位于栈的增长方向上,是不稳定和不被保证的。 那么返回结构体的函数则不同,你可以发现返回结构体的函数是工作正常有效的。在add 函数中有一个临时性结构体t,毫无疑问,t 将在add 函数返回时被释放,但由于t 被当做“值”进行返回,因此编译器将保证add 的返回值对于add 的调用者(caller)来说是有效的。 另外需要明确的一点是,我个人觉得,现实里这种返回结构体的方式比较少见,后面将会看到这样做会产生临时对象和多余拷贝过程,效率不高。常见方法是传递结构体指针。但作为语言上允许的方式,有必要弄清楚编译器如何实现这种方式,而要弄清楚这个问题,需要查看汇编代码。使用VC6 输入上述代码,下面分别给出其汇编代码。 (1)debug 版本,汇编代码如下。 small_struct_debug 下面是实现方式的栈示意图:

第九章使用结构体类型处理组合数据 c语言

第九章使用结构体类型处理组合数据 1.定义和使用结构体变量 2.结构体数组 3.结构体指针 4.用结构体变量和结构体变量的指针作函数参数 5.用指针处理链表 6.共用体、枚举类型 正文 1.定义和使用结构体变量 若只保存某个学生的学号:可以使用int 变量。 若保存所有学生的学号:可以使用int 型的数组。 同理,若保存所有学生的姓名:可以使用char型的数组。 若保存所有学生某科成绩:可以使用float 型的数组。 但是,如果要同时保存某一个学生的学号,姓名,性别、入学时间及各科成绩,该用什么保存? 自己建立结构体类型 将一个学生的学号、姓名、性别、年龄和地址分别用以下变量来表示: int num; char name[20]; char sex; int age; char addr[30]; Num name sex age score addr 100101 Li Fun M 18 87.5 Beijing 声明一个结构体类型的一般形式为: struct 结构体名 {成员表列=类型名+成员名}; 如:struct student { int num;char name[20];char sex; int age;float score;char addr[30]; } 可以采取以下3种方法定义结构体类型变量:

(1)先声明结构体类型再定义变量名 例如:struct student student1, student2; | | | 结构体类型名结构体变量名 定义了student1和student2为struct student类型的变量,即它们具有struct student 类型的结构. student1 100102 WangLi F 20 98 Beijing student2 100101 ZhangXin M 19 90.5 Shanghai 在定义了结构体变量后,系统会为之分配内存单元。 例如:student1和student2在内存中各占63个字节(4+20+1+4+4+30=63)。(我们的VC) 注意: 将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于后者不仅要求指定变量为结构体类型,而且要求指定为某一特定的结构体类型,因为可以定义出许许多多种具体的结构体类型。 (2)在声明类型的同时定义变量 这种形式的定义的一般形式为: struct结构体名 { 成员表列 }变量名表列; struct student {int num; char name[20]; char sex; int age; float score; char addr[30]; }student1,student2;//它的作用与第一种方法相同,即定义了两个struct //student 类型的变量student1 student2 (3) 直接定义结构体类型变量 //注意: (2)对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。 (3)成员也可以是一个结构体变量。 (4)成员名可以与程序中的变量名相同,二者不代表同一对象。 其一般形式为: struct { 成员表列 }变量名表列; 即不出现结构体名。 例如:struct date

c++中关于结构体长度的计算问题

[C++]字节对齐与结构体大小 [C++] 2010-09-24 21:40:26 阅读172 评论0 字号:大中小订阅 说明: 结构体的sizeof值,并不是简单的将其中各元素所占字节相加,而是要考虑到存储空间的字节对齐问题。这些问题在平时编程的时候也确实不怎么用到,但在一些笔试面试题目中出是常常出现,对sizeof我们将在另一篇文章中总结,这篇文章我们只总结结构体的sizeof,报着不到黄河心不死的决心,终于完成了总结,也算是小有收获,拿出来于大家分享,如果有什么错误或者没有理解透的地方还望能得到提点,也不至于误导他人。 一、解释 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如

有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int 型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。 二、准则 其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则: 1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节; 3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。 三、基本概念

i2c结构体关系

理清i2c中的个结构体关系 通过上面的讲解,已基本上简单地介绍完i2c驱动的方方面面,或许你还是对这 里面的众多结构体之间的联系很迷惑,下面就来分析一下 i2c_driver 、 i2c_client 、i2c_adapter 和 i2c_algorithm 这 4 个数据结构的作用及其盘根错节的关系。 (1)i2c_adapter 与 i2c_algorithm i2c_adapter 对应于物理上的一个适配器,而 i2c_algorithm 对应一套通信方法。一个 I2C 适配器需要 i2c_algorithm 中提供的通信函数来控制适配器上产生特定的 访问周期。缺少 i2c_algorithm 的 i2c_adapter 什么也做不了,因此 i2c_adapter 中包含其使用的 i2c_algorithm 的指针。 i2c_algorithm 中的关键函数 master_xfer() 用于产生 I2C 访问周期需要 的信号,以 i2c_msg (即 I2C 消息)为单位。 i2c_msg 结构体也非常关键,代码清 单给出了它的定义。 1 struct i2c_msg { 2 __u16 addr; /* 设备地址 */ 3 __u16 flags; /* 标志 */ 4 __u16 len; /* 消息长度 */ 5 __u8 *buf; /* 消息数据 */ 6 }; (2)i2c_driver 与 i2c_client i2c_driver 对应一套驱动方法,是纯粹的用于辅助作用的数据结构,它不对应于任何的 物理实体。 i2c_client 对应于真实的物理设备,每个 I2C 设备都需要一个 i2c_client 来描述。 i2c_client 一般被包含在 i2c 字符设备的私有信息结构体中。i2c_driver 与i2c_client 发生关联的时刻在i2c_driver 的attach_adapter() 函数被运行时。 attach_adapter() 会探测物理设备,当确定一 个 client 存在时,把该 client 使用的 i2c_client 数据结构的 adapter 指针指 向对应的 i2c_adapter 。 driver 指针指向该 i2c_driver ,并会调用 i2c_adapter 的 client_register() 函数。相反的过程发生在 i2c_driver 的 detach_client() 函数被调用的时候。 (3)i2c_adpater 与 i2c_client i2c_adpater 与 i2c_client 的关系与 I2C 硬件体系中适配器和设备的关系一致,即 i2c_client 依附于 i2c_adpater 。由于一个适配器上可以连接多个 I2C 设备,所以一个 i2c_adpater 也可以被多个 i2c_client 依附, i2c_adpater 中包 括依附于它的 i2c_client 的链表。 7.2 i2c驱动的编写建议 那么对于一个驱动工程师,如何编写自己的i2c相关的驱动,下面仅提供个参考方案:(1)提供 I2C 适配器的硬件驱动,探测、初始化 I2C 适配器(如申请 I2C 的 I/O 地 址和中断号)、驱动 CPU 控制的 I2C 适配器从硬件上产生各种信号以及处理 I2C 中断等。 (2)提供 I2C 适配器的 algorithm ,用具体适配器的 xxx_xfer() 函数填充 i2c_algorithm 的 master_xfer 指针,并把 i2c_algorithm 指针赋值给 i2c_adapter 的 algo 指针。 (3)实现I2C 设备驱动与i2c_driver 接口,用具体设备yyy 的yyy_attach_adapter() 函数指针、yyy_detach_client() 函数指针和yyy_command() 函数指针的赋值给i2c_driver 的attach_adapter 、

C语言结构体习题及答案

第9章结构体 1.定义以下结构体类型 struct s { int a; char b; float f; }; 则语句printf("%d",sizeof(struct s))的输出结果为【】。 A) 3 B) 7 C) 6 D) 4 2.当定义一个结构体变量时,系统为它分配的内存空间是【】 A)结构中一个成员所需的内存容量 B)结构中第一个成员所需的内存容量 C)结构体中占内存容量最大者所需的容量 D)结构中各成员所需内存容量之和 3.定义以下结构体类型 struct s { int x; float f; }a[3]; 语句printf("%d",sizeof(a))的输出结果为【】 A) 4 B) 12 C) 18 D) 6 4.定义以下结构体数组 struct c { int x; int y; }s[2]={1,3,2,7}; 语句printf("%d",s[0].x*s[1].x)的输出结果为【】 A) 14 B) 6 C) 2 D) 21 5.运行下列程序段,输出结果是【】 struct country { int num; char name[10]; }x[5]={1,"China",2,"USA",3,"France",4, "England",5, "Spanish"}; struct country *p; p=x+2; printf("%d,%c",p->num,(*p).name[2]); A) 3,a B) 4,g C) 2,U D) 5,S

6.下面程序的运行结果是【】。 struct KeyWord { char Key[20]; int ID; }kw[]={"void",1,"char",2,"int",3,"float",4,"double",5}; main() { printf("%c,%d\n",kw[3].Key[0], kw[3].ID); } A) i,3 B) n,3 C) f,4 D) l,4 7.定义以下结构体类型 struct student { char name[10]; int score[50]; float average; }stud1; 则stud1占用内存的字节数是【】。 A) 64 B) 114 C) 228 D) 7 8.如果有下面的定义和赋值,则使用【】不可以输出n中data的值。struct SNode { unsigned id; int data; }n,*p; p=&n; A) p.data B) n.data C) p->data D) (*p).data 9.根据下面的定义,能输出Mary的语句是【】。 struct person { char name[9]; int age; }; struct person class[5]={"John",17,"Paul",19,"Mary",18,"Adam",16}; A) printf("%s\n",class[1].name); B) printf("%s\n",class[2].name); C) printf("%s\n",class[3].name);

实验二 有关结构体和共用体的程序设计参考答案

实验2:有关结构与共同体的程序设计 一、实验目的 1.掌握结构体类型和结构体变量的定义、引用方法; 2.掌握结构体类型数组和结构体类型指针的概念和应用; 3.掌握共用体的概念和使用; 4.能用结构体类型解决实际问题。 二、实验要求 1.了解结构体类型和简单数据类型、结构体类型和共用体类型的区别; 2.复习结构体变量、结构体指针与结构体数组的相关理论课程; 3.完成各项实验任务及问题讨论。 三、实验内容 1.输入和运行下面的程序,并分析输出结果。 ①#include main() { union EXAMPLE { struct { int x,y; }in; int a,b; }e; e.a=1;e.b=2; e.in.x=e.a*e.b; e.in.y=e.a+e.b; printf(“%d,%d\n”,e.in.x,e.in.y); } 输出结果:4,8 解答:对于共用体e,有三个成员in,a,b,它们在内存中的覆盖关系如下图: 即e.a,e.b,e.in.x占相同的内存单元, 执行e.a=1;e.b=2;后e.a,e.b,e.in.x的值为2, 执行e.in.x=e.a*e.b;后e.a,e.b,e.in.x的值为2*2=4, 执行e.in.y=e.a+e.b;e.in.y=4+4=8。

main() { union { int i[2]; long k; char c[4]; }r,*s=&r; s->i[0]=0x39; s->i[1]=0x38; printf(“%c\n”,s->c[0]); } 输出结果:9 解答:对于共用体r,有三个成员i,k,c,它们在内存中的覆盖关系如下图: i[0] k i[1] 执行s->i[0]=0x39;s->i[1]=0x38;赋值语句后,内存中存储的数据值如上图所示。 2.完善程序 ①下面程序的功能是输入学生的姓名和成绩,然后输出。 #include struct studinf { char name[20];/* 学生姓名*/ int score;/* 学生成绩*/ } stu, *p; void main ( ) { p=&stu; printf("Enter name:"); gets(p->name); printf("Enter score: "); scanf("%d",&(*p).score); printf("Output: %s, %d\n",https://www.360docs.net/doc/ae11294150.html,,stu.score); } 目标:掌握结构体成员引用的三种等价表达方式。 ②输入N个整数,储存输入的数及对应的序号,并将输入的数按从小到大的顺序进行排列。要求:当两个整数相等时,整数的排列顺序由输入的先后次序决定。例如:输入的第3个整数为5,第7个整数也为5,则将先输入的整数5排在后输入的整数5的前面。程序如下:

(1)定义结构体的关键字是

(1) 定义结构体的关键字是,定义共用体的关键字是。 (2) 结构体和共用体的相同点是,不同点是。 (3) 若有以下定义和语句,则sizeof(a)的值是__ ___,而sizeof(b)的值是__ _。struct tu { int m; char n; int y;}a; struct { float p, char q; struct tu r} b; (4) 设有下面结构类型说明和变量定义,则变量a在内存所占字节数是。如果将该结构改成共用体,结果为。 struct stud { char num[6]; int s[4]; double ave; } a; (5) 下面程序用来输出结构体变量ex所占存储单元的字节数,请填空。 struct st { char name[20]; double score; }; main() { struct st ex ; printf("ex size: %d\n",sizeof( )); } (6) 下面定义的结构体类型拟包含两个成员,其中成员变量info用来存入整形数据;成员变量link是指向自身结构体的指针,请将定义补充完整。 struct node { int info; link; } (7) 以下程序执行后输出结果是。 main() { union { unsigned int n; unsigned char c; } u1; u1.c='A'; printf("%c\n",u1.n); } (8) 变量root如图所示的存储结构,其中sp是指向字符串的指针域,next是指向该结构的指针域,data用以存放整型数。请填空,完成此结构的类型说明和变量root的定义。 root struct { char *sp ; __ __; _ _; } root; 2. 阅读下面的程序,写出程序结果 (1) struct info { char a,b,c;}; main() { struct info s[2]={{‘a’,‘b’,‘c’},{‘d’,‘e’,‘f’}};int t; t=(s[0].b-s[1].a)+(s[1].c-s[0].b); printf("%d\n",t); } (2)

结构体指针的典型应用(通过姓名查找相关信息)

对录入的学生的学号、年龄、分组、成绩通过输入姓名进行查找,如果没有则输出“not exist!”。 #include "stdafx.h" #include #include "string.h" void main(){ struct stu{ char *name; int num; int age; char group; float score; }stus[] = { {"Zhou ping", 5, 18, 'C', 145.0}, {"Zhang ping", 4, 19, 'A', 130.5}, {"Liu fang", 1, 18, 'A', 148.5}, {"Cheng ling", 2, 17, 'F', 139.0}, {"Wang ming", 3, 17, 'B', 144.5} /*可以输入更多*/ }, *ps; char st_name[23]; /*字符数可以增加*/ printf("input name:"); gets(st_name); const n=sizeof(stus) / sizeof(struct stu); int cla[n]; int h; for(h=0;h

C语言结构体习题及答案知识讲解

C语言结构体习题及 答案

第9章结构体 1.定义以下结构体类型 struct s { int a; char b; float f; }; 则语句printf("%d",sizeof(struct s))的输出结果为【】。 A) 3 B) 7 C) 6 D) 4 2.当定义一个结构体变量时,系统为它分配的内存空间是【】 A)结构中一个成员所需的内存容量 B)结构中第一个成员所需的内存容量 C)结构体中占内存容量最大者所需的容量 D)结构中各成员所需内存容量之和 3.定义以下结构体类型 struct s { int x; float f; }a[3]; 语句printf("%d",sizeof(a))的输出结果为【】 A) 4 B) 12 C) 18 D) 6 4.定义以下结构体数组 struct c { int x; int y; }s[2]={1,3,2,7}; 语句printf("%d",s[0].x*s[1].x)的输出结果为【】 A) 14 B) 6 C) 2 D) 21

5.运行下列程序段,输出结果是【】 struct country { int num; char name[10]; }x[5]={1,"China",2,"USA",3,"France",4, "England",5, "Spanish"}; struct country *p; p=x+2; printf("%d,%c",p->num,(*p).name[2]); A) 3,a B) 4,g C) 2,U D) 5,S 6.下面程序的运行结果是【】。 struct KeyWord { char Key[20]; int ID; }kw[]={"void",1,"char",2,"int",3,"float",4,"double",5}; main() { printf("%c,%d\n",kw[3].Key[0], kw[3].ID); } A) i,3 B) n,3 C) f,4 D) l,4 7.定义以下结构体类型 struct student { char name[10]; int score[50]; float average; }stud1; 则stud1占用内存的字节数是【】。 A) 64 B) 114 C) 228 D) 7 8.如果有下面的定义和赋值,则使用【】不可以输出n中data的值。 struct SNode { unsigned id; int data; }n,*p; p=&n; A) p.data B) n.data C) p->data D) (*p).data 9.根据下面的定义,能输出Mary的语句是【】。

第9章结构体类型与共用体类型习题及答案

第九章结构体类型与公用体类型习题及其答案9-3编写程序,使用结构体类型,输出一年十二个月的英文名称及相应天数。 解:#include "stdio.h" struct date { char month[10] ; int daynumber ; } main() { int i ; date a[12] ={{"January",31},{"February",29},{"March",31},{"Aprial",30}, {"May",31},{"June",30},{"july",31},{"August",31},{"September",30} ,{"October",31},{"November",30},{"December",31}} ; for(i=0;i<12;i++); printf("%d 月:%s %d\n",i+1,a[i].month,a[i].daynumber) ; } 思考:如何对结构体变量进行初始化?对结构体变量的引用为何要体现为分量(或成员)的引用? 9-4 编写程序求空间任一点到原点的距离,点用结构体描述。并请考虑求空间中任意两点的距离的程序。 解:#include "stdio.h" #include "math.h" struct point { float x ; float y ; float z ; } void main() { double d1,d2,d ;

point p1,p2 ; printf("请输入第一个点的坐标:"); scanf("%f,%f,%f",&p1.x,&p1.y,&p1.z); printf("请输入第二个点的坐标:"); scanf("%f,%f,%f",&p2.x,&p2.y,&p2.z); d1=sqrt(p1.x*p1.x+p1.y*p1.y+p1.z*p1.z); d2=sqrt(p2.x*p2.x+p2.y*p2.y+p2.z*p2.z); d=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)+(p2.z-p1.z)*( p2.z-p1.z)); printf("第一个点到原点的距离:%f\n",d1); printf("第二个点到原点的距离:%f\n",d2); printf("两点间的距离:%f\n",d); } 9-5 编写输入、输出10个朋友数据的通讯录程序,每个朋友数据包括姓名、地址、邮编、电话、传呼、手机等数据。 解:#include "stdio.h" struct AddressBook { char name[10] ; char address[30] ; char mailnumber[7] ; char telphone[12] ; char byphone[16] ; char movephone[1] ; } void main() { int i ; AddressBook fd[10] ; for(i=0;i<10;i++) { printf("请输入第%d个朋友的信息:\n",i+1); printf("姓名:");

javastruct()关于java结构体

javastruct A library to treat java objects as C structs. Project HomeDownloads Wiki IssuesSource Search for HowToUseJavaStruct This page explains how to use JavaStruct library. Featured, Phase-Implementation Updated Feb 4, 2010 by mda...@https://www.360docs.net/doc/ae11294150.html, Introduction Struct classes can be used to greatly simplfy network protocol codes of Java applications when working with embedded devices and other applications which uses C style structs. Instead of manually encoding and decoding messages, JavaStruct allows programmers to treat java classes as c structs. JavaStruct uses Java 5 annotations to mark Classes and fields as structs. JavaStruct is not the first attempt to provide struct like functionality, Jean-Marie Dautelle's Javolution library also has an excellent struct implementation. But instead of using special classes in Javolution, POJO approach is preferred JavaStruct. General usage JavaStruct fa?ade class is used to pack and unpack struct classes. Below is a simple unit test method for checking a struct class. S truct fields hasan order value, because Java JVM specification does not tell anything about order of the class members. They are ordered as their appearance in Sun's implementation but it differs on other JVM's. So every Struct field has to supply an order value. @StructClass public class Foo{ @StructField(order =0) public byte b; @StructField(order =1) public int i; } try{ // Pack the class as a byte buffer Foo f =new Foo(); //媒体处理器 f.b =(byte)1; f.i =1;

定义结构体的关键字是

1. 填空题 (1) 定义结构体的关键字是,定义共用体的关键字是。 (2) 结构体和共用体的相同点是,不同点是。 (3) 若有以下定义和语句,则sizeof(a)的值是__ ___,而sizeof(b)的值是__ _。struct tu { int m; char n; int y;}a; struct { float p, char q; struct tu r} b; (4) 设有下面结构类型说明和变量定义,则变量a在内存所占字节数是。如果将该结构改成共用体,结果为。 struct stud { char num[6]; int s[4]; double ave; } a; (5) 下面程序用来输出结构体变量ex所占存储单元的字节数,请填空。 struct st { char name[20]; double score; }; main() { struct st ex ; printf("ex size: %d\n",sizeof( )); } (6) 下面定义的结构体类型拟包含两个成员,其中成员变量info用来存入整形数据;成员变量link是指向自身结构体的指针,请将定义补充完整。 struct node { int info; link; } (7) 以下程序执行后输出结果是。 main() { union { unsigned int n; unsigned char c; } u1; u1.c='A'; printf("%c\n",u1.n); } (8) 变量root如图所示的存储结构,其中sp是指向字符串的指针域,next是指向该结构的指针域,data用以存放整型数。请填空,完成此结构的类型说明和变量root的定义。 root sp next data struct { char *sp ; __ __; _ _; } root; 2. 阅读下面的程序,写出程序结果 (1) struct info { char a,b,c;}; main() { struct info s[2]={{‘a’,‘b’,‘c’},{‘d’,‘e’,‘f’}};int t; t=(s[0].b-s[1].a)+(s[1].c-s[0].b); printf("%d\n",t); }

相关文档
最新文档