大量經驗證的 C 算法程式碼 (如《C 常用算法程式集》) 為工程應用提供寶貴資產。但舊式 C 碼與現代編譯器常有不相容處,需系統性移植。本文以該書前 15 章數值計算程式為例,示範移植技巧並提供 C++ 陣列/矩陣模板類封裝。
// 舊式 K&R 風格
int agaus(a, b, n) int n; double a[], b[]; { ... }
// 修正為 ANSI 原型
int agaus(double a[], double b[], int n);
// 或指標形式
int agaus(double* a, double* b, int n);
// 呼叫方式
agaus(&a[0][0], &b[0], n); // 二維陣列傳首元素位址
double* v = (double*)malloc(n * m * sizeof(double)); // ANSI C 要求
// 原寫法:extern double hremzf(); 耦合度高
// 改為函數指標參數
void hremz(double a, double b, double p[], int n, double eps,
double (*hremzf)(double x));
// 呼叫
hremz(a, b, p, 4, eps, hremzf);
char* buffer = (char*)malloc(n * sizeof(char));
sprintf(buffer, "%c", xy[i][j]);
strcat(str, buffer); // 累積至字串
// 最後 free(buffer)
template
class TArray {
protected:
T* pdata; unsigned int length;
public:
TArray(); TArray(unsigned int); TArray(const TArray&);
virtual ~TArray();
TArray& operator=(TArray&);
TArray& operator+(TArray&); TArray& operator-(TArray&);
const T& operator[](unsigned int) const;
T& operator[](unsigned int); // 含邊界檢查
const T* GetData() const;
unsigned int GetLength();
void SetLength(unsigned int, bool = true);
};
template
class TMatrix {
protected:
unsigned int rows, cols;
TArray array;
public:
class Row { // 巢狀類別支援 mat[i][j] 雙下標
TMatrix& matrix; unsigned int row;
public:
Row(TMatrix& m, unsigned int r) : matrix(m), row(r) {}
T& operator[](unsigned int col) const
{ return matrix.Select(row, col); }
};
TMatrix(); TMatrix(unsigned int, unsigned int);
TMatrix(const TMatrix&); virtual ~TMatrix();
T& Select(unsigned int, unsigned int); // 核心存取含邊界檢查
Row& operator[](unsigned int);
// 矩陣運算子 +, -, *, == 等
bool LoadFromArray(T[], unsigned int, unsigned int);
bool LoadFromString(char*, char, char);
bool ResetMatrix(unsigned int, unsigned int);
bool ReverseMatrix();
void ZeroMatrix(); void RandomMatrix(int max);
};
template
T& TMatrix::Select(unsigned int i, unsigned int j) {
char msg[50];
if (i >= rows) sprintf(msg, "Error -- Invalid row: %d", i), throw(msg);
if (j >= cols) sprintf(msg, "Error -- Invalid colum: %d", j), throw(msg);
return array[i * cols + j];
}
// 應用端
try {
TMatrix<> mat(2, 3);
for (i = 0; i < 2; i++)
for (j = 0; j < 4; j++) // 故意越界 j < 4
cout << mat[i][j] << "\t";
}
catch (char* str) { cout << str << endl; }
// 輸出:
// ... Error -- Invalid colum: 3

圖一:演示程式介面 (左:演算法目錄樹, 右:計算結果, 下:原始碼視窗)
移植後的程式庫滿足一般工程數值計算需求,並為後續擴充奠定堅實基礎。