Redy基本数据类型--整数

Redy基本数据类型--整数

()简介

在每种编程语言的基本数据类型里面,整数肯定是少不了。Redy同样,支持整数,不过不像c语言,整数有多种类型。在Redy里面整数只有两种,一种为普通整数,一种为长整数。这一章讲述的是整数,长整数会在后面的章节讲到。

普通整数简称整数,一种与机器相关的数据类型,在32位机长,表示范围为:-231~231-1。在64位机器上,表示范围为:-263~263-1


()整数的数据结构

整数的源代码位于src/rtype/中,有两个文件:bt_int.h , bt_int.c 

(1)结构体定义

代码3.2.1

/* prefix bt short for base type*/
struct bt_int
{
        struct robject i_base;  /*继承robject*/
        int i_value;    /**/
};
typedef struct bt_int BtInt;

为了后面方便表示,用typedef对结构体重定义为BtInt

(2)成员说明

  1. i_base表于继承结构体robject,这种使用方法在上一章有介绍

  2. i_value用于保存整数的数值

(3)重载运算符

在前面Robject那一章讲到过,如果某种数据类型支持指定的运算符,那么该数据类型就必须实现struct rexpr_ops 中相对应的成员函数,例如,下面一段代码;

代码3.2.2

a=1      #变量a引用整数类型
c=3      #变量c引用整数类型
d=a+c    #d=a->r_expr_ops->ro_add(a,c)
e=-a     #e=a->r_expr_ops->ro_negative(a)
print a  #调用 a->r_expr_ops->ro_print(a)
  1. redy解析器运行到第3条语句(d=a+c)时,判断出这是二元运算符'+',就会在变量a所引用的对象成员r_expr_op中查找成员函数ro_add,如果该成员函数没有实现,则解析器判定整数类型不支持二元运算符'+',然后报错。如果实现了,则调用a->r_expr_ops->ro_add(a,c),并把返回值赋值给变量d

  2. 当解析器运行到第4行语句(e=-a),解析器判断出这是一元运算符'-'后,同样在变量a所引用的对象成员r_expr_op中查找成员函数ro_negative,如果没有实现,则报错;如果实现,则调用a->r_expr->ops->ro_negative(a),并把返回值赋值给e

  3. 当解析器运行到第5行语句(print a),这是一条输出语句,这时查找的成员函数为ro_print,如果没有实现,则调用系统默认的输出方法。如果实现则调用a->r_expr_ops->ro_print(a)

综上所述,如果上面那一小段代码想要正确的运行,那么就需要结构体rexpr_ops中三个成员函数:ro_add, ro_negative ,ro_print


(a)一元运算符

整数总共实现了一元运算符有'+' , '- ' , '~' 。其中:

  1. '+'表示正号,返回值为自身。

  2. '-'表示负号,返回值为自身的相返数。

  3. '~'表示取反,返回值为自身取反后的值

(b)二元运算符

对于整数来说,所有二元运算符都支持,具体如下表:


运算符\类型

整数

长整数

浮点数

字符串

数组

ro_mul(*)

整数

长整数

浮点数



ro_div(/)

整数

长整数

浮点数



ro_mod(%)

整数

长整数

浮点数



ro_plus(+)

整数

长整数

浮点数



ro_minus(-)

整数

长整数

浮点数



ro_lshift(<<)

整数

长整数




ro_rshift(>>)

整数

长整数




ro_and(&)

整数

长整数




ro_and(|)

整数

长整数




ro_and(^)

整数

长整数




ro_cmp

整数

整数





说明:例如在第一行ro_mul中,表示:整数*整数=整数;整数*浮点数=浮点数;整数*长整数=长整数;但是整数不能和字符串还有数组相乘。

如下面的代码:

代码3.2.3

a=1
b=a*3        #合法,运行后b引用类型为整数
b=a*3L       #合法,运行后b引用类型为长整数
b=a*3.01     #合法,运行后b引用类型为浮点数
b=a*"hello"  #非法,解析器会报错,整数不支持与字符串相乘
b=a*[3,4]    #非法,解析器会报错,整数不支持与数组相乘

在实现ro_mul时,代码如下:

代码3.2.4

static Robject* bi_mul(Robject* left,Robject* right)
{
        int type=rt_type(right);  /*获取类型*/
        if(type==RT_INT)   /*right为整数*/
        {
                          /*类型转换:Robject转换为BtInt*/
                int value=R_TO_I(left)->i_value*R_TO_I(right)->i_value;
                BtInt* ret=bt_int_create(value);
                return I_TO_R(ret);
        }
        else if(type==RT_FLOAT) /*right为浮点数*/
        {
                .....    /*做整数与浮点数的乘法*/
                do_int_mul_float(left,right);
                .....
        }
        else if(type==RT_LONG) /*right为长整数*/
        {
                ....     /*做整数与长整数的乘法*/
                do_int_mul_long(left,right);
                ....
        }
        else
        {
                ......  /*报错*/
                do_error_report();
                .....
        }
        .....
};


上面代码只是用于大概说明,具体找码可以在bt_int.c中找到

(c)逻辑运算

在结构体rexpr_ops中,ro_bool用于逻辑运算。对于整数如果整数的值不为0,则返回值为true,为0则返回为false

(d)其它

输出语句ro_print



(4)结构体rexpr_ops

代码3.2.5

static struct  rexpr_ops bt_int_expr_ops=
{
        /* unary operator + - */
        .ro_negative=bi_negative,
        .ro_positive=bi_positive,

        /* arithmetic * / % */
        .ro_mul=bi_mul,
        .ro_div=bi_div,
        .ro_mod=bi_mod,

        /* arithmetic + - */
        .ro_plus=bi_plus,
        .ro_minus=bi_minus,

        /* bit_operator << >>*/
        .ro_lshift=bi_lshift,
        .ro_rshift=bi_rshift,

        /* simple compare operator used for 
         * < <= == != >= > */
        .ro_cmp=bi_cmp,

        /* bit_operator & | ^ ~ */
        .ro_bit_and=bi_and,
        .ro_bit_or=bi_or,
        .ro_bit_xor=bi_xor,
        .ro_bit_negated=bi_negated,

        /* logic operator and or not */
        .ro_bool=bi_booleaned,

        /*print */
        .ro_print=bi_print,

};



在上面定义变量bt_int_expr_ops时,使用了gcc的扩展语法,如果某一个成员并未在上面出现,则表示该成员的值为0


()整数的接口


(1)构造函数

代码3.3.1

BtInt* bt_int_create(int value);
BtInt* bt_int_from_str(char* str);
BtInt* bt_int_malloc();

其中:

(1)bt_int_from_str表示从字符串中生成整数的数据结构,字符串表示的数可以为:

  1. 二进制,要求以'0b'或者是'0B'开头,后接一个或多个字符,但后接字符只能为'0''1'。如 '0b010101110' , '0B10101'

  2. 八进制,要求以'0'或者'0o'或者'0O'开头,后接一个或多个字符,但后接字符只能为'0'~'7'。如'045712' '0o145'

  3. 十进制,要求以字符'1'-'9'其中之一开头,后接零个或多个字符,但后接字符只能为'0'~'9',如'478554'

  4. 十六进制,要求以字符'0x'或者'0X'开头,后接一个或多个字符,但后接字符只能为'0'~'9'或者为'a'~'f'或者'A'~'F',如'0xaf233322' '0xAf2ffabc'

  5. 字符串'0',表示数值为0

  6. 其它,返回值为NULL

(2)bt_int_creat表示从一个int型生成BtInt

(3)bt_int_malloc创建一个BtInt,其数值为0,其代码如下:

代码3.3.2

inline BtInt* bt_int_malloc()
{
        BtInt* ret=(BtInt*)malloc(sizeof(*ret));  /*分配内存*/
        ret->i_value=0;  
        Robject* base=&ret->i_base;  /*设置父类属性*/

        base->r_name="Integer"; /*型数类型的名称为"integer"*/
        base->r_expr_ops=&bt_int_expr_ops;  /*支持的运算符类型*/
        base->r_type=RT_INT;    /*用于表示该对象为整型*/
        base->r_ops=&bt_int_ops; 
        return ret;
}


(2)释放函数

代码3.3.3

void bt_int_free(BtInt*);


(3)属性设置与获取

代码3.3.4

/*value getter and setter */
static inline int bt_int_get(BtInt* bti)
{
        return bti->i_value;
}
static inline void bt_int_set(BtInt* bti,int value)
{
        bti->i_value=value;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值