2006年08月01日
骤雨初歇,密云未散,风雷犹自低鸣。
曲池沟壑,是处处盈盈。
楼外双双燕子,惜春晚,更舞娉婷。
同嬉戏,穿帘拂柳,重影照幽屏。
 
萦萦,
憔悴损,红笺觅就,锦字难成。
恐霜毫象管,难赋深情。
翠钿朱钗无用,胭脂冷,鸾镜尘生。
寒烟暮,边城画角,寂寞与谁听。
2006年07月28日

长笛裂,

倚栏长啸清江月,

清江月,

霜风渐冷,

雁声悲咽。

岁华如箭忽惊觉,

十年未趁樽前约,

樽前约,

平生意气,

把酒商略。

2006年06月16日

浣溪沙  
 
欧阳炯
 
相见休言有泪珠,酒阑重得叙欢娱,凤屏鸳枕宿金铺。
兰麝细香闻喘息,绮罗纤缕见肌肤,此时还恨薄情无。

无限恨,恨尽思无涯。鹧鸪声声为何事?惊起残梦扰落花。帘卷玉钩斜。

温词:

千万恨,恨极在天涯。山月不知心里事,水风空落眼前花。摇曳碧云斜。

2006年04月17日

#include<stdio.h>

#include<ctype.h>

#include<stdlib.h>

char token[61];     /*存放表达式字符串的数组*/

int n=0;

void error(void)     /*报告错误函数*/

{

   printf("ERROR!\n");

   exit(1);

}

void match(char expected)   /*检查字符匹配的函数*/

{

   if(token[n]==expected)

     token[++n]=getchar();

   else error();

}

double term(void);     /*计算乘除的函数*/

double factor(void);   /*处理括号和数字的函数*/

double exp(void)       /*计算加减的函数*/

{

   double temp=term();

   while((token[n]==’+')||(token[n]==’-'))

     switch(token[n])

     {

       case’+':match(‘+’);

              temp+=term();

              break;

       case’-':match(‘-’);

              temp-=term();

              break;

     }

     return temp;

}

double term(void)

{

    double div;

    double temp=factor();

    while((token[n]==’*')||(token[n]==’/'))

     switch(token[n])

     {

       case’*':match(‘*’);

              temp*=factor();

              break;

       case’/':match(‘/’);

              div=factor();

              if(div==0)       /*处理除数为零的情况*/

              {

                 printf("The divisor is zero!\n");

                 exit(1);

               }

              temp/=div;

              break;

     }

     return temp;

}

double factor(void)

