Difficulty Understanding C Pointer Syntax
Given the following C definitions:
#define SYNC_BYTE_1 0x5A
#define SYNC_BYTE_2 0xA5
and pointer declaration:
UINT8 *pCommandData;
pCommandData = GetCommandBufferPointer( LINGO_GENERAL, stringLength + 3 );
What exactly are the following two lines of code doing with the pointer?
*pCommandData++ = SYNC_BYTE_1;
*pCommandData++ = SYNC_BYTE_2;
I specifically don't understand the use of *
and the ++
in this instance. If the pointer's address is being incremented 开发者_StackOverflow社区shouldnt the *
be replaced with a &
?
pCommandData
is a pointer to some piece of memory. The first line
*pCommandData++ = SYNC_BYTE_1;
sets the value at that address to 0x5A
, and then increments the pointer pCommandData
to the next address. The next line
*pCommandData++ = SYNC_BYTE_2;
works similarly: it sets the value that pCommandData
points to, to 0xA5
, and then increments the pointer to the next address.
Perhaps a picture would be useful. Before either line executes, the memory in the neighborhood of wherever pCommandData
points to might look like this:
| |
+--------+
pCommandData -----> | |
+--------+
| |
+--------+
| |
+--------+
| |
After *pCommandData++ = SYNC_BYTE_1;
:
| |
+--------+
pCommandData --+ | 0x5A |
| +--------+
+--> | |
+--------+
| |
+--------+
| |
And after *pCommandData++ = SYNC_BYTE_2;
:
| |
+--------+
pCommandData --+ | 0x5A |
| +--------+
| | 0xA5 |
| +--------+
+--> | |
+--------+
| |
This:
UINT8 *pCommandData;
*pCommandData++ = SYNC_BYTE_1;
*pCommandData++ = SYNC_BYTE_2;
is equivalent to:
UINT8 *pCommandData;
*pCommandData = SYNC_BYTE_1;
pCommandData++;
*pCommandData = SYNC_BYTE_2;
pCommandData++;
or:
UINT8 *pCommandData;
pCommandData[0] = SYNC_BYTE_1;
pCommandData[1] = SYNC_BYTE_2;
pCommandData += 2;
The construct of:
*pCommandData++ = SYNC_BYTE_1;
Simply means set the value pointed to by pCommandData
to SYNC_BYTE_1
, then increment the pointer to point to the next location. Since pCommandData
is a pointer to an unsigned 8-bit integer, that means it will be incremented to point to the next (following) 8-bit value.
The pointer itself is being incremented, to point to the next byte.
This works exactly like if it had been written:
*pCommandData = value;
pCommandData++;
You would use &pCommandData
to get the address of the pointer itself, but that is not what happens here. Using *pCommandData
gives you access to the object the pointer points to (if any :-).
The effect of:
*pCommandData++ = SYNC_BYTE_1;
is:
*pCommandData = SYNC_BYTE_1;
pCommandData++;
The chunk of data pCommandData is pointing to is set to 0x5A
, then the pointer is set to the next byte which is itself set to 0xA5
. In the end the pointer is set to the next byte in the memory.
You can rewrite the code to something like this:
*pCommandData = SYNC_BYTE_1;
pCommandData = pCommandData + 1;
*pCommandData = SYNC_BYTE_2;
pCommandData = pCommandData + 1;
It's putting sync byte values into pCommandData, that's why you see *pCommandData, afterwards you increment it to go to next byte.
The expression
*p++ = rval ;
is read as
*(p++) = rval ;
which instructs the compiler to
- save the value of
p
as p1. - increment p
- Dereference p1
- Assign the value of
rval
to the dereferenced thingy.
edited to note: I'd never write *p++
as it's very confusing unless you're clear on operator precedence. I'd make my intent clear by explicitly writing *(p++)
.
Postfix ++
has a higher precedence than unary *
, so expressions of the form *p++
are parsed as *(p++)
; IOW, you're dereferencing the result of p++
.
What does that mean in the context of your code?
Given the expression *pCommandData++ = SYNC_BYTE_1
, here's a rough explanation of what's happening:
The expression
pCommandData++
is evaluated. The result of the expression is the current value ofpCommandData
, which is a pointer value. As a side effect, the value ofpCommandData
is updated. Exactly when this update occurs is not specified beyond the fact that it must occur before the next sequence point.The result of the expression
pCommandData++
is dereferenced using the*
operator. The result of this larger expression is an lvalue (an expression that refers to an object in memory such that we can read or modify that object).We assign the value SYNC_BYTE_1 to the lvalue that was computed in step 2.
Semantically, it's the same as writing:
*pCommandData = SYNC_BYTE_1;
pCommandData++;
精彩评论