简体   繁体   中英

Using typedef definition

typedef short int (SPTR) [2];    
SPTR *p,*q;

how to interpret p and q.?

Further the question goes like this:

char a2D[5][3] =    
{
  { 1,  2,  3},
  { 4,  5,  6},
  { 7,  8,  9},
  {10, 11, 12},
  {13, 14, 15}
};
p = q = (short int (*)[2])a2D[1];
printf("%X %X\n", (*++p)[1], (q[1])[2]);   

Can someone help me on understanding how the code behaves..

SPTR , as defined, is an alias for "Array of 2 shorts". Thus, SPTR * is the same as "pointer to array of 2 shorts", namely, short int (*)[2] .

Similarly, p and q are pointers to an array of 2 shorts.

The code is picking a 2D array of chars and interpreting its 2nd position ( a2D[1] ) as an array of 2 shorts pointed to by p and q . In other words, this array of 3 chars:

{ 4, 5, 6 }

Is interpreted as array of short, and both p and q point to it. Since p is a pointer to an array of 2 shorts, then incrementing p will make it go sizeof(short)*2 positions forward. Why? Well, incrementing p is the same as making it point to the next array of 2 shorts, which is sizeof(short)*2 bytes away.

Assuming 8 bit chars and 16 bit shorts, (*++p)[1] will increment p by 32 bits, so now p is pointing at the sub-array { 8, 9 } (this is the effect of ++p ). Then, we dereference p , which means "pick the array at that location". Now, we have an array indexing operator, which you can think of as adding 1 to the new value of *p ( (*p)+1 is going to point to {10, 11, 12} , remember it goes forward 16 bits because that's the size of each element in an array of short), and then dereferencing that. Because this is interpreted as short, dereferencing will actually read both 10 and 11 , since we assumed earlier that each char is 8 bits. Thus, p "thinks" he's reading a short, so 16 bits (2 chars) will be read.

And now, what happens depends on whether your machine is little endian or big endian. If it prints B0A , then it's little endian, because it interpreted 10 as being the least significant byte. Otherwise, it's big endian.

The same method can be used to understand what happens with (q[1])[2] , which is the same as q[1][2] . Think of it as *(*(q+1)+2) : q+1 points to 8 . Adding 2 to *(q+1) and then dereferencing it is the same as indexing an array of shorts in position 2, so you will get whatever is stored 32 bits after that, which is 12 . The same happens as before, depending on your machine's endianness. Either it will print C0D or D0C .

How to interpret p and q ?

typedef short int (SPTR) [2];  //Have brackets around SPTR or not. Its the same.

SPTR instance is of type short int [2] .

SPTR *p, *q;

p and q are of type short int (*) [2]


Understand code posted by OP and Improvements

Since you are using p and q to hold the address of elements from a2D , it is good to have SPTR typedef' d as

typedef char SPTR [2];

Later,

p = q = (char (*)[2])a2D[1]; // Assigns p & q to point to element '4' in a2D array 
printf("%X %X\n", (*++p)[1], (q[1])[2]);

As mentioned, p points to a char array of size 2.

*p gives you the address of the first element of the array.

For char a[2] , a gives you the address of the first element of the array, a[0] or *(a+0) gives you the value of the first element in the array.

Similarly in this case, (*p)[0] or *((*p)+0) gives you the first element of the array pointed to by p . In your case, it will be 4 . Same for q as both hold the same address.

(*p)[1] gives you the second element of the array pointed to by p

In expression, (*++p) , p is incremented by 1 . This is pointer arithmetic, 1 is scaled to size of the data type pointed to by p . So, p is incremented by 2 * sizeof (char) and now points to 6 .

(*++p)[0] gives you 6 . In your case, it is (*++p)[1] , so it gives you 7.

q[1][1] is similar to (*(q+1))[1] . Increment q by 1 . Same Pointer arithmetic mentioned for p applies q also. And, again now both p and q point to same address. So q[1][1] also gives you 7 .

q[1][2] is one char next to q[1][1] and hence, will give you 8


Note:

  • a is of type pointer-to-char
  • p is of type pointer-to-array-of-2-chars

Both are different by type. I have mentioned a , just to easily understand the expressions involving *p

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM