简体   繁体   English

使用typedef定义

[英]Using typedef definition

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

how to interpret p and q.? 如何解释p和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". 如定义的, SPTR是“ 2个短裤的数组”的别名。 Thus, SPTR * is the same as "pointer to array of 2 shorts", namely, short int (*)[2] . 因此, SPTR *与“指向2个short的数组的指针”相同,即short int (*)[2]

Similarly, p and q are pointers to an array of 2 shorts. 同样, pq是指向2个短裤的数组的指针。

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 . 该代码正在选择一个2D字符数组,并将其第二个位置( a2D[1] )解释为2个由pq指向的短裤数组。 In other words, this array of 3 chars: 换句话说,这是3个字符的数组:

{ 4, 5, 6 }

Is interpreted as array of short, and both p and q point to it. 被解释为short数组, pq指向它。 Since p is a pointer to an array of 2 shorts, then incrementing p will make it go sizeof(short)*2 positions forward. 由于p是指向2个短裤的数组的指针,因此递增p将使其前进sizeof(short)*2位置。 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. 好吧,递增p等于使其指向2个short的下一个数组,即sizeof(short)*2个字节。

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 ). 假设8位字符和16位短裤, (*++p)[1]将使p增加32位,因此现在p指向子数组{ 8, 9 } (这是++p的作用) 。 Then, we dereference p , which means "pick the array at that location". 然后,我们取消引用p ,这意味着“在该位置拾取数组”。 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. 现在,我们有了一个数组索引运算符,您可以将其视为*p的新值加1( (*p)+1指向{10, 11, 12} ,记住它向前16位因为这就是short数组中每个元素的大小),然后取消引用。 Because this is interpreted as short, dereferencing will actually read both 10 and 11 , since we assumed earlier that each char is 8 bits. 因为这被解释为简短,所以解引用实际上将同时读取1011 ,因为我们之前假设每个char是8位。 Thus, p "thinks" he's reading a short, so 16 bits (2 chars) will be read. 因此, p “认为”他正在读取一个简短的内容,因此将读取16位(2个字符)。

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. 如果输出B0AB0A小尾数,因为它将10解释为最低有效字节。 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] . 可以使用相同的方法来了解(q[1])[2] ,这与q[1][2] Think of it as *(*(q+1)+2) : q+1 points to 8 . 将其视为*(*(q+1)+2)q+1指向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 . 将2加到*(q+1) ,然后对其取消引用与在位置2上索引一个短裤数组相同,因此您将获得32位之后存储的值,即12 The same happens as before, depending on your machine's endianness. 与以前一样,取决于计算机的字节序。 Either it will print C0D or D0C . 它将打印C0DD0C

How to interpret p and q ? 如何解释pq

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

SPTR instance is of type short int [2] . SPTR实例的类型为short int [2]

SPTR *p, *q;

p and q are of type short int (*) [2] pq的类型为short int (*) [2]


Understand code posted by OP and Improvements 了解OP和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 由于使用pq来保存a2D中元素的地址,因此最好将SPTR

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指向大小为2的char数组。

*p gives you the address of the first element of the array. *p为您提供数组第一个元素的地址。

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. 对于char a[2]a为您提供数组第一个元素的地址, a[0]*(a+0)为您提供数组中第一个元素的值。

Similarly in this case, (*p)[0] or *((*p)+0) gives you the first element of the array pointed to by p . 同样在这种情况下, (*p)[0]*((*p)+0)给出p指向的数组的第一个元素。 In your case, it will be 4 . 您的情况将是4 Same for q as both hold the same address. q相同,因为它们都具有相同的地址。

(*p)[1] gives you the second element of the array pointed to by p (*p)[1]给出p指向的数组的第二个元素

In expression, (*++p) , p is incremented by 1 . 在表达式(*++p) ,p递增1 This is pointer arithmetic, 1 is scaled to size of the data type pointed to by p . 这是指针算法,将1缩放为p指向的数据类型的大小。 So, p is incremented by 2 * sizeof (char) and now points to 6 . 因此, p增加2 * sizeof (char) ,现在指向6

(*++p)[0] gives you 6 . (*++p)[0]给您6 In your case, it is (*++p)[1] , so it gives you 7. 在您的情况下,它是(*++p)[1] ,因此可以得到7。

q[1][1] is similar to (*(q+1))[1] . q[1][1]类似于(*(q+1))[1] Increment q by 1 . q递增1 Same Pointer arithmetic mentioned for p applies q also. p提到的相同指针算法也适用q And, again now both p and q point to same address. 而且,现在pq再次指向相同的地址。 So q[1][1] also gives you 7 . 所以q[1][1]也给您7

q[1][2] is one char next to q[1][1] and hence, will give you 8 q[1][2]q[1][1]旁边的一个字符,因此,将给您8


Note: 注意:

  • a is of type pointer-to-char apointer-to-char的类型
  • p is of type pointer-to-array-of-2-chars ppointer-to-array-of-2-chars的类型

Both are different by type. 两者的类型不同。 I have mentioned a , just to easily understand the expressions involving *p 我已经提到a ,只是为了轻松理解涉及*p的表达式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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