0

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

现在我有一组从结构统计返回值的函数,这与我需要的相反。

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);
}
4

3 回答 3

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);
}

您将希望函数序列化(写入文件)和反序列化(从文件读取)。

于 2013-11-08T20:39:26.340 回答
0

这不是一个完整的答案,而是专门针对函数定义部分解决您上面的问题,如果我需要为单打+双打做加法

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

你真的可以自由地在你的结构中声明和使用数据的许多变体。通常情况下,不会编写像 this 这样的特定函数,而是将指向结构的指针传递给工作函数,成员将用于提供值或接收值,然后使用 new 返回给调用函数信息。我真的认为看看@ChuckCottrill 的答案(在同一篇文章中)值得你花时间。

于 2013-11-08T20:36:47.480 回答
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;
}
于 2013-11-08T20:15:34.080 回答