pointers and multidimensional arrays in C
I was following a tutorial and got lost when my program wouldn't compile and it is exactly the same as the working program in the tutorial..
#include <stdio.h> #include <stdbool.h> int main() { int array[3][4]= {1,2,3,4,5,6,7,8,9,10,11,12}; int *aPtr = &array; for(;aPtr < array+4; aPtr++ ) { printf("%d\n ", *aPtr); } return 0; } I gets a compile error that says the following: warning: initialization from incompatible pointer type [enabled by default] for the line : int *aPtr = &array; I'm using gedit and no make file just gcc -o.. the program in the tutorial builds for the guy just fine. do I need a header file?? |
Quote:
int *aPtr = &array[0][0]; Further EDIT GCC also hates your for loop Code:
for(;aPtr < array+4; aPtr++ ) Code:
for(;aPtr < (int *)array+4; aPtr++ ) |
Actually, the parser is doing its job! The point is that array is actually of type int*, that is, it is a pointer to the first element of the array. &array is a pointer to the location that contains the array pointer, and is therefore superfluous (and wrong).
int *aPtr = array should work. |
Quote:
C multidimensional arrays are essentially arrays of arrays (if that makes sense to you). and a single-dimensional array is treated much like a simple pointer. As a result, gcc will also happily let you get away with array[0], instead of (int*)array, or &array[0][0] |
I agree with the two style recommendations of:
Code:
int *aPtr = &array[0][0]; Cautionary note: Be aware of how the pointer moves and what is considered to be a row versus a column in that two dimensional array. Further, another thing you could have, and should have done would be: Code:
int array[3][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; I shan't do it, I'll let you the OP debug as you see fit. You could use gdb and step through it and examine the pointer value as the loop progresses. Just cautionary. I tend to not use stuff that's "tricky" which I don't understand. Sorry, that sounds bad, like me saying 'code I don't understand is tricky and hence I avoid it' but ... well that's a harsh truth in my world. Make sure "you" understand it if you intend to use it as part of your regular coding efforts. |
Quote:
I should point out that according to an ANSI C book I have here that that method is perfectly legal so I have no idea why GCC is complaining about it. GCC 4.8.2 used for testing (including the old -ansi switch) |
Quote:
Code:
int *aPtr = &array; /* incorrect */ |
I usually keep an example Makefile copy around so that I can re-use flags. There are more, but these tend to work very well for me:
Code:
CFLAGS= -I. -O0 -ggdb -Wformat=2 -Werror -Wall -Wextra -Wswitch-default -Wswitch |
Quote:
Code:
int *aPtr; |
Quote:
Code:
tmp.c: in function 'main': |
Don't ever use that code in a real program
Quote:
In short: If I saw those constructs in live code, I'd hunt down the responsible programmer with a paintball gun. a much more sane way of doing the loop: int i; for(i=0; i<4; i++) { printf("%d\n ", aPtr[i] ); } Or, (if you actually wanted to change aPtr as a side effect: for(i=0; i<4; i++) { printf("%d\n ", *aPtr++ ); } |
Code:
int array[3][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; Quote:
the expression array is equivalent to &array[0]. Since array is 3 arrays of arrays of 4 ints, array[0] is an array of 4 ints, so &array[0] is a pointer to an array of 4 ints rather than a pointer an int. |
Quote:
|
Quote:
All of the above are legal -- but I would describe the first three as variable degrees of silly and stupid, because it's not very clear exactly what you're trying to do. The first one is especially problematic because it is context dependant. Since (in this case) array is a 'real' array, &array will return the address of the array. However, if it were a passed-in variable, it would be implemented as a pointer, and &array would/should returrn the address of the pointer (possibly depending on the pedantic correctness of the implementation) Because that construct is context and/or implementation dependant, I would declare it to be especially stupid. |
Quote:
Quote:
|
All times are GMT -5. The time now is 07:04 PM. |