2015-10-04 1 views
1

У меня есть структура, в которой я бы хотел передать свои поля определенным функциям. Например, одно из полей в моей структуре - это оценки викторины студентов для quiz1, 'quiz1'. Я хотел бы рассчитать среднее значение, max и min всех запросов. Я хотел бы создать функцию для каждого вычисления, но я не знаю, как передать конкретное поле структуры данной функции. вот что у меня есть:Передача поля Struct в функцию в C

структура:

struct studentData { 
     char name[30]; 
     int quiz1; int quiz2; 
     int quiz3; int quiz4; 
     int mid1; int mid2; 
     int finalexam; 
    } ; 

средняя функция:

double calcFAverage(struct studentData *record, int reccount) 
{ 
    float sum_F,F_avg; 
    int k; 
      // calculate the score sums 
      for (k=0; k<reccount; k++) 
      { 
       sum_F += record[k].finalexam; 
      } 
      F_avg = sum_F/reccount; 

    return F_avg; 
} 

в основном:

struct studentData record[100]; 
calcFAverage(record,reccount); 

Переменная reccount содержит число записей для структуры. Но, как вы видите, средняя функция специфична только для итоговых экзаменов. Как я могу сделать это так, чтобы я мог передать любое из полей в структуре и получить его среднее значение. Прямо сейчас у меня есть средняя функция для каждого поля, которое действительно является плохим способом сделать это, я думаю.

+0

С чистым C вам нужно передать смещение, чтобы счет можно было получить с помощью '* ((int *) ((char *) & record [k] + offset))'. Если вы используете C++, вы можете передать указатель на член класса, такой как & studentData :: mid1 –

+1

@YakumoRan: есть технический термин для этого предложения: Yuck! –

ответ

2

Ваша структура данных не предназначена для поддержки вычислений, которые вы пытаетесь сделать. Вам нужно перепроектировать структуру. Если вы хотите добавить множество результатов викторины 1, или Окончательных результатов экзамена, то вам нужно что-то больше похоже:

enum { QUIZ1, QUIZ2, QUIZ3, QUIZ4, MID1, MID2, FINAL }; 

struct studentData 
{ 
    char name[30]; 
    int marks[7];  
}; 

и теперь вы можете использовать:

double calcFAverage(struct studentData *record, int n_recs, int markid) 
{ 
    double sum_F = 0.0 
    // calculate the score sums 
    for (int k = 0; k < n_recs; k++) 
     sum_F += record[k].marks[markid]; 

    double F_avg = sum_F/n_recs; 

    return F_avg; 
} 

И называть его :

double ave = calculateFAverage(students, n_students, FINAL); 
+2

Отличный ответ. Чистота, удобочитаемость, удобство в обслуживании, расширяемость - без подхалима. – clearlight

0

Как комментарий Yakumo, используйте выравнивание данных. Другой, возможно, лучший вариант - поместить оценки в массив, как и другой ответ. Например:

int quiz1offset = (int)(&(record[0].quiz1)) - (int)(record);//This is the location of quiz1 relative to the location of its struct 

average(records,reccount,quiz1offset); 


double average(struct studentData *record, int reccount, int offset) 
{ 
double sum,avg; 
int k; 
     // calculate the score sums 
     for (k=0; k<reccount; k++) 
     { 
      sum += *(int *)((int)(record+k) + offset); 
      //equivalent form is sum += *(int *)((int)&record[k] + offset); 
     } 
     avg = sum/reccount; 

return avg; 
} 
+1

Это неудобный завышенный подход. В простых случаях, подобных этому, такие подходы обычно являются признаком того, что они недостаточно хорошо разработаны. – clearlight

 Смежные вопросы

  • Нет связанных вопросов^_^