【问题标题】:Adding matrix as pointer添加矩阵作为指针
【发布时间】: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_tableconst 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 替换为&amp;signal_table[0][0] 会更自然,它也是const uint8_t * 类型并指向同一事物。
  • 一般来说,在指向某个元素的指针上使用指针算法来访问二维数组的不同行中的元素(将二维数组视为平面一维数组)会导致到未定义的行为。指向字符类型(charsigned charunsigned char)的指针有一个例外,它可以合法地用于访问二维数组的任何字节。 uint8_t 可能在某些 C 实现中未定义为字符类型(它可以定义为扩展整数类型),这将不允许这种用法。如果uint8_tunsigned char 是同一类型,则可以。

标签: arrays c pointers matrix


【解决方案1】:

尽量避免编写不必要的晦涩或复杂的代码。你的函数可能应该写成:

void initLamp(uint8_t time, const uint8_t datatable[ROWS][COLS], uint64_t *outdata)

或者使用 VLA 语法:

void initLamp(uint8_t time, 
              size_t rows, 
              size_t cols, 
              const uint8_t datatable[rows][cols], 
              uint64_t *outdata)

如果是后者,则称其为:

initLamp(0, ROWS, COLS, signal_table, &returndata);

for 循环应该被简化为使用数组语法:

for(size_t r = 0; r < rows; r++)
{
  for(size_t c = 0; c < cols; c++)
  {
    datatable[r][c] = something;
  }
}

另一个问题是代码中的1 &lt;&lt; ... 部分,这很可能是隐藏的错误。 1int 类型的整数常量。您最终可能会将数据移入符号位,这是一个未定义的行为错误。如果是uint64_t,您应该使用1ULL(uint64_t)1

【讨论】:

  • 感谢您的提示,特别是对于隐藏的错误,因为我为此苦苦挣扎了几分钟。
猜你喜欢
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
相关资源
最近更新 更多