C语言——结构体

C语言——结构体


宗旨:技术的学习是有限的,分享的精神是无限的。


1、结构体的作用:个人理解,结构体就是把一堆相关的数据打包成一个结构,使其放在一块内存区域。——项目之中尽量使用结构体,而不要单独使用数组。

 

2、结构体的声明与定义

规范:

1)如果此结构体在多个文件中使用就放在头文件中(.h文件中);如果此结构体只在本文件中使用,则放在源文件中(.c文件中),并加以static限定。

2)如果是用typedef起别名,则以_t作为后缀;如果是用static限定的则不用_t后缀。

typedef __packed struct
{
  uint8_t datetime[6];    // 年月日,时分秒 (BCD) -- 连续驾驶开始/结束时间
  int16_t altitude;  // 海拔
  int32_t longitude; // 经度
  int32_t latitude;  // 纬度
} gbt19056_fatigue_info_t;// __packed表示一字节对齐,单片机编程中常用
// gbt19056_fatigue_info_t相当于类型名,类似于int,float之类的

static struct
{
  rtc_timer_t timer_check;
  uint16_t attr; // 区域属性
  ca8gps_event_data_t event;
} t808_area;

结构体声明的时候一定要注意字节对齐的问题,加上__packed为了一字节对齐,否则默认是4字节对齐的。

定义和声明:定义分配内存,声明不分配内存。

 

3、结构体的初始化接口

规范:函数名大写的是对外接口,函数名全小写加下划线的是对内接口。

typedef重命名的要先定义一个变量,然后再使用,如下:

gbt19056_fatigue_info_t info1; // 访问则是info1.altitude = 0x012;

gbt19056_fatigue_info_t *info2; // 访问则是info2->altitude = 0x012;

static限定的则直接使用,t808_area. attr = 0x55;

一般项目中要写初始化函数:

void gbt19056_fatigue_init(void)
{
  memset(&info, 0, sizeof(gbt19056_fatigue_info_t));

  memcpy(info2->datetime, date, sizeof(info2->datetime));
  info2->altitude = 0;
  info2->longitude = 0x7FFFFFFF;
  info2->latitude = 0x7FFFFFFF;
}


4、结构体访问接口

比较大型一点的项目之中,多个文件会用到一些结构中的成员,因此写成接口形式。

规范:一般少使用全局变量,需要某些值的时候以函数接口形式给予。

uint16_t T808AreaAddr(void)
{
  return t808_area. attr;
}

void GBT19056FatigueTime(char *data)
{
  memcpy(data, info2->datetime, sizeof(info2->datetime));
}


5、结构体中一些技巧

处理批量类似事情:

// 一个命令字对应一个处理函数,用for循环扫描
// 命令字有的用枚举, 有的用宏
typedef enum
{
  T808_CUSTOM_CAMERA_COUNT      = 1,
  T808_CUSTOM_DISTANCE_TYPE     = 2,
  T808_CUSTOM_OIL               = 3,
  T808_CUSTOM_VERSION           = 4
} t808_t;
// 再三强调,起别名的类型一定要加_t后缀以示区分
typedef uint8_t (*handler_t)(char *data, uint8_t length);

typedef struct
{
// 变量类型和函数参数随机应变
  uint8_t cmd;
  uint8_t length;
  handler_t hander;
} t808_custom_entry_t ;

static uint8_t t808_custom_camera_count(char *data, uint8_t length);
static uint8_t t808_custom_disdance _type(char *data, uint8_t length);
static uint8_t t808_custom_oil(char *data, uint8_t length);
static uint8_t t808_custom_version(char *data, uint8_t length);

//===========================================================
// 定义好结构之后,用数组装载整个命令及其处理函数
static const  t808_custom_entry_t t808_custom_entries[] =
{
  {T808_CUSTOM_CAMERA_COUNT, 1, t808_custom_camera_count},
  {T808_CUSTOM_DISTANCE_TYPE, 1, t808_custom_disdance _type},
  {T808_CUSTOM_OIL, 22, t808_custom_oil},
  {T808_CUSTOM_VERSION, 14, t808_custom_version},
};

// 在一个函数中用for循环扫描
static void
custom_setting(client_t*client, t808_hdr_t *request, uint16_t length)
{
  t808_custom_entry_t*entry;

  for(entry = t808_custom_entries; entry->handler; ++entry)
  {
    if(entry->cmd == request->cmd)
    {
      entry->handler(data, length); // 只是一个轮廓,仅供参考

      break;
    }
  }
}


 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值