不同场景下的代码举例

笔记 · 15 天前 · 64 人浏览
不同场景下的代码举例

1. 类型 & 字节转换

char short int

  • 智能家居:网关协议,mac地址、ip地址、端口号上报

  • 智慧农业:温湿度采集,小数点数据上传云平台

    float temp = 38.6;
    char *ip = "192.168.1.1";

    char temp_array[2] = { 38, 6 };
    char ip_array[4] = { 192, 168, 1, 1 };

    typedef unsigned char unit8;
    typedef unsigned char unit16;
    typedef unsigned char unit32;

时间戳举例:

    #include <stdio.h>

    typedef unsigned char unc;
    typedef unsigned int unit;

    // 66C8 6B78 
    unc time_buf[4] = { 0x66, 0xC8, 0x6B, 0x78 };
    unit time;

    unit u8Tou32B(unc* buffer)
    {
        return (((((((unit)buffer[0]) << 8) 
                         | buffer[1]) << 8)
                         | buffer[2]) << 8)
                         | buffer[3];
    }

    int main()
    {
        time = u8Tou32B(time_buf);
        printf("time = %ld s\n", time);
    }

2. if & switch

前者用于两种状态情况下或者某个范围内,后者用于多状态配合枚举更加直观。

  • 智能家居:控制灯的开关

  • 智能音箱:网络连接状态

    typedef enum
    {
        NET_INIT = 0,
        NET_CONNECTING, 
        NET_CONNECT_SUCCESS,
        NET_CONNECT_FAIL,
        NET_ERROR,   
    } E_NET_STATUS;


    int main()
    {
        E_NET_STATUS net_status;

        switch (/* expression */)
        {
        case /* constant-expression */:
            /* code */
            break;

        default:
            break;
        }
    }

3. for & while

两者可以互换,保持某种特定条件循环建议使用后者。

  • 自动售卖机: 判断是否存在待处理订单

  • 智能音箱:打印当前搜索到的wifi信息

  • 自动售卖机:判断当前所以订单的金额(有收入有退币 )

    #include <stdio.h>

    int main()
    {
        int status;
        while(status == true )
        {
            // 存在订单
        }

        int wifi_array[20] = { 0 };
        int count = sizeof(wifi_array) / sizeof(*wifi_array);
        for (int i = 0; i < count; i++)
        {
            // 打印
        }
    }

4. static

控制变量的存储方式和作用范围以及管理生命周期。

  • 点餐屏:统计损耗使用次数

      #include <stdio.h>
    
      void Used()
      {
          static int used = 0;
          printf("used:%d\n", (used ++) + 1);
      }
    
      int main()
      {
         for(int i = 0; i < 5; i++)
         {
              Used();
         }
      }

5. #define

强大且无敌的替换

  • 代码中定义测试与发布版本

  • 定义某个特定功能的开关

常见用法:

    #define APPID "123456"

    #define PI 3.14

    #define MAX_LEN (100 + 1)

    #define MAX(a, b) ((a) > (b) ? (a) : (b))

    #define SWAP(a, b) do { \
        int t = 0; \
        t = a; \
        a = b; \
        b = t; \
    } while(e)

    //将一个字母转换为大写
    #define UPCASE(c) (((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c))
    //判断字符是不是18进值的数字
    #define DECCHK(c) ((c) >= '0' && (c) <= '9')
    //防止溢出的一个方法
    #define INC_SAT(val) (val = ((va1) + 1 > (val)) ? (val) + 1 : (val))
    //返回数组元素的个数
    #define ARR_SIZE(a) (sizeof((a)) / sizeof((a[0])))

    #define CONNECT(a,b) a##b
    #define TOCHAR(a) @#a
    #define TOSTRING(a) #a

用来定义测试与发布版本以及日志信息:

    #include <stdio.h>

    #define VERSION_PRE 1
    // #define VERSION_GOLD 1
    #define LOG_OPEN 1

    int main()
    {
    #ifdef LOG_OPEN
        printf("just1n.cn\n");
    #ifdef VERSION_PRE
        printf("PRE__VERSION__ \n");
        // todo
    #elif VERSION_GOLD
        printf("GOLD__VERSION__ \n");
        // todo
    #endif

    #endif
    }

6. strcut

具有相同类型或不同类型的数据构成的数据集合。

  • 自动售货机:设备所有资源管理(设备状态、网络状态、电机状态、传感器状态、订单状态等)

      #include <stdio.h>
    
      typedef struct 
      {
          int num;
          int time;
          int money;
      } T_Pay;
    
      typedef struct 
      {
          int used;
          int time;
          int id;
      } T_Manager;
    
      typedef struct 
      {
          int system_status;
          int net_status;
          int motor_status[4];
          int pay_status;
          T_Pay m_Pay;
          T_Manager m_Manager;
    
          void* (statusCallbackfunc)();
      } T_Device;
    
      int main()
      {
          T_Device g_Device_1;
      }

7. 指针 *

变量为了表示数据而生,指针为了传递数据为生。

  • 智能音箱:音频处理
    #include <stdio.h>

    void pcmSpeex(char *data)
    {
        //TODO
    }

    int main()
    {
        char pcm_data_char;
        char pcm_data_arrary[4096];

        pcmSpeex(&pcm_data_char);
        pcmSpeex(pcm_data_arrary);
    }

8. 回调函数

通过函数指针来调用的函数,观察者模式,事件模型。

  • 送餐机器人:底盘移动到目标位置后,通知应用程序

  • 智能音箱:网络状态改变后,通知应用程序

传统方式

  • 开放变量,让别人直接获取

  • 通过getStatus()类似的函数定时获取

    #include <stdio.h>

    // 工具代码
    typedef struct 
    {
        int status;
        void (*statusChange)();
    } T_Device;

    T_Device g_Device;

    void addCallbackFunc(void (*pstatusChange)(int status))
    {
        g_Device.statusChange = pstatusChange;
    }

    int getStatus()
    {
        return g_Device.status;
    }

    void run()
    {
        g_Device.status = 10;
        if(g_Device.status == 10)
        {
            if(g_Device.statusChange != NULL)
            {
                g_Device.statusChange(g_Device.status);
            }
        }
    }


    // 用户代码
    void callBack(int status)
    {
        printf("callBack: status = %d\n", status);
    }

    int main()
    {
        // for(;;)
        // {
        //     int status = getStatus();
        // }

        addCallbackFunc(callBack);
        run();
    }

  回调的重点在于获取这个实时变化的值不是由我本身去获取,而是把获取后的操作方法告诉数据拥有者,让拥有者自己去获取并且处理数据,而我只是提供一个方法。

9. 其它场景:数据拷贝和动态内存分配

例如智能音箱进行配网时,获取到网络列表后,进行过滤,写出过滤函数。

  • malloc 裸机不建议使用,带操作系统的可以
  • freertos 实现类内存管理池
  • Linux 有内存管理的模块(实际访问映射表、不直接访问硬件地址)
    void handleWifiList(const char *plistdata, int len)
    {
        char *mdata = (char *)malloc(len);
        memcpy(mdata, plistdata, len);

        // 业务处理 ....

        free(m_data);
    }
C
  1. L 15 天前

    我要是有你这样的学习效率就好了啊啊啊啊啊点评完毕哈哈你真棒

    1. Justin_Wu (作者)  14 天前
      @L

      领导莅临?

Theme Jasmine by Kent Liao

本网站由 又拍云 提供CDN加速/云存储服务

鄂ICP备2023005457号    鄂公网安备 42011302000815号