简体   繁体   English

有关函数指针的C问题

[英]C question regarding pointers in a function

I have two questions regarding this code. 关于此代码,我有两个问题。

  1. What does the double*** pdata and int*** pmask mean? double*** pdataint*** pmask是什么意思? A pointer to a pointer to a pointer? 指向指针的指针? Why or when is this necessary? 为什么或何时有此必要?

  2. int and double are different types, but are double* and int* also different. intdouble是不同的类型,但是double*int*也不同。 Can we operate on them without a cast? 我们可以在没有演员的情况下对其进行操作吗?

Here's the code I'm puzzled about: 这是我很困惑的代码:

static int makedatamask(int nrows, int ncols, double*** pdata, int*** pmask)
    { int i;
      double** data;
      int** mask;
      data = malloc(nrows*sizeof(double*));
      if(!data) return 0;
      mask = malloc(nrows*sizeof(int*));
      if(!mask)
      { free(data);
        return 0;
      }
      for (i = 0; i < nrows; i++)
      { data[i] = malloc(ncols*sizeof(double));
        if(!data[i]) break;
        mask[i] = malloc(ncols*sizeof(int));
        if(!mask[i])
        { free(data[i]);
          break;
        }
      }
      if (i==nrows) /* break not encountered */
      { *pdata = data;
        *pmask = mask;
        return 1;
      }
      *pdata = NULL;
      *pmask = NULL;
      nrows = i;
      for (i = 0; i < nrows; i++)
      { free(data[i]);
        free(mask[i]);
      }
      free(data);
      free(mask);
      return 0;
    }

Yes - the types are triple pointers or pointers to pointers to pointers. 是的-类型是三重指针或指向指针的指针。 Occasionally they are necessary, but be very scared. 有时它们是必要的,但非常害怕。 In this case, you are allocating two similarly sized 2D arrays, and you have to return the two values by reference, so the triple pointers are necessary, at least while you keep the current function design. 在这种情况下,您要分配两个大小相似的2D数组,并且必须通过引用返回两个值,因此至少在保持当前函数设计的同时,必须使用三重指针。

Yes - a double * and an int * are different types; 是的double *int *是不同的类型; they point to different types. 他们指向不同的类型。 You can do appropriate operations on them without a cast. 您可以对它们进行适当的操作而无需强制转换。 However, if you are thinking that you can combine the two parallel operations into one, you are probably mistaken. 但是,如果您认为可以将两个并行操作组合为一个,则可能会弄错。

Your error recovery might be simpler if you created some sub-functions: 如果创建了一些子功能,则错误恢复可能会更简单:

static int **alloc_2d_int_array(int nrows, int ncols)
{
    ...
}

static double **alloc_2d_double_array(int nrows, in ncols)
{
    ...
}

Your main allocation function would then simply call these two sequentially. 然后,您的主要分配函数将简单地依次调用这两个函数。 If the second failed, the main allocation function would call the cleanup for the first allocated array. 如果第二个失败,则主分配函数将为第一个分配的数组调用清除。 The cleanup code probably needs the relevant size, so you'd probably have: 清理代码可能需要相关的大小,因此您可能需要:

static void free_2d_double_array(int nrows, double **array)
{
    ...
}

static void free_2d_int_array(int nrows, int **array)
{
    ...
}

These functions might even be visible outside the source (not static ). 这些功能甚至可能在源外部可见(不是static )。

You might also consider using a structure to describe the arrays (rows and columns), and the pointers to the arrays. 您可能还考虑使用一种结构来描述数组(行和列)以及指向数组的指针。 This would allow you to avoid the explicit triple-pointer notation too. 这将使您也避免使用显式三指针表示法。

struct double_array
{
    int      nrows;
    int      ncols;
    double **array;
};

Etc. 等等。

A) A*** may be a pointer to an array of pointers, or an double dimensional array of pointers A)A ***可以是指向指针数组的指针,也可以是二维数组的指针
B) int and double are different types and cannot operate without cast B)int和double是不同的类型,没有强制转换就无法运行

What does the double*** pdata and int*** pmask mean? double *** pdata和int *** pmask是什么意思? A pointer to a pointer to a pointer? 指向指针的指针?

Yes. 是。

[When] is this necessary? [何时]这是必要的?

When, as this function does, you want to return a pointer-to-pointer value, by pointer. 像此函数一样,当您希望按指针返回指针到指针的值时。 You can also return these by value of course, but this function does it by pointer because it "returns" multiple pointers. 您当然也可以按值返回这些,但是此函数通过指针完成,因为它“返回”了多个指针。

int and double are different types, but are double* and int* also different. int和double是不同的类型,但是double *和int *也不同。 Can we operate on them without a cast? 我们可以在没有演员的情况下对其进行操作吗?

I'm not sure what you mean, but but you can't expect to cast int* to double* or vice versa; 我不确定您的意思,但是您不能期望将int*double* ,反之亦然; int and double most likely have a different representation in memory for the same values (as far as they can represent the same values) and different sizes. 对于相同的值(只要它们可以表示相同的值)和大小, intdouble很有可能在内存中具有不同的表示形式。 You'd also be violating the "strict aliasing" rule of C by saying 您还会说出违反C的“严格别名”规则

double *p = WHATEVER;
int *q = p;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM