Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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).
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..
the program in the tutorial builds for the guy just fine.
do I need a header file??
Note that those are simply warnings -- not errors. Just letting you know that you're doing kinda weird stuff.
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]
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}};
Note also that my interpretation is that the loop code, while legal syntax is bounding the limit test on the start pointer of the array, plus 4 integers beyond that start. In short, "pointing at 5". aPtr++ moves the pointer up by one integer at a time. array+4 is base address of array, plus either an offset of 4 integers, 4 array entries, or 4 sub-array entries. I'd have to run and detail the addresses as the pointer progressed to know correctly.
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.
I tested that one and GCC hated it as well, which is why I mentioned GCC's over the top parser as been annoying.
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)
gcc is not complaining about that one. That one is actually correct. Please note the difference between that and the syntax actually used in the original post:
Code:
int *aPtr = &array; /* incorrect */
int *aPtr = array; /* correct */
gcc is not "hard core". Conforming to standards is a good thing. It helps you write good code.
gcc is not complaining about that one. That one is actually correct. Please note the difference between that and the syntax actually used in the original post:
Code:
int *aPtr = &array; /* incorrect */
int *aPtr = array; /* correct */
gcc is not "hard core". Conforming to standards is a good thing. It helps you write good code.
Code:
tmp.c: in function 'main':
tmp.c:11:16: warning: initialization from incompatible pointer type [enabled by default]
int *aPtr = array;
^
I suggest you actually try GCC and not talk theory, because I have and it is complaining about that.
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.
.....
I'd have to run and detail the addresses as the pointer progressed to know correctly.
The example code is great for showing the equivalences between pointers and array -- but I don't consider it to be either portable, nor particularly easy to understand. I can think of at least two different 'reasonable' results for that code; I'd have to (carefully) read that portion of "The 'C' Programming Language" to figure out which was the 'proper' way of doing things; and I wouldn't bet my life that some implementations wouldn't do it 'the other way'.
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++ );
}
int array[3][4]= {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *aPtr = &array; /* incorrect */
int *aPtr = array; /* incorrect */
int *aPtr = array[0]; /* correct */
int *aPtr = &array[0][0]; /* correct */
// similarly:
for(;aPtr < array+4; aPtr++ ) /* incorrect */
for(;aPtr < array[4]; aPtr++ ) /* incorrect (because it goes past end of array) */
for(;aPtr < array[3]; aPtr++ ) /* correct */
for(;aPtr < &array[3][0]; aPtr++ ) /* correct */
for(;aPtr < &array[2][4]; aPtr++ ) /* correct */
Quote:
Originally Posted by wildwizard
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.
Due to array decay,
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.
Last edited by ntubski; 08-24-2015 at 10:47 AM.
Reason: add definition of array variable
int *aPtr = &array; /* incorrect */
int *aPtr = array; /* incorrect */
int *aPtr = array[0]; /* correct */
int *aPtr = &array[0][0]; /* correct */
Arrays and pointers in C are (somewhat) intechangable.
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.
The first one is especially problematic because it is context dependant.
Yeah, I meant all those statements specifically in the case where array has type int[3][4], I've now edited that in.
Quote:
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)
Indeed, this show that arrays and pointers are not interchangeable.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.