【发布时间】:2022-01-01 23:13:33
【问题描述】:
我有一个函数用于传递一个矩阵和一个变量作为指针(我简化了它,也许在这种形式下它没有意义,但我不想粘贴整个代码:)
uint64_t returndata = 0;
uint32_t binary_lock = 0;
void initLamp(uint8_t time, const uint8_t *datatable, uint64_t *outdata)
{
for(uint8_t k = 0; k < ROW; k++)
{
if(*(datatable + k * COLS) == time)
{
binary_lock |= (1 << k);
}
}
for(uint8_t i = 0; i < ROW; i++)
{
*outdata |= (1 << (3 * i));
}
}
我还有一个名为 datafield.h 的文件,其中包含矩阵:
static const uint8_t signal_table[][COLS] =
{
{22, 24, 63, 67}, // 1A
{87, 89, 31, 35}, // 1B
{0 , 2, 21, 24}, // 1C
{0 , 3, 22, 43}, // 1D
}
主要我需要像这样引用函数,以避免错误和警告:
int main(void)
{
initLamp(0, *signal_table, &returndata);
}
问题是:我对使用 main 函数有点怀疑。我几乎可以肯定'&returndata' 的用法是正确的,但为什么我必须将'*' 运算符放在'signal_table' 之前。我以为我只需要像 &signal_table 一样给出矩阵的地址,但这样它就不起作用了。
【问题讨论】:
-
signal_table的类型为const uint8_t [4][4]。作为一元*的操作数,signal_table从const uint8_t [4][4]转换为const uint8_t (*)[4](指向const uint8_t的数组长度为4的指针),所以*signal_table的类型为const uint8_t [4]。*signal_table作为函数调用参数,由const uint8_t [4]转换为const uint8_t *,与函数参数兼容。将*signal_table替换为&signal_table[0][0]会更自然,它也是const uint8_t *类型并指向同一事物。 -
一般来说,在指向某个元素的指针上使用指针算法来访问二维数组的不同行中的元素(将二维数组视为平面一维数组)会导致到未定义的行为。指向字符类型(
char、signed char、unsigned char)的指针有一个例外,它可以合法地用于访问二维数组的任何字节。uint8_t可能在某些 C 实现中未定义为字符类型(它可以定义为扩展整数类型),这将不允许这种用法。如果uint8_t与unsigned char是同一类型,则可以。