......
var
a: Integer;
pa: ^Integer; //Pinteger / pointer to integer
pa := @a;
pa contains the address of "a" in memory.
....
GetMem( pData , 64 );
Now pData is a pointer on first byte of 64 . How to write some data in e.g. 32nd byte? Mystery, huh?var
data: PByte; // Pointer to dynamic byte-array
i: integer;
begin
data:=AllocMem(64); // reserve 64 bytes
for i:=0 to 63 do
data[i] := i; // Set data in dynamic array
writeln(inttostr(data[32])); // prints out "32"
FreeMem(data); // Free all (64) bytes
end;
"@" returns the address of a variable.pa := @a;Wait for minute. pa variable contains pointer, not address. Address is got by calling Ofs(a);
pa contains the address of "a" in memory.
I agree that Pointers are very stupid device. For example I take 64 bytes of memory byCode: [Select]GetMem( pData , 64 );
Now pData is a pointer on first byte of 64 . How to write some data in e.g. 32nd byte? Mystery, huh?
type
PInteger = ^Integer;
var
IntPtr: PInteger; // at this stage it is only an address
IntPtr := New(PInteger); // allocate memory for it
IntPtr^ := 100;
N := IntPtr^;
Dispose(IntPtr); // release memory allocated to it
addr := @(IntPtr); // memory address where it begins
size := SizeOf(Integer); // size of allocated memory segment
N := Integer(IntPtr); // value retrieved by type casting
the answer is
- for untyped pointer
(PByte(pdata) + 32)^
- for typed pointer (pointer to byte)
(pdata + 32)^
Which makes sense, if you accept that pdata contains the address of the first byte in the memory block.
as for pointer arithmetic, it depends on the type of pointer:
(somepointer + 32)
does not mean 32 BYTES after somepointer. But it does mean 32 times the size of the element identified by the type of the pointer.
This is how i do it:Thats cool. i didnt know i could reserve memory.. were did you learn that?Code: [Select]var
data: PByte; // Pointer to dynamic byte-array
i: integer;
begin
data:=AllocMem(64); // reserve 64 bytes
for i:=0 to 63 do
data[i] := i; // Set data in dynamic array
writeln(inttostr(data[32])); // prints out "32"
FreeMem(data); // Free all (64) bytes
end;
- for untyped pointer
(PByte(pdata) + 32)^
- for typed pointer (pointer to byte)
(pdata + 32)^
Which makes sense, if you accept that pdata contains the address of the first byte in the memory block.
Over the pointers are not defined any operations other than testing equality and inequality.
Adding the integer will cause error of incompatibility types.
Pointers are not addresses because RAM address is dword value from $00000000 to $FFFFFFFF.
Pointers are not addresses
Pointers are not addresses because RAM address is dword value from $00000000 to $FFFFFFFF.
This is a big problem with modern languages which have more and more abstraction from the actual processor level.
ObjectPascal | C# | comment |
------------ | --- | --------- |
class | class* | object type |
object/instance | object/instance | instance of class = the actual dynamic variable |
value | value | content of a variable |
pointer | reference | (variable containing) the address of a value |
uses windows;
var
SH: TSHFileOpStruct;
shpFrom_C67,shpTo_C67:pointer;
path0,path1:string;
begin
sh.hwnd:=0;
sh.wFunc:=2;
GetMem( sh.pFrom, $200 );FillChar(sh.pFrom^, $200, 0);
GetMem( sh.pTo , $200 );FillChar(sh.pTo^ , $200, 0);
sh.pFrom:=pchar(Utf8ToAnsi(path0));
sh.pTo:=pchar(Utf8ToAnsi(path1));
sh.fFlags:=$251;
sh.fAnyOperationsAborted:=longbool(0);
sh.hNameMappings:=nil;
sh.lpszProgressTitle:=nil;
SHFileOperation(sh);
system.assign(f2,Utf8ToAnsi(path0));
end;
Problem is that I must make pFrom & pToare double-null terminated. How to do that? When I debugging I see that for i:=1 to length(Utf8ToAnsi(path0)) do
sh.pFrom^[i-1]:=Utf8ToAnsi(path0)[i];
Such solution as above is stupid!!!for i:=1 to length(Utf8ToAnsi(path0)) do
sh.pFrom^[i-1]:=Utf8ToAnsi(path0)[i];
for i:=1 to length(Utf8ToAnsi(path0)) do
sh.pFrom{^}[i-1]:=Utf8ToAnsi(path0)[i];
PChar( [code]sh.pFrom[0] ):=PChar(Utf8ToAnsi(path0));
Isn't UTF8 string sometimes longer than ANSI string? Ain't the whole point that it sometimes makes 1 character out of 2 bytes, so that it can support wider range of characters.
I don't know if this works.. but instead of for-loop, something like:Code: [Select]PChar( [code]sh.pFrom[0] ):=PChar(Utf8ToAnsi(path0));
Isn't UTF8 string sometimes longer than ANSI string? Ain't the whole point that it sometimes makes 1 character out of 2 bytes, so that it can support wider range of characters.
Yes, Anna should probably be using a W version of this Windows API, supposing it exists. Then she would need to convert the utf8 string to utf-16 using UTF8ToUTF16 and then copy the resulting string to the Windows record string array. I think that := will be able to copy a UnicodeString to a array of WideChar.
Isn't UTF8 string sometimes longer than ANSI string? Ain't the whole point that it sometimes makes 1 character out of 2 bytes, so that it can support wider range of characters.
I don't know if this works.. but instead of for-loop, something like:Code: [Select]PChar( [code]sh.pFrom[0] ):=PChar(Utf8ToAnsi(path0));
Or first convert it into temporary string so you also know the real length it's reduced to.
I think every programmer should learn some assembly, or at least C, to understand what is actually going on.If anything, this thread proves those words to be absolutely true.
This is a big problem with modern languages which have more and more abstraction from the actual processor level. If a programmer doesn't know how the code translates into low-level binary then he/she can make inefficient programs.
Juha
Beside of an explanation of pointers, there is one good question I guess. What is the real use case of pointers in standard business app dev? Or for example in which operations pointers are must have to use. I am quite new to pointers, realy interesting.In any kind of application, business or otherwise, the ability to use pointers adeptly gives the programmer a lot of flexibility in how to manage memory. This in turn can greatly simplify code as well as having a noticeable impact on the program's performance.
In any kind of application, business or otherwise, the ability to use pointers adeptly gives the programmer a lot of flexibility in how to manage memory. This in turn can greatly simplify code as well as having a noticeable impact on the program's performance.
On the other hand, there is a group of programming languages that explicitly prohibits memory management, i.e. they have no pointer concept. For example, the Java and .NET family. Don't even count the script languages.That's true but, for instance .net applications often feel clumsy and slow (unless on a very, very fast machine) the same is often true of Java programs. Of course, for simple things they do ok but, when it comes to real programs they inevitably fall short of the mark.
That's true but, for instance .net applications often feel clumsy and slow (unless on a very, very fast machine) the same is often true of Java programs.Indeed they are.
Of course, for simple things they do ok but, when it comes to real programs they inevitably fall short of the mark.Putting aside most of the Android apps, some of them quite sophisticated, there are for example: Apache Hadoop and ASP.NET - frameworks for a large scale Web applications, Eclipse and NetBeans, M$ Visual Studio, M$ SQL Management Studio, etc. Very real (some of them - to my regret).
I like and use AWK relatively often and, for some things it is wonderful but, I don't see something like Oracle or Photohop written in AWK given its totally absent facilities to manage memory.I don't know for AWK, but PHP have a lion share in the server side languages (>75%).
And all that without the pointer concept.I'm not saying that many programs can't be written without using pointers but, a program that takes good advantage of the flexibility pointers provide will always have some advantages over one that doesn't.
I don't know for AWK, but PHP have a lion share in the server side languages (>75%).AWK is a text manipulation language. Very simple, easy to learn and really useful to manipulate text. I recommend it. Good tool to have in one's toolbox.
Putting aside most of the Android apps, some of them quite sophisticated, there are for example: Apache Hadoop and ASP.NET - frameworks for a large scale Web applications, Eclipse and NetBeans, M$ Visual Studio, M$ SQL Management Studio, etc.I cannot comment on some of the programs you mentioned but, I use Visual Studio regularly and it's rather far from being a speed demon (no surprise since it is a .net front end.) It's got a lot of nice features but, it's a rather clumsy program. I'd rather not use it but sometimes it is helpful.
Probably most real use cases are image manipulations/comparisons? Video coding/decoding? As mentioned Windows API, other works with *dll 3rd party. I think the most hardware drivers are using pointers.
Mark,
or refer to our example of a Pointer being like your credit-card of your bank-account from some weeks ago
When I started explaining this stuff to perplexed students people didn't have credit cards.I'm still remembering the time when the Pascal pointers were strongly typed and the things you can only do with them were new(), dispose() and =.
I'm still remembering the time when the Pascal pointers were strongly typed and the things you can only do with them were new(), dispose() and =.
Now, the classes are the better substitute, you can create/free them, can't do arithmetic, etc. This topic makes me wonder about how long I haven't used the ^ symbol. It seems to have been a long time ago, because I don't remember well.
Address of variable in memory can both be constant and variable. [$40000000] = 3 is example of variable with constant address. But address can also be variable. For example when you access array element it's address is calculated like <Address of array> + <Size of element> * <Index>. Another opportunity - to store address of one variable in another variable. That's, what pointer actually is.Speaking of pointers and arrays, the C language once startled me with the commutativity of it's subscript operator [].
Dump of assembler code for function main:
0x00000000004004f6 <+0>: push %rbp
0x00000000004004f7 <+1>: mov %rsp,%rbp
=> 0x00000000004004fa <+4>: movl $0x1,-0x1c(%rbp)
0x0000000000400501 <+11>: movl $0x1,-0x1c(%rbp)
0x0000000000400508 <+18>: movl $0x1,-0x1c(%rbp)
0x000000000040050f <+25>: mov $0x0,%eax
0x0000000000400514 <+30>: pop %rbp
0x0000000000400515 <+31>: retq
var obj: TObject;
as a pointer?...
a[5] = 1; 5[a] = 1;
So what is a pointer and what is an index? The answer is obvious for experienced, but maybe not so obvious for for a novice.
Take a very simple program as an example, a checkbook program (not much to such a program.) It would be expected that the program can present the information sorted by payee, date, check number, amount and possibly other criteria.
Without using pointers sorting the checks is a real pain...
@440bxI wouldn't consider that a pointer but, if instead of TObject, it had been "class of object" (I probably have the syntax wrong, I stay away from objects/classes like the plague) then I would definitely consider that a pointer (a hidden one which makes it worse.)
Do you considerCode: [Select]var obj: TObject;
as a pointer?
Because, AFAIK it is a reference. And you can use TObjectList or some other container from the template library to do that job. Without using the ^.
If sorting is a job suitable for the inexperienced, how is it that it's taken 60 years for people to agree how to do it?Designing sorting algorithms is definitely not for the inexperienced but, the inexperienced definitely want to use someone's sorting algorithm and, when they do, understanding pointers would quite likely serve them well.
And if sorting and searching are so trivial,I didn't say that sorting and searching are trivial. What I say is that even something as trivial as a checkbook program needs them. Because of that, a programmer should, at least, be familiar with a number of algorithms for them which means they should have a reasonable understanding of pointers.
However I'd suggest that the fact that the operations benefit from pointers and that pointers are tricky beasts means that searching and sorting operations should always be encapsulated: as they are of course with FPC's TStringList.The problem is that hiding pointers has consequences, many of them really bad. Among those consequences is that there are too many programmers who don't really understand what is happening in their programs because they don't see the hidden pointers. The result is, they are much more likely to make a mistake than someone who see what is happening behind the scenes. Not too mention that the program's design will likely be "less than optimal".
<snip> which would make reference counting memory managers more tractable.reference counting memory managers... just what a programmer needs, some "memory manager" to get in the way of the programmer's design.
Basically, and to take an image, a pointer could be seen as one of the traffic panels on a crossroads, each pointing to its own distant city (i.e. each to its variable). The address of a pointer (for ex., @pTowardsBigCity) could be seen as the location of the city named "BigCity". Following a pointer, i.e. dereferencing it (pTowardsBigCity^), means to follow its direction, in order to reach the desired address, to arrive at the variable that we want to know, to see (i.e. to visit the desired city). There are many crossroads, each with its traffic panels. So, each crossroad, traffic panel, has its address too (for ex., @@pTowardsBigCityFromTrafficPanelNum1), to possibly distinguish them from each other (practical, if they all point to the same city, in one region).
:)
I've just found what pointers and setters are. 8-)