嵌入式中常用的巧妙方法 - (汇总)

概述

        做项目,掌握以下方法,可提高开发效率,把时间全部放在需求上。

1、快速获取结构体成员大小

#include <stdio.h>   

// 获取结构体成员大小
#define  GET_MEMBER_SIZE(type, member)   sizeof(((type*)0)->member)

// 获取结构体成员偏移量
#define  GET_MEMBER_OFFSET(type, member)  ((size_t)(&(((type*)0)->member)))

typedef struct _test_struct0
{
	char x;
	char y;
	char z;
}test_struct0;

typedef struct _test_struct1
{
	char a;
	char c;
	short b;
	int d;
	test_struct0 e;
}test_struct1;

int main(int arc, char* argv[])
{
	printf("GET_MEMBER_SIZE(test_struct1, a) = %ld\n", GET_MEMBER_SIZE(test_struct1, a));
	printf("GET_MEMBER_SIZE(test_struct1, c) = %ld\n", GET_MEMBER_SIZE(test_struct1, c));
	printf("GET_MEMBER_SIZE(test_struct1, b) = %ld\n", GET_MEMBER_SIZE(test_struct1, b));
	printf("GET_MEMBER_SIZE(test_struct1, d) = %ld\n", GET_MEMBER_SIZE(test_struct1, d));
	printf("GET_MEMBER_SIZE(test_struct1, e) = %ld\n", GET_MEMBER_SIZE(test_struct1, e));
	printf("test_struct1 size = %ld\n", sizeof(test_struct1));

	printf("GET_MEMBER_OFFSET(a): %ld\n", GET_MEMBER_OFFSET(test_struct1, a));
	printf("GET_MEMBER_OFFSET(c): %ld\n", GET_MEMBER_OFFSET(test_struct1, c));
	printf("GET_MEMBER_OFFSET(b): %ld\n", GET_MEMBER_OFFSET(test_struct1, b));
	printf("GET_MEMBER_OFFSET(d): %ld\n", GET_MEMBER_OFFSET(test_struct1, d));
	printf("GET_MEMBER_OFFSET(e): %ld\n", GET_MEMBER_OFFSET(test_struct1, e));

	return 0;
}

运行结果: 

 

2、文件操作

文件操作平时用得很多,为了方便使用,可以自己根据实际需要再封装一层:

#include <stdio.h>   

static int file_opt_write(const char* filename, void* ptr, int size)
{
	FILE* fp;
	size_t num;

	fp = fopen(filename, "wb");
	if (NULL == fp)
	{
		printf("open %s file error!\n", filename);
		return -1;
	}

	num = fwrite(ptr, 1, size, fp);
	if (num != size)
	{
		fclose(fp);
		printf("write %s file error!\n", filename);
		return -1;
	}

	fclose(fp);

	return num;
}

static int file_opt_read(const char* filename, void* ptr, int size)
{
	FILE* fp;
	size_t num;

	fp = fopen(filename, "rb");
	if (NULL == fp)
	{
		printf("open %s file error!\n", filename);
		return -1;
	}

	num = fread(ptr, 1, size, fp);
	if (num != size)
	{
		fclose(fp);
		printf("write %s file error!\n", filename);

		return -1;
	}
	fclose(fp);

	return num;
}

typedef struct _test_data_info
{
	char a;
	char c;
	short b;
	int d;
}test_data_info;

int main(int arc, char* argv[])
{
#define FILE_NAME  "./test_file"

	test_data_info write_data = { 0 };
	write_data.a = 1;
	write_data.b = 2;
	write_data.c = 3;
	write_data.d = 4;
	printf("write_data.a = %d\n", write_data.a);
	printf("write_data.b = %d\n", write_data.b);
	printf("write_data.c = %d\n", write_data.c);
	printf("write_data.d = %d\n", write_data.d);
	file_opt_write(FILE_NAME, (test_data_info*)&write_data, sizeof(test_data_info));

	test_data_info read_data = { 0 };
	file_opt_read(FILE_NAME, (test_data_info*)&read_data, sizeof(test_data_info));
	printf("read_data.a = %d\n", read_data.a);
	printf("read_data.b = %d\n", read_data.b);
	printf("read_data.c = %d\n", read_data.c);
	printf("read_data.d = %d\n", read_data.d);

	return 0;
}

运行结果:

 

3、进度条

有时候,加上进度条可以比较方便知道当前的下载进度、写入文件的进度等。

#include <stdio.h>    
#include <string.h>    
#include <windows.h>

typedef struct _progress_t
{
	int cur_size;
	int sum_size;
}progress_t;

void progress_bar(progress_t* progress_data)
{
	int percentage = 0;
	int cnt = 0;
	char proBuf[102];

	memset(proBuf, '\0', sizeof(proBuf));

	percentage = (int)(progress_data->cur_size * 100 / progress_data->sum_size);
	printf("percentage = %d %%\n", percentage);

	if (percentage <= 100)
	{
		while (cnt <= percentage)
		{
			printf("[%-100s] [%d%%]\r", proBuf, cnt);
			fflush(stdout);
			proBuf[cnt] = '#';
			Sleep(1);
			cnt++;
		}

	}
	printf("\n");
}

int main(int arc, char* argv[])
{
	progress_t progress_test = { 0 };
	progress_test.cur_size = 82;
	progress_test.sum_size = 100;
	progress_bar(&progress_test);

	return 0;
}

运行结果:

4、日志输出

日志输出常常需要带一些格式。最简单的方式如:

// 定义日志等级
typedef enum {
    LOG_DEBUG,
    LOG_INFO,
    LOG_WARNING,
    LOG_ERROR,
} log_level_t;

// 封装的日志函数
void log_message(log_level_t level, const char* message, const char* file, int line) {
    switch (level) {
    case LOG_DEBUG:
        printf("DEBUG: %s (%s:%d)\n", message, file, line);
        break;
    case LOG_INFO:
        printf("INFO: %s (%s:%d)\n", message, file, line);
        break;
    case LOG_WARNING:
        printf("WARNING: %s (%s:%d)\n", message, file, line);
        break;
    case LOG_ERROR:
        printf("ERROR: %s (%s:%d)\n", message, file, line);
        break;
    default:
        break;
    }
}

// 在代码中使用封装的日志函数
int main() {

    log_message(LOG_INFO, "This is an info message", __FILE__, __LINE__);
    log_message(LOG_DEBUG, "This is a debug message", __FILE__, __LINE__);
    log_message(LOG_WARNING, "This is a warning message", __FILE__, __LINE__);
    log_message(LOG_ERROR, "This is an error message", __FILE__, __LINE__);

    return 0;
}

运行结果:

5、总结 

        介绍完毕,希望能帮助到你,蟹蟹参阅!!!

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ch_champion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值