Just one question:

Is the two dimensional array coordinates in C opposite to what the coordinates used in plotting in the CARTESIAN PLANE???

please answer and thanks

Did you mean, [column][row] because I think what is used in the Cartesian plane is [row][column]?

Edited 6 Years Ago by bflack: n/a

No. C is definitely row and then column order.

Cartesian is given as x,y, where x is the horizontal value, and y is the vertical value. So x = C's column, and y = C's row.

C has some functions that directly correspond to Cartesian coordinates, though. I'm thinking of gotoxy(x,y)

Edited 6 Years Ago by Adak: n/a

I usually don't even bother with the C array's. I go straight to the point and access the array's member directly. That way I make my own rules to how I index my array. Many situations call for many types of arrays, and I find the C array a bit too limited.

Instead of...

int Array[5][10];
Array[1][2] = 69;

I prefer...

#define ROWMAX 5

int *Array = malloc(5 * 10 * sizeof(int));
((int *)(Array + (sizeof(int) * (1 + (2 * ROWMAX)))))[0] = 69;
free(Array);

I know it looks complicated but its sooo much more flexible!
If you don't want to use malloc, here's another way...

int Array[5][10];
int *ArrayPtr = &Array;
((int *)(ArrayPtr + (sizeof(int) * (1 + (2 * ROWMAX)))))[0] = 69;

That way you don't need to free memory later.
Too complicated? Use a macro like I do...

#define ArrayItem(x,i1,i2,r) ((int *)(x + (sizeof(int) * (i1 + (i2 * r)))))[0]

int Array[5][10];
int *ArrayPtr = &Array;
ArrayItem(ArrayPtr,1,2,ROWMAX) = 69;

This really gives you a lot of power over the typical C arrays, especially if you exclusively use the pointers of the array elements instead of index iterators in for loops, like this...

int *ArrayStart = &Array;
int *ArrayEnd = ArrayStart + (sizeof(int) * 5 * 10);
int *ArrayCurrent;

for (ArrayCurrent = ArrayStart; ArrayStart != ArrayEnd; ArrayCurrent += sizeof(int)) {
   // ArrayCurrent[0] is now pointing to the next item in the array. You don't need
   // to keep track of the index.
}

That demonstrates a one dimentional array.

If you were to use ArrayCurrent[1] inside the for loop, that will return the value of the NEXT item in the array as opposed to the current item. So to make this multidimensional, you have lots of approaches but I guess the easiest is to change ArrayCurrent += sizeof(int) to ArrayCurrent += (sizeof(int) * ROWMAX) or something like that. That way each loop iteration deals with one row of your array at a time rather than every single element.

This technique is even more powerful when dealing with array's of structures and even nested structures.

Pointers f**king rule!

Edited 6 Years Ago by N1GHTS: n/a

Pointers do kick butt!

This is against my religion, however:

((int *)(Array + (sizeof(int) * (1 + (2 * ROWMAX)))))[0] = 69;

I haven't found it's set of horns or pitchfork, just yet - but I'm still looking! ;)

I like mallocing arrays however. That's an important skill to practice from time to time. Especially 2 and 3 dimension arrays.

In general, I'll use indexing for array logic, though. It's cleaner and clearer, imo.

I usually don't even bother with the C array's. I go straight to the point and access the array's member directly. That way I make my own rules to how I index my array. Many situations call for many types of arrays, and I find the C array a bit too limited.

Instead of...

int Array[5][10];
Array[1][2] = 69;

I prefer...

#define ROWMAX 5

int *Array = malloc(5 * 10 * sizeof(int));
((int *)(Array + (sizeof(int) * (1 + (2 * ROWMAX)))))[0] = 69;
free(Array);

I know it looks complicated but its sooo much more flexible!
If you don't want to use malloc, here's another way...

int Array[5][10];
int *ArrayPtr = &Array;
((int *)(ArrayPtr + (sizeof(int) * (1 + (2 * ROWMAX)))))[0] = 69;

That way you don't need to free memory later.
Too complicated? Use a macro like I do...

#define ArrayItem(x,i1,i2,r) ((int *)(x + (sizeof(int) * (i1 + (i2 * r)))))[0]

int Array[5][10];
int *ArrayPtr = &Array;
ArrayItem(ArrayPtr,1,2,ROWMAX) = 69;

This really gives you a lot of power over the typical C arrays, especially if you exclusively use the pointers of the array elements instead of index iterators in for loops, like this...

int *ArrayStart = &Array;
int *ArrayEnd = ArrayStart + (sizeof(int) * 5 * 10);
int *ArrayCurrent;

for (ArrayCurrent = ArrayStart; ArrayStart != ArrayEnd; ArrayCurrent += sizeof(int)) {
   // ArrayCurrent[0] is now pointing to the next item in the array. You don't need
   // to keep track of the index.
}

That demonstrates a one dimentional array.

If you were to use ArrayCurrent[1] inside the for loop, that will return the value of the NEXT item in the array as opposed to the current item. So to make this multidimensional, you have lots of approaches but I guess the easiest is to change ArrayCurrent += sizeof(int) to ArrayCurrent += (sizeof(int) * ROWMAX) or something like that. That way each loop iteration deals with one row of your array at a time rather than every single element.

This technique is even more powerful when dealing with array's of structures and even nested structures.

Pointers f**king rule!

I dont understand this

((int *)(Array + (sizeof(int) * (1 + (2 * ROWMAX)))))[0] = 69;

because since Array is already an integer pointer, the arithmetic used is pointer arithmetic.
So I think there is no need for sizeof(int) there.
Also,
if you want to refer Array[1][2] the expression should be

* ((int*)((array+2+(1*COL_MAX)))) = 69;

where COL_MAX is 10 as in the example , 2 is the column index and 1 is the row index. Which will refer to the 13 the element of that array.

Edited 6 Years Ago by sree_ec: n/a

@sree_ec

I figured it needed some bug fixes. Yeah, your right about the sizeof() thing.

The thing is, I usually don't use int* as my array pointer type, I instead use void* which is actually not necessary, but I got used to doing it this way as I work with some complex structure array's and I like to control its size strategically. So I got that mixed up with that example code.

@Adak

As for this style of pointer use being evil, Id rather see it as an evil genius. Both methods convert to practically the same assembly code to retrieve the pointer to the element, and as an assembly programmer, I find it more meaningful to me just to push the pointer around than to use C "user friendly" conventions.

You make my point, however Night. You made an error in your code, just trying to display it.

You might need that kind of control in your work, and I agree that indeces become pointers "under the hood" of C arrays - but whenever a simple index will suffice, that's clearly the way I want to work with arrays.

I assure you, I can be VERY creative with errors when working with a complex pointer program. Oh yes! ;)

The wonderful thing about C is that you have so many ways to do the same thing, and to have the option to go that low level is just exciting. All the years i've programmed in so many different languages and nothing quite beats the raw power of the original bad boy.

ok i get it... in C, its (y,x) instead of (x,y). Am i right?

This explanation might help.

Array[a]

will address this kind of matrix:

[0][1][2][3][4]
------->

which is basically a numbered line going right and growing in value.

In the C two dimensional array...

Array[a]

The first parameter [a] is going in the same direction, its the same array, but adds a new dimension to it.

b=0 >> [a=0][a=1][a=2][a=3][a=n]
b=1 >> [a=0][a=1][a=2][a=3][a=n]
b=2 >> [a=0][a=1][a=2][a=3][a=n]
b=n >> [a=0][a=1][a=2][a=3][a=n]

The grid created by this causes the first parameter to behave like X on a cartesian plane going towards the right from 0, while the second parameter adds equal length rows below it and continuing downward stopping at your array's limit. This would be Y going in the negative direction starting from 0.

Now, the point I made earlier is that arrays, being it is in computer memory, is a linear allocation of memory, the reality is that the "shape" of the array is physically like this:

Array[2][3]

[0,0][1,0][0,-1][1,-1][0,-2][1,-2]
-------->

NOTE: This is in the cartesian convention, in C it would not be negative numbers.

Physically, all the data "plotted" on these points are in fact strung together in a line.

So unless you are interested in accessing the array by pointer, there really isn't any reason to consider the C array to be [x][y] or [y][x], because there is nothing in the structure of C that even remotely makes it cartesian compatible. So the definition you use in your program for the MEANING of the two parameters in the C array will always be correct as long as you stay consistent.

Edited 6 Years Ago by N1GHTS: n/a

This article has been dead for over six months. Start a new discussion instead.