#include <stdio.h>
#include <math.h>
void swap(int n, double A[][100], double b[], int r, int k);
void Eliminate(int n, double A[][100], double b[]);
void Substitude(int n, double A[][100], double b[], double x[]);
//以下程序为了和通常所说的矩阵第一行第一列适应,舍去第零行第零列
//若需要从第零行第零列开始储存,请修改各个循环初始条件与中止条件 (i = 1; ;i <= n) => (i = 0; ; i < n)
int main() {
int n;
double A[100][100] = {}, b[100] = {}, x[100] = {};
scanf("%d", &n); //读入矩阵大小 n , 增广矩阵 (A|b)
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%lf", &A[i][j]);
}
scanf("%lf", &b[i]);
}
Eliminate(n, A, b);
Substitude(n, A, b, x);
//输出解向量
for (int i = 1; i <= n; i++) {
printf("%lf ", x[i]);
}
}
void swap(int n, double A[][100], double b[], int r, int k) {
//交换增广矩阵 (A|b) 之 r,k 两行
for (int i = 1; i <= n; i++)
{
double temp = A[r][i];
A[r][i] = A[k][i];
A[k][i] = temp;
}
double temp = b[r];
b[r] = b[k];
b[k] = temp;
}
void Eliminate(int n, double A[][100], double b[]) {
//消元
for (int k = 1; k <= n - 1; k++) {
//选择主元
int r = k;
double max = A[k][k];
for (int i = k; i <= n - 1; i++)
{
if (A[i + 1][k] >= A[i][k])
{
max = A[i + 1][k];
r = i + 1;
}
}
//若主元行与操作行不同,交换两行
if (k != r)
{
swap(n, A, &b[0], k, r);
}
//消元
for (int i = k + 1; i <= n; i++)
{
double l = A[i][k] / A[k][k];
b[i] = b[i] - l * b[k];
for (int j = k; j <= n; j++)
{
A[i][j] = A[i][j] - l * A[k][j];
}
}
}
}
void Substitude(int n, double A[][100], double b[], double x[]) {
//回代
for (int i = n; i > 0; i--)
{
double s = 0.0;
for (int j = n; j > i; j--)
{
s += A[i][j] * x[j];
}
x[i] = (b[i] - s) / A[i][i];
}
}
今天在写列主消元法的代码时候一直结果不对,代码调半天,后来才发现原来其中二维数组传参发生错误,函数对于数组的操作并没有作用到目标矩阵上
错误写法
void swap(int n, double A[][100], double b[], int r, int k) {
//交换增广矩阵 (A|b) 之 r,k 两行
for (int i = 1; i <= n; i++)
{
double temp = A[r][i];
A[r][i] = A[k][i];
A[k][i] = temp;
}
double temp = b[r];
b[r] = b[k];
b[k] = temp;
}
//调用方式错误
swap(n, &A[100], &b[0], k, r);
正确写法
void swap(int n, double A[][100], double b[], int r, int k) {
//交换增广矩阵 (A|b) 之 r,k 两行
for (int i = 1; i <= n; i++)
{
double temp = A[r][i];
A[r][i] = A[k][i];
A[k][i] = temp;
}
double temp = b[r];
b[r] = b[k];
b[k] = temp;
}
//调用方式正确
swap(n, A, &b[0], k, r);
注意:二维矩阵函数传参方式有多种,本文仅针对一种,详情见其他博客