On pointer basics in C
Regarding pointers (in structs for this case), I understand that if 'a' were a struct and 'b' declared within the struct, then we can access the data through:
a->b
And now, I've recently found out C has a lot of shortcuts regarding poin开发者_运维问答ters, one of which would be the arrow operator as above.
I've seen 'a->b' being written as '[a] + b', such that:
a->b <=> [a] + b //meaning that they are interchangeable
However, I am having trouble making sense of this what '[a] + b' actually means and would really appreciate someone laying the details out for me (or perhaps I misread and the above is nonsense !). Many thanks in advance!
In the C language, [a] + b
means nothing. It is a syntax error. Your book probably uses that notation to explain something, but out of context it means nothing. However, it is similar-looking enough to several other pointer shortcuts as to cause confusion. So to dispel that confusion, here are all the pointer shortcuts I can think of:
a->b
is a synonym for(*a).b
, that is, accessing a member of a pointer to astruct
type.a[b]
is a synonym for*(a + b)
, that is, accessing an array element by performing pointer arithmetic to a specified offset.- Note that, due to the above,
a[b]
is synonymous withb[a]
, becausea[b]
<=>*(a + b)
<=>*(b + a)
<=>b[a]
. Evil tricksters will do things like0[x]
or5["string"]
to confuse you. Fear not, for now you know the answer.
- Note that, due to the above,
*&a
is a synonym fora
, that is, dereferencing an address. It creates a pointer, then dereferences it immediately, yielding the original object.- Note that
&a[b]
translates to&*(a + b)
which translates toa + b
. Both&a[b]
anda + b
create pointers to an array element in the same way. Which way is the "best" way depends on personal preference, place of employment, and phase of the moon. - Note that
&*a
is not the same as*&a
. The latter creates a pointer, then dereferences it, yielding the original object. The former assumesa
is a pointer, dereferences it, then takes the address of the result, yielding the original pointer.&*a
is mandated by the standard not to dereference the pointer and can be safely used on aNULL
pointer.
- Note that
*(type *)&a
is an evil hack that you may see from time to time. It takes the address ofa
, casts the pointer to a pointer to atype
, and dereferences it. This is usually unspecified behavior*, but in practice will cause the bits of objecta
to be reinterpreted as atype
object. This allows you to get at e.g. the bitwise representation offloat
s or other objects. There are perhaps better ways to accomplish that goal, but if you ever stumble across this line of code, you'll at least know what the authors intended by it.
I'll add more if I think of them.
*I say unspecified because, if you did int i = -1; printf("%u\n", *(unsigned int)&i);
, the C standard doesn't mandate whether this would print the value UINT_MAX
(for two's complement), UINT_MAX - 1
(for one's complement) or (unsigned int)INT_MAX + 2
(for sign-and-magnitude).
As already pointed out, [a]+b
isn't valid C. Maybe he meant
a->b <=> a[0].b
精彩评论