12

I've just started learning to program in C, and to improve my understanding of pointers and arrays, I tried to refer to the elements of an array without creating any pointer at all:

for(k1 = 0; k1 < ROW; k1++){
    for(k2 = 0; k2 < COLUMN; k2++){

        array[k1][k2] = k1*COLUMN + k2 + 1;

        printf("[%d][%d] = %d\n", k1, k2, *(array[k1] + k2));

    }
}

The entire code compiles and runs flawlessly.

I imagine having to create a pointer for every single array in a big source code seems to be highly inefficient.

So, rather than having the address of an array stored and retrieved by using a pointer, is it a bad programming practice to use the address of the array directly, as shown above?

  • Using printf "[%d][%d] = %d\n", k1, k2, array[k1] [k2])); would avoid the pointer arithmic and is easier to understand. – Kasper van den Berg Dec 22 '15 at 15:11
  • 1
    Haha, you got me. I did that only as an experiment to gain better understanding of how pointers and arrays work. – Niko Gambt Dec 22 '15 at 15:14
  • Pointer arithmetic is actually about 30% faster than using array indexes. – Andy Jan 22 '16 at 19:18
16

It's "bad" only to the extent that's less readable. a[x] is the same thing as *(a+x), so there's no difference in efficiency or behavior (in fact, x[a] will also work). It's just that a[x] is usually a lot more intuitive to us humans.

But that's not to say readability isn't a big deal. To see how big, think about how you would "read" these two expressions if you saw them in code:

  • *(a+x) = "The thingy pointed to by the sum of pointer a and integer x"
  • a[x] = "The xth member of array a"

Similarly, when you need to refer to the address of an array element:

  • (a+x) = "The sum of pointer a and integer x"
  • &a[x] = "The address of the xth member of array a"

Most of the time, the [] versions are just easier to understand when you're looking at non-trivial code operating on several different arrays (especially arrays of arrays). That's why the [] operator exists in the first place.

P.S. Doing this sort of thing strictly as a learning exercise is a very good idea. It's important to understand that arrays really are just pointers and offsets.

  • This. Thank you. I've just realized deep down what I really want to know is whether or not, when there's a need to refer to the address of any array element, and then refer to the address of another element, and then another, is it still bad NOT to use a pointer and, instead, use the array directly the way I did ? This question of mine has been really difficult to pin point, that's why I didn't type it in the OP. Anyway, since I didn't ask it, your answer is satisfactory. – Niko Gambt Dec 22 '15 at 15:42
  • 1
    @NikoGambt You can always ask another question =) – Ixrec Dec 22 '15 at 15:44
  • 1
    What do you mean only to the extent...? The entire point of programming languages is to make code easier for humans to read. If we didn't care about that, then we'd all be writing op codes in hexadecimal. – Solomon Slow Dec 22 '15 at 15:57
  • 2
    Arrays aren't pointers, the just decay to pointers implicitly. – CodesInChaos Jan 22 '16 at 18:17
4

Yes, it's bad practice, but not for inefficiency reasons.

Array operator uses pointer arithmetric under the hood, so they're equally efficient.

Problem with pointer arithmetric is that it's very error prone and harder to read.

Rule of thumb: Don't use pointer arithmetric unless you have to.

  • 1
    Since it uses pointer arithmetic anyway, doesn't that mean pointers are also just as equally error-prone and hard to read? – Niko Gambt Dec 22 '15 at 15:11
  • 1
    @NikoGambt compilers are quite good at doing pointer arithmic under the hood and will rarely make 'mistakes'; it's the programmers who will make mistakes with nasty bugs as a consequence. – Kasper van den Berg Dec 22 '15 at 15:13
  • @KaspervandenBerg Yes, I agree. However, I'm interested in errors made by programmers, and I'm just not quite sure if it is a bad programming practice to do what I did there above, in cases where there is a need to refer to the address of an array, if such cases do exist. – Niko Gambt Dec 22 '15 at 15:22
  • 1
    @NikoGambt Writing something that is less readable for performance purposes is almost always bad practice, but writing something that is less readable for no gain is unequivocally bad practice. – Neil Dec 22 '15 at 15:27
  • @Neil My little experiment is not pointless. By doing that, I learned that the compiler seems to make an array of pointers to refer to a multi-dimensional array. However, since you said readability is more important than performance, I guess it's still a bad programming practice. – Niko Gambt Dec 22 '15 at 15:31
0

Cool your learning c, you just discovered one of c little tongue twisters. You are not doing pointer arithmetic on an array, but an array of pointers. Doing pointer arithmetic on arrays is not possible. An array decays to a pointer but is not a pointer type it self. What you my have (see comment by cmaster) is

int *array[]; //This is a array to pointers of type *int. 

array[k1] + k2; //This is pointer arithmetic on one pointer stored in the array  

Dereferencing this pointer gives the value your just calculated pointer, points to. There is generally no point in doing what you are doing. But you can linearised the array and then a stride in it, like this.

int array[y_dim*x_dim]; 
int index = x_dim*y + x; 
array[index]; //Gives you the element in x, y!

Stride her is x_dim. Hope my answer is clarifying!

  • It's not clear from the OP whether it uses an int* array[ROW]; an int array[ROW][COLUMN];, or an int (*array)[COLUMN];. Either of these three definitions can be used with the code in the OP. – cmaster Jan 22 '16 at 17:09
  • yes i am aware of that, my answer is a little clumsy on that point. I correct it, thanks! – fhtuft Jan 22 '16 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.