这个变量如何在 cpp 中用作 int 和数组?



我正在尝试将一些代码从C++移植到Java。代码在C++中如下所示:

uint8_t r, g, b, bit, limit, *ptr;
...
if(y < nRows) {
// Data for the upper half of the display is stored in the lower bits of each byte.
ptr = &matrixbuff[backindex][y * WIDTH * (nPlanes - 1) + x]; // Base addr
// Plane 0 is a tricky case -- its data is spread about,
// stored in least two bits not used by the other planes.
ptr[WIDTH*2] &= ~B00000011;           // Plane 0 R,G mask out in one op
if(r & 1) ptr[WIDTH*2] |=  B00000001; // Plane 0 R: 64 bytes ahead, bit 0
if(g & 1) ptr[WIDTH*2] |=  B00000010; // Plane 0 G: 64 bytes ahead, bit 1
if(b & 1) ptr[WIDTH]   |=  B00000001; // Plane 0 B: 32 bytes ahead, bit 0
else      ptr[WIDTH]   &= ~B00000001; // Plane 0 B unset; mask out
// The remaining three image planes are more normal-ish.
// Data is stored in the high 6 bits so it can be quickly
// copied to the DATAPORT register w/6 output lines.
for(; bit < limit; bit <<= 1) {
*ptr &= ~B00011100;            // Mask out R,G,B in one op
if(r & bit) *ptr |= B00000100; // Plane N R: bit 2
if(g & bit) *ptr |= B00001000; // Plane N G: bit 3
if(b & bit) *ptr |= B00010000; // Plane N B: bit 4
ptr  += WIDTH;                 // Advance to next bit plane
}
} else {
// Data for the lower half of the display is stored in the upper
// bits, except for the plane 0 stuff, using 2 least bits.
ptr = &matrixbuff[backindex][(y - nRows) * WIDTH * (nPlanes - 1) + x];
*ptr &= ~B00000011;                  // Plane 0 G,B mask out in one op
if(r & 1)  ptr[WIDTH] |=  B00000010; // Plane 0 R: 32 bytes ahead, bit 1
else       ptr[WIDTH] &= ~B00000010; // Plane 0 R unset; mask out
if(g & 1) *ptr        |=  B00000001; // Plane 0 G: bit 0
if(b & 1) *ptr        |=  B00000010; // Plane 0 B: bit 0
for(; bit < limit; bit <<= 1) {
*ptr &= ~B11100000;            // Mask out R,G,B in one op
if(r & bit) *ptr |= B00100000; // Plane N R: bit 5
if(g & bit) *ptr |= B01000000; // Plane N G: bit 6
if(b & bit) *ptr |= B10000000; // Plane N B: bit 7
ptr  += WIDTH;                 // Advance to next bit plane
}
}

我不明白ptr的用

法它被声明为 int:

uint8_t ... *ptr;

然后它被设置为某个值

ptr = &matrixbuff...

后来它似乎被用作数组

ptr[WIDTH*2] &= ~B00000011;

什么?有人可以解释一下吗(然后在 Java 中这可能吗)

它被声明为 int:

uint8_t ... *ptr;

与 Java 和许多其他从 C 派生语法的语言不同,C++ 允许您在单个声明中声明不同类型的变量。虽然rgb等都是uint8_t,但ptr不是,因为它前面有星号。此前缀使ptr成为指向uint8_t指针

然后它被设置为某个值

ptr = &matrixbuff[some_index]

同样,前缀提供了一个线索:这一次,它是前缀运算符&,它获取后面表达式的地址。

但后来它似乎被用作数组

ptr[WIDTH*2] &= ~B00000011;

这也没错,因为C++允许您像使用数组一样使用指针。在某些情况下,它也允许您使用数组,就好像它是指针一样,但通常不应混淆这两个概念。

长话短说,如果你有一个T*类型的指针p和一个整数值i,表达式p[i]等效于*(p+i),并引用类型T的值,该值位于i大小的Tp指向的地址的偏移量处。因此,指针的行为模仿数组的行为。

在 Java 中,您必须将ptr上的操作转换为matrixbuff上的操作,索引计算为ptr上的索引和ptr本身的索引的组合,例如

ptr[WIDTH]

会成为

matrixbuff[backindex][y * WIDTH * (nPlanes - 1) + x + WIDTH]
//                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^
//                              Origin                Index

声明数组时,将连续分配内存。如果你在C++中声明一个像char *c这样的变量,你实际上可以给它分配一个字符串,比如:c = "abcd";在这里,每个字母a-d都存储在连续的内存位置,因此您可以c[0],c[1],c[2],c[3]访问它们,实际上它们是:*c, *(c+1), *(c+2), *(c+3)

在 Java 中,您可以将uint8_t *ptr声明为byte[] ptr;您可以在这里参考为什么byte适合uint8_t

最新更新