基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量。
需要注意的是,结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。
结构体的定义和定义结构体变量:
一
标准的结构体定义如下:
struct stuff{
char job[20];
int age;
float height;
};
定义结构体变量 struct stuff Lvweining;
二
struct stuff{
char job[20];
int age;
float height;
}Lvweining,Qiji;
这种方法等价于上面的结构体标准定义加上定义结构体变量。这就像int a,b一样的道理,a,b的类型是int ,Lvweining,Qiji
的类型是struct stuff
结构体。
三
struct{
char job[20];
int age;
float height;
}Lvweining;
如果该结构体你只用一个变量Lvweining
就够了,而不需要再去定义其他的结构体变量,那么你可以使用这种方法 。
结构体的内部成员赋值:
使用第一种结构体定义,那么定义结构体变量的时候,可如下赋值:
struct stuff Lvweining = {"manager",30,185};
不过整体赋值仅限于定义结构体变量的时候,在使用过程中只能对成员逐一赋值,这和数组的赋值非常类似。struct stuff faker = Lvweining;
3.结构体成员依次赋值,较为麻烦
Lvweining.job[0] = 'M';
Lvweining.job[1] = 'a';
Lvweining.age = 27;
Lvweining.height = 185;
结构体成员变量的访问除了可以借助符号".",还可以用"->"访问。如果你的结构体变量是struct stuff Lvweining
这样定义的,那么用.访问结构体成员变量,如果你的结构体变量是用struct stuff *Lvweining
这样定义的,那么用->访问结构体成员变量。区别就是Lvweining
是结构体对象的时候是".",Lvweining
是结构体指针的时候是"->"。
下面看一个FFMpeg中结构体使用的经典例子
enum {
COLOR_FormatYUV420Planar = 0x13,
COLOR_FormatYUV420SemiPlanar = 0x15,
COLOR_FormatYCbYCr = 0x19,
COLOR_FormatAndroidOpaque = 0x7F000789,
COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00,
COLOR_QCOM_FormatYUV420SemiPlanar32m = 0x7fa30c04,
COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7fa30c03,
COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100,
COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced = 0x7f000001,
};
static const struct {
int color_format;
enum AVPixelFormat pix_fmt;
} color_formats[] = {
{ COLOR_FormatYUV420Planar, AV_PIX_FMT_YUV420P },
{ COLOR_FormatYUV420SemiPlanar, AV_PIX_FMT_NV21 },
{ COLOR_QCOM_FormatYUV420SemiPlanar, AV_PIX_FMT_NV21 },
{ COLOR_QCOM_FormatYUV420SemiPlanar32m, AV_PIX_FMT_NV21 },
{ COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, AV_PIX_FMT_NV21 },
{ COLOR_TI_FormatYUV420PackedSemiPlanar, AV_PIX_FMT_NV21 },
{ COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced, AV_PIX_FMT_NV21 },
{ 0 }
};
在这里 static const
是用来修饰color_formats[]
数组的关键字。表示color_formats[]
这个数组的内容是
struct {
int color_format;
enum AVPixelFormat pix_fmt;
}
这个结构体,数组里面的内容则是对 这个数组中的每个结构体的赋值,就像struct stuff Lvweining = {"manager",30,185}。
上面的这个例子为了好看 可以拆开写,如下:
先定义一个结构体:
struct {
int color_format;
enum AVPixelFormat pix_fmt;
}ColorFormat;
定义结构体变量:
ColorFormat color_format1 = { COLOR_FormatYUV420Planar, AV_PIX_FMT_YUV420P },
ColorFormat color_format2 ={ COLOR_FormatYUV420SemiPlanar, AV_PIX_FMT_NV21 }
ColorFormat color_format3 ={ COLOR_QCOM_FormatYUV420SemiPlanar, AV_PIX_FMT_NV21 },
ColorFormat color_format4 ={ COLOR_QCOM_FormatYUV420SemiPlanar32m, AV_PIX_FMT_NV21 }
ColorFormat color_format5 ={ COLOR_QCOM_FormatYUV420PackedSemiPlanar64x32Tile2m8ka, AV_PIX_FMT_NV21 }
ColorFormat color_format6 ={ COLOR_TI_FormatYUV420PackedSemiPlanar, AV_PIX_FMT_NV21 }
ColorFormat color_format7 ={ COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced, AV_PIX_FMT_NV21 }
声明一个数组:
ColorFormat color_formats[] = {color_format1,color_format2,color_format3,color_format4,color_format5,color_format6,color_format7}
可以发现 我们上面在每次定义结构体变量的时候都需要在声明类型的前面加上struct。
估计某人觉得经常多写一个struct太麻烦了,于是就发明了:
typedef struct stuff
{
int x;
int y;
}LVWEINING;
LVWEINING p1;
// 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候,。
这个stuff可以省略不写,但是LVWEINING是必须要的,typedef是定义的LVWEINING这个别名,在这里typedef定义LVWEINING是一个stuff结构体的别名,我们在使用的时候使用的是LVWEINING这个结构体的别名。在这里我们能看出 结构体是一种自定义的数据类型,就像系统的int float一样。typedef int a; 就是我们定义a为int的别名。系统中也大量使用了这个,像typedef long long int64_t; typedef SIZE_TYPE size_t;等等。