分享几个实用的代码片段(第二弹)

Posted 嵌入式大杂烩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分享几个实用的代码片段(第二弹)相关的知识,希望对你有一定的参考价值。

大家好,我是杂烩君。

本次我们再来分享几个实用的代码小片段。

快速获取结构体成员大小

获取结构体成员大小及偏移量的方式有多种。最简便的方式:

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#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;

运行结果:

文件操作

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#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_struct

 char a;  
 char c; 
 short b;         
 int d;
test_struct;

int main(int arc, char *argv[])

    #define FILE_NAME  "./test_file"

    test_struct 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_struct*)&write_data, sizeof(test_struct));

    test_struct read_data = 0;
    file_opt_read(FILE_NAME, (test_struct*)&read_data, sizeof(test_struct));
    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;

运行结果:

进度条

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h>    
#include <string.h>    
#include <unistd.h>    

typedef struct _progress

    int cur_size;
    int sum_size;
progress_t;

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

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

    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", proc, cnt);
            fflush(stdout);  
            proc[cnt] = '#';  
            usleep(100000);
            cnt++;
        

      
    printf("\\n");


int main(int arc, char *argv[])

    progress_t progress_test = 0;

    progress_test.cur_size = 65;
    progress_test.sum_size = 100;
    progress_bar(&progress_test);
    
    return 0;

运行结果:

日志输出

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

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h> 

#define LOG_D(fmt, args...) do\\
                            \\
                                printf("<<File:%s  Line:%d  Function:%s>> ", __FILE__, __LINE__, __FUNCTION__);\\
                                printf(fmt, ##args);\\
                            while(0)

int main(int arc, char *argv[])

    char ch = 'a';
    char str[10] = "ZhengN";
    float float_val = 10.10;
    int num = 88;
    double double_val = 10.123456;
    LOG_D("字符为 %c \\n", ch);
    LOG_D("字符串为 %s \\n" , str);
    LOG_D("浮点数为 %f \\n", float_val);
    LOG_D("整数为 %d\\n" , num);
    LOG_D("双精度值为 %lf \\n", double_val);
    LOG_D("八进制值为 %o \\n", num);
    LOG_D("十六进制值为 %x \\n", num);

 return 0;

运行结果:

可阅读往期文章:

C语言、嵌入式中几个非常实用的宏技巧

一个简单的日志模块

后台运行生成core文件

这个是我们上一篇文章分享一种你可能不知道的bug定位方法介绍的,方便大家使用,也汇总在这里。

代码:

左右滑动查看全部代码>>>

// 微信公众号:嵌入式大杂烩
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>

#define SHELL_CMD_CONF_CORE_FILE    "echo /var/core-%e-%p-%t > /proc/sys/kernel/core_pattern"
#define SHELL_CMD_DEL_CORE_FILE     "rm -f /var/core*"

static int enable_core_dump(void)

    int ret = -1;
    int resource = RLIMIT_CORE;
    struct rlimit rlim;

    rlim.rlim_cur = 1 ? RLIM_INFINITY : 0;
    rlim.rlim_max = 1 ? RLIM_INFINITY : 0;

    system(SHELL_CMD_DEL_CORE_FILE);

    if (0 != setrlimit(resource, &rlim))
    
        printf("setrlimit error!\\n");
        return -1;
    
    else
    
        system(SHELL_CMD_CONF_CORE_FILE);
        printf("SHELL_CMD_CONF_CORE_FILE\\n");
        return 0;
    

    return ret;


int main(int argc, char **argv)

    enable_core_dump();

    printf("==================segmentation fault test==================\\n");

    int *p = NULL;
    *p = 1234;

    return 0;

以上就是本次分享的几个小的代码片段。

期待你的三连支持!

注意

由于微信公众号近期改变了推送规则,如果您想经常看到我们的文章,可以在每次阅读后,在页面下方点一个「赞」或「在看」,这样每次推送的文章才会第一时间出现在您的订阅列表里。

猜你喜欢:

分享一种你可能不知道的bug定位方法

分享一种修改配置文件的方法

《嵌入式大杂烩周记第 13 期:lz4》

《嵌入式并行多线程处理器,了解一下!》

《分享一种修改配置文件的方法》

《分享几个实用的代码片段(附代码例子)》

《废旧板子再利用:搭建无线调试环境!》

《嵌入式段错误的3种调试方法汇总!》

《简说TCP通信非阻塞接收(附代码例子)》

《TCP server如何与多个client通信?》

《TCP通信常用接口的使用封装》

《写国际化的嵌入式代码,时间问题如何处理?》

《Linux命令行万能解压命令》

《嵌入式软件中,总线错误的坑?替大家先踩一步》

《分享嵌入式软件调试方法及几个有用的工具!》

《分享两点提高编程能力的建议!》

《嵌入式开发中常见3个的C语言技巧》

《分享几个嵌入式 C 中的实用技巧》

在公众号聊天界面回复1024,可获取嵌入式资源;回复 m ,可查看文章汇总

以上是关于分享几个实用的代码片段(第二弹)的主要内容,如果未能解决你的问题,请参考以下文章

访问非法内存为什么不会出错?

访问非法内存为什么不会出错?

分享几个实用的代码片段(附代码例子)

分享几个实用的代码片段(附代码例子)

#yyds干货盘点# Java并发面试题第二弹

0基础学算法 第二弹 排序