二维数组与矩阵乘法

这篇博客介绍了如何在C语言中使用动态和静态内存分配方案定义二维数组,并实现了矩阵相乘的功能。动态二维数组通过结构体封装,静态二维数组直接在栈上分配。代码中包含了初始化、随机赋值、打印数组和矩阵相乘的函数,并提供了测试案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、二维数组:二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,类型说明符 数组名[常量表达式][常量表达式]。一维数组的每一空间里存储的又是另外一个一维数组的首地址,这样构成的一个类似于矩形的存储空间便是二维数组。

2、在这里用动态和静态两种空间分配方案来定义和初始化二维数组。

3、矩阵相乘图示:
在这里插入图片描述

4、代码:

#include <stdio.h>
#include <stdlib.h>

#define ROWS 4
#define COLUMNS 5

//二维数组 (动态) 
typedef struct TwoDArray{
	int rows;//行 
	int columns;//列 
	int** elements;
} TwoDArray, *TwoDArrayPtr;

//(静态) 
typedef struct TwoDStaticArray{
	int rows;
	int columns;
	int elements[ROWS][COLUMNS];
} TwoDStaticArray, *TwoDStaticArrayPtr;

//二维数组(动态)的初始化 
TwoDArrayPtr initTwoDArray(int paraRows, int paraColumns){
	int i;
	TwoDArrayPtr resultPtr = (TwoDArrayPtr)malloc(sizeof(struct TwoDArray));
	resultPtr->rows = paraRows;
	resultPtr->columns = paraColumns;
	
	resultPtr->elements = (int**)malloc(paraRows * sizeof(int*));
	
	for (i = 0; i < paraRows; i ++){
		resultPtr->elements[i] = (int*)malloc(paraColumns * sizeof(int));
	}
	
	return resultPtr;
}

//初始化二维数组(静态)并打印地址 
TwoDStaticArrayPtr initTwoDStaticArray(){
	int i, j;
	TwoDStaticArrayPtr resultPtr = (TwoDStaticArrayPtr)malloc(sizeof(struct TwoDStaticArray));
	resultPtr->rows = ROWS;
	resultPtr->columns = COLUMNS;
	for (i = 0; i < ROWS; i ++){
		for (j = 0; j < COLUMNS; j ++){
			resultPtr->elements[i][j] = i * 10 + j;
			printf("(%d , %d): %d \n", i, j, &(resultPtr->elements[i][j]));
		}
	}
	return resultPtr;
}

//随机给数组赋值 
void randomizeTwoDArray(TwoDArrayPtr paraPtr, int paraLowerBound, int paraUpperBound){
	int i, j;
	for (i = 0; i < paraPtr->rows; i ++){
		for (j = 0; j < paraPtr->columns; j ++){
			paraPtr->elements[i][j] = rand() % (paraUpperBound - paraLowerBound) + paraLowerBound;
		}
	}
}

//打印数组 
void printTwoDArray(TwoDArrayPtr paraPtr){
	int i, j;	
	for (i = 0; i < paraPtr->rows; i ++){
		for (j = 0; j < paraPtr->columns; j ++){
			if(j<paraPtr->columns-1)
			printf("%d , ", paraPtr->elements[i][j]);
			else
			printf("%d ", paraPtr->elements[i][j]);
		}
		printf("\r\n");
	}
}

//矩阵相乘 
TwoDArrayPtr matrixMultiply(TwoDArrayPtr paraPtr1, TwoDArrayPtr paraPtr2){
	int i, j, k, sum;
	if (paraPtr1->columns != paraPtr2->rows){
		printf("矩阵不能相乘!\n");
		return NULL;
	}
		
	TwoDArrayPtr resultPtr = initTwoDArray(paraPtr1->rows, paraPtr2->columns);

	for (i = 0; i < paraPtr1->rows; i ++){
		for (j = 0; j < paraPtr2->columns; j ++){
			sum = 0;
			for (k = 0; k < paraPtr1->columns; k ++){
				sum += paraPtr1->elements[i][k] * paraPtr2->elements[k][j];
			}
			resultPtr->elements[i][j] = sum;
			printf("sum = %d; ", sum);
		}
	}
	printf("\nthe result is:\n");
	return resultPtr;
}

//数组随机赋值和矩阵相乘的测试 
void twoDArrayTest(){
	TwoDArrayPtr tempPtr1, tempPtr2, tempPtr3;
	tempPtr1 = initTwoDArray(3, 2);
	randomizeTwoDArray(tempPtr1, 1, 5);
	printf("The first matrix:\r\n");
	printTwoDArray(tempPtr1);

	tempPtr2 = initTwoDArray(2, 4);
	randomizeTwoDArray(tempPtr2, 4, 9);
	printf("The second matrix:\r\n");
	printTwoDArray(tempPtr2);

	tempPtr3 = matrixMultiply(tempPtr1, tempPtr2);
	printTwoDArray(tempPtr3);
	
	tempPtr1 = initTwoDArray(4, 3);
	randomizeTwoDArray(tempPtr1, -5, 5);
	printf("The first matrix:\r\n");
	printTwoDArray(tempPtr1);
	
	tempPtr2 = initTwoDArray(3, 2);
	randomizeTwoDArray(tempPtr2,0, 9);
	printf("The second matrix:\r\n");
	printTwoDArray(tempPtr2);
	
	tempPtr3 = matrixMultiply(tempPtr1, tempPtr2);
	printTwoDArray(tempPtr3);
}

//main函数 
int main(){
	twoDArrayTest();
	TwoDStaticArrayPtr tempPtr = initTwoDStaticArray();
	return 1;
}


5、运行结果:

