我正在尝试将一些代码从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编写的)
答案 0 :(得分:3)
它被声明为int:
uint8_t ... *ptr;
与Java和许多其他语言从C派生语法不同,C ++允许您在单个声明中声明不同类型的变量。虽然r
,g
,b
等都是uint8_t
,但ptr
不是,因为星号前缀为星号。此前缀使ptr
指针为uint8_t
。
然后将其设置为某个值
ptr = &matrixbuff[some_index]
同样,前缀提供了一个线索:这次是前缀运算符&
,它接受后面表达式的地址。
但它似乎用作数组
ptr[WIDTH*2] &= ~B00000011;
这也是正确的,因为C ++允许您使用指针,就好像它是一个数组一样。在某些情况下,它允许您使用数组,就像它也是指针一样,但通常不应混淆这两个概念。
长话短说,如果你有p
类型的指针T*
和整数值i
,则表达式p[i]
等同于*(p+i)
,并且指T
的{{1}}大小i
与T
所指向的地址相距p
类型的值。因此,指针的行为模仿了数组的行为。
在Java中,您必须将ptr
上的操作转换为matrixbuff
上的操作,其索引计算为ptr
上的索引与ptr
本身索引的组合,例如
ptr[WIDTH]
会变成
matrixbuff[backindex][y * WIDTH * (nPlanes - 1) + x + WIDTH]
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^
// Origin Index
答案 1 :(得分:1)
声明数组时,内存是连续分配的。如果在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;
您可以参考here为什么byte
适用于uint8_t
?