您的位置:首页 > 其它

Nim 中的引用和指针

2015-09-17 18:11 253 查看

引用和指针

引用是介绍多对一关系的一种方式。这意味着不同的引用可以指向和修改相同的内存单元。在Nim中分为跟踪引用和非跟踪引用(反跟踪)。非跟踪引用也叫做指针。跟踪引用指向一个垃圾收集堆上的对象,反跟踪指向手动分配的对象或内存中其他地方的对象。因此反跟踪引用是不安全的。然而对于某些低级操作(访问硬件)反跟踪引用是不可避免的。

引用用 ref 关键字声明,指针用 ptr 关键字声明。

方括号[] 能够访问存取引用指向的数组、字符串、序列的值。 . 运算符能够访问存取元组、对象的域。

创建一个新的追踪对象,要用到内置函数new()。为了处理反追踪内存函数alloc(),dealloc(),realloc()函数可以使用。

引用:

type
Node = ref NodeObj
NodeObj = object
le, ri: Node
data: int

var
n: Node
new(n)
n.data = 5
# no need to write n[].data; in fact n[].data is highly discouraged!
echo n.data

type
TnodeArr = array[10,Node]
var myNodeArr:TnodeArr
for i in 0..5:
new(myNodeArr[i])
myNodeArr[i].data = i

myNodeArr[0].ri = myNodeArr[1]
myNodeArr[5].ri = myNodeArr[0]
myNodeArr[0].le = myNodeArr[5]
myNodeArr[5].le = myNodeArr[4]

for i in 1..4:
myNodeArr[i].ri = myNodeArr[i+1]
myNodeArr[i].le = myNodeArr[i-1]

for i in 0..5:
echo myNodeArr[i].data,"==>",myNodeArr[i].le.data,"    ",myNodeArr[i].ri.data

输出:

5
0==>5    1
1==>0    2
2==>1    3
3==>2    4
4==>3    5
5==>4    0


指针:

type
Data = tuple[x, y: int, s: string]

# allocate memory for Data on the heap:
var d = cast[ptr Data](alloc0(sizeof(Data)))

# create a new string on the garbage collected heap:
d.s = "abc"
echo d[]

# tell the GC that the string is not needed anymore:
GCunref(d.s)

# free the memory:
dealloc(d)


输出:
(x: 0, y: 0, s: abc)


int 在内存中的存储

import strutils

type
myint = ref int

var
refvar1:myint
refvar2:myint
var1:int
var2:int

var1 = 6
var2 = 6

new refvar1                     #注意使用 引用前要 new
new refvar2

echo repr(var1)             #repr 返回的是 变量 var1 的字符串表达。 如果是整形,返回整形的值,如果是字符串,返回字符串存储位置和字符串。
echo repr(refvar1)

refvar1 = cast[myint](addr(var1))                #addr 返回的是 变量var1在内存中的地址。    此时引用指向了变量 var1 的地址。

echo BiggestInt(cast[int](addr(var1))).toHex(12)    #把var1 的地址转换成十六进制数输出。
echo repr(refvar1)               #ref 0x624e00 --> 6     表示引用refvar1 指向变量地址为 0x624e00的变量, 变量var1 的内容是 6.

refvar2 = cast[myint](addr(var2))

echo BiggestInt(cast[int](addr(var2))).toHex(12)
echo repr(refvar2)


string 在内存中存储

import strutils

var
var1 = "yrs"
refvar1:ref string

echo BiggestInt(cast[int](addr(var1))).toHex(12)      #var1 的地址
echo BiggestInt(cast[int](var1)).toHex(12)            #var1 的内容
echo repr(var1)                                     #var1 的内容为存放 字符串 "yrs" 的地址。

new refvar1

refvar1 = cast[ref string](addr(var1))             #此时引用refvar1 的内容是 var1 的地址,也就是refvar1 指向 var1.
echo repr(refvar1)                          #ref 0x624dd0 --> 0x7f3c2808d050"yrs"  代表的意思是:引用refvar1 的内容为var1的地址 0x624dd0,
#0x7f3c2808d050 是var1 的内容, 也是存储字符串 "yrs" 的地址。
echo refvar1[]                        #[]是字符串,序列等的解引用,  . 是对 对象域的解引用。


用一张图片来表示:



由此可见int 和 string 在内存中存储是不一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: