struct

本文部分转载自http://www.cnblogs.com/qyaizs/articles/2039101.html,在此感谢作者!

 1 首先://注意在C和C++里不同
    在C中定义一个结构体类型要用typedef:
    typedef struct Student
    {
    int a;
    }Stu;
    于是在声明变量的时候就可:Stu stu1;(如果没有typedef就必须用struct Student stu1;来声明)
    这里的Stu实际上就是struct Student的别名。Stu==struct Student
    另外这里也可以不写Student(于是也不能struct Student stu1;了,必须是Stu stu1;)
    typedef struct
    {
    int a;
    }Stu;
    但在c++里很简单,直接
    struct Student
    {
    int a;
    };    
    于是就定义了结构体类型Student,声明变量时直接Student stu2;
======================================================================================

  2.其次:
    在c++中如果用typedef的话,又会造成区别:
    struct   Student   
    {   
    int   a;   
    }stu1;//stu1是一个变量  

 
    typedef   struct   Student2   
    {   
    int   a;   
    }stu2;//stu2是一个结构体类型=struct Student  

 
    使用时可以直接访问stu1.a
    但是stu2则必须先   stu2 s2;
    然后               s2.a=10;

 

 typedef struct和struct的区别:

 

 

    typedef struct tagMyStruct
    {
     int iNum;
     long lLength;
    } MyStruct;

    上面的tagMyStruct是标识符,MyStruct是变量类型(相当于(int,char等))。

 

 

    这语句实际上完成两个操作:

      1) 定义一个新的结构类型

    struct tagMyStruct
    {  
     int iNum;
     long lLength;
    };

  分析:tagMyStruct称为“tag”,即“标签”,实际上是一个临时名字,不论是否有typedefstruct 关键字和tagMyStruct一起,构成了这个结构类型,这个结构都存在。

  我们可以用struct tagMyStruct varName来定义变量,但要注意,使用tagMyStruct varName来定义变量是不对的,因为struct 和tagMyStruct合在一起才能表示一个结构类型。

  2) typedef为这个新的结构起了一个名字,叫MyStruct。

    typedef struct tagMyStruct MyStruct;

  因此,MyStruct实际上相当于struct tagMyStruct,我们可以使用MyStruct varName来定义变量。

  2.

    typedef struct tagMyStruct
    {
     int iNum;
     long lLength;
    } MyStruct;

    在C中,这个申明后申请结构变量的方法有两种:

    (1)struct tagMyStruct 变量名

    (2)MyStruct 变量名

    在c++中可以有

    (1)struct tagMyStruct 变量名

    (2)MyStruct 变量名

    (3)tagMyStruct 变量名

 

2016-10-23 17:23:16

 

计算机组成原理教导我们,这样有助于加快计算机的取数速度,否则就得多花指令周期了。

 

为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上。
字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

 

 

结构体对齐问题,结构体以体内字段的内存占用数最大的字段为基本对齐基础。

指定对齐方式

可以使用#pragma pack(N)来指定结构体成员的对齐方式
对于指定的对齐方式,其成员的地址偏移以及结构的总的大小也有下面三个约束条件

    1. 结构体第一个成员的地址和结构体的首地址相同
    2. 结构体每个成员的地址偏移需要满足:N大于等于该成员的大小,那么该成员的地址偏移需满足默认对齐方式(地址偏移是其成员大小的整数倍);N小于该成员的大小,那么该成员的地址偏移是N的整数倍。(结构体成员对齐的规则如下: 将自己的本身在内存中实际占用的字节和当前由#pragma pack(n)设定的n进行比较,取其中最下的那个作为结构体当前成员的对齐方式,但是不影响其他结构体成员的对齐方式。)
    3. 结构体总的大小需要时N的整数倍,如果不是需要在结构体的末尾进行填充。
    4. 如果N大于结构体成员中最大成员的大小,则N不起作用,仍然按照默认方式对齐。

 

 

 

 

 

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <errno.h>
 4 #include <stdlib.h>
 5 #include <signal.h>
 6 #include <string.h>
 7 #include <iostream>
 8 #include <sys/wait.h>
 9 #pragma pack(2)//#pragma pack(n)这个预处理,主要的功能是改变内存对齐方式的选项,按照给定的n字节进行内存对齐
10 using namespace std;
11 struct test{
12     char a;
13     int b;
14     short c;
15 }test;
16 struct test1{
17     char a;
18     long b;
19     short c;
20     char d;
21 }test1;
22 struct test2{
23    char a;
24    short b;
25    char c;
26    long d;
27 }test2;
28 struct buffer
29 {
30     long data_len;   //长度
31     char d;
32     char data[0];  //起始地址
33 }buffer;
34 int main()
35 {
36     printf("test$$$$$$$$$$$$$$$:%lu\n", sizeof(test));//12
37     printf("%#x %#x %#x\n", &test.a, &test.b, &test.c);
38     printf("test1@@@@@@@@@@@@@:%lu\n", sizeof(test1));//24
39     printf("%#x %#x %#x %#x\n", &test1.a, &test1.b, &test1.c, &test1.d);
40     printf("test2###########:%lu\n", sizeof(test2));//16
41     printf("%#x %#x %#x %#x\n", &test2.a, &test2.b, &test2.c, &test2.d);
42     printf("buffer############:%lu\n", sizeof(buffer));//16
43     printf("%#x %#x %#x\n", &buffer.data_len, &buffer.d, &buffer.data);
44 
45     return 0;
46 }

 

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 #include <iostream>
 6 using namespace std;
 7 typedef struct test0{
 8     char a[3];
 9     int b;
10     char c;
11 }sttest0;
12 typedef struct test1{
13     char a[4];
14     int b;
15     char c;
16 }sttest1;
17 typedef struct test2{
18     char a[7];
19     int b;
20     char c;
21 }sttest2;
22 typedef struct test3{
23     char a[8];
24     int b;
25     char c;
26 }sttest3;
27 typedef struct test4{
28     char a[9];
29     int b;
30     char c;
31 }sttest4;
32 int main()
33 {
34     printf("%lu %lu %lu %lu %lu\n", sizeof(sttest0), sizeof(sttest1), sizeof(sttest2), sizeof(sttest3), sizeof(sttest4));
35 
36     printf("address$$$$$$$$$$$$$$$$$\n");
37     sttest0 t0;
38     sttest1 t1;
39     printf("%p %p %p\n", &t0.a, &t0.b, &t0.c);
40     printf("%p %p %p\n", &t1.a, &t1.b, &t1.c);
41     return 0;
42 }

 

 

 

posted @ 2015-09-07 14:24  PKICA  阅读(473)  评论(0编辑  收藏  举报