C编程-在处理多维数组的函数中使用的指针

C编程-在处理多维数组的函数中使用的指针,c,arrays,pointers,multidimensional-array,C,Arrays,Pointers,Multidimensional Array,我有以下两个功能: double** transpose(double **a, int r, int c){ static double trans[100][100]; int i,j; for(i = 0; i < r; i++) for(j = 0; j < c; j++) trans[j][i] = a[i][j]; return trans; } double(*matrixMultiply(dou

我有以下两个功能:

double** transpose(double **a, int r, int c){
    static double trans[100][100];
    int i,j;
    for(i = 0; i < r; i++)
        for(j = 0; j < c; j++)
            trans[j][i] = a[i][j];
    return trans;
}

double(*matrixMultiply(double a[10][10], double b[10][10],
    int rowA, int colB, int colARowB))[10]{
    static double c[10][10];
    int i, j, k;
    for(i = 0; i < rowA; i++)
        for(j = 0; j < colB; j++){
            c[i][j] = 0;
            for(k = 0; k < colARowB; k++)
                c[i][j] += a[i][k]*b[k][j];
        }
    return (double*) c;
}
double**转置(double**a、int r、int c){
静态双反式[100][100];
int i,j;
对于(i=0;i
虽然我确实理解算法,但有人能解释一下这两个函数返回什么(类型、指针…)?第二个函数似乎返回数组,但我认为C中的函数不能返回数组

真的被这些指针弄糊涂了


另外,为什么数组(
trans
c
)声明为静态?据我所知,当你声明一个静态变量或函数时,它不能被导入到另一个文件中使用,但这里的情况并非如此

这两个函数都试图返回指向数组的指针。两者都做得不对,无法在我的系统上编译

除非它是
sizeof
或一元
&
运算符的操作数,或者是用于初始化声明中字符数组的字符串文字,否则“T
的N元素数组”类型的表达式将被转换(“衰减”)为“指向
T
的指针”类型的表达式,表达式的值将是数组第一个元素的地址

transpose
函数中,我们返回表达式
trans
trans
具有类型“100元素数组的
T
”,其中
T
是“100元素数组的
”。它不是
sizeof
或一元
&
运算符的操作数,因此它被转换(“衰减”)为“指向
T
”类型的表达式,在这种情况下,它是“指向
double
的100元素数组的指针”(
double(*)[100]
),“指向
double
”的指针,(
double**

编译器应该抱怨这个函数。我的函数是这样的:

gcc -c -std=c99 -pedantic-errors -Wall transpose.c
transpose.c: In function âtransposeâ:
transpose.c:7: error: return from incompatible pointer type
matrixMultiply
函数中,
c
具有类型“double
的10元素数组的10元素数组”,该类型“衰减”为“指向
double
的10元素数组的指针”(
double(*)[10]
)。第二个函数具有正确的返回类型-
double(*)[10]
-但是他们在return语句中将
c
强制转换为
double*
,从而把事情搞砸了,我们得到了与之前相同的错误:

gcc -c -std=c99 -pedantic-errors -Wall matrixMultiply.c
matrixMultiply.c: In function âmatrixMultiplyâ:
matrixMultiply.c:11: error: return from incompatible pointer type
他们应该写封信

return c;
一切都会好起来的

读取第二个函数定义的方法如下:

        matrixMultiply                           -- matrixMultiply
        matrixMultiply(                   )      -- is a function taking
        matrixMultiply( /* some params */ )      -- some parameters (omitted for brevity)
       *matrixMultiply( /* some params */ )      -- returning a pointer
      (*matrixMultiply( /* some params */ ))[10] -- to a 10-element array
double(*matrixMultiply( /* some params */ ))[10] -- of double
请注意,两个函数都有希望工作的唯一原因(一旦类型问题得到解决)就是说
trans
c
都声明为
static
,这意味着它们的生命周期扩展到整个程序,而不仅仅是它们各自函数的生命周期。如果没有
static
关键字,它们将在其封闭函数返回后停止存在,这些指针将变得无效。

这不一定是好的做法-这些函数不再是可重入的,也不是线程安全的。最好将目标数组作为参数传递给函数,但请注意,指向10个元素数组的指针与指向11个元素数组的指针是不同的、不兼容的类型-如果必须处理具有不同租用大量的柱子,这可能会变得很棘手。VLAs可以提供帮助:

void transpose( int r, int c, double arr[r][c], double trans[c][r] )
{
  ...
}

假设您有可用的VLA(您应该在C99和C2011系统上使用,尽管它们在C2011中是可选的)。如果您不这样做…这会变得更困难。

double**
不是2D数组,不能指向2D数组。指针不是数组。不,您不能向函数传递数组或从函数传递数组。但您可以向数组传递指针。返回指向静态对象的指针的另一个问题是可能出现意外的别名。这是一个问题OP案例中的特殊风险——如果其中一个函数的返回值在后续调用中作为参数传递回该函数,那么实际行为不太可能是预期的。或者,如果对其中一个函数执行单独和独立的调用,则previ函数返回的指针可能会出人意料我们随后的调用指向不同的数据。非常感谢您的回答以及您花时间写下所有这些。现在一切都清楚了。我为函数中的错误感到抱歉,但为我辩护,它们不是我的。我从昨天的编程课程中复制粘贴了它们。似乎老师没有注意……哦,好吧。@ROBlackSnail:C语言几乎都是由那些自己教得很差的人教得很差,数组/指针语义学是许多错误信息和错误实践转移的地方之一。它不是一个很好的学习资源,但它是C语言标准的书签——如果没有其他东西,它会告诉你这些东西应该是怎样的工作。