资源预览内容
第1页 / 共60页
第2页 / 共60页
第3页 / 共60页
第4页 / 共60页
第5页 / 共60页
第6页 / 共60页
第7页 / 共60页
第8页 / 共60页
第9页 / 共60页
第10页 / 共60页
亲,该文档总共60页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
R+1.1+2=3 2.C 3.面向对象 4.Lisp 5.省略括号 6.常量对象 7.运算符 DIY 8.无缝内联汇编 9.伪代码 10.模板函数 11.宏 12.函数指针 13.动态调用函数 14.元函数 15.Javascript 16.反射 17.闭包 18.多重继承 19.可变参数 20.默认参数 21.多线程 22.本地调用 23.类型转换 24.动态数组 25.多参数组 26.重载 27.指针和引用 28.全局变量 29.成员变量 30.局部变量 31.常量 32.控制结构 33.模板类 34.包 35.堆 36.库 37.编译和链接 38. 39.图形界面 40.文言文 41.语言特性 42.函数对象 43.效率 44.惰性求值1.1+2=3第一个 R+程序:main a=1 b=2 puts a+b 2.CR+支持 C 风格,上一个程序可以写成这样:void main() int a=1; int b=2; puts(a+b); 对比上一节的程序可以看到 R+的一些特点: *更彻底地类型推断,C+11 需要使用关键字 auto,R+可以省略 auto *函数定义和函数调用均可省略后面的小括号 *语句后面的分号也可以省略 *对于返回值为 void 的函数,可以省略 void(标准 C 默认返回 int)3.面向对象R+支持 C#(Java)风格,上一个程序可以写成这样:public class main public static void main() int a=1; int b=2; puts(a+b); 4.LispR+支持 Lisp 风格,C+的中缀表达式和 Lisp 的 S 表达式可以混合使用:main int a int b = a 1 = b 2 rf print + a b 其中 rf print + a b 等价于 rf print (a+b) 等价于 rf.print(+ a b) 等价于 rf.print(a+b)注意 S 表达式不以逗号作为分隔符,所以适当的时候需要加上括号。另一个 S 表达式的例子: example/4_2.h5.省略括号控制结构(if/for/while)后面的小括号是可以省略的,比如有一个递归求和的 函数:int sum(int a) if a运算符)借助于 R+的运算符自定义功能可以实现一些很有趣的功能,比如: D=(AB)(AC) 这是数学书上的一个表达式,在 R+里只要自定义和两个运算符然后设定好 优先级,再写两个运算符函数:friend vector operator(vectori(int a) if a(a-1) T a 像下面这样调用就可以了:main puts func(10) puts func(10)puts func 10 puts func 10 R+的模板函数十分强大,不仅支持模板函数作为类的成员,还支持模板动态生 成:main int* p=1p p.to.printl putsl typeof(p.to)A a puts a.func puts a.func class A int m_a=2int func return m_a+T 可以看到模板函数和普通函数使用方法完全相同,也不需要关键字 template, 看起来更简洁一些。但是 R+的模板函数暂不支持类型推测,也就是说调用模板 函数时后面的尖括号是必须的。11.宏R+的 define 是在预处理阶段进行替换,功能比较弱,一般不需要使用。R+另 有一个更好用的宏 mac,mac 宏属于类的成员,而不是作用于全局,这样可以更 好地封装。比如: mac fadd(a,b) a+b 等价于 C 语言的 #define fadd(a,b) (a)+(b)对于 mac 宏 R+会自动加上一些小括号避免优先级问题: c=fadd(1,2)*fadd(1,2) puts c 将输出正确的值 9。另外 R+还支持另一种不自动加括号的宏,比如:mac fadd2(a,b) a+b 这时用 c=fadd2(1,2)*fadd2(1,2) puts c 得到的是 5,显然不是我们想要的结果。但是这种宏另有不错的用法,请看下面的例子:main pro=1 for i=2;i v #v.push(1,99,2)拆分宏的另一种用法请参考 example/11_3.h。12.函数指针R+使用一个比 C 语言更简单的函数指针语法,比如有一个这样的函数:int fadd(int a,int b) return a+b; C 语言通常是这样: typedef int (*FADD)(int,int); FADD p=fadd; p(1,2); 或者 int (*p)(int,int)=fadd; p(1,2);可以看到 C 语言必须要指定函数指针的类型,但 R+可以直接这样调用: intreturn y; d0(c) c.printlJSON 序列化和反序列化: a=90,91,92,123,abc:1.9,ef:1,0.2 a.stringify.printl a.stringify.parse.stringify.printl其中 parse 函数是用 eval 实现的: var parse() s=friend var _SELF()a=+torstr+;return a f=s.cstr void* temp sub esp,4 mov ebx,f calle rf.c_eval_txt mov temp,esp add esp,4 s_ret.m_p=temp 对象属性存取: a=a.myfunc=function(a,b)return a+b a.myfunc(1,2).printl a.myfunc.typestr.printla.mydata=4 a.mydata.printl a.mydata=99.9 a.mydata.printl amydata.printlR+的动态类型区分整数和浮点数,调用 typestr 方法可以获取到类型字符串:类型说明 void空类型 int整数 double浮点数 rstr字符串 dic字典(表) function函数目前 R+对 JS 的支持还不完善,有几点需要注意: 1.所有的 JS 函数(function)都必须返回一个 var。 2.动态类型和 JSON 都只能使用单引号字符串。 3.JSON 不能在全局变量和成员变量处初始化。 4.动态类型的效率较低。 5.动态类型只能解释运行。 (如果不使用 eval 可以编译运行,请自行 DIY)16.反射R+拥有完整的反射和自省机制,解释器和 R+代码几乎可以融为一体:import rpp.hmain tasm* p=im_a=2; . R+则是这样:class A int m_astatic void thread(A汇编的关键字不可以用来命名变量,但可以命名函数,比如 vector 类中有一个 push 函数,和汇编关键字 push 同名,下面这样没有问题: vector a a.push(2)R+用 rbuf 代替 STL 的 vector,用 rstr 代替 string,用法大致相同。push 就 是 vector 的 push_back,而 cstr 就是 string 的 c_str。打开 rsrc/basic.h 可以找到: #define vector rbuf #define string rstr要注意的是 rbuf 的 size 方法和 count 方法是不同的: vector a a.push(2) putsl a.size putsl a.count 输出是: 4 1即 size 返回所有元素占用的字节数,而 count 返回元素个数,这和 STL 是有区 别的。25.多参数组R+没有静态数组,新版本也不再提供数组定义的语法糖,仅使用多参数组(数 组运算符带多个参数)来实现多维数组:import “rbufm.h“main rbufm arr(5,5)for i=0;i arr(5,3,4)for i=0 to 4 for j=0 to 2 for k=0 to 3 arri,j,k=j arri,j,k.print 需要注意的是,如果将数组作为函数参数传递,会传递数组的拷贝,也就是说, 形参数组和实参数组互不影响。如果形参数组和实参数组需要共享内存,那么可 以传递引用:func(rbufmi5 A(Ai=10) . 重复定义两个名字和类型都相同的变量也是允许的: vector v v.push(2) v.count.printvector v v.count.print 输出是 1 0 因为 R+中定义变量会先析构后构造,这表示将一个变量重新初始化。故 R+的 类必须支持空构造函数(即使没有编译器也会自动生成一个) ,并且需要在析构 的时候判断是否已经析构: class A int* m_pA() m_p=r_new5 A() if(m_p!=null) r_deletem_p m_p=null 另外,可以使用赋值运算符进行类型推断: a=1+2 等价于 auto a=1+2 等价于 int a=1+231.常量R+目前还不具备 perl 那种强大字符串处理能力,不过也向它学习了一些经验。 对于双引号扩起来的字符串,编译器并不会总是提供语法糖(请参考 No.6) ,实 际上它还是标准 C 的以 0 结尾的 ASCII 串。所以,为了方便处理,R+还提供了 一个用单引号字符串: 123 等价于 rstr(“123“)因此,单引号字符串完全可以当做内置字符串使用,转换成 C 字符串可以这样: 123.cstr连续两个反斜杠表示从当前位置到本行末均为单引号字符串,并且不进行转义: s=abc123 等价于 s=abc123 主要用于字符串内部转义字符和引号很多的情况。R+没有字符常量,但是提供一个反单引号: a 等价于整数 97表示单个字符的方法是: r_char(“a“) 或者 r_char(a)如果整数比较长可以用下划线分隔: 1_0000_0000 等价于 100000000以 0x 开头的常量表示 16 进制整型常量, 以 0b 开头的常量表示二进制整型常量: 0xa 等价于 0b1010 等价于 10双精度浮点(double)常量目前只有小数写法,比如: 0.532.控制结构选择结构和大多数语言一样:if . dosomething elif . dosomething else dosomething对于省略花括号的情况,编译器会自动加上花括号,对于花括号没有单独占一行 的情况,编译器会自动换行,要注意编译器提示的行号是自动处理之后的行号。打开 rsrc/basic.h 可以找到: #define elif else if 即 elif 是一个宏。条件结构是这样:switch . case 1: . case 2: . default: . 可以省略花括号和冒号: switch . case 1 . case 2 . default .R+的条件结构不需要 break,default 是可选的,但如果有必须排在最后。 (实 际上目前 R+还没有进行 switch 优化)带增量的循环结构: for i=1;i=10) 其中 ifn 是语法糖: ifn(i=10) 等价于 if(i=10) break; R+的 goto
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号