Written by rdc
如果您阅读文章
指针简介,您将知道指针包含内存位置地址。您可以使用参考运算符*来处理这些存储单元中的数据。使用单个数据项的指针不是一个问题,但是如果您需要将多个数据项存储在一起并使用指针进行操作,该怎么办?它可以有点棘手,除非你了解数据如何存储在内存中。
计算机中的单个内存位置为1字节长。足够大以容纳一个ANSI字符(而不是Unicode字符,它们是宽字符并且是两个字节。我们在本文中不讨论Unicode字符。)但是,所有数据类型的宽度不是单个字节。这是一个简单的程序,显示每个数据类型的字节长度。
Dim a As Byte
Dim b As Short
Dim c As Integer
Dim d As LongInt
Dim au As UByte
Dim bu As UShort
Dim cu As UInteger
Dim du As ULongInt
Dim e As Single
Dim f As Double
Dim g As Integer Ptr
Dim h As Byte Ptr
Dim s1 As String * 10 'fixed string
Dim s2 As String 'variable length string
Dim s3 As ZString Ptr 'zstring
s1 = "Hello World!"
s2 = "Hello World from FreeBasic!"
s3 = Allocate( Len( s2 ) + 1 )
*s3 = s2
Print "Byte: ";Len(a)
Print "Short: ";Len(b)
Print "Integer: ";Len(c)
Print "Longint: ";Len(d)
Print "UByte: ";Len(au)
Print "UShort: ";Len(bu)
Print "UInteger: ";Len(cu)
Print "ULongint: ";Len(du)
Print "Single: ";Len(e)
Print "Double: ";Len(f)
Print "Integer Pointer: ";Len(g)
Print "Byte Pointer: ";Len(h)
Print "Fixed String: ";Len(s1)
Print "Variable String: ";Len(s2)
Print "ZString: ";Len(*s3)
Deallocate s3
Sleep
输出为:
Byte: 1
Short: 2
Integer: 4
LongInt: 8
UByte: 1
UShort: 2
UInteger: 4
ULongInt: 8
Single: 4
Double: 8
Integer Pointer: 4
Byte Pointer: 4
Fixed String: 10
Variable String: 27
ZString: 27
请注意,指针的长度始终为4个字节长(与整数相同),无论指向的数据如何,因为指针包含内存地址而不是数据。
查看不同数据类型的长度,您可以看到,如果您要
赋值足够的空间用于10个整数,则需要40个字节的内存。每个整数占用4个字节。所以问题是,你如何从内存缓冲区访问每个整数值?答案,指针数学。看看下面的程序。
Option Explicit
Dim a As Integer
Dim aptr As Integer Ptr
'Allocate enough space for 2 integers
aptr = Allocate(Len(a) * 2)
'Load our first integer
*aptr = 1
Print "Int #1: ";*aptr
'Move the pointer to the next integer position
'aptr + 4
*(aptr + 4) = 2
Print "Int #2: ";*(aptr + 4)
Deallocate aptr
Sleep
End
在这个程序中,我们定义了两个变量,一个
整数和一个
整数指针,aptr。Aptr将指向将包含两个整数的内存缓冲区。
赋值函数需要我们需要的缓冲区的大小,所以我们将
整数的大小乘以2,以保留8个字节的内存(每个整数将占用4个字节的空间)。
在赋值过程之后,aptr包含我们的内存缓冲区的第一个字节的地址。存储第一个整数只是使用参考运算符并将值设置为1的问题。要打印出值,我们再次使用* aptr。
现在,我问你一个问题:编译器如何知道值1需要4个字节而不是1或2个字节?因为我们将aptr定义为
integer ptr .编译器知道一个整数需要4个字节,因此将数据加载到四个字节的内存中。这就是为什么当我们打印出我们得到的值1而不是一些奇怪的数字。
要将第二个值加载到缓冲区中,我们使用:
*(aptr + 4) = 2
这可能看起来有点奇怪乍一看。Aptr指向我们的内存缓冲区中的第一个字节。一个整数是4个字节长,所以要到下一个整数字节的位置,我们必须添加4到aptr。我们需要添加操作的括号,因为引用运算符*的优先级高于+。括号确保我们先执行添加操作,然后应用间接运算符。
请注意,我们没有直接增加aptr。如果我们这样做,aptr将不再指向内存缓冲区的启动,并且当我们释放缓冲区时程序会崩溃,因为它将在内存缓冲区之外的
取消赋值内存。如果需要直接增加一个指针,那么创建一个临时指针变量并增加它,而不是在原始赋值中使用的指针。
内存缓冲区和指针是在内存中存储和操作数据的强大方式。必须注意,以确保您正在根据存储在缓冲区中的数据类型正确访问数据。