聊聊c语言结构体那些道道

来源:互联网 发布:重庆seo推荐盛庆策动 编辑:程序博客网 时间:2024/04/27 22:39

在c语言的编程中,结构体的使用频率是非常高的,那到底结构体是什么?表现形式是什么?为什么要用结构体?怎么用?下面就简单的解答一下。
结构体定义:结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体的形式:
struct 结构名
{
类型 变量名;
类型 变量名;

} ;
结构名是结构的标识符不是变量名。
类型为五种数据类型(整型、浮点型、字符型、指针型和 无值型),也可以为另一个结构体的名。
小插曲–>
如:

typedef struct women{    Int    Score ;    char   age;}girl;typedef struct test{    Int  a;    girl  lisi;}student;   

说明:typedef的作用类似于给结构体women和test起了一个别名,分别为girl和student,之后如果想要使用结构体,可以直接调用girl和student。在Student结构体中第二个成员lisi的类型则是上一个定义的结构体girl。

结构体的赋值:
1) 结构体变量名.成员名
2) 指针变量->成员名, 或者 (*指针变量).成员名

结构体的好处:我们可以把结构体当成一个表格,我们可以建立这个结构体如下

Typedef struct test{Int nameInt score;Int age;...}stu;

现在有一个工作是将班级里所有学生的信息保存一遍,比如姓名、考试成绩、年龄等等。最直接的方式是在excel中的第一行开始一次输入张三、李四、、、的考试成绩等信息,这样做虽然可以将所有信息统计完并记录下来,但是可读性很差。想要找到班里其中一个同学的全部信息也是比较麻烦,那我们就可以制作一个表格模板,模板上有姓名栏、成绩栏等等(如同上段程序所示),把模板打印多张发给同学,每个人填好后上交(如下段程序)。这样之后查单个同学的信息时就比较方便。

stu  banjimingdan[N];//N个学生Banjimingdan[1].name=...;//学生1的姓名Banjimingdan[1].score=...;//学生1的分数Banjimingdan[1].sge=...;//学生1的年龄

其实结构体增加了一类或相关信息的统一管理,上面举得例子比较不明显,,我们平时使用stm32或其他处理器时会常常在初始化函数中遇到类似以下情况:

mml_uart_config_t                           config;//创建配置使用的结构体configconfig.baudrate = K_LITE_UART0_DEFAULT_BAUDRATE;config.data_bits = MML_UART_DATA_TRANSFER_SIZE_8_BITS;config.flwctrl = MML_UART_HW_FLOW_CTL_DISABLE;config.parity = MML_UART_PARITY_NONE;config.parity_mode = MML_UART_PARITY_MODE_ONES;config.rts_ctl = MML_UART_RTS_IO_LEVEL_LOW;config.stop_bits = MML_UART_STOPBITS_ONE;config.handler = (mml_uart_handler_t)uart0_handler;//给结构体里的参数一一赋值result = mml_uart_init(MML_UART_DEV0, config);//将结构体传给init函数进行初始化

mml_uart_config_t 就是库函数已经建立的结构体,我们要配置串口的相关参数时就可以使用mml_uart_config_t 定义一个自己的结构体config(这个名字可以随便取)。

typedef struct{    mml_uart_tarsfer_size_t                     data_bits;    mml_uart_parity_t                           parity;    mml_uart_parity_mode_t                      parity_mode;    mml_uart_stop_bits_t                        stop_bits;    mml_uart_flow_ctl_t                         flwctrl;    mml_uart_rts_ctl_t                          rts_ctl;    unsigned int                                baudrate;    volatile mml_uart_handler_t                 handler;} mml_uart_config_t;

从config结构体中可以很清晰的看出我们配置串口的几个参数,这样的话就不需要我们仔细的研究手册,哪些参数和串口有关,哪些需要设置等。给结构体赋值是就是比较简单的结构体名+“.”+成员=需要赋的值。赋值完后,结构体config中就有了实际的参数,下一步就是将该结构体送入库函数中的 mml_uart_init,进行初始化。
想想最初学习51单片机时设置寄存器的步骤,有没有觉得现在更简单明了了?

结构体的实际应用:
结构体的数据主要作用可以分为两类:一类是存储,可以用来被查看等,类似于枚举类型。另一类则是交换,将数据传出或传入。
实际应用中大部分是将结构体里的数据传出或传入。上面介绍的串口的初始化中,config结构体中数据被填完后就直接传递给了mml_uart_init函数,这是结构体使用的一种简单的方法。另一种则是结构体的指针。

typedef struct one{    __int32 name;    char   age;}boy;typedef struct two{    __int32 name;    char   age;}girl;void add(girl *oonr,boy *oner,char *sum){    *sum= oonr->age+oner->age ; }int main(int argc, char *argv[]){    boy *boy1;    girl girl1;    boy1=(boy *)malloc(1*sizeof(boy));    boy1->age=1;    girl1.age=2;    char num;    add(&girl1,boy1,&num);    free(boy1);    printf("sum:%d!\n",num);    return 0;}

上面的代码主函数中定义了两个结构体*boy1 girl1,类型分别是boy和girl。其中*boy是定义了一个结构体指针。add函数主要实现了两个指针类型的入参中的年龄相加并将和送到sum地址中。

在给girl1中的age赋值是是比较简单的形式,girl1.age=2;boy1中的age赋值时则采用了指针类型的赋值方式boy1->age=1;由于add函数的入参和出参都是采用了指针,所以调用时需要将参数的地址传入,三个参数的地址分别为&girl1,boy1,&num。这是一个简单的结构体指针的使用,作用便是提高了运行的效率,当然巧用指针编写程序也会使得程序高大上。

写到c语言的结构体,必然会想到共用体和枚举类型。共用体用的相对枚举和结构体要少的多,枚举的相关介绍在我之前的文章中也提到过,自己也可以上网搜搜,一看就明白。

不管是单独用指针还是结构体的指针,都会提高代码的质量,但是用不好会反而降低代码质量。

2 0
原创粉丝点击