使用typedef定义

时间:2013-10-30 13:14:37

标签: c pointers typedef

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

如何解释p和q。?

此外,问题是:

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]);   

有人可以帮助我理解代码的行为......

2 个答案:

答案 0 :(得分:4)

根据定义,

SPTR是“Array of 2 shorts”的别名。因此,SPTR *与“指向2个短裤数组的指针”相同,即short int (*)[2]

同样,pq是指向2个短裤数组的指针。

代码正在挑选一个二维chars数组并将其第二个位置(a2D[1])解释为由pq指向的2个短裤的数组。换句话说,这个3个字符的数组:

{ 4, 5, 6 }

被解释为短数组,pq都指向它。由于p是指向2个短片数组的指针,因此递增p将使其前进sizeof(short)*2个位置。为什么?好吧,递增p与指向2个短裤的下一个数组相同,即sizeof(short)*2个字节。

假设8位字符和16位短路,(*++p)[1]p增加32位,所以现在p指向子数组{ 8, 9 }(这是++p)的效果。然后,我们取消引用p,这意味着“在该位置选择数组”。现在,我们有一个数组索引运算符,您可以将其视为向*p的新值添加1((*p)+1将指向{10, 11, 12},请记住它前进16位因为这是短数组中每个元素的大小),然后解除引用。因为这被解释为short,所以取消引用实际上会同时读取1011,因为我们之前假设每个char都是8位。因此,p“认为”他正在读短片,所以将读取16位(2个字符)。

现在,发生的事情取决于您的机器是小端还是大端。如果它打印B0A,那么它是小端,因为它将10解释为最不重要的字节。否则,它是大端。

可以使用相同的方法来了解(q[1])[2]会发生什么,这与q[1][2]相同。可以将其视为*(*(q+1)+2)q+1指向8。向*(q+1)添加2然后解除引用它与在位置2中索引短路数组相同,因此您将获得在此之后存储的32位的任何内容,即12。这与以前一样,取决于您的机器的字节顺序。它会打印C0DD0C

答案 1 :(得分:2)

如何解释pq

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

SPTR实例的类型为short int [2]

SPTR *p, *q;

pq的类型为short int (*) [2]


了解OP和改进发布的代码

由于您使用pq来保存a2D中元素的地址,因此SPTR typedef'很好 如

typedef char SPTR [2];

后来,

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]);

如上所述,p指向大小为2的char数组。

*p为您提供数组第一个元素的地址。

对于char a[2]a为您提供数组第一个元素的地址,a[0]*(a+0)为您提供第一个元素的值数组。

同样在这种情况下,(*p)[0]*((*p)+0)会为您提供p指向的数组的第一个元素。在您的情况下,它将是4。与q相同,因为它们都拥有相同的地址。

(*p)[1]为您提供p

指向的数组的第二个元素

在表达式(*++p)中,p增加1。这是指针算术,1被缩放到p指向的数据类型的大小。因此,p增加2 * sizeof (char),现在指向6

(*++p)[0]为您提供6。在你的情况下,它是(*++p)[1],所以它给你7.

q[1][1](*(q+1))[1]类似。按q增加1p提到的相同指针算法也适用q。而且,现在pq都指向同一地址。因此q[1][1]也会为您提供7

q[1][2]q[1][1]旁边的一个字符,因此会给您8


注意:

  • a的类型为pointer-to-char
  • p的类型为pointer-to-array-of-2-chars

两者的类型不同。我之前提到过a,只是为了轻松理解涉及*p

的表达式