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?
3 Answers 3
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 pointera
and integerx
"a[x]
= "Thex
th member of arraya
"
Similarly, when you need to refer to the address of an array element:
(a+x)
= "The sum of pointera
and integerx
"&a[x]
= "The address of thex
th member of arraya
"
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– Niko Gambt2015年12月22日 15:42:43 +00:00Commented Dec 22, 2015 at 15:42
-
1@NikoGambt You can always ask another question =)Ixrec– Ixrec2015年12月22日 15:44:49 +00:00Commented Dec 22, 2015 at 15:44
-
1What 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– Solomon Slow2015年12月22日 15:57:44 +00:00Commented Dec 22, 2015 at 15:57
-
2Arrays aren't pointers, the just decay to pointers implicitly.CodesInChaos– CodesInChaos2016年01月22日 18:17:58 +00:00Commented Jan 22, 2016 at 18:17
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.
-
1Since it uses pointer arithmetic anyway, doesn't that mean pointers are also just as equally error-prone and hard to read?Niko Gambt– Niko Gambt2015年12月22日 15:11:01 +00:00Commented Dec 22, 2015 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– Kasper van den Berg2015年12月22日 15:13:57 +00:00Commented Dec 22, 2015 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– Niko Gambt2015年12月22日 15:22:42 +00:00Commented Dec 22, 2015 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– Neil2015年12月22日 15:27:45 +00:00Commented Dec 22, 2015 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– Niko Gambt2015年12月22日 15:31:58 +00:00Commented Dec 22, 2015 at 15:31
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];
anint array[ROW][COLUMN];
, or anint (*array)[COLUMN];
. Either of these three definitions can be used with the code in the OP.cmaster - reinstate monica– cmaster - reinstate monica2016年01月22日 17:09:17 +00:00Commented Jan 22, 2016 at 17:09 -
yes i am aware of that, my answer is a little clumsy on that point. I correct it, thanks!fhtuft– fhtuft2016年01月22日 18:08:26 +00:00Commented Jan 22, 2016 at 18:08
printf "[%d][%d] = %d\n", k1, k2, array[k1] [k2]));
would avoid the pointer arithmic and is easier to understand.