{

    double temp;

    char number[61];

    int i=0;

    if(token[n]==’(‘)

    {

       match(‘(‘);

       temp=exp();

       match(‘)’);

    }

    else if(isdigit(token[n])||token[n]==’.')

    {

       while(isdigit(token[n])||token[n]==’.')   /*将字符串转换为浮点数*/

       {

         number[i++]=token[n++];

         token[n]=getchar();

       }

       number[i]=’\0′;

       temp=atof(number);

    }

    else error();

    return temp;

}

main()

{

    double result;

    FILE *data=fopen("61590_4.dat","at");

    if(data==NULL)

       data=fopen("61590_4.dat","wt");

    if(data==NULL)

      return 0;

    token[n]=getchar();

    result=exp();

    if(token[n]==’\n’)

    {

       token[n]=’\0′;

       printf("%s=%g\n",token,result);

       fprintf(data,"%s=%g\n",token,result);

    }

    else error();

    fclose(data);

    return 0;

}

这个程序是在VC上调试的,如果要在linux下面运行的话,注意一下strtod这个库函数。

大学学习数据结构时,结业作业就是这道题,我记得我们班几乎都时copy我们班一个编程牛人的(该牛人现在在intel)。

原理非常简单,用两个栈,一个栈放运算符,一个栈放操作数。读取输入,碰到操作数就直接入操作数栈,碰到运算符,就取运算符栈栈顶元素,比较它们的优先级,如果刚读取的操作符优先级大于栈顶元素的优先级,则将刚读取的运算符入栈,否则循环取运算符栈和操作数栈中的元素进行运算,运算结果入操作数栈,直到运算符栈内无元素,或者碰到‘(’,或者碰到优先级更低的元素。其实就是将中缀表达示转化未后缀表达式:

1+(2+3)*8/2+9

后缀表达式为:

123+8*2/+9+

该实现包含如下四个文件:

calc.c

calc.h

stack.c

stack.h

关于栈的操作,只提供了接口,照着接口实现就行了。

/*

stack.h

*/

#ifndef __STACK_H__
#define __STACK_H__

#include "calc.h"

typedef calc_T ELEM_STACK_TYPE;

typedef struct stack_T
{
 ELEM_STACK_TYPE key;
 struct stack_T* next;
}stack_T;

typedef struct stack_api_T
{
 int (*pop)(stack_T** top, ELEM_STACK_TYPE* key);
 int (*push)(stack_T** top, ELEM_STACK_TYPE key);
 int (*empty)(stack_T* top);
 int (*top)(stack_T* top, ELEM_STACK_TYPE* key);
}stack_api_T;

int init_stack(stack_api_T** s);
void destroy_stack(stack_api_T* s);

#endif

/*

calc.h

*/

#ifndef __CALC_H__
#define __CALC_H__

typedef enum opt_type
{
 OPT_ERRO,
 OPT_OVER,
 OPT_DATA,
 OPT_CHAR
}opt_type;

typedef struct calc_T
{
 opt_type type;
 char opt_c;
 char opt_d[10];
}calc_T;


#endif

/*

calc.c

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"
#include "calc.h"

char buf[50] = "1+(1+2)*8";
#define  EPSINON 0.000001

calc_T get_elem(char** s)
{
 calc_T ret;
 char *p = *s;
 char tmp_string[10];

 if(*p == ‘)’ || *p == ‘(‘ || *p == ‘+’ ||
    *p == ‘-’ || *p == ‘*’ || *p == ‘/’)
 {
   ret.type = OPT_CHAR;
   ret.opt_c = *p;
   p++;
   *s = p;
   return ret;
 }
 else if(*p >= ‘0′ && *p <= ‘9′)
 {
   ret.type = OPT_DATA;
   ret.opt_d[0] = *p;
   ret.opt_d[1] = 0;
   p++;
   while(*p >= ‘0′ && *p <= ‘9′ || *p == ‘.’)
   {
    tmp_string[0] = *p;
    tmp_string[1] = 0;
    strcat(ret.opt_d, tmp_string);
    p++;
   }
   *s = p;
   return ret;
 }
 else if(*p == 0)
 {
  ret.type = OPT_OVER;
  return ret;
 }
 else
 {
  ret.type = OPT_ERRO;
  return ret;
 }
}

int cmp_pri(char dst, char src)
{
 if(dst == ‘*’ || dst == ‘/’)
 {
  if(src == ‘*’ || src == ‘/’)
   return 0;
  else
   return 1;
 }
 else
 {
  if(src == ‘*’ || src == ‘/’)
   return -1;
  else
   return 0;
 }
}

void deal_zero(char *s)
{
 int i;
 int n = strlen(s);

 for(i=n-1; i>=0; –i)
 {
  if(s[i] != ‘0′)
   break;
 }
 if(s[i] == ‘.’)
  s[i] = ‘\0′;
 else
  s[i+1] = ‘\0′;
}

int main(int argc, char** argv)
{
 char *p;
 stack_api_T* s = NULL;
 stack_T* st_ch = NULL; /* charater stack */
 stack_T* st_da = NULL; /* data stack */
 calc_T opt;
 calc_T tmp;
 calc_T opt_data_1;
 double data_1;
 calc_T opt_data_2;
 double data_2;
 calc_T opt_result;
 double result;

#if 1
 if(argc < 2)
 {
  printf("usage: %s expression\n", argv[0], argv[1]);
  return 0;
 }
 p = argv[1];
#else
 p = buf;
#endif
 init_stack(&s);

 opt = get_elem(&p);
 while(opt.type != OPT_OVER)
 {
  switch(opt.type)
  {
  case OPT_CHAR:
   if(s->top(st_ch, &tmp) < 0)
   {
    s->push(&st_ch, opt);
    break;
   }
   if(opt.opt_c == ‘(‘)
   {
    s->push(&st_ch, opt);
   }
   else if(opt.opt_c == ‘)’)
   {
    while(s->pop(&st_ch, &tmp) >= 0 && tmp.opt_c != ‘(‘)
    {
      s->pop(&st_da, &opt_data_1);
      data_1 = strtod(opt_data_1.opt_d, NULL);
      s->pop(&st_da, &opt_data_2);
      data_2 = strtod(opt_data_2.opt_d, NULL);
      switch(tmp.opt_c)
      {
      case ‘+’:
       result = data_1 + data_2;
       break;
      case ‘-’:
       result = data_2 – data_1;
       break;
      case ‘*’:
       result = data_1 * data_2;
       break;
      case ‘/’:
       if(data_1 >= -EPSINON && data_1 <=EPSINON)
       {
        printf("Error 005, divisor can’t be a zero.\n");
        return -1;
       }
       result = data_2 / data_1;
       break;
      default:
       break;
      }
      opt_result.type = OPT_DATA;
      sprintf(opt_result.opt_d, "%f", result);
      s->push(&st_da, opt_result);
    }
    if(tmp.opt_c != ‘(‘)
    {
     printf("Error 001, illegal expression.\n");
     return -1;
    }
   }
   else
   {
    if(tmp.opt_c == ‘(‘ || cmp_pri(opt.opt_c, tmp.opt_c) > 0)
    {
     s->push(&st_ch, opt);
     break;
    }
    else
    {
     while(s->pop(&st_ch, &tmp) >= 0
      && tmp.opt_c != ‘(‘
      && cmp_pri(tmp.opt_c, opt.opt_c) >= 0)
     {
      s->pop(&st_da, &opt_data_1);
      data_1 = strtod(opt_data_1.opt_d, NULL);
      s->pop(&st_da, &opt_data_2);
      data_2 = strtod(opt_data_2.opt_d, NULL);
      switch(tmp.opt_c)
      {
      case ‘+’:
       result = data_1 + data_2;
       break;
      case ‘-’:
       result = data_2 – data_1;
       break;
      case ‘*’:
       result = data_1 * data_2;
       break;
      case ‘/’:
       if(data_1 >= -EPSINON && data_1 <=EPSINON)
       {
        printf("Error 005, divisor can’t be a zero.\n");
        return -1;
       }
       result = data_2 / data_1;
       break;
      default:
       break;
      }
      opt_result.type = OPT_DATA;
      sprintf(opt_result.opt_d, "%f", result);
      s->push(&st_da, opt_result);
     }
     if(cmp_pri(tmp.opt_c, opt.opt_c) < 0)
     {
      s->push(&st_ch, tmp);
     }
     s->push(&st_ch, opt);
    }
   }
   break;
  case OPT_DATA:
   s->push(&st_da, opt);
   break;
  case OPT_ERRO:
  default:
   printf("Error 002, illegal expression.\n");
   return -1;
  }
  opt = get_elem(&p);
 }

 while(s->pop(&st_ch, &tmp) >= 0)
 {
  s->pop(&st_da, &opt_data_1);
  data_1 = strtod(opt_data_1.opt_d, NULL);
  s->pop(&st_da, &opt_data_2);
  data_2 = strtod(opt_data_2.opt_d, NULL);
  switch(tmp.opt_c)
  {
  case ‘+’:
   result = data_1 + data_2;
   break;
  case ‘-’:
   result = data_2 – data_1;
   break;
  case ‘*’:
   result = data_1 * data_2;
   break;
  case ‘/’:
   if(data_1 >= -EPSINON && data_1 <=EPSINON)
   {
     printf("Error 005, divisor can’t be a zero.\n");
     return -1;
   }
   result = data_2 / data_1;
   break;
  default:
   printf("Error 003, illegal expression.\n");
   return -1;
   break;
  }
  opt_result.type = OPT_DATA;
  sprintf(opt_result.opt_d, "%f", result);
  s->push(&st_da, opt_result);
 }
 s->pop(&st_da, &opt_result);
 if(!s->empty(st_ch) || !s->empty(st_da))
 {
  printf("Error 004, illegal expression.\n");
  return -1;
 }
 deal_zero(opt_result.opt_d);
 printf("%s\n", opt_result.opt_d);

 destroy_stack(s);
 return 0;
}

2006年02月28日

int 

my_printf (void *my_object, const char *my_format, …) __attribute__ ((format (printf, 2, 3)));

my_printf是一个你自己写的函数,比如可能是对vsnprintf等函数进行了封装等等。粗体部分关键字“__attribute__”可以为函数声明赋属性值,其目的是让编译程序可以优化处理。

关键字“__attribute__”可以为函数(Function Attributes),变量(Variable Attributes)和结构成员(Type Attributes)赋属性。具体可以查看gcc手册(http://gcc.gnu.org/onlinedocs/)。这里用到的是函数属性,其语法为:“__attribute__ ((attribute-list))”,并置于函数声明尾部“;”之前。

format (archetype, string-index, first-to-check)

format属性告诉编译器,按照printf, scanf, strftimestrfmon的参数表格式规则对该函数的参数进行检查。“archetype”指定是哪种风格;“string-index”指定传入函数的第几个参数是格式化字符串;“first-to-check”指定从函数的第几个参数开始按上述规则进行检查。

例如:上述例子中,函数my_printf对其参数按“printf”的参数格式进行检查,my_printf的第二个参数的格式化字符串,从my_printf的第三个参数开始进行检查。

       还有,在编译时只用指定了-Wformat选项,才会出现警告信息。(我们一般都是-Wall的,没问题)

       这样,利用这样一个GCC的编译关键字就能在编译时对你指定的函数进行某种规则检查。赶快行动,在你的程序中加入这些,让编译器来为你做检查吧。(我在程序中加入这些,马上编译,立刻就发现一个long型变量使用%d进行格式化的错误)

    引出的一个题外话:如果上述函数my_printf是一个类的成员函数,那么上述声明就应该写成:

int

my_printf (void *my_object, const char *my_format, …)  __attribute__ ((format (printf, 3, 4)));

为什么现在是34

为什么现在是34

my_printf (void *my_object, const char *my_format, …)  __attribute__ ((format (printf, 3, 4)));

为什么现在是34

为什么现在是34

因为类成员函数有一个隐含的参数“this”指针作为函数的第一个参数。

 

 

 

 

2006年02月14日

target:

/> gdbserver 192.168.0.52:5050 foo

// 192.168.0.52 为host的IP地址,5050为任一未使用的端口

host:

/> arm-elf-gdb foo.gdb

(gdb) target remote 192.168.0.142:5050

//192.168.0.142为target的IP地址,5050为指定的端口号

今天早上妹妹打电话过来,

告诉我今天是情人节,

记得要给她嫂子送上玫瑰花和巧克力

2005年12月09日

一个不应该被忘记的日子。