Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 尝试为任意大小的矩阵编写矩阵乘法器_C_Arrays_Matrix - Fatal编程技术网

C 尝试为任意大小的矩阵编写矩阵乘法器

C 尝试为任意大小的矩阵编写矩阵乘法器,c,arrays,matrix,C,Arrays,Matrix,尝试用C编写任意大小矩阵的矩阵乘法函数。我尝试以下函数签名: void matrixMult(void *A, int Xa, int Ya, void *B, int Xb, int Yb); (在我对其进行故障排除时,它暂时返回void,待它按我希望的方式工作后,我将进行适当的返回) X和Y参数用于通知传入数组的尺寸函数(据我所知,这是必要的,因为在C中,数组不知道自己的大小)。我传入两个空指针A和B,以及它们的尺寸 我的问题:一旦我在函数中,我如何将空指针转换回int数组,以便读取它们?

尝试用C编写任意大小矩阵的矩阵乘法函数。我尝试以下函数签名:

void matrixMult(void *A, int Xa, int Ya, void *B, int Xb, int Yb);
(在我对其进行故障排除时,它暂时返回void,待它按我希望的方式工作后,我将进行适当的返回)

X和Y参数用于通知传入数组的尺寸函数(据我所知,这是必要的,因为在C中,数组不知道自己的大小)。我传入两个空指针A和B,以及它们的尺寸

我的问题:一旦我在函数中,我如何将空指针转换回int数组,以便读取它们?我尝试了以下方法:

(int)*A[someX][someY]
,但我得到一个关于“无效使用void指针”的编译器错误


编辑

以下是我目前的全部功能(在排除故障时更新):

