Pointers are often used in lower-level languages, such as C, as an efficient way to access and perform operations on memory buffers. In C, as with many other languages which allow their use, a pointer is simply a variable with a value: that value is the address of a region of memory, and the memory can be accessed by dereferencing the pointer.
The current generation of languages have generally eschewed pointers, and most big thinkers in programming discourage their use. As The C Programming Language states:
Pointers have been lumped with goto statement as a marvelous way
to create impossible-to-understand programs. ... With discipline, however,
pointers can be used to achieve clarity and simplicity.
It's for this reason that the team behind the development of C# ran against the trend of removal for pointer syntax, and included pointers in the language.
Pointers and unsafe blocks
C# is one of the languages in the .NET family, and as such is run under the Common Language Runtime (CLR). It's the runtime that takes care of memory operations and lower-level functionality on the program's behalf, so that the program doesn't normally have to worry about pointers or memory buffers.
The language does, however, provide a way for pieces of code to avoid the
constraints of the CLR. Any blocks marked as unsafe will not be
managed by the runtime, and it's up to the programmer to test and ensure that
the code works as expected.
An unsafe block in a method
As can be seen in this example, pointer dereferencing and casts are both
allowed to happen inside an unsafe block, such that pointer
operations within these blocks proceed much as they would under C.
A graphic example: The fire effect
One of the first things a budding coder wants to learn is how to make a game, and the first stage in that journey is how to output graphics to the screen. Among the simplest demonstrations of graphical output are the two-dimensional colour effects: palette rotation, plasma, and the effect being explored here, fire.
The effect relies on the screen being represented as a memory buffer, running left-to-right and top-down; accessing consecutive memory locations will run through the whole buffer in sequence. An averaging algorithm is applied across the buffer, which runs as follows:
Fire algorithm, applied to a memory buffer
The effect of this is that the larger values, from the line beneath, are transferred in lesser form up the screen; combined with a forced decrement on the averaged value, the effect is a randomised fading from high values at the bottom, to zero at the top. With the appropriate palette to define high values as white, going through yellow and red to black, it's easy to make this look like a burning fire.
It's a situation that's ideal for pointers: dereferencing a pointer to get the value at the current pixel, adding constants on to get to the pixels around the current one, and then pushing the pointer along to do the next byte.
Putting the effect on-screen
The simplest way of using this effect to get something on the screen is to use a Windows Form; the Form base class will handle all the window instantiation and mouse events, leaving us to concentrate on putting data into the window. By holding a handle to an 8-bit bitmap image, and drawing that image into the window, the Bitmap class will do all the work of calculating palette colours and translating them from the bitmap indices.
fire.cs: Rendering the fire
In the full example above, the unsafe block in the paint
handler is where the averaging algorithm is applied across the bitmap buffer,
through the use of pointers. By running this code for a few seconds, the
following is produced on-screen.
Figure 1: The fire algorithm applied to a bitmap buffer
So that's how it works. Some languages in the current crop forbid the use of pointers altogether: C# allows their use, but only if you promise to keep things clean, because the runtime won't do it for you.
Copyright Imran Nazar <tf@imrannazar.com>, 2008.
Article dated: 1st Nov 2008