• C结构体struct


    C结构体struct

    2、结构体定义

    1、结构体就是可以把变量包含到里面的东西

    struct就代表要定义一个结构体,sensors是这个结构体的名字, 然后是一个大括号 { }

    大括号里面就随意定义变量啦~

    图片

    怎么使用里面的变量呢?

    注意:结构体是一个数据类型就像是int和char一样的这种类型。

    既然是一种数据类型, 那么就可以用这个数据类型定义变量。

    定义一个该结构体的变量:

    图片

    为啥要那样子定义啊?

    答:你去问造C语言的那帮家伙去!问问他们为啥要设计成这样子!

    然后操作结构体变量里面的成员变量。当我们定义好结构体变量后,在初始化变量里面的成员变量时就会自动出现结构体里面的成员变量,如果这个代码是你一个一个敲出来的话,你就会感叹结构体在单片机中是那么的奇妙!

    图片

    图片

    图片

    有人会问为啥是结构体变量中间加个点?

    答:你去问造C语言的那帮家伙去!问问他们为啥要设计成这样子。

    2、其实定义结构体变量可以下面这样子

    图片

    也可以定义多个:

    图片

    图片

    发现了没,每个结构体变量都是单独拥有结构体里面的全部成员变量。

    就像是最开始说的,如果再增加一套传感器:温湿度、光照强度、烟雾浓度、酒精浓度。

    使用结构体的话只需要再定义一个结构体变量即可

    但很多时候,我们在单片机中见到的结构体并不是上面那样定义的,而是在前面加了一个typedef 关键字。

    这样的例子在库函数的头文件中,我们经常会看到如下结构体:

    图片

    3、typedef关键字

    先看一下百度百科对typedef的定义:

    图片

    总结一句就是:typedef可以把一个数据类型取一个别的名字

    typedef {数据类型} {别的名字}

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    
    typedef int zhjiguoxin;//zhjiguoxin就是int
    
    zhjiguoxin value = 0;
    
    int main(void)
    { 
     uart_init(115200);//串口初始化
     delay_init(); 
    
     printf("value=%d\r\n",value);
     
        while(1)
     { 
     } 
    }
    

    图片

    图片

    虽然typedef可以给变量取别名,但是没有谁会像上面那样取名字,我这里只是举一个例子。

    4、结构体的精髓

    注意:

    1、下面的代表了这个结构体数据类型

    图片

    2、给这个数据类型起一个别名

    注意是三部分, typedef {数据类型} {别的名字}。所以sensor就代表了这个结构体了。

    建议初学者把下面这张图保存到你的电脑,这样你就永远也不会忘记typedef在结构体中的用法了,也能很快的记住结构体这个东东。

    图片

    3、以后定义结构体变量的时候,就不需要像最开始那样struct sensors sen;这样的定义结构体变量了,只需要sensor sen;即可。

    图片

    4、结构体名字可以省略

    注意结构体定义可以不写结构体名,对C语言来说,那个sensors不叫结构体名,而是叫标签(tag)。C语言结构体名是struct关键字 + tag。所以为了简便,我们看到的单片机中的结构体都是写成如下的形式。

    图片

    5、结构体的变量可以放任何变量

    1、结构体变量可以放任何变量(int型指针)

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    typedef struct 
    {
     float temperature; //温度
     char  humidity;    //湿度
     char  alcohol;    //酒精浓度
     int   illumination;//光照强度
     char  CO;  //一氧化碳浓度
     int   *p;  //int型的指针变量
    } sensor;
    sensor sen;
    int value =0;
    int main(void)
    {
     uart_init(115200);//串口初始化
     delay_init(); 
     sen.p=&value;//把value的地址赋值 
     //打印p代表的地址里面的值(其实就是打印value的值)
     printf("value=%d\r\n",*(sen.p)); 
        while(1)
     { 
     } 
    }
    

    既然是指针变量,所以给指针变量赋值时当然是赋值的是一个地址。

    图片图片

    2、结构体变量可以放任何变量(函数指针)

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    typedef struct 
    {
     float temperature; //温度
     char  humidity;    //湿度
     char  alcohol;    //酒精浓度
     int   illumination;//光照强度
     char  CO;  //一氧化碳浓度
     int   *p;  //int型的指针变量
     void (*fun)();
    } sensor;
    sensor sen;
    void function()
    {
     printf("zhiguoxin\r\n");
    }
    int value =0;
    int main(void)
    { 
     uart_init(115200);//串口初始化
     delay_init(); 
     sen.fun=function; 
     sen.fun(); 
        while(1)
     { 
     } 
    }
    

    既然是函数指针变量,所以给函数指针变量赋值时当然是赋值的也是地址,并且还要是一个函数的地址,而一个函数的函数名就是该函数的地址。所以才会有下面的把函数function();的地址function赋值给函数指针fun。

    这样大家是不是很清楚了?如果不清楚,建议看个3遍以上!

    图片

    图片

    3、结构体变量可以放任何变量(结构体变量)

    这就是结构体嵌套,在一个结构体内包含了另一个结构体作为其成员。当出现结构体嵌套时,必须以级联方式访问结构体成员,即通过成员选择运算符逐级找到最底层的成员时再引用。

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    
    typedef struct 
    {
      int i;
    }zhiguoxin;
    
    typedef struct 
    {
     float temperature; //温度
     char  humidity;    //湿度
     char  alcohol;    //酒精浓度
     int   illumination;//光照强度
     char  CO;  //一氧化碳浓度
     int   *p;  //int型的指针变量
     void (*fun)(); 
     zhiguoxin guougo; 
    }sensor;
    
    sensor sen;
    
    int main(void)
    { 
     uart_init(115200);//串口初始化
     delay_init();
     
     sen.guougo.i=100;
     printf("i=%d\r\n",sen.guougo.i);
      
        while(1)
     { 
     } 
    }
    

    图片

    图片

    4、结构体变量可以放任何变量(结构体指针)

    结构体是一个数据类型。当然,数据类型也可以定义对应的指针变量啦。

    就像是int 类型可以定义 int *p; 一样

    图片

    所以,当大家如果发现你的代码中结构体是通过—>访问的话,那么这个结构体变量一定是指针类型的变量。

    同理,如果代码中结构体是通过.访问的话,那么这个结构体变量就不是指针变量,而是一般的变量。

    图片

    图片

    总结:至此,有关结构体在单片机中的应用,相信你已经掌握的差不多了。大家可能感觉本文的内容太简单了,但只有把这个简单的基础性知识打牢,你才能进步得更快,否则你总感觉自己的代码差点意思。

    来源:果果小师弟


    版权归原作者所有,如有侵权,请联系删除。

  • 相关阅读:
    使用respondsToSelector:来发现对象是否响应消息
    使用iskindofclass来发现对象是否是某类或其子类的实例
    集合set的使用
    字典的使用
    数组的使用
    对NSNumber的理解
    数组、字典和集合的定义
    强引用strong和弱引用weak的定义
    类工厂方法的定义
    POJ 2262 / UVa 543
  • 原文地址:https://www.cnblogs.com/dapenson/p/16324089.html
Copyright © 2020-2023  润新知