The first matrix:
2 , 4
3 , 1
2 , 1
The second matrix:
7 , 7 , 6 , 8
4 , 4 , 5 , 6
sum = 30; sum = 30; sum = 32; sum = 40; sum = 25; sum = 25; sum = 23; sum = 30; sum = 18; sum = 18; sum = 17; sum = 22; 
the result is:
30 , 30 , 32 , 40
25 , 25 , 23 , 30
18 , 18 , 17 , 22
The first matrix:
-4 , -4 , 0
-3 , 2 , 1
-4 , -1 , -3
-2 , -3 , -3
The second matrix:
6 , 5
8 , 5
2 , 0
sum = -56; sum = -40; sum = 0; sum = -5; sum = -38; sum = -25; sum = -42; sum = -25;
the result is:
-56 , -40
0 , -5
-38 , -25
-42 , -25
(0 , 0): 10557272
(0 , 1): 10557276
(0 , 2): 10557280
(0 , 3): 10557284
(0 , 4): 10557288
(1 , 0): 10557292
(1 , 1): 10557296
(1 , 2): 10557300
(1 , 3): 10557304
(1 , 4): 10557308
(2 , 0): 10557312
(2 , 1): 10557316
(2 , 2): 10557320
(2 , 3): 10557324
(2 , 4): 10557328
(3 , 0): 10557332
(3 , 1): 10557336
(3 , 2): 10557340
(3 , 3): 10557344
(3 , 4): 10557348
<think>好的,我现在需要帮助用户理解如何使用二维数组实现矩阵乘法。首先,我得回忆一下矩阵乘法的数学定义。矩阵乘法要求第一个矩阵的列数等于第二个矩阵的行数,结果矩阵的行数是第一个矩阵的行数,列数是第二个矩阵的列数。例如,如果矩阵A是m×n,矩阵B是n×p,那么结果矩阵C就是m×p,每个元素C[i][j]是A的第i行和B的第j列的点积。 接下来,我需要考虑如何在代码中用二维数组表示矩阵。根据引用[3],二维数组在内存中是按行排列的,所以定义两个二维数组作为输入矩阵,再定义一个结果数组。例如,如果用户给出的矩阵A是3×2,矩阵B是2×3,那么结果应该是3×3的矩阵。 然后,编写三重循环来实现乘法。外层两个循环遍历结果矩阵的每个元素C[i][j],最内层循环计算点积,即累加A[i][k] * B[k][j]的和,其中k从0到第一个矩阵的列数减一。需要注意数组的索引是否正确,避免越界。 用户可能需要示例代码,所以得写一个具体的例子,比如两个2x3和3x2的矩阵相乘,得到2x2的结果。代码中要初始化两个矩阵,然后进行计算,最后输出结果矩阵。同时,要解释每个循环的作用,特别是最内层循环如何对应数学中的点积运算。 另外,根据用户提供的引用[1]和引用[2],矩阵运算需要满足维度要求,所以在代码中需要检查输入矩阵的维度是否匹配,否则无法进行乘法。但用户的问题可能更关注实现步骤,所以示例代码可以假设输入矩阵已经符合条件,但最好在解释中提到这一点。 最后,要确保代码语法正确,比如在C语言或Python中的二维数组定义和循环结构是否正确。根据用户提供的示例代码,可能更倾向于Python,但引用[3]提到的是嵌入式C语言二维数组,所以可能需要用C语言示例。不过用户的问题没有指定语言,可能需要提供两种,但根据引用中的例子,可能C更合适。不过之前的快速排序示例是Python,所以需要确认。用户的问题里示例代码是Python,但引用[3]是C,所以可能需要用C或根据用户情况选择。但用户现在的问题是“如何使用二维数组实现矩阵乘法”,可能更通用,所以用C或Python都可以,但需要明确。假设用户需要Python示例,因为之前的示例是Python,但根据引用[3],可能用户需要C的。需要仔细看引用。 引用[3]是关于嵌入式C语言二维数组,而用户的问题可能希望用C来实现,但原问题的示例代码是Python。这里可能需要确认,但用户的问题提到“二维数组”,在C和Python中都可以实现。但根据引用[2]中的问题,要求编写矩阵乘积的代码,可能用户希望看到具体的实现,比如在C中使用嵌套循环。 不过用户的问题中的示例代码是Python的快速排序,所以可能用户更倾向于Python。或者需要根据引用[2]中的情况,可能用户的问题中的引用[2]是要求编写矩阵乘法的代码,可能示例代码是Python。需要综合判断。 现在需要综合考虑,可能用户希望用Python,因为之前的示例是Python,但引用[3]是C语言的。但用户的问题可能希望用任何语言,所以可能需要用两种,但更可能希望用Python。或者用户可能更关注逻辑,所以用伪代码或具体步骤。但用户明确要求示例代码,所以需要给出具体的代码示例。 假设用户希望用Python,因为之前的示例是Python。所以需要编写Python代码实现矩阵乘法。例如,定义两个二维数组,然后计算结果矩阵的每个元素。 不过需要确保矩阵乘法的条件,即第一个矩阵的列数等于第二个矩阵的行数。在代码中需要处理这个条件,但用户可能只需要核心逻辑,所以可以省略检查,假设输入正确。 然后,解释代码的每个部分,尤其是三重循环的结构,以及如何对应数学中的行和列的相乘相加。 同时,可能用户会问及时间复杂度,或者优化方法,但根据问题,用户主要需要实现方法,所以重点放在代码和解释上。 最后,生成相关问题,例如如何优化矩阵乘法的性能,或者如何处理不同维度的矩阵等。</think>### 矩阵乘法实现步骤 矩阵乘法$C = A \times B$需满足:**矩阵$A$的列数等于矩阵$B$的行数**,结果矩阵$C$的行数等于$A$的行数,列数等于$B$的列数[^1]。具体步骤如下: 1. **定义二维数组** 用二维数组表示矩阵,例如: ```c int A[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 2行3列 int B[3][2] = {{7, 8}, {9, 10}, {11, 12}}; // 3行2列 int C[2][2] = {0}; // 结果矩阵初始化为0 ``` 2. **三重循环计算乘积** 外层循环遍历$A$的行,中层循环遍历$B$的列,内层循环计算点积: ```c for (int i = 0; i < 2; i++) { // 遍历A的行 for (int j = 0; j < 2; j++) { // 遍历B的列 for (int k = 0; k < 3; k++) { // 计算点积 C[i][j] += A[i][k] * B[k][j]; } } } ``` 3. **输出结果矩阵** ```c for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { printf("%d ", C[i][j]); } printf("\n"); } ``` ### 示例代码 以下代码实现两个矩阵乘法: ```c #include <stdio.h> int main() { int A[2][3] = {{1, 2, 3}, {4, 5, 6}}; int B[3][2] = {{7, 8}, {9, 10}, {11, 12}}; int C[2][2] = {0}; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 3; k++) { C[i][j] += A[i][k] * B[k][j]; } } } // 输出结果 for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { printf("%d ", C[i][j]); } printf("\n"); } return 0; } ``` ### 代码解释 - **三重循环逻辑**:外层循环`i`遍历$A$的每一行,中层循环`j`遍历$B$的每一列,内层循环`k`累加$A[i][k] \times B[k][j]$的值,对应数学公式: $$C_{i,j} = \sum_{k=0}^{n-1} A_{i,k} \cdot B_{k,j}$$ - **内存布局**:二维数组在内存中按行连续存储,例如$A[1][0]$在内存中紧跟$A[0][2]$[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白123**

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值