簡體   English   中英

C編程的好習慣與否?

[英]C programming good practice or not ?

我已經寫了一小段代碼來計算二次方程式,但是如果判別式為負,我希望它寫出該二次方程式沒有實際數值。 為了實現這一點,我必須調用第四個參數為0的函數,我認為我不知道為什么,這將是不好的編程習慣? 是這種情況還是我只是過於挑剔我的代碼? 謝謝。 (我之所以這樣問,是因為我不想在編程的“職業生涯”初期就養成不良習慣)。 這是代碼。

#include <stdio.h>
#include <math.h>
#include <string.h>

double quadratic_equation(double a, double b, double c, double d);

int main(void)
{
    char command[20];
    int i;

    printf("Enter your command: ");
    fgets(command, 20, stdin);

    for (i = 0; i < 20; i++) {
        if (command[i] == '\n') {
            command[i] = '\0';
            break;
        }
    }

    if (strcmp(command, "quadratic equation") == 0) {
        double a, b, c, x;

        printf("Enter A: ");
        scanf("%lf", &a);
        printf("Enter B: ");
        scanf("%lf", &b);
        printf("Enter C: ");
        scanf("%lf", &c);

        x = quadratic_equation(a, b, c, 0); // THIS PIECE HERE MIGHT BE BAD PRACITCE ? 

        if (x == 0) {
            printf("There are no real numerical values to this quadratic equation.");
        }

        else {
            printf("------------\n");
            printf("x1 = %.2f\n", quadratic_equation(a, b, c, 1));
            printf("x2 = %.2f", quadratic_equation(a, b, c, -1));
        }
    }

    return 0;
}

double quadratic_equation(double a, double b, double c, double d) {
    double discriminant, x, insideroot;

    insideroot = ((b*b) - (4*a*c));

    if (insideroot < 0) {
        return 0;
    }

    discriminant = sqrt(insideroot);
    x = (-b + (d * discriminant)) / (2 * a);

    return x;
}

非常感謝您的幫助:d!

這當然是不好的做法。 由於公式abc的根是任意double確實需要某種傳遞。

我建議使用一個指向int的指針的參數。 如果指針為NULL則將其忽略,否則將根據實際根是否存在將其設置為1或0:

double quadratic_equation(double a, double b, double c, int *root_exists) {
    double discriminant;

    discriminant = ((b*b) - (4*a*c));

    if (discriminant < 0) {
        if (root_exists != NULL) *root_exists = 0;
        return 0.0;
    }

    x = (-b + sqrt(discriminant)) / (2 * a);

    if (root_exists != NULL) *root_exists = 1;

    return x;
}

一個更嚴格的方法是這樣的:

typedef struct {
    int num_roots;
    double roots[2];
} quadratic_roots_t;

quadratic_roots_t quadratic_equation(double a, double b, double c) {
    quadratic_roots_t roots;
    double d;

    d = b*b - 4*a*c;

    if (d < 0.0) {
        roots.num_roots = 0;
    } else if (d == 0.0) {
        roots.num_roots = 1;
        roots.roots[0] = -b / (2 * a);
    } else {
        roots.num_roots = 2;
        roots.roots[0] = (-b - sqrt(d)) / (2 * a);
        roots.roots[1] = (-b + sqrt(d)) / (2 * a);
    }

    return roots;
}

我會說這不是一件好事。 您可以做的是這樣的:

int quadratic_equation(double a, double b, double c, double *root_a, double *root_b) {
    double discriminant = ((b*b) - (4*a*c));

    if (discriminant < 0) {
        return -1;
    }

    if (root_a != NULL) {
        *root_a = (-b + sqrt(discriminant)) / (2 * a);
    }
    if (root_b != NULL) {
        *root_b = (-b - sqrt(discriminant)) / (2 * a);
    }

    return 0;
}

然后您可以這樣稱呼:

double root_a;
double root_b;
int ok = quadratic_equation(a, b, c, &root_a, &root_b);
if (ok < 0) {
    // It wasn't OK. Print out an error.
} else {
    // It was OK. Print out the results.
}

請注意,您還應該檢查函數中的其他錯誤情況,並為其返回-1。 例如a為零。

考慮使用返回值指示是否一切正常,並將數組傳遞給函數以接收返回值:

enum QE_Status { QE_OK = 0, QE_NON_QUADRATIC, QE_COMPLEX_ROOTS, QE_NULL_POINTER };

enum QE_Status quadratic_equation(double a, double b, double c, double *r)
{
    double discriminant;

    if (r == 0)
        return QE_NULL_POINTER;
    if (a == 0.0)
        return QE_NON_QUADRATIC;

    discriminant = (b * b) - (4 * a * c);

    if (discriminant < 0)
        return QE_COMPLEX_ROOTS;

    discriminant = sqrt(discriminant);
    r[0] = (-b + discriminant) / (2 * a);
    r[1] = (-b - discriminant) / (2 * a);
    return QE_OK;
}

您可以擴展系統以處理數值不穩定性(因為b*b幾乎等於4*a*c ,或者因為a很小,等等)。

調用代碼可以是:

 double a, b, c, x[2];

 if (quadratic_equation(a, b, c, x))
     ...oops, something went wrong...

要么:

 switch (quadratic_equation(a, b, c, x))
 {
 case QE_OK:
     ...print or use results in x...
     break;
 case QE_NON_QUADRATIC:
 case QE_COMPLEX_ROOTS:
     ...print appropriate error message about user's data...
     break;
 case QE_NULL_POINTER:
     ...Oops - programming error...
     break;
 }

我肯定會稱其為不好的做法,因為代碼非常不清楚。

首先,您將調用該函數三次,一次應足夠。

我會考慮在您的quadratic_equation()函數中返回/填充列表,而不是一一返回根。

這也可以讓您確定是否存在真正的根-如果沒有,僅返回一個空列表。

總體而言,這將比您當前的解決方案優雅得多,並且無需事先檢查是否有任何解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM