2015-04-07 139 views
2

说完看着我周围已经建立了接受矩阵并执行不管它是什么,我需要它的功能,如下所示:传递矩阵功能,C

float energycalc(float J, int **m, int row, int col){ 
... 
} 

在主数组的大小定义和填充,但是我不能passs这个函数本身:

int matrix[row][col]; 
... 
E=energycalc(J, matrix, row, col); 

这在编译过程中导致警告

"project.c:149: warning: passing argument 2 of ‘energycalc’ from incompatible pointer type project.c:53: note: expected ‘int **’ but argument is of type ‘int (*)[(long unsigned int)(col + -0x00000000000000001)]’

并导致分段错误。

任何帮助非常感谢,谢谢。

+0

'浮子energycalc(浮Ĵ,INT行,INT山口,INT米[行] [山口]){' – BLUEPIXY

+2

数组的数组是不一样的指针的指针,例如参见[本老回答我的](http://stackoverflow.com/a/18440456/440558),看看为什么。你可以通过指向数组的指针(例如'int(* m)[]')。 –

+0

@ legends2k这个问题只有'C'标记...当我冷静地抱怨我的回答时,我发现了困难的方式。 –

回答

2

将二维数组传递给C中的函数通常会让新手感到困惑。
原因是他们认为数组是指针,并且不理解数组如何衰减指针。
请务必记住,当作为参数传递数组转换为其第一个元素的指针。
在函数调用

E = energycalc(J, matrix, row, col); 

matrix被转换为指针,其是matrix[0]其第一个元素。这意味着通过matrix相当于通过&matrix[0]。请注意,&matrix[0]的类型是int(*)[col](指向数组col int的指针),因此是matrix。这表明函数energycalc的第二个参数必须是int(*)[col]类型。函数声明更改为

float energycalc(int col, int (*m)[col], int row, float J); 

,并致电功能

E = energycalc(col, matrix, row, J); 
+1

或者直接声明指针参数为'int m [row] [col]',这样更具可读性。 – Lundin

+0

@Lundin;或'int m [] [col]'。 – haccks

+0

你想省略其中一个维度的任何原因? – Lundin

3

如果阵列被声明为

int matrix[row][col]; 

然后改变函数声明

float energycalc(float J, int m[][col], int row, int col){ 

T类型的二维数组的名称不衰减到T**

如果col是一个局部变量,则需要在matrix之前调用参数为col的函数。这样做是为了使col在函数中可见。

+0

@BLUEPIXY,对不起,我不明白 –

+2

看到[DEMO](http://ideone.com/QarBmz)'error:'col'undeclared here(not in a function)' – BLUEPIXY

+1

@CoolGuy;使用float float energycalc(float J,int m [] [col],int row,int col)编译器不知道col是否会产生错误。你必须在'int m [] [col]''中使用它之前必须放置'col'。 – haccks

3

该函数应该声明如下

float energycalc(float J, int row, int col, int (*m)[col]); 

如果你的编译器支持可变长度数组。

否则,如果在声明

int matrix[row][col]; 

col是一些常数,则函数可以声明如下方式

float energycalc(float J, int m[][col], int row); 

提供恒定的col函数之前定义。

你的函数声明

float energycalc(float J, int **m, int row, int col); 

是合适的,当你有一个数组声明如下

int * matrix[row]; 

和阵列中的每个元素是动态分配的像例如

for (int i = 0; i < row; i++) matrix[i] = malloc(col * sizeof(int)); 
0

我认为你可以做这样的事情在C

float function_name(int mat_width, int mat_height, float matrix[mat_width][mat_height]) { 
    ... function body... 
} 
+0

如果'mat_width'和'mat_heigth'是编译时常量,你可以。如果是的话,它们应该用大写(因为惯例),然后这是最好的方法,因为它明确无误地记录了函数期望指向N乘M矩阵的指针,而不仅仅是一个指向随机类型的指针,而不知道它是否是一个数组和大小。 – Bregalad

+0

@Bregalad这不是真的......你可以mat_width和mat_height可以是变量,你可以每次发送不同的值......我认为这不是标准的C,而是一个扩展。 –

+1

@Bregalad这些是可变长度数组(VLA)。您可能想要将您的C知识更新为16年前发布的C99。 – Lundin

0

指针到指针不是数组,也不指向二维数组。它与数组,句点无关,所以忘了你曾经听说过指向指针和数组的指针。 (这种混淆可能来自大量困惑的想成为编程老师/作者,他们告诉大家他们应该在分配动态二维数组时使用指针指针,这只是一个简单的不好的建议,因为它不会分配一个真正的阵列分配在相邻的存储器单元中,而不是分散在整个堆中的分解查找表。See this以供参考,以便实际分配这样的阵列。)

假设您的编译器不是完全古老的,只需使用可变长度数组(VLA),这是C99标准中C语言引入的功能。

#include <stdio.h> 

void print_matrix (size_t row, size_t col, int matrix[row][col]); 


int main (void) 
{ 
    int matrix[2][3] = 
    { 
    {1,2,3}, 
    {4,5,6} 
    }; 

    print_matrix(2, 3, matrix); 

    return 0; 
} 

void print_matrix (size_t row, size_t col, int matrix[row][col]) 
{ 
    for(size_t r=0; r<row; r++) 
    { 
    for(size_t c=0; c<col; c++) 
    { 
     printf("%d ", matrix[r][c]); 
    } 
    printf("\n"); 
    } 
}