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