一个函数传递整数统计信息并返回包含结果的结构

时间:2013-11-08 20:03:47

标签: c

我需要帮助编写一个传递输入值的函数,并返回一个包含calculate_TB,calculate_TB等结果的结构

现在我有一组函数可以从struct stats返回值,这与我需要的相反。

struct stats

{
    int singles;
    int doubles;
    int triples;
    int home_runs;
    int at_bats;
    int hits;
    int BA;
    int TB;
    int HR_ratio;
    int SA;
};

........功能................

int main()
{


    int i, hits;



    hits_number=calculate_hits_number(sta);

    /* calling function  */
    calculate_TB(sta);


    calculate_BA(sta);


    calculate_HR_ratio(sta);


    calculate_SA(sta);



     /* printing the output using arrays */

    printf("%6d",hits_number);
    printf("\t\t\t%6d", sta.TB);
    printf("\t\t\t\t%6d", sta.BA);
    printf("\t\t\t\t%6d",sta.HR_ratio);
    printf("\t\t\t\t%6d", sta.SA);
    printf("\n");

 return (0);
}

3 个答案:

答案 0 :(得分:2)

你基本上想要一个构造函数

定义你的类型,

typedef struct stats
{
    //char playername[100]; //you probably want a place to record player names...
    int singles;
    int doubles;
    int triples;
    int home_runs;
    int walks;
    int be; //base on error
    int Ko; //strikeout
    int go; //groundout
    int fo; //flyout
    int sc; //sacrifice out
    int rbi;  //runs batted in, reflects scoring, sacrifices, etc
    int at_bats;
    //calculated
    int hits;
    float BA;
    float OBP;
    float PWR;
    float HR_ratio;
    int TB;
    int SA;
} StatObj;

现在您需要创建/初始化StatObj。有些语言称之为构造函数,

StatObj* StatNew() //maybe pass playername?
{
    StatObj* so = malloc(sizeof(StatObj));
    //recorded
    so->singles = 0;
    so->doubles = 0;
    so->triples = 0;
    so->homeruns = 0;
    so->walks   = 0;
    so->at_bats = 0;
    so->be      = 0; //base on error
    so->ko      = 0; //strikeout
    so->go      = 0; //groundout
    so->fo      = 0; //flyout
    so->sc      = 0; //sacrificeout
    so->rbi     = 0; //runs batted in, reflects scoring, sacrifices, etc
    //calculated
    so->hits    = 0;
    so->BA      = 0.0;
    so->PWR     = 0.0;
    so->OBP     = 0.0;
    so->HR_ratio = 0.0;
    so->TB      = 0;
    so->SA      = 0;
    //what about walks, HBP (hit by pitch), BoE (base on error) OBP (on base pct)?
    return so;
}

您需要一个功能来(重新)计算您的统计数据。

void calculate(StatObj* sta)
{
    int hits, onbase;
    float power;
    if(!sta) return;
    hits = sta->singles + sta->doubles + sta->triples + sta->homeruns;
    onbase = hits + sta->walks + sta->be;
    power = (sta->singles + 2*sta->doubles + 3*sta->triples + 4*sta->homeruns)
    //what about sacrifices?
    //calculate other stats as you define them
    sta->hits = hits;
    sta->BA = (hits*1.0)/(sta->at_bats*1.0);
    sta->OBP = (onbase*1.0)/(sta->at_bats*1.0);
    sta->PWR = (power*1.0)/(sta->at_bats*1.0);
    HR_ratio = (sta->homeruns*1.0)/(sta->at_bats*1.0);
    //sta->TB;
    //sta->SA;
}

int StatPrint(StatObj* sta)
{
    if(!sta) return;
    /* printing the output using arrays */
    printf("%6d",sta->hits);
    printf("BA\t\t\t\t%6.4f", sta->BA);
    printf("OBP\t\t\t\t%6.4f", sta->OBP);
    printf("TB\t\t\t%6f", sta->TB);
    printf("PWR\t\t\t\t%6.4f",sta->PWR);
    printf("HR%\t\t\t\t%6.4f",sta->HR_ratio);
    printf("SA\t\t\t\t%6.4f", sta->SA);
    printf("\n");
    //et cetera
}

您需要一个功能来记录每个atbat和结果。您可以将每个atbat的结果作为符号/值传递,然后更新原始统计信息。然后你可以有一个功能来(重新)计算你的统计数据。这是record_atbat函数,

// 1 single, 2 double, 3 triple, 4 homerun
// x strikeout, k strikeout, e error, w walk
// f - flyout, g - groundout, s - sacrifice, ...
// do you want to record double play? triple play?
void record_atbat( StatObj* sta, int ab, int result, int rbi )
{
    if(!sta) return;
    sta->at_bats++;
    sta->rbi += rbi;
    switch(result)
    {
    case 1: case '1':
        sta->singles++;
        break;
    case 2: case '2':
        sta->doubles++;
        break;
    case 3: case '3':
        sta->triples++;
        break;
    case 4: case '4':
        sta->homeruns++;
        break;
    case 'w':
        sta->walks++;
        break;
    case 'e':
        sta->be++;
        break;
    // k/x=strikeout, f=flyout, g=groundout, s=sacrifice, ...
    case 'k': case 'x':
        sta->ko++;
        break;
    case 'f':
        sta->fo++;
        break;
    case 'g':
        sta->go++;
        break;
    case 's':
        sta->sc++;
        break;
    //base on error, affects on-base percentage
    default:
        break;
    }
    calculate(sta); //keep stats current
}

您需要创建至少一个StatObj实例

int main()
{
    int i, hits;

    StatObj* sta = StatNew();  //you could create an array of these, one per player
    //StatObj* players[100];   //you probably want to record a bunch of players...

    record_atbat( sta, 1, 0 ); //single
    record_atbat( sta, 'k', 0 ); //strikeout
    record_atbat( sta, 2, 1 ); //double
    record_atbat( sta, 'w', 0 ); //walk
    record_atbat( sta, 'k', 0 ); //strikeout

    hits_number=calculate_hits_number(sta);
    /* calling function  */
    calculate(sta);

    StatPrint(sta);

    return (0);
}

您将需要函数序列化(写入文件)和反序列化(从文件中读取)。

答案 1 :(得分:0)

我不确定我理解你的问题,但你只是想要一个函数从一堆参数初始化你的结构并自动调用calculate_XX吗?如果是这样,请看一下:

typedef struct stats stats;

stats *your_function(int your_arguments) {

    stats *mystruct = malloc(sizeof(stats));
    if(!mystruct)
        // Initialisation failed, do something.

    mystruct->whatever_field = your_arguments;
    // ...
    mystruct->BA = calculate_BA(arguments_for_this);
    // ...
    return mystruct;
}

答案 2 :(得分:0)

这不是一个完整的答案,但如果我需要为单曲+双打添加,请专门解决上面函数定义部分的问题:

int singles_plus_doubles(struct stats temp)
{
   return temp.singles+temp.doubles;
}

您可以自由地声明并使用结构中的多种数据变体。通常,编写这样一个特定的函数没有完成,而是一个指向结构的指针将传递给一个工作函数,成员将用于提供值,或接收值,然后返回到调用函数new信息。我真的认为看看@ ChuckCottrill的答案( in this same post )是值得的。