简体   繁体   English

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

[英]C programming - pointers used in functions that work with multidimensional arrays

I have the following 2 functions: 我有以下两个功能:

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;
}

While I do understand the algorithms, can someone explain me what these 2 functions return (types, pointers...) ? 虽然我理解算法,有人可以解释一下这两个函数返回的内容(类型,指针......)? The second seems to return an array, but I thought that functions in C can't return arrays ... 第二个似乎返回一个数组,但我认为C中的函数不能返回数组...

Getting really confused with these pointers... 真的对这些指针感到困惑......

Also why are the arrays ( trans and c ) declared as static? 为什么数组( transc )声明为静态? As far as I get it, when you declare a variable or a function with static it can't be imported for use in another file, but that's defenetely not the case here ... 据我所知,当你用静态声明一个变量或一个函数时,它不能被导入以便在另一个文件中使用,但这在某种情况下并非如此......

Both functions are attempting to return pointers to arrays. 这两个函数都试图返回指向数组的指针。 Both are doing it wrong and fail to compile on my system. 两者都做错了 ,无法在我的系统上编译。

Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T " will be converted ("decay") to an expression of type "pointer to T ", and the value of the expression will be the address of the first element of the array. 除非它是sizeof或一元&运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则将将“N元素数组T ”的表达式转换为(“衰减”)到表达式“指向T指针”,表达式的值将是数组的第一个元素的地址。

In the transpose function, we're returning the expression trans . transpose函数中,我们返回表达式 trans trans has type "100-element array of T ", where T is "100-element array of double ". trans具有类型“ T 100个元素数组”,其中T是“100个元素的double数组”。 It's not the operand of the sizeof or unary & operators, so it is converted ("decays") to an expression of type "pointer to T ", which in this case is "pointer to 100-element array of double " ( double (*)[100] ), NOT "pointer to pointer to double ", ( double ** ). 它不是sizeof或一元&运算符的操作数,因此它被转换(“衰减”)到“指向T指针”类型的表达式,在这种情况下是“指向100个元素的double精度数组”( double (*)[100] ),而不是 “指向double指针的指针”,( double ** )。

The compiler should complain about that function. 编译器应该抱怨该功能。 Mine does, like so: 我的确如此:

gcc -c -std=c99 -pedantic-errors -Wall transpose.c
transpose.c: In function âtransposeâ:
transpose.c:7: error: return from incompatible pointer type

In the matrixMultiply function, c has type "10-element array of 10-element array of double ", which "decays" to "pointer to 10-element array of double " ( double (*)[10] ). matrixMultiply函数中, c具有类型“10元素数组的double元素10元素”,其“衰减”为“指向double元素的10元素数组”( double (*)[10] )。 The second function has the right return type - double (*)[10] - but then they MESS IT UP by casting c to double * in the return statement, and we get the same error as before: 第二个函数具有正确的返回类型- double (*)[10] -但他们搞砸了铸造cdouble *在return语句,我们得到了相同的错误面前:

gcc -c -std=c99 -pedantic-errors -Wall matrixMultiply.c
matrixMultiply.c: In function âmatrixMultiplyâ:
matrixMultiply.c:11: error: return from incompatible pointer type

They should have just written 他们应该刚写完

return c;

and everything would have been alright. 一切都会好起来的。

The way to read that second function definition is as follows: 读取第二个函数定义的方法如下:

        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

Note that the only reason either function has a hope of working (once the type issues are straightened out) is that both trans and c are declared static , meaning that their lifetimes extend over the entire program, not just the lifetimes of their respective functions. 注意,函数有希望工作的唯一原因(一旦类型问题被理顺), transc都被声明为static ,这意味着它们的生命周期延伸到整个程序,而不仅仅是它们各自函数的生命周期。 Without that static keyword, they would cease to exist after their enclosing functions return, and those pointers would become invalid . 如果没有那个static关键字,它们将在它们的封闭函数返回后停止存在 ,并且这些指针将变为无效

This is not necessarily good practice - these functions are no longer re-entrant and not thread-safe. 这不一定是好的做法 - 这些功能不再是可重入的,也不是线程安全的。 It would be better to pass the target arrays as parameters to the functions, but be aware that a pointer to a 10-element array is a different, incompatible type from a pointer to an 11-element array - if you have to deal with arrays with different numbers of columns, that could get tricky. 将目标数组作为参数传递给函数会更好,但要注意,指向10元素数组的指针与指向11元素数组的指针是不同的不兼容类型 - 如果必须处理数组使用不同数量的列,这可能会变得棘手。 VLAs can help with that: VLA可以帮助解决这个问题:

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

assuming you have VLAs available (you should on C99 and C2011 systems, although they've been made optional in C2011). 假设您有可用的VLA(您应该在C99和C2011系统上,尽管它们在C2011中已经可选)。 If you don't ... this gets harder. 如果你不这样做......这会变得更难。

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

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