#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#include<math.h>
// 定义一个结构体类型,表示一个矩阵
typedef struct matrix
{
int nrow; // 矩阵的行数
int ncol; // 矩阵的列数
double data[10][10]; // 矩阵的数据,最大为 10 x 10
} matrix;
// 定义一个函数,用于显示一个矩阵的内容
void display_matrix(matrix m)
{
int i,j;
// 用两层循环遍历矩阵的每个元素
for(i=0; i<m.nrow; i++)
{
for(j=0; j<m.ncol; j++)
{
// 打印矩阵的当前元素,保留小数点后六位
printf(" %f",m.data[i][j]);
}
// 换行
printf("\n");
}
}
// 定义一个函数,用于计算一个矩阵的转置
matrix matrix_t(matrix m)
{
int i,j;
matrix c; // 定义一个新的矩阵,用于存储转置结果
c.nrow=m.ncol; // 转置后的矩阵的行数等于原矩阵的列数
c.ncol=m.nrow; // 转置后的矩阵的列数等于原矩阵的行数
// 用两层循环遍历原矩阵的每个元素
for (i = 0; i < m.nrow; i++)
{
for(j = 0; j < m.ncol; j++)
{
// 将原矩阵的第 i 行第 j 列的元素赋值给转置后的矩阵的第 j 行第 i 列
c.data[j][i] = m.data[i][j];
}
}
display_matrix(c); // 调用 display_matrix 函数,显示转置后的矩阵
return c; // 返回转置后的矩阵
}
// 定义一个函数,用于计算两个矩阵的加法
matrix matrix_add(matrix a, matrix b)
{
matrix c; // 定义一个新的矩阵,用于存储加法结果
c.nrow=a.ncol; // 结果矩阵的行数等于两个矩阵的行数
c.ncol=a.nrow; // 结果矩阵的列数等于两个矩阵的列数int i, j;
// 用两层循环遍历两个矩阵的每个元素
for (i = 0; i < a.nrow; i++)
{
for(j = 0; j < a.ncol; j++)
{
// 将两个矩阵的对应元素相加,赋值给结果矩阵的对应位置
c.data[i][j]=a.data[i][j]+b.data[i][j];
}
}
display_matrix(c); // 调用 display_matrix 函数,显示加法结果
return c; // 返回加法结果
}
// 定义一个函数,用于计算两个矩阵的减法
matrix matrix_minus(matrix a, matrix b)
{
matrix c; // 定义一个新的矩阵,用于存储减法结果
c.nrow=a.ncol; // 结果矩阵的行数等于两个矩阵的行数
c.ncol=a.nrow; // 结果矩阵的列数等于两个矩阵的列数int i, j;
// 用两层循环遍历两个矩阵的每个元素
for (i = 0; i < a.nrow; i++)
{
for(j = 0; j < a.ncol; j++)
{
// 将两个矩阵的对应元素相减,赋值给结果矩阵的对应位置
c.data[i][j]=a.data[i][j]-b.data[i][j];
}
}
display_matrix(c); // 调用 display_matrix 函数,显示减法结果
return c; // 返回减法结果
}
// 定义一个函数,用于计算两个矩阵的乘法
matrix matrix_mul(matrix a, matrix b)
{
matrix c; // 定义一个新的矩阵,用于存储乘法结果
c.nrow=a.ncol; // 结果矩阵的行数等于第一个矩阵的行数
c.ncol=b.nrow; // 结果矩阵的列数等于第二个矩阵的列数int i, j,k;
// 用三层循环遍历两个矩阵的每个元素
for (i = 0; i < a.nrow; i++)
{
for(j = 0; j < b.ncol; j++)
{
double tmp=0; // 定义一个临时变量,用于存储乘法的中间结果
for(k=0; k<a.ncol; k++)
// 将第一个矩阵的第 i 行的每个元素与第二个矩阵的第 j 列的每个元素相乘,并累加到临时变量中
tmp+=a.data[i][k]*b.data[k][j];
c.data[i][j]=tmp; // 将临时变量的值赋值给结果矩阵的对应位置
}
}
display_matrix(c); // 调用 display_matrix 函数,显示乘法结果
return c; // 返回乘法结果
}
// 定义一个函数,用于计算一个矩阵的逆
int matrix_inv(matrix m)
{
int i,j;
int ndimen=m.nrow; // 获取矩阵的行数(假设是方阵)
double a_matrix[3][3]; // 定义一个临时的 3 x 3 矩阵,用于存储计算过程中的结果
int k, k1, k2, k3, j2, i2, kme[20], kmf[20]; // 定义一些辅助变量,用于记录矩阵的行列交换
for (i=0;i<ndimen;i++){
for(j=0;j<ndimen;j++)
a_matrix[i][j]=m.data[i][j]; // 将原矩阵的数据复制到临时矩阵中
}
double tmp, tmp2, b_tmp[20], c_tmp[20]; // 定义一些临时变量,用于存储计算过程中的中间值i2 = j2 = 0; // 初始化 i2 和 j2 为 0
for (k = 0; k < ndimen; k++) // 从第 0 行开始,遍历每一行
{
tmp2 = 0.0; // 初始化 tmp2 为 0.0
for (i = k; i < ndimen; i++) // 从第 k 行开始,遍历每一行
{
for (j = k; j < ndimen; j++) // 从第 k 列开始,遍历每一列
{
if (fabs(a_matrix[i][j] ) <= fabs(tmp2)) // 如果当前元素的绝对值小于等于 tmp2
continue; // 跳过当前元素
tmp2 = a_matrix[i][j];//最大值 // 否则,将当前元素赋值给 tmp2,作为最大值
i2 = i; // 记录最大值所在的行号
j2 = j; // 记录最大值所在的列号
}
}
if (i2 != k) // 如果最大值所在的行号不等于 k
{
for (j = 0; j < ndimen; j++) // 遍历每一列
{
tmp = a_matrix[i2][j]; // 交换第 i2 行和第 k 行的元素
a_matrix[i2][j] = a_matrix[k][j];
a_matrix[k][j] = tmp;
}
}
if (j2 != k) // 如果最大值所在的列号不等于 k
{
for (i = 0; i < ndimen; i++) // 遍历每一行
{
tmp = a_matrix[i][j2]; // 交换第 j2 列和第 k 列的元素
a_matrix[i][j2] = a_matrix[i][k];
a_matrix[i][k] = tmp;
}
}
kme[k] = i2; // 记录第 k 次交换的行号
kmf[k] = j2; // 记录第 k 次交换的列号
for (j = 0; j < ndimen; j++) // 遍历每一列
{
if (j == k) // 如果是第 k 列
{
b_tmp[j] = 1.0 / tmp2; // 将最大值的倒数赋值给 b_tmp[j]
c_tmp[j] = 1.0; // 将 1.0 赋值给 c_tmp[j]
}
else // 如果不是第 k 列
{
b_tmp[j] = -a_matrix[k][j] / tmp2; // 将第 k 行第 j 列的元素的相反数除以最大值赋值给 b_tmp[j]
c_tmp[j] = a_matrix[j][k]; // 将第 j 行第 k 列的元素赋值给 c_tmp[j]
}
a_matrix[k][j] = 0.0; // 将第 k 行第 j 列的元素赋值为 0.0
a_matrix[j][k] = 0.0; // 将第 j 行第 k 列的元素赋值为 0.0
}
for (i = 0; i < ndimen; i++) // 遍历每一行
{
for (j = 0; j < ndimen; j++) // 遍历每一列
{
a_matrix[i][j] = a_matrix[i][j] + c_tmp[i] * b_tmp[j]; // 将第 i 行第 j 列的元素加上 c_tmp[i] 乘以 b_tmp[j] 的结果
}
}
}
for (k3 = 0; k3 < ndimen; k3++) // 从第 0 行开始,遍历每一行
{
k = ndimen - k3 - 1; // 计算当前行号的倒序
k1 = kme[k]; // 获取第 k 次交换的行号
k2 = kmf[k]; // 获取第 k 次交换的列号
if (k1 != k) // 如果行号不等于 k
{
for (i = 0; i < ndimen; i++) // 遍历每一行
{
tmp = a_matrix[i][k1]; // 交换第 k1 列和第 k 列的元素
a_matrix[i][k1] = a_matrix[i][k];
a_matrix[i][k] = tmp;
}
}
if (k2 != k) // 如果列号不等于 k
{
for(j = 0; j < ndimen; j++) // 遍历每一列
{
tmp = a_matrix[k2][j]; // 交换第 k2 行和第 k 行的元素
a_matrix[k2][j] = a_matrix[k][j];
a_matrix[k][j] = tmp;
}
}
}
for (i=0;i<ndimen;i++){ // 遍历每一行
for(j=0;j<ndimen;j++) // 遍历每一列
printf(" %f",a_matrix[i][j]); // 打印临时矩阵的元素,保留小数点后六位
printf("\n"); // 换行
}
return (0); // 返回 0,表示函数执行成功
}
// 定义一个函数,用于计算一个矩阵与一个数的乘法
matrix matrix_numMulti(matrix a){
int n; // 定义一个整型变量,用于存储输入的数
matrix c; // 定义一个新的矩阵,用于存储乘法结果
c.nrow=a.nrow; // 结果矩阵的行数等于原矩阵的行数
c.ncol=a.ncol; // 结果矩阵的列数等于原矩阵的列数int i, j;
printf("请输入一个数:"); // 提示用户输入一个数
scanf("%d",&n); // 从标准输入读取一个整数,赋值给 n
for (i = 0; i < a.nrow; i++) // 遍历原矩阵的每一行
{
for(j = 0; j < a.ncol; j++) // 遍历原矩阵的每一列
{
c.data[i][j]=a.data[i][j]*n; // 将原矩阵的第 i 行第 j 列的元素乘以 n,赋值给结果矩阵的对应位置
}
}
display_matrix(c); // 调用 display_matrix 函数,显示乘法结果
return c; // 返回乘法结果}
// 定义一个函数,用于显示程序的功能菜单
void interface()
{
printf("----------------------------————————————————————————————\n");
printf("----------------------------————————————————————————————\n");
printf(" 1.显示A、B矩阵 2.求矩阵A的转置\n"); // 1.显示两个已定义的矩阵 A 和 B,2.计算并显示矩阵 A 的转置
printf(" 3.求两矩阵的和 4.求两矩阵的差\n"); // 3.计算并显示矩阵 A 和 B 的加法结果,4.计算并显示矩阵 A 和 B 的减法结果
printf(" 5.求两矩阵的积 6.求矩阵A的逆\n"); // 5.计算并显示矩阵 A 和 B 的乘法结果,6.计算并显示矩阵 A 的逆
printf(" 7.数乘 8.退出程序 \n"); // 7.提示用户输入一个数,计算并显示矩阵 A 与该数的乘法结果,8.退出程序
printf(" 0.查看程序功能 \n"); // 0.重新显示程序的功能菜单
printf("----------------------------————————————————————————————\n");
printf("----------------------------————————————————————————————\n");
}
int main()
{
//文件读取,int dim1,dim2; int ta[3][3];int tb[3][3];
/*oo.txt 文件
3
1 2 3
5 4 3
6 5 4
3
2 5 4
3 4 5
9 6 4
*/
int dim1,dim2; // 定义一个整型变量,表示矩阵的维度(假设是 3 x 3 的方阵)
int ta[3][3]; // 定义一个二维数组,表示矩阵 A 的数据
int tb[3][3];
int i,j;
FILE *fp;
fp=fopen("oo.txt","r");
if(fp==NULL){
printf("无法打开文件!");
return 0;
}fscanf(fp,"%d",&dim1);
for(i=0;i<3;i++){
for(j=0;j<3;j++){
fscanf(fp,"%d",&ta[i][j]);
}
}
fscanf(fp,"%d",&dim2);
for(i=0;i<3;i++){
for(j=0;j<3;j++){
fscanf(fp,"%d",&tb[i][j]);
}
}
//可输出查看是否成功读取
/* for(i=0;i<3;i++){
for(j=0;j<3;j++){
printf("%d",ta[i][j]);
}
printf("\n");
}
*/
fclose(fp);
matrix a,b; // 定义两个矩阵类型的变量,分别表示矩阵 A 和 B
a.nrow=a.ncol=dim1; // 设置矩阵 A 的行数和列数为 dim
for(i=0; i<a.nrow; i++) // 遍历每一行
{
for(j=0; j<a.ncol; j++) // 遍历每一列
{
a.data[i][j]=(double)(ta[i][j]); // 将二维数组的数据赋值给矩阵 A 的数据
}
}
b.nrow=b.ncol=dim2; // 设置矩阵 B 的行数和列数为 dim
for(i=0; i<b.nrow; i++) // 遍历每一行
{
for(j=0; j<b.ncol; j++) // 遍历每一列
{
b.data[i][j]=tb[i][j]; // 将二维数组的数据赋值给矩阵 B 的数据
}
}interface(); // 调用 interface 函数,显示程序的功能菜单
int choice=0; // 定义一个整型变量,用于存储用户的选择
while(choice>=0&&choice<8) // 当用户的选择在 0 到 7 之间时,循环执行
{
printf("\n请选择:"); // 提示用户选择
scanf("%d",&choice); // 从标准输入读取一个整数,赋值给 choice
switch(choice) // 根据 choice 的值,执行相应的操作
{
case 0: // 如果 choice 为 0
interface(); // 重新显示程序的功能菜单
break; // 跳出 switch 语句
case 1: // 如果 choice 为 1
printf("A:\n"); // 打印 A
display_matrix(a); // 调用 display_matrix 函数,显示矩阵 A
printf("B:\n"); // 打印 B
display_matrix(b); // 调用 display_matrix 函数,显示矩阵 B
break; // 跳出 switch 语句
case 2: // 如果 choice 为 2
printf("A的转置:\n"); // 打印 A 的转置
matrix_t(a); // 调用 matrix_t 函数,计算并显示矩阵 A 的转置
break; // 跳出 switch 语句
case 3: // 如果 choice 为 3
printf("A+B:\n"); // 打印 A + B
matrix_add(a,b); // 调用 matrix_add 函数,计算并显示矩阵 A 和 B 的加法结果
break; // 跳出 switch 语句
case 4: // 如果 choice 为 4
printf("A-B:\n"); // 打印 A - B
matrix_minus(a,b); // 调用 matrix_minus 函数,计算并显示矩阵 A 和 B 的减法结果
break; // 跳出 switch 语句
case 5: // 如果 choice 为 5
printf("AxB:\n"); // 打印 A x B
matrix_mul(a,b); // 调用 matrix_mul 函数,计算并显示矩阵 A 和 B 的乘法结果
break; // 跳出 switch 语句
case 6: // 如果 choice 为 6
printf("A的逆:\n"); // 打印 A 的逆
matrix_inv(a); // 调用 matrix_inv 函数,计算并显示矩阵 A 的逆
break; // 跳出 switch 语句
case 7: // 如果 choice 为 7
printf("A的数乘"); // 打印 A 的数乘
matrix_numMulti(a); // 调用 matrix_numMulti 函数,提示用户输入一个数,计算并显示矩阵 A 与该数的乘法结果
default: // 如果 choice 不在 0 到 7 之间
printf("成功退出!\n"); // 打印退出信息
}
}
return 0; // 返回 0,表示程序正常结束
}