#杂注警告(禁用:8057)
#包括
无效矩阵结果(整数**A、整数Xa、整数Ya、整数**B、整数Xb、整数Yb);
int main(int argc,char*argv[]){
//[x][y]x-->行;y-->列
INTA[3][5]={
{  1,  2,  3,  4,  5 }
, { 10, 20, 30, 40, 50 }
, {  4,  8, 15, 16, 23 }
};
int b[5][7]={
{  1,  2,  3,  4,  5,  6,  7 }
, { 10, 20, 30, 40, 50, 60, 70 }
, {  4,  8, 15, 16, 23, 42,  0 }
, {  1,  2,  3,  4,  5,  6,  7 }
, { 10, 20, 30, 40, 50, 60, 70 }
};
矩阵结果((整数**)a,3,5,(整数**)b,5,7);
printf(“完成”\n);
返回0;
}
无效矩阵结果(整数**A、整数Xa、整数Ya、整数**B、整数Xb、整数Yb){
printf(“起始矩阵mult\n”);
int i,j;

对于(i=0;i如果我正确理解了你的问题,你可以这样做

int **a = A;
为什么您要直接使用
void*
而不是
int**A

编辑1 根据下面的评论:请参见(
f3
)以及

编辑2 像这样声明和初始化它们:

int **a;

a = malloc(sizeof(*a) * 3);
for (i = 0; i < 3; i++) {
    a[i] = malloc(sizeof(int) * 5);
}
int**a;
a=malloc(sizeof(*a)*3);
对于(i=0;i<3;i++){
a[i]=malloc(sizeof(int)*5);
}

原型必须是双指针。此外,您不需要取消引用(除非最里面的指针是指针本身),因为您要将其强制转换为int。除非类型是int*

void matrixMult(void **A, int Xa, int Ya, void **B, int Xb, int Yb);
不需要取消引用,因为它只是一个基本的int

(int)A[someX][someY]
如果你有,比方说一个int,你需要去引用它,但即使这样,你也会去引用演员表之外的内容

*(int *)A[someX][someY]

在取消引用指针之前,必须让编译器知道类型是什么。否则,尝试取消引用void*

会出现错误。如果您有C99,您可以简单地使用可变长度数组,它们就是为它设计的。忘记指向指针的指针,只需执行以下操作即可

void matrixMult(size_t n, size_t m, size_t k, double A[n][m], double B[m][k], double C[n][k]);
这里很重要的一点是,参数列表中的大小是第一位的,因此当涉及到
A
B
C
时,它们是已知的。在函数中,您可以通过类似
A[i][j]
的方式访问单个矩阵元素

然后要分配这样的矩阵,你必须小心不要在堆栈上分配它们

double (*A)[n][m] = malloc(*A);
应该这样做


真的试着忘记将矩阵定义为指针数组,每个指针都必须分配自己的块等等。这非常复杂,容易出错,并且增加了不必要的间接级别。

void*
不是某种模板类型参数。因为需要将指针强制转换为某种类型,所以namely指针指向的数据类型,并且整个操作都是针对该类型编译的,仅使用
void*
指针在这里没有什么意义。或者添加一个参数,告诉传递的类型,并相应地在函数中分支,或者更好地使用适当的类型并相应地命名函数。同样,y您不应该使用双指针:根据内存分配,它可能会破坏缓存位置

要保存键入内容,请使用宏:

#define MATRIXMULT(type, typeshort) void matrixMult##typeshort(\
##type *A, int const Xa, int const Ya, ##type *B, int const Xb, int const Yb)\
{ \
    printf("starting matrix mult\n"); \
    int i, j, k; \
\
    if(Ya != Xb || Xa != Yb) \
        return; // dimensions don't match \
\
    for (i=0; i<Xa; i++) { \
        for (j=0; j<Ya; j++) { \
            A[i*Ya + j]=0; \
            for(k=0; k < Xa; k++) \
                A[i*Ya + j] += A[i*Ya + k] * B[k*Yb + j]; \
    } \
}

MATRIXMULT(double, d)
MATRIXMULT(float, f)
MATRIXMULT(int, i)

因此,使用宏很容易在多个变量中获得相同的函数。通过上述宏扩展,您可以调用
matrixMultd
matrixMultf
matrixMulti

,使用该签名,您不能使用双数组表示法,因为编译器不知道数组行有多大。您必须使用poiINTER算术。
int[5][7]
int**
更像
int*
。将函数更改为
int*
并使用
a[x+y*宽度]
当访问元素时。@Banthar但那将是UB?更不用说不清楚了。@Daniel:我认为没有任何其他方法可以动态访问静态多维数组。因为他的维数是常量(2D),所以它将始终是一个双指针。使用void*是因为我没有经验@C:-}我想要的是一种传递任意大小数组的方法。所以我可以更改sig。使用int**a,然后,传递数组?现在尝试…不,你不能传递任意大小的n维数组。你可以传递指针:-)现在阅读常见问题解答;见我的编辑上面;现在我在sig中使用int**A,在函数调用中使用&A;编译器中出现不兼容的类型错误。谢谢你的FAQ链接!编辑:Doh!无与伦比的。类型错误是因为我也没有更新函数定义。@loneboat读取这些,然后读取。事实上,总有一天阅读所有的清单会带来奇迹(对我来说的确如此)。非常感谢这些——我认为你让我走上了正确的道路!我已经在PHP lala land工作了好几年,我正在尝试重新学习C语言。或者他可以使用一个int**来保存自己的演员阵容。有趣的是,你能详细介绍一下宏在这方面是如何工作的吗?我不怎么使用宏,但它看起来很方便。谢谢@loneboat:这只是一点预处理器的魔力。在写MATRIXMU时
#define MATRIXMULT(type, typeshort) void matrixMult##typeshort(\
##type *A, int const Xa, int const Ya, ##type *B, int const Xb, int const Yb)\
{ \
    printf("starting matrix mult\n"); \
    int i, j, k; \
\
    if(Ya != Xb || Xa != Yb) \
        return; // dimensions don't match \
\
    for (i=0; i<Xa; i++) { \
        for (j=0; j<Ya; j++) { \
            A[i*Ya + j]=0; \
            for(k=0; k < Xa; k++) \
                A[i*Ya + j] += A[i*Ya + k] * B[k*Yb + j]; \
    } \
}

MATRIXMULT(double, d)
MATRIXMULT(float, f)
MATRIXMULT(int, i)
void matrixMultd(
double *A, int const Xa, int const Ya, double *B, int const Xb, int const Yb)
{ 
    printf("starting matrix mult\n"); 
    int i, j, k; 

    if(Ya != Xb || Xa != Yb) 
        return;

    for (i=0; i<Xa; i++) { 
        for (j=0; j<Ya; j++) { 
            A[i*Ya + j]=0; 
            for(k=0; k < Xa; k++) 
                A[i*Ya + j] += A[i*Ya + k] * B[k*Yb + j]; 
    } 
}