首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

C 程式移植至 Visual C++ 6.0 整合開發環境完整指南

     編輯:關於VC++

前言

大量經驗證的 C 算法程式碼 (如《C 常用算法程式集》) 為工程應用提供寶貴資產。但舊式 C 碼與現代編譯器常有不相容處,需系統性移植。本文以該書前 15 章數值計算程式為例,示範移植技巧並提供 C++ 陣列/矩陣模板類封裝。

一、ANSI C 相容性修正

1. 函數參數宣告現代化

// 舊式 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);  // 二維陣列傳首元素位址

2. malloc 回傳值強制轉型

double* v = (double*)malloc(n * m * sizeof(double));  // ANSI C 要求

3. 回呼函數參數化 (函數指標)

// 原寫法: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);

4. 控制台輸出導向字串緩衝區

char* buffer = (char*)malloc(n * sizeof(char));
sprintf(buffer, "%c", xy[i][j]);
strcat(str, buffer);  // 累積至字串
// 最後 free(buffer)

二、C++ 物件導向封裝與強健化

痛點

  • C 缺乏異常處理機制
  • 陣列邊界檢查缺失,易造成不可預期錯誤

解決方案:模板類別封裝

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

三、成果與優勢

圖一:演示程式介面 (左:演算法目錄樹, 右:計算結果, 下:原始碼視窗)

  • 符合 ISO C/C++ 標準,跨平台可移植
  • 改善原程式擴充性與彈性不足
  • 修正數個效能 Bug
  • 加入異常處理與邊界檢查,大幅提升可除錯性與健壯度
  • 陣列/矩陣操作獲得強力支援,語法自然 (mat[i][j])

結語

移植後的程式庫滿足一般工程數值計算需求,並為後續擴充奠定堅實基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved