Skip to main content
GameDev.net gamedev.net
🔒 Locked

Pointer arithmetic and arrays.

Started by MeshGearFox Oct 14, 2008 at 10:17 PM 8 replies 1.2k views
Original Post
MeshGearFox
MeshGearFox
I'm well aware that this is odd and that this is probably something I SHOULDN'T do in a professional/more serious context. What I want to do is loop through an array without integer's to access specific array positions. This is a two or three dimensional array, consisting of chars. The arrays are all 16 elements in size. Instead of using actual integer values to access positions in these arrays, I instead have two (or three) arrays of booleans, four elements each, representing binary numbers from 0 to 15. Now, doing this in the more rational way, if I wanted to access something in an array, I'd just do something like cout << z[14][2] << endl; or whatever. However, instead, I'm trying to handle this using that binary number array thing.
    char array[16] = "abcdefghijklmno";
    char *i;
    bool byte[4] = {1,0,0,0};
    i = array;
    i++;
    cout << *i << endl;    
    i = array;
    cout << *i << endl;
    if(byte[0] == 1) {
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;
        i++;        
    }
    if(byte[1] == 1) {
        i++;
        i++;
        i++;
        i++;
    }
    if(byte[2] == 1) {
        i++;
        i++; 
    }
    if(byte[3] == 1) {
        i++; 
    }    
    cout << *i << endl;
This is sort of how I'm doing it right now (While loops would obviously be used in each of the if statements. I'm not really sure why I wrote that like I did, there). Anyway, is there any way to do something similar, for a 2D or 3D array? Or some other way I could iterate through the char array wihout directly accessing the various locations in the array using actual integers?
ApochPiQ
ApochPiQ
Can you describe exactly why you need this behaviour? It seems to me there may be a cleaner solution to the root problem at hand.
Hodgman
Hodgman
I'm not exactly sure what you're trying to do, but may I suggest a replacement for your if/++ section?
bool bits[4] = {1,0,0,0};bool* pBit = bits;int numBits = sizeof(bits)/sizeof(bool);while( numBits ){    --numBits;    if(*pBit == 1) {        i += 1<<numBits;         }    ++pBit;}
DevFred
DevFred
Pointer arithmetic is more than just the ++ operator. This
Quote:
i = array;    if(byte[0] == 1) {        i++;        i++;        i++;        i++;        i++;        i++;        i++;        i++;    }    if(byte[1] == 1) {        i++;        i++;        i++;        i++;    }    if(byte[2] == 1) {        i++;        i++;    }    if(byte[3] == 1) {        i++;    }

can be replaced by a single line:
i = array + (byte[0] << 3 | byte[1] << 2 | byte[2] << 1 | byte[3]);

Note that if you made byte little endian instead of big endian, the code would look more symmetric:
i = array + (byte[3] << 3 | byte[2] << 2 | byte[1] << 1 | byte[0]);

Oh, and please don't name pointers i. It's very confusing.
Zahlman
Zahlman
Quote:
Original post by MeshGearFox
Anyway, is there any way to do something similar, for a 2D or 3D array?


Here's a hint:

int test[4][4] = {  {0, 1, 2, 3},  {4, 5, 6, 7},  {8, 9, 10, 11},  {12, 13, 14, 15}};int* memory = reinterpret_cast<int*>(test);for (int i = 0; i < 16; ++i) {  std::cout << memory << '\n';}
MeshGearFox
MeshGearFox
I think this is doing what I want it to do but I still don't understand that thing you were doing with the left-shifts.

#include <iostream>using namespace std;int main(){    struct byte {        bool eight;        bool four;        bool two;        bool one;    };        int array[16][16];        for(int y = 0; y < 16; y++) {        for(int x = 0; x < 16; x++) {            array[x][y] = x,y;        }    }                        byte xcoord = {0,0,0,0};     byte ycoord = {1,1,1,1};        int *i;    i = &array[0][0];        cout << *i << endl;    if(xcoord.eight) { i += 8; }    if(xcoord.four) { i += 4;}    if(xcoord.two) { i += 2; }    if(xcoord.one) { i += 1;}    if(ycoord.eight) { i += (8 * 16); }    if(ycoord.four) { i += (4 * 16);}    if(ycoord.two) { i += (2 * 16); }    if(ycoord.one) { i += 16; }    cout << *i << endl;        char bill;    cin >> bill;    return 0;}        
DevFred
DevFred
Quote:
Original post by MeshGearFox
    for(int y = 0; y < 16; y++) {        for(int x = 0; x < 16; x++) {            array[x][y] = x,y; // <--- this probably doesn't do what you want        }    }

Do you know what the comma operator does? It evaluates the first operand, throws the result away, and then evaluates the second operand. Thus x,y is equivalent to y.

And this
Quote:
Original post by MeshGearFox
    int *i;    i = &array[0][0];        if(xcoord.eight) { i += 8; }    if(xcoord.four) { i += 4;}    if(xcoord.two) { i += 2; }    if(xcoord.one) { i += 1;}    if(ycoord.eight) { i += (8 * 16); }    if(ycoord.four) { i += (4 * 16);}    if(ycoord.two) { i += (2 * 16); }    if(ycoord.one) { i += 16; }

can be replaced by
    int *i = &array    [ycoord.eight << 3 | ycoord.four << 2 | ycoord.two << 1 | ycoord.one]    [xcoord.eight << 3 | xcoord.four << 2 | xcoord.two << 1 | xcoord.one];
Nyarlath
Nyarlath
Quote:
Original post by DevFred
Thus x,y is equivalent to y.

But the comma operator has less priority to respect to the assignment, so array[x][y] = x,y; is equivalent to array[x][y] = x; y; and array[x][y] = x;
DevFred
DevFred
You are right.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.