【问题标题】:incompatible pointer types passing short * to short *(*)[ ]将短 * 传递给短 *(*)[ ] 的不兼容指针类型
【发布时间】:2020-02-05 22:42:39
【问题描述】:

当然,我在这里做错了,但是看着这个我无法弄清楚为什么我会收到这些警告:

warning: incompatible pointer types passing '__int16_t *' (aka 'short *') to parameter of type '__int16_t *(*)[4]' [-Wincompatible-pointer-types]
        hammingDistance2d(ptr0, ptr1);

在我的小代码段中:

void hammingDistance2d(__int16_t *src0[N][N],
                       __int16_t *src1[N][N]){
    int i, j;
    __uint16_t Hdis[N][N] = {0};

    for (i=0 ; i<N; i++){
        for (j=0; j<N; j++){
            __uint16_t z = *src0[i][j] ^ *src1[i][j];
            while (z > 0)
            {
                Hdis[i][j] += z & 1;
                z >>= 1;
            }
        }
    }
int main(){

    __int16_t src0[N][N] = {  { 1, 1, 1, 1},
                              { 2, 2, 2, 2},
                              { 3, 3, 3, 3},
                              { 4, 4, 4, 4} };
    __int16_t src1[N][N] = {  { 1, 1, 1, 1},
                              { 2, 2, 2, 2},
                              { 5, 5, 5, 5}, // different row
                              { 4, 4, 4, 4} };
    __int16_t *ptr0 =  &src0[0][0];
    __int16_t *ptr1 =  &src1[0][0];

    hammingDistance2d(ptr0, ptr1);
    return 0;
}

我想继续使用指向数组的中间指针。

【问题讨论】:

  • 为什么使用__int16_t(系统类型;双下划线前缀为实现保留)而不是int16_t(类型名称的可用版本)?
  • *src0[N][N] 是一个二维指针数组,您将一个二维整数数组的一个元素的地址传递给该指针。

标签: c arrays pointers implicit-conversion


【解决方案1】:

这些变量

__int16_t *ptr0 =  &src0[0][0];
__int16_t *ptr1 =  &src1[0][0];

被显式声明为具有__int16_t * 类型。

但是对应的函数参数

void hammingDistance2d(__int16_t *src0[N][N],
                       __int16_t *src1[N][N]){

实际上有__int16_t * ( * )[N]的类型。

没有从第一种类型到第二种类型的隐式转换。所以编译器会报错。

看来你的意思是如下

void hammingDistance2d(__int16_t src0[N][N],
                       __int16_t src1[N][N]){
    int i, j;
    __uint16_t Hdis[N][N] = {0};

    for (i=0 ; i<N; i++){
        for (j=0; j<N; j++){
            __uint16_t z = src0[i][j] ^ src1[i][j];
            while (z > 0)
            {
                Hdis[i][j] += z & 1;
                z >>= 1;
            }
        }
    }
}

函数调用可能看起来像

hammingDistance2d( src0, src1 );

如果你想声明用作函数参数的中间指针,那么你应该写

__int16_t ( *ptr0 )[N] =  src0;
__int16_t ( *ptr1 )[N] =  src1;

然后像这样调用函数

hammingDistance2d( ptr0, ptr1 );

【讨论】:

  • 谢谢@Vlad。如果我想在这里使用指针,那么正确的形式是什么?
  • @Amir 你的意思是在函数中使用指针而不是下标运算符吗?
  • 感谢@Vlad,我想这是我的问题,我认为就像 &src[0] 具有起始地址的一维数组一样,&src[0][0] 必须具有2d 也是一样的。
  • @Amir address 的值可以重合,但表达式的类型不同。而且您可能不会将两个下标运算符应用于 __int16_t * 类型的指针
【解决方案2】:

您正在传递一个 __int16 的二维数组,但您的函数需要一个指向 __int16_t 的指针。

修复函数定义以使用您发送的内容。

void hammingDistance2d(__int16_t src0[N][N],
                       __int16_t src1[N][N]){
    int i, j;
    __uint16_t Hdis[N][N] = {0};

    for (i=0 ; i<N; i++){
        for (j=0; j<N; j++){
            __uint16_t z = src0[i][j] ^ src1[i][j];
            while (z > 0)
            {
                Hdis[i][j] += z & 1;
                z >>= 1;
            }
        }
    }

并将其称为:

hammingDistance2d(src0, src1);

【讨论】:

    【解决方案3】:

    函数期待:

    __int16_t *src0[N][N]
    

    哪个类型(如编译器所建议的那样)__int16_t *(*)[4],或者用英语表示:指向 [pointer to [array of 4 __int16_t]] 的指针(注意我使用的方括号是为了强调)。

    你有什么:

    __int16_t src0[N][N] = {  { 1, 1, 1, 1},
                              { 2, 2, 2, 2},
                              { 3, 3, 3, 3},
                              { 4, 4, 4, 4} };
    

    类型为__int16_t (*)[4],即:指向[array of 4 __int16_t]的指针。

    你可能打算声明:

    hammingDistance2d(__int16_t src0[N][N], __int16_t src1[N][N]) {
        // ...
    }
    

    等同于:

    hammingDistance2d(__int16_t (*src0)[N], __int16_t (*src1)[N]) {
        // ...
    }
    

    请注意,在这种情况下,您不必必须使用 * 运算符取消引用 src0[i][j]。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 2021-06-29
      • 1970-01-01
      相关资源
      最近更新 更多