FreeBASIC マニュアルのトップに戻る

FreeBASIC (POINTER | PTR)

目次→言語リファレンス→変数とデータ型→標準のデータ型→データ型修飾語→PTR←オリジナル・サイト

(POINTER | PTR) 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

変数宣言の型修飾語

構文:
... as DataType {Pointer | Ptr}

dim symbolname as DataType {Pointer | Ptr}

記述:
ポインタ変数を宣言します。
変数型は、事前定義された型またはユーザー定義型にすることができます。
Pointer と同じです。

演算子 @ (Address of) operator あるいは、Varptr は、変数のアドレスを取得するために使われます。
演算子 * (Value of) operator は、ポインターを逆参照する(ポインターの指す値を取得する)ために使われます。すなわち、ポインターが指し示している記憶域に保存した実際の値(実体)にアクセスします。

例:
' ポインタを作成します。
Dim p As Integer Ptr

' ポインタ「p」を使って示すつもりの、整数値を作成します。
Dim num As Integer = 98845

' 変数「num」が占領するメモリ・アドレスを、p に代入します。
p = @num

' メモリに保存したい実際の値を表示します。
Print "メモリに保存したい実際の値 num は:";num
Print

' ポインタ「p」で示されたメモリに保存された値を表示します。
Print "ポインタ 'p' のアドレスに保存された値 *p は:";*p
Print

' ポインタ「p」が指し示すメモリ上の場所を表示します。
Print "ポインタ 'p' が指すメモリのアドレス p は:"; p

Sleep


Dim p As ZString Pointer
Dim text As String
text = "Hello World!"
p = StrPtr(text) + 6
Print text
Print *p
Sleep

'' Output:
'' Hello World!
'' World!



Type mytype
    a As Integer = 12345
End Type

Dim As mytype mt

Dim As mytype Ptr pmt
pmt = @mt

Print (*pmt).a  '' or Print pmt->a

'' Output:
'' 12345



ULong 数にポインタを使う方法
'How to use a pointer for a ULong number
'ULong 数にポインタを使う方法 1
'by badidea ≫ Dec 05, 2020 8:58
'https://www.freebasic.net/forum/viewtopic.php?f=2&p=278177&sid=b8c9ab54417184c36b828d3cfda7cb7f#p278175

'以下の結果が表示されるはずです:
'120
'86
'52
'18

Dim Number As ULong
Dim NumPtr As UByte Ptr
Dim Index As Byte

Number = &H12345678
NumPtr = Cast(UByte Ptr, @Number) 'ポインタ(メモリアドレス)に Cast() を使います

For Index = 0  To 3
  Print Peek(NumPtr)
  NumPtr = NumPtr + 1
Next

Sleep

'How to use a pointer for a ULong number
'ULong 数にポインタを使う方法 2
'by fxm ≫ Dec 05, 2020 19:05
'https://www.freebasic.net/forum/viewtopic.php?f=2&p=278188#p278187

Dim Number as ULongInt

Number = &H123456789ABCDEF0
Print Hex(Number)
Print

Print Hex(Peek(ULongInt, @Number))  '' @Number は既に ULongInt ptr
For n as Integer = 1 to 0 step -1
    Print Hex(Peek(ULong, Cptr(ULong ptr, @Number) + n)) & " ";
Next n
Print
For n as Integer = 3 to 0 step -1
    Print Hex(Peek(UShort, Cptr(UShort ptr, @Number) + n)) & " ";
Next n
Print
For n as Integer = 7  to 0 step -1
    Print Hex(Peek(UByte, Cptr(UByte ptr, @Number) + n)) & " ";
Next n
Print

Sleep

'123456789ABCDEF0
'
'123456789ABCDEF0
'12345678 9ABCDEF0
'1234 5678 9ABC DEF0
'12 34 56 78 9A BC DE F0

