6-13 函式指標(理科實驗班)

yesno233233發表於2024-03-09

6-13 函式指標(理科實驗班)

分數 10
作者 何振峰
單位 福州大學
夢山高中現需要將某普通班的最優秀學生調整入理科實驗班。為此,將從兩個方面考察學生,一是數學和英語兩門課的總分;另一個是所有四門課的總分。分別找出兩科總分和全科總分的第一名,並從中決定調整人選。

輸入將首先輸入學生數n, (n為不超過80的正整數);接下來依次輸入各位學生的學號,數學、英語、語文、理科綜合成績。學號及四科成績均為不超過300的正整數。

輸出時:第一行輸出兩科總分第一的學號,第二行輸出四科總分第一的學號。 約定在兩位學生成績相同時,優先選擇學號較小的學生;各位學生的學號均不相同。

裁判測試程式樣例:

#include <iostream>
using namespace std;
const int N=80;
struct Student{
  int num;
  int score[4];
};

/* 請在這裡填寫答案 */

int main()
{
  int i, j, k, n;
  bool s2(const Student &, const Student &);
  bool s4(const Student &, const Student &);
  Student st[N];
   cin>>n;
   for(i=0;i<n;i++){
      cin>>st[i].num;
      for(j=0;j<4;j++) cin>>st[i].score[j];
    }
   cout<<select(st, n, s2)<<endl;
   cout<<select(st, n, s4)<<endl;
}

輸入樣例:

3
6 148 150 120 252
5 148 150 117 260
7 145 148 128 287

輸出樣例:

5
7

程式碼長度限制
16 KB
時間限制
400 ms
記憶體限制
64 MB

參考程式碼

bool s2(const Student &a, const Student &b) //為了給select函式返回true或false
{
    // 比較數學和英語兩門課的總分
    int sumA = a.score[0] + a.score[1];
    int sumB = b.score[0] + b.score[1];
    if (sumA == sumB) return a.num < b.num; // 分數相同,學號小的優先,如果a學號小於b,即a排名前於b,返回true
    return sumA > sumB; // 分數高的優先,若a排名前於b,返回true
}

bool s4(const Student &a, const Student &b) //為了給select函式返回true或false
{
    // 比較所有四門課的總分
    int sumA = a.score[0] + a.score[1] + a.score[2] + a.score[3];
    int sumB = b.score[0] + b.score[1] + b.score[2] + b.score[3];
    if (sumA == sumB) return a.num < b.num; // 分數相同,學號小的優先,如果a學號小於b,即a排名前於b,返回true
    return sumA > sumB; // 分數高的優先,若a排名前於b,返回true
}

int select(Student st[], int n, bool (*compare)(const Student&, const Student&)) {
    int idx = 0; // 記錄當前最優秀學生的索引
    for (int i = 1; i < n; i++) {
        if ( compare(st[i], st[idx]) ) //如果st[i]排名前於st[idx],返回ture,更新索引
        {
            idx = i; // 更新最優秀學生的索引
        }
    }
    return st[idx].num; // 返回最優秀學生的學號
}

函式指標知識

在C++中,函式指標是一種特殊的指標,它指向函式而不是變數。函式指標可以用於呼叫函式,也可以作為引數傳遞給其他函式。這在實現回撥函式或策略模式時非常有用。

bool (*compare)(const Student&, const Student&)是一個函式指標的宣告。讓我們分解這個宣告以更好地理解它:

bool 表示這個函式返回一個布林值(truefalse)。

(*compare) 是函式指標的名稱,即 compare。括號(*) 表明這是一個指標。

(const Student&, const Student&) 表示這個函式接受兩個引數,每個引數都是對 Student 型別物件的常量引用。使用常量引用(const T& ,T表示所引用物件的型別)可以避免複製大型物件,並確保函式不會修改這些物件。

整個表示式 bool (*compare)(const Student&, const Student&) 宣告瞭一個名為 compare 的函式指標,它指向一個接受兩個 Student 型別的常量引用作為引數,並返回布林值的函式。

在上下文中,這種函式指標用於比較兩個 Student 物件。例如,你可以定義多個比較函式(比如按照兩科總分比較、四科總分比較等),然後根據需要將這些函式的地址作為引數傳遞給 select 函式。select 函式透過呼叫傳遞給它的比較函式來決定哪個 Student 物件是“最優”的。

這種方式提供了極大的靈活性,因為你可以在不改變 select 函式實現的情況下,透過傳遞不同的比較函式來改變選擇標準。這是一種實現多型行為的技巧,允許在執行時決定使用哪個函式。

相關文章