const pointer fix to a variable variable
I can't figure out how to tell C that I want a pointer开发者_如何学JAVA that will not move. It will always point to the same array. That said, the array members are not constant, but the array itself is global and so, it is at a fixed position.
So, when I code this:
#include <stdio.h>
int v[2]={0, 1};
const int *cpv=v;
int main(void)
{
v[1]=2; printf("%d\n", v[1]);
*(cpv+1)=3; printf("%d\n", v[1]);
cpv[1]=4; printf("%d\n", v[1]);
}
And get this errors:
constp.c: In function ‘main’:
constp.c:9: error: assignment of read-only location '*(cpv + 4u)'
constp.c:10: error: assignment of read-only location '*(cpv + 4u)'
I understand that the compiler thinks I need a const int v[2]
to use with a const int *iv
. How do I get a constant pointer to do the job?
If you see the error message, I'm not even moving the pointer (like pv++
). I'm just dereferencing it dislocated some bytes.
If I do this:
int *pv=cpv;
*(pv+1)=5; printf("%d\n", v[1]);
printf("%p == %p !?\n", cpv, pv);
I get this warning, but it works:
constp.c:9: warning: assignment discards qualifiers from pointer target type
pointer# ./constp
5
0x601020 == 0x601020 !?
Thanks, Beco.
Move the const
qualifier:
int *const cpv=v;
Explanation: in the C declaration rules, this is read from right to left starting at the identifier: "cpv
is a constant pointer to int
". Your version would be read "cpv
is a pointer to int
constant".
Note that cpv+1
will still get you a pointer to the int
after *cpv
; making a pointer const
only prevents ++
, --
, +=
and -=
on it.
You are using a pointer to const, not a const pointer.
const int *cpv=v;
should turn into:
int *const cpv=v;
Pointers kind of "read backwards":
const int * p;
In this case, "p
" is a (variable) "pointer" to a "const int
". Literally, read that backwards, with the '*
' meaning "pointer": "Pointer ... to int const".
Curiously, the following is the same thing:
int const * p; // same thing
Reading backwards, it says, "pointer ... to const int" (the same thing).
So, if you want your pointer to be "constant" (not variable), you need to read-backwards and do just that:
int * const p; // p cannot change
Now, "p
" is a constant pointer to a non-constant integer. Not to belabor, but reading backwards that's, "const pointer ... to int".
Using the "same thing" example above, we can now have a constant pointer to a constant integer (the following are the same):
const int * const p;
int const * const p;
You should read them backwards, and they both say the same thing, "contant pointer ... to constant int".
int * const cpv=v;
Having said that, why do you need the pointer at all? The compiler will be able to do a better job if you would access the variable v directly. If you go via a pointer, the generated code have to read the pointer from memory each time you access the array.
#include <stdio.h>
int v[2]={0, 1};
//const int * cpv=v; // cpv is a pointer to int const
// int const * cpv=v; // cpv is a pointer to const int == same as above ==
int *const cpv=v; // cpv is a constant pointer to int
// int const *const cpv=v; // cpv is a constant pointer to const int
//const int *const cpv=v; // cpv is a constant pointer to int const == same as above ==
//const int const *const cpv=v; // == same as above ==
int main(void)
{
v[1]=2; printf("%d\n", v[1]);
*(cpv+1)=3; printf("%d\n", v[1]);
cpv[1]=4; printf("%d\n", v[1]);
}
精彩评论