【问题标题】:C: 'the incompatible pointer types passing' warning is important?/Passing multi-dimentional array to functionC:'不兼容的指针类型传递'警告很重要?/将多维数组传递给函数
【发布时间】:2021-06-21 07:15:39
【问题描述】:

我想写一个函数,它接受一个指向多维数组的指针。例如:

#include <stdio.h>

void print_matrix(int channel, int row, int column, int *matrix);

int main(void) {
    int test[4][5][6];
    int counter = 1;
    for (int channel = 0; channel < 4; channel++) {
        for (int row = 0; row < 5; row++) {
            for (int column = 0; column < 6; column++) {
                test[channel][row][column] = counter;
                counter += 1;
            }
        }
    }

    print_matrix(4, 5, 6, test);
}

void print_matrix(int channel, int row, int column, int *matrix) {
    for (int chn = 0; chn < channel; chn++) {
        for (int r = 0; r < row; r++) {
            for (int c = 0; c < column; c++) {
                printf("%d ", *(matrix + (chn * row * column + r * column + c)));
            }
            printf("\n");
        }
        printf("\n\n");
    }
}

但是当我编译代码时,编译器给出了以下警告。

warning: incompatible pointer types passing 'int [4][5][6]' to parameter of type 'int *' [-Wincompatible-pointer-types]

在我问这个问题之前,我搜索了警告并找到了不同的解决方案。喜欢

void print_matrix(int channel, int row, int column, int matrix[channel][row][column]) ...

如果我没记错的话,我知道 C 将数组保存为顺序的。例如:

int holder[2][3][4]; // is equal to int holder[24] in ram
                     //holder[0][1][0] is equal to *(holder + 4)

我的问题是警告很重要吗?如果我知道该怎么做,我可以忽略这个警告吗?

【问题讨论】:

  • 你可以使用print_matrix(4, 5, 6, &amp;test[0][0][0]) ;
  • 谢谢。你想告诉我test和&test[0][0][0]有什么区别吗?它们都表示相同的内存位置但编译器在 &test[0][0][0] 情况下没有给出任何警告?
  • 每个警告都很重要
  • 编译器警告类型错误。每个变量都有一个地址和一个类型。 &amp;test[0][0][0] 的类型就是 int*。作为参数传递时test 的类型衰减为int(*)[5][6]
  • 想象一个红色激光指针,它指向火车并将其指向名为test 的火车。红色的激光光斑会照射到一个座位上,就像一个指向座位的绿色激光指针(你可以指向名为test的火车第一节车厢的第一个座位)。两束激光击中同一个点,但它们非常不同......并且生成的机器代码(但不是编译器)是色盲的 :-)

标签: arrays c pointers


【解决方案1】:

这种警告非常重要:在大多数情况下,它表示潜在的未定义行为。

在您的特定情况下,因为您知道对象的几何形状,并且test 衰减为指向其第一个元素(二维矩阵)的指针,该指针恰好与指向第一个矩阵元素的指针具有相同的值,您的代码具有预期的行为。

然而,将指针显式传递给第一个矩阵元素会更好:

int main(void) {
    int test[4][5][6];
    int counter = 1;
    for (int channel = 0; channel < 4; channel++) {
        for (int row = 0; row < 5; row++) {
            for (int column = 0; column < 6; column++) {
                test[channel][row][column] = counter;
                counter += 1;
            }
        }
    }

    print_matrix(4, 5, 6, &test[0][0][0]);
    return 0;
}

【讨论】:

  • 感谢您的回答。我有点困惑。 test 和 &test[0][0][0] 有什么区别?它们都表示相同的内存位置。
  • 是的,但没有相同的类型。 test 是 int [4][5][6] 类型,test[0] 是 int [5][6] 类型,test[0][0] 是 int [6] 并且 test[0][0][0] 是 int。前面的所有变量都表示相同的内存位置(只是因为它是实际的数组开始),但类型不同。而你的函数等待 int * 类型。由于数组衰减,所有前面的表达式都“转换”为int *,这是函数所期望的,但是编译器会抛出一个警告,因为你的代码不应该有这种行为(函数等待@987654329 @ 但你给了int [4][5][6])
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 2011-01-10
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多