开发者

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

  1. save the value of p as p1.
  2. increment p
  3. Dereference p1
  4. 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:

  1. The expression pCommandData++ is evaluated. The result of the expression is the current value of pCommandData, which is a pointer value. As a side effect, the value of pCommandData is updated. Exactly when this update occurs is not specified beyond the fact that it must occur before the next sequence point.

  2. 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).

  3. 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++;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