Chinaunix首页 | 论坛 | 博客
  • 博客访问: 318838
  • 博文数量: 85
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 800
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-18 15:21
文章分类

全部博文(85)

文章存档

2017年(1)

2016年(19)

2015年(55)

2014年(10)

我的朋友

分类: C/C++

2015-05-23 13:01:23

在友善之臂的EEPROM的示例程序中看到有一些不一样的地方,使用了__LINE__这样的预编译宏。而且其用法也是比较好,使得主程序简洁明了。所以就学习了一下。

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <getopt.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include "24cXX.h"

  11. #define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);//__LINE__编译后输出所在行,使用宏定义好处:编译器会确定所在行
  12. void do_usage_if(int b, int line)
  13. {
  14.     const static char *eeprog_usage =
  15.         "I2C-24C08(256 bytes) Read/Write Program, ONLY FOR TEST!\n"
  16.         "FriendlyARM Computer Tech. 2009\n"
  17.         "Usage: -r/-w\n";
  18.     if(!b)
  19.         return;
  20.     fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);
  21.     exit(1);
  22. }


  23. #define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);//退出信息输出,同样使用了__LINE__信息
  24. void do_die_if(int b, char* msg, int line)
  25. {
  26.     if(!b)
  27.         return;
  28.     fprintf(stderr, "Error at line %d: %s\n", line, msg);
  29.     fprintf(stderr, "    sysmsg: %s\n", strerror(errno));
  30.     exit(1);
  31. }


  32. static int read_from_eeprom(struct eeprom *e, int addr, int size)
  33. {
  34.     int ch, i;
  35.     for(i = 0; i < size; ++i, ++addr)
  36.     {
  37.         die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");
  38.         if( (i % 16) == 0 )
  39.             printf("\n %.4x| ", addr);
  40.         else if( (i % 8) == 0 )
  41.             printf(" ");
  42.         printf("%.2x ", ch);
  43.         fflush(stdout);
  44.     }
  45.     fprintf(stderr, "\n\n");
  46.     return 0;
  47. }

  48. static int write_to_eeprom(struct eeprom *e, int addr)
  49. {
  50.     int i;
  51.     for(i=0, addr=0; i<256; i++, addr++)
  52.     {
  53.         if( (i % 16) == 0 )
  54.             printf("\n %.4x| ", addr);
  55.         else if( (i % 8) == 0 )
  56.             printf(" ");
  57.         printf("%.2x ", i);
  58.         fflush(stdout);
  59.         die_if(eeprom_write_byte(e, addr, i), "write error");
  60.     }
  61.     fprintf(stderr, "\n\n");
  62.     return 0;
  63. }

  64. int main(int argc, char** argv)
  65. {
  66.     struct eeprom e;
  67.     int op;

  68.     op = 0;

  69.     usage_if(argc != 2 || argv[1][0] != '-' || argv[1][2] != '\0');
  70.     op = argv[1][1];

  71.     fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n");
  72.     die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0, //若打开错误
  73.             "unable to open eeprom device file "
  74.             "(check that the file exists and that it's readable)");
  75.     switch(op)
  76.     {
  77.     case 'r':
  78.         fprintf(stderr, " Reading 256 bytes from 0x0\n");
  79.         read_from_eeprom(&e, 0, 256);
  80.         break;
  81.     case 'w':
  82.         fprintf(stderr, " Writing 0x00-0xff into 24C08 \n");
  83.         write_to_eeprom(&e, 0);
  84.         break;
  85.     default:
  86.         usage_if(1);
  87.         exit(1);
  88.     }
  89.     eeprom_close(&e);

  90.     return 0;
  91. }
主要是集中在两个函数上
void do_usage_if(int b, int line)
void do_die_if(int b, char* msg, int line)
并且使用了宏定义,使得___LINE__对应使用的地方替换成对应所在行号

扩展学习
ANSI
标准说明了C中的五个预定义的宏名。它们是:


__FILE__ 包含当前程序文件名的字符串
__LINE__ 表示当前行号的整数
__DATE__ 包含当前日期的字符串
__STDC__ 如果编译器遵循ANSI C标准,它就是个非零值
__TIME__ 包含当前时间的字符串
 注意,是双下划线,而不是单下划线 。

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。




阅读(1038) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~