ULong は 4バイトに分割されています(1つのULong = 4バイト)。
ULong を使うので、UByte(0〜255)を用いて、fb32 ビットカラーを処理・抽出する標準的な方法が得られます。
注:FreeBASIC 1.08〜 で、SetEnviron を追加しなくても、日本語環境で描画画面が表示されるように改善されました。
ポインタを使う方法
'How to use a pointer for a ULong number
'ULong 数にポインタを使う方法 3
'by dodicat ≫ Dec 05, 2020 20:07
'https://www.freebasic.net/forum/viewtopic.php?f=2&p=278188#p278188
 
' Sets the graphics method GDI
' 描画方法を GDI に設定
SetEnviron("fbgfx=GDI")

ScreenRes 600,400,32,,64  '64 = 透過表示可
Width 600\8,400\16        'get 16 pixel high font

Color RGB(0,0,0),RGB(255,255,255) '前景色,背景色
Cls
Dim Number As ULong

Number =&H12345678

Print Hex(Number)
Dim As UByte c(3)

For i As Long = 0  To 3
    c(i)=Cast(UByte Ptr,@number)[i]
    Print Hex(c(i)),c(i)
Next
Print Hex(RGBA(c(2),c(1),c(0),c(3)))
Circle(300,200),100,RGBA(c(2),c(1),c(0),c(3)),,,,f

Sleep
Integer は、32ビットコンパイラでは 4バイト、64ビットコンパイラでは 8バイトなので、freebasic で Integer を使うと、不要な複雑さとエラー発生で、時間を浪費することになるかもしれません。

ULong は4 つの UByte(たとえば、&h12、&h34、&h56、&h78)で構成され、2つに分割する必要があります(文字列の 8 要素を取得する、上位 4ビットと下位 4ビット)。
各文字列要素の ASCIIコード(16進形式)を取得するには、各「1 /2 UByte」に、48(0〜9の値の場合)または 55(10〜15の値の場合)を追加する必要があります。
'How to use a pointer for a ULong number
'ULong 数にポインタを使う方法 5
'by fxm ≫ Dec 06, 2020 21:11 

'https://www.freebasic.net/forum/viewtopic.php?f=2&p=278188#p278214


Declare Function NumSizeByByteToString(Number As ULong,NumSize As Byte,Endianness As Boolean) As String

'Convert Number (ULong) to a string based on size in bytes of Number
Function NumSizeByByteToString(_
  ByVal Number As ULong,_
  ByVal NumSize As Byte,_
  ByVal Endianness As Boolean) As String

'Convert a number specified by size in bytes to a string that
'is the same size in bytes.
'parameters:
'   Number = number to convert specified by size
'   NumSize = Byte size of number to convert as a string
'          can be 1,2,4
'   Endianness = True (big) or False (small) order for number
'                Big Endianness order is low Byte then high Byte
'                Small Endianness order is High Byte then low Byte
'Number is returned as a string that is the same size in bytes.
'Note: Size is not validated.
Dim NumPtr As Byte Ptr
Dim Inc As Byte
Dim Index As Byte
Dim StrValue As String
Dim Strpointer As ZString Ptr

If Endianness Then
  'Big Endianness order is low Byte then high Byte
  NumPtr = Cast(UByte Ptr, @Number)+NumSize-1  '' <--- modified
  Inc = -1
Else
  'Small Endianness order is High Byte then low Byte
  NumPtr = Cast(UByte Ptr, @Number)+4-NumSize  '' <--- modified
  Inc = 1
End If

'create a temporary string to place Number in.
StrValue = String(2*NumSize,0)  '' <--- modified

'point to start of string
StrPointer = StrPtr(StrValue)

'Convert Number (ULong) to a string based on size in bytes of number
For Index = 0 To 2*NumSize-1
  'First method
  If (Index Mod 2 = 0 And Endianness = TRUE) Or (Index Mod 2 = 1 And Endianness = FALSE) Then  '' <--- added
    StrValue[Index] = ((Peek(UByte,NumPtr) And &hF0) Shr 4)  '' <--- added
  Else  '' <--- added
    StrValue[Index] = (Peek(UByte,NumPtr) And &h0F)  '' <--- added
  End If  '' <--- added
  If StrValue[index] <= 9 Then  '' <--- added
    StrValue[index] += 48       '' <--- added
  Else                          '' <--- added
    StrValue[index] += 55       '' <--- added
  End If                        '' <--- added
  If Index Mod 2 = 1 Then       '' <--- added
    NumPtr = NumPtr + Inc       '' <--- added
  End If                        '' <--- added
  'second method
  'poke UByte,Strpointer + Index,Peek(UByte,NumPtr)  '' <--- not modified
Next

Return StrValue
End Function

'***************************************************************
'ここからコードが呼び出されます。
'***************************************************************

Dim Number As ULong
Dim NumSize As Byte
Dim StrNumber As String
Dim Endianness As Boolean

Number = &h12345678

NumSize = 2

Endianness = TRUE

StrNumber = NumSizeByByteToString(Number,NumSize,Endianness)

Print "StrNumber = ";StrNumber
Sleep

End

'How to use a pointer for a ULong number
'ULong 数にポインタを使う方法 6
'by fxm ≫ Dec 06, 2020 21:11 

'https://www.freebasic.net/forum/viewtopic.php?f=2&p=278188#p278214

Declare Function NumSizeByByteToString(Number As ULong, NumSize As Byte) As String

'Convert Number (ULong) to a string based on size in bytes of Number
Function NumSizeByByteToString(ByVal Number As ULong, ByVal NumSize As Byte) As String

'Convert a number specified by size in bytes to a string that
'is the same size in bytes.
'parameters:
'   Number = number to convert specified by size
'   NumSize = Byte size of number to convert as a string
'          can be 1,2,4
'Number is returned as a string that is the same size in bytes.
'Note: Size is not validated.
  Return Right(Hex(Number, 8), 2 * NumSize)  'Hex 関数を使う
End Function

'***************************************************************
'ここからコードが呼び出されます。
'***************************************************************

Dim Number As ULong
Dim NumSize As Byte
Dim StrNumber As String

Number = &h12345678

NumSize = 2

StrNumber = NumSizeByByteToString(Number, NumSize)

Print "StrNumber = "; StrNumber
Sleep

End

'How to use a pointer for a ulong number
'by dodicat ≫ Dec 10, 2020 11:44
'
'https://www.freebasic.net/forum/viewtopic.php?f=2&t=29019&p=278332#p278332


Dim Number As ULong
Dim StrNumber As String
Dim Index As UByte

Number = &h12345678

StrNumber = Hex(Number, 8) 'convert Number to an 8-byte-string
For Index = 1 To Len(StrNumber) Step 2
   Print Mid(StrNumber, Index, 2)
Next

Print

strnumber = * Cast(ZString Ptr,@Number)
For n As Long=0 To 3
Print Hex(strnumber[n])
Next n

Sleep

追加解説:
dim a as Integer = 100 
dim pa as Integer ptr = @a 
print pa 
print *pa 
とした場合、
変数 a はコンパイラにより自動的にメモリ上に Integer型の領域を確保され、100が代入されます。
2行目は、その確保されたアドレスを変数 pa に格納しています。
@a は、address of a という意味です。
3行目は、変数 pa が指し示すアドレスを表示します。
4行目は、ポインタが保持するアドレスにあるInteger型の値を取得して、値の100が表示されます。
*pa は、value of pa という意味です。

通常、newallocate でメモリ領域を確保し、ポインタ型にそのアドレスを格納し、処理後に deletedeallocate でメモリを開放します。
普通の変数宣言は、コンパイラがメモリの確保と開放をスコープ基準でやってくれますが、ポインタ型の変数宣言はプログラマ自身がメモリの確保と開放を動的に行う必要があります。



方言差:

QBからの違い:

参照:
標準のデータ型に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2021-02-22 15:18:52
日本語翻訳:WATANABE Makoto、原文著作者:SysOp

ホームページのトップに戻る

表示-非営利-継承