arrays && functions && pointers
Derek Parnell
derek at nomail.afraid.org
Sun Jun 18 19:55:01 PDT 2006
On Mon, 19 Jun 2006 01:11:37 +0000 (UTC), MM wrote:
> In C I used to do stuff like:
>
> void foo (TILE (*tiles)[TILEW][TILEH]){
> (*tiles)[0][0].z++; //random operation :)
> }
>
> But as I see in your (very complete :) explanation I can just do:
>
> Void foo (TILE tiles[TILEW][TILEH]){
> tiles[0][0].z++;
> }
>
> This is not slower? I ask this because this foo will be an excessively used
> function in the game loop ;)
>
> btw. How do I reset all the data of a rectangular array?
> something like:
> tiles[][]=0;
D does not *yet* support rectangular arrays. Here is a demo program that
simulates them.
import std.stdio;
import std.string;
// Define the layout of a single tile.
struct TILE
{
int z;
int y;
long x;
real w;
}
// Define a map, which is rectangular array of tiles.
class Map
{
TILE[] mTiles; // The tiles are stored in the dynamic array.
int mWidth; // Record the dimensions used to create it.
int mHeight;
// Create a map of a specific size.
this(int w, int h)
{
mTiles.length = w*h;
mWidth = w;
mHeight = h;
}
// Overload the array '[]' fetch operator.
// I've chosen to return a pointer to the requested tile rather
// than pass the title data. This is a performance issue but
// opens it up to potential bugs (eg. accidental updates).
// e.g.
// TILE local_copy = vMap[w,h];
// int zValue = vMap[w,h].z;
TILE* opIndex(int w, int h)
{
if (w > mWidth || w < 0)
throw new Exception(std.string.format("Bad Width '%s'", w));
if (h > mHeight || h < 0)
throw new Exception(std.string.format("Bad Height '%s'", h));
return (&(mTiles[w*mHeight + h]));
}
// Overload the array '[]' store operator.
// This needs to return the address of the tile so that the caller
// can easily access a tile's members by name.
// e.g.
// vMap[w,h].z = somevalue;
TILE* opIndexAssign(int w, int h)
{
if (w > mWidth || w < 0)
throw new Exception(std.string.format("Bad Width '%s'", w));
if (h > mHeight || h < 0)
throw new Exception(std.string.format("Bad Height '%s'", h));
return (&(mTiles[w*mHeight + h]));
}
// Overload the array '[]' store operator.
// This version allows you to replace an entire TILE in one go.
// This returns the address of the tile so that the caller
// can easily chain assignments.
// e.g.
// TILE someTile;
// vMap[w,h] = someTile;
// zValue = (vMap[w,h] = someTile).z;
TILE* opIndexAssign(TILE pData, int w, int h)
{
if (w > mWidth || w < 0)
throw new Exception(std.string.format("Bad Width '%s'", w));
if (h > mHeight || h < 0)
throw new Exception(std.string.format("Bad Height '%s'", h));
mTiles[w*mHeight + h] = pData;
return (&(mTiles[w*mHeight + h]));
}
// Used to clear every TILE in the map.
void Clear()
{
mTiles[] = TILE.init;
}
}
const TILEW = 256;
const TILEH = 512;
void foo (Map pTiles)
{
// Grab a reference to a tile.
auto lTile = pTiles[3,2];
// Update some members.
lTile.z++;
lTile.x = 30000;
lTile.w = 4.123;
}
void main()
{
// Create the map of tiles.
auto vMap = new Map(TILEW, TILEH);
// Use 'foo' to update a specific tile.
foo(vMap);
writefln("A z=%s x=%s w=%s", vMap[3,2].z, vMap[3,2].x, vMap[3,2].w);
// Clear all tiles.
vMap.Clear();
writefln("B %s", vMap[3,2].z);
// Update a member of a specific tile.
vMap[3,2].z = 17;
writefln("C %s", vMap[3,2].z);
// Replace a specific tile with a totally new one.
TILE lTile;
lTile.z = 42;
vMap[3,2] = lTile;
writefln("D %s", vMap[3,2].z);
// Try to reference a tile out of the map.
writefln("E %s", vMap[3000,2000].z);
}
--
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
19/06/2006 12:52:45 PM
More information about the Digitalmars-d-learn
mailing list