英文:
Getting number of rows in 2D array: my function always returns 1 - Arduino
问题
我正在为在esp32上的LED项目中使用的功能编写代码。我正在使用二维数组来存储RGB十六进制代码,并调用我的gradientFunction来发送到BLE控制器,但颜色的数量可能会变化:
...
if (counter == 0) {
uint8_t rgb[4][3] = { {0xff, 0x00, 0x00}, {0xff, 0x11, 0x11}, {0xea, 0x1f, 0x10}, {0xff, 0x00, 0x00} };
gradientFunction(rgb);
Serial.println("红色渐变");
}
}
void gradientFunction(uint8_t rgb[][3]) {
int length = sizeof(rgb) / sizeof(rgb[0]);
Serial.println(length);
for (int i = 0; i < length; i++) {
uint8_t bytes[9] = {0x7b, 0x01 + i, 0x0e, 0xfd, rgb[i][0], rgb[i][1], rgb[i][2], length, 0xbf};
pRemoteCharacteristic->writeValue(bytes, 9);
delay(100);
}
}
然而,计算行数(length)返回1。打印sizeof(rgb)返回4,sizeof(rgb[0])返回3。这导致只有1个颜色代码被传输到BLE控制器。
我似乎无法弄清楚在计算行数时出了什么问题,或者我是否调用了函数错误?
英文:
I am writing a function for use in a LED project on a esp32. I am using 2D arrays to store RGB hex codes and calling my gradientFunction to send to a BLE controller, but the number colors of may vary:
...
if (counter == 0) {
uint8_t rgb[4][3] = { {0xff, 0x00, 0x00}, {0xff, 0x11, 0x11}, {0xea, 0x1f, 0x10}, {0xff, 0x00, 0x00} };
gradientFunction(rgb);
Serial.println("Red gradient");
}
}
void gradientFunction(uint8_t rgb[][3]) {
int length = sizeof(rgb) / sizeof(rgb[0]);
Serial.println(length);
for (int i = 0; i < length; i++) {
uint8_t bytes[9] = {0x7b, 0x01 + i, 0x0e, 0xfd, rgb[i][0], rgb[i][1], rgb[i][2], length, 0xbf};
pRemoteCharacteristic->writeValue(bytes, 9);
delay(100);
}
}
However, calculating the number of rows (length) returns 1. Printing sizeof(rgb) returns 4 and sizeof(rgb[0]) returns 3. This results in only 1 color code being transmitted to the BLE controller.
I can't seem to figure where I am going wrong with calculating the number of rows, or am I calling the function incorrectly?
答案1
得分: 2
C编程常见问题:当数组传递给函数时,它会“衰减”为指向第一个元素的指针。这正是你能够使用空维度开始uint8_t rgb[][3]
的原因:无论维度uint8_t [n][3]
的第一个项始终是uint8_t [3]
,与_n_无关。
-
因此,
sizeof(rgb)
给出了指向第一个元素的指针的大小。第一个元素是uint8_t [3]
,指向它的指针是uint8_t (*)[3]
。在32位ESP32上为4。 -
而
sizeof(rgb[0])
实际上给出了第一个元素的大小,类似于sizeof(uint8_t[3])
,意味着3。 -
4 / 3使用整数运算得到截断的1。
要解决这个问题,可以像这样重写函数:
void gradientFunction(uint8_t x, uint8_t y, uint8_t rgb[x][y]) {
uint16_t size = x * y;
当然,这假设x和y永远不会大于255。由于这是一个微控制器,我故意使用尽可能小的整数类型。在PC上,你可能会使用size_t
而不是。
英文:
C programming FAQ: an array when passed to a function "decays" into a pointer to the first element. This is the very reason why you are able to type uint8_t rgb[][3]
with an empty dimension to begin with: the first item of an array of dimensions uint8_t [n][3]
is always uint8_t [3]
regardless of n.
-
Therefore
sizeof(rgb)
gives the size of a pointer to the first element. The first element beinguint8_t [3]
and a pointer to one beinguint8_t (*)[3]
. Size 4 on a 32 bit ESP32. -
Whereas
sizeof(rgb[0])
actually gives the size of the first element, similar tosizeof(uint8_t[3])
, meaning 3. -
4 / 3 with integer arithmetic gives a truncated 1.
To solve this, rewrite the function like this instead:
void gradientFunction(uint8_t x, uint8_t y, uint8_t rgb[x][y]) {
uint16_t size = x * y;
This of course assuming that x and y are never larger than 255. Since this is a microcontroller, I'm intentionally using as small as possible integer types. On a PC you wouldn't care and use size_t
instead.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论