views:

72

answers:

4

Say I have a 2D array of random boolean ones and zeroes called 'lattice', and I have a 1D array called 'list' which lists the addresses of all the zeroes in the 2D array. This is how the arrays are defined:

define n 100  
bool lattice[n][n];  
bool *list[n*n];

After filling the lattice with ones and zeroes, I store the addresses of the zeroes in list:

for(j = 0; j < n; j++)
{   
    for(i = 0; i < n; i++)
    {
        if(!lattice[i][j])  // if element = 0
        {
            list[site_num] = &lattice[i][j];  // store address of zero
            site_num++;
        }
    }
}

How do I extract the x,y coordinates of each zero in the array? In other words, is there a way to return the indices of an array element through referring to its address?

EDIT: I need to make the code as efficient as possible, as I'm doing lots of other complicated stuff with much larger arrays. So a fast way of accomplishing this would be great

A: 

How do I extract the x,y coordinates of each zero in the array? In other words, is there a way to return the indices of an array element through referring to its address?
You can't. Simple as that. If you need that information you need to pass it along with the arrays in question.

bool *list[n*n]; is an illegal statement in C89 (EDIT: Unless you made n a macro (yuck!)), you may wish to note that variable length arrays are a C99 feature.

Billy ONeal
I really wish whoever downvoted would leave a comment as to why.
Billy ONeal
@Billy not my vote, but if you know both the array's starting point and the size with which it was allocated (actually it is enough to know all the sizes except that for the first index) you *can* find the indicies from a pointer to an element.
dmckee
@dmckee: Yes, that is correct. It seems that the OP is looking to get the size an array was defined with though outside of the block containing the array. There is no way to just ask C what an array was defined as.
Billy ONeal
+1  A: 

One solution is to map (x, y) to a natural number (say z).

z = N * x + y
x = z / N (integer division)
y = z % N

In this case, you should use int list[N * N];

Another solution is to just store the coordinates when you find a zero, something like:

list_x[site_num] = x;
list_y[site_num] = y;
site_num++;

Or you can define a struct of two ints.

Yassin
I'm guessing the second method is faster, since there's no arithmetic involved?
Eddy
+1  A: 

Well, it is possible with some pointer arithmetic.

You have the address of your first element of lattice and the addresses of all zero-fields in list. You know the size of bool. By subtracting the first-elements address from a zero-field address and dividing by the size of bool you get a linar index. This linear index can be calculated into the 2-dim index by using modulo and division.

But why don't you store the 2-dim index within your list instead of the address? Do you need the addess or just the index?
And you should think about turning the for-loops around (outer loop i, inner loop j).

tanascius
I just need the index. So storing the x,y coordinates in list would be the fastest way of doing it?By the way, bool does work in the C99 standard
Eddy
Yep, I'd store just i*n+j within an integer array. You are right about C99, thanks for pointing this out - I edited my answer.
tanascius
A: 
struct ListCoords
{
   int x, y;
} coords[n*n];

for(i = 0; i < site_num; i++)
{
    int index = list[i] - &lattice[0][0];
    coords[i].x = index % n;
    coords[i].y = index / n;
}

I may have the % and / operators backwards for your needs, but this should give you the idea.

dash-tom-bang