Mini Project — Student Grade Manager
0%
Mini Project  ·  Functions + Arrays

Student Grade
Manager

A complete mini project using functions, arrays, and strings. Enter marks for 5 students across 5 subjects — the program computes totals, averages, grades, and finds the class topper.

7
Functions
~80
Lines of code
5
Concepts used
Real
Useful program
§1

What We Are Building

Project overview

A Student Grade Manager for a class of 5 students with 5 subjects each. The program will:

  • Store 5 student names and their marks in 5 subjects
  • Calculate each student's total marks and average
  • Assign a letter grade (A, B, C, D, F) based on the average
  • Find the class topper — the student with the highest average
  • Find the highest and lowest mark in the entire class
  • Print a neat formatted report card table

Each of these jobs is a separate function. That's the key — split the work into small pieces, one function per job.

Concepts used in this project:

  • 1D arrays — store totals, averages, one value per student
  • 2D arrays — marks[5][5] — row = student, column = subject
  • 2D string array — names[5][20] — store 5 student names
  • Functions — 7 functions, each doing one job
  • Loops — nested loops to process every mark in the grid
project structure
§2

Project Structure — 7 Functions

Plan before coding

Before writing any code, plan which functions you need. Good rule: one function = one job. If a function does two different things, split it into two functions.

The 7 functions in this project
main()
Calls all other functions in order. The director — no calculations here.
inputData()
Reads all student names and marks from the user. Fills the arrays.
calcTotals()
Computes total marks for each student. Stores in totals[] array.
calcAverages()
Divides each total by 5 (subjects). Stores in avg[] array.
getGrade()
Takes one average, returns the letter grade A/B/C/D/F.
findTopper()
Scans avg[] and returns the index of the highest average.
Why plan first? When you write the plan, you see that getGrade() only needs one number (the average) and gives back one character. That's a simple, clean function. Planning stops you from writing one huge messy function that does everything.
the complete program
§3

Complete Program — Read Every Line

Full source code
student_grade_manager.c
C
#include <stdio.h>
#include <string.h>

/* ── Constants ─────────────────────────────────────────── */
#define STUDENTS 5
#define SUBJECTS 5

/* ── Global arrays — shared by all functions ─────────── */
char  names[STUDENTS][20];        /* student names */
int   marks[STUDENTS][SUBJECTS];   /* marks grid */
int   totals[STUDENTS];            /* total per student */
float avg[STUDENTS];               /* average per student */

/* ── Function prototypes ─────────────────────────────── */
void  inputData(void);
void  calcTotals(void);
void  calcAverages(void);
char  getGrade(float average);
int   findTopper(void);
void  printReport(void);

/* ═══════════════════════════════════════════════════════
   MAIN — calls functions in order, does nothing itself
═══════════════════════════════════════════════════════ */
int main() {
    printf("=== STUDENT GRADE MANAGER ===\n\n");

    inputData();       /* Step 1: get names and marks */
    calcTotals();      /* Step 2: add up each student's marks */
    calcAverages();    /* Step 3: divide to get averages */
    printReport();     /* Step 4: show the report card */

    return 0;
}

/* ═══════════════════════════════════════════════════════
   INPUT — reads all student names and marks
═══════════════════════════════════════════════════════ */
void inputData(void) {
    int i, j;
    char subjects[SUBJECTS][10] = {
        "Maths", "Science", "English", "History", "C Prog"
    };

    for (i = 0; i < STUDENTS; i++) {
        printf("Student %d name: ", i + 1);
        scanf("%s", names[i]);

        printf("Enter marks for %s:\n", names[i]);
        for (j = 0; j < SUBJECTS; j++) {
            printf("  %-10s: ", subjects[j]);
            scanf("%d", &marks[i][j]);
        }
        printf("\n");
    }
}

/* ═══════════════════════════════════════════════════════
   CALC TOTALS — adds up all marks for each student
═══════════════════════════════════════════════════════ */
void calcTotals(void) {
    int i, j;
    for (i = 0; i < STUDENTS; i++) {
        totals[i] = 0;
        for (j = 0; j < SUBJECTS; j++)
            totals[i] += marks[i][j];
    }
}

/* ═══════════════════════════════════════════════════════
   CALC AVERAGES — divides total by number of subjects
═══════════════════════════════════════════════════════ */
void calcAverages(void) {
    int i;
    for (i = 0; i < STUDENTS; i++)
        avg[i] = (float)totals[i] / SUBJECTS;
}

/* ═══════════════════════════════════════════════════════
   GET GRADE — takes average, returns A/B/C/D/F
═══════════════════════════════════════════════════════ */
char getGrade(float average) {
    if      (average >= 90) return 'A';
    else if (average >= 75) return 'B';
    else if (average >= 55) return 'C';
    else if (average >= 35) return 'D';
    else                     return 'F';
}

/* ═══════════════════════════════════════════════════════
   FIND TOPPER — returns index of student with highest avg
═══════════════════════════════════════════════════════ */
int findTopper(void) {
    int i, topIdx = 0;
    for (i = 1; i < STUDENTS; i++)
        if (avg[i] > avg[topIdx])
            topIdx = i;
    return topIdx;
}

/* ═══════════════════════════════════════════════════════
   PRINT REPORT — formatted report card table
═══════════════════════════════════════════════════════ */
void printReport(void) {
    int   i, j, topIdx;
    int   highest = marks[0][0], lowest = marks[0][0];

    /* ── Find highest and lowest mark in class ───────── */
    for (i = 0; i < STUDENTS; i++)
        for (j = 0; j < SUBJECTS; j++) {
            if (marks[i][j] > highest) highest = marks[i][j];
            if (marks[i][j] < lowest)  lowest  = marks[i][j];
        }

    /* ── Print header ────────────────────────────────── */
    printf("\n");
    printf("============================================================\n");
    printf("               STUDENT REPORT CARD\n");
    printf("============================================================\n");
    printf("%-12s  M1  M2  M3  M4  M5  Total   Avg  Grade\n", "Name");
    printf("------------------------------------------------------------\n");

    /* ── Print each student row ──────────────────────── */
    for (i = 0; i < STUDENTS; i++) {
        printf("%-12s", names[i]);
        for (j = 0; j < SUBJECTS; j++)
            printf("%4d", marks[i][j]);
        printf("  %5d  %6.1f    %c\n",
               totals[i], avg[i], getGrade(avg[i]));
    }

    /* ── Summary ─────────────────────────────────────── */
    printf("------------------------------------------------------------\n");
    topIdx = findTopper();
    printf("Class Topper : %s  (%.1f avg)\n", names[topIdx], avg[topIdx]);
    printf("Highest Mark : %d\n", highest);
    printf("Lowest Mark  : %d\n", lowest);
    printf("============================================================\n");
}
sample output
§4

Sample Run — What It Looks Like

Full program output
terminal — sample run with 5 students
output
=== STUDENT GRADE MANAGER ===

Student 1 name: Ananta
Enter marks for Ananta:
  Maths     : 85
  Science   : 90
  English   : 78
  History   : 88
  C Prog    : 95

Student 2 name: Priya
Enter marks for Priya:
  Maths     : 92
  Science   : 88
  English   : 95
  History   : 82
  C Prog    : 90

Student 3 name: Rahul
Enter marks for Rahul:
  Maths     : 60
  Science   : 55
  English   : 70
  History   : 65
  C Prog    : 58

Student 4 name: Vikram
Enter marks for Vikram:
  Maths     : 78
  Science   : 82
  English   : 75
  History   : 88
  C Prog    : 80

Student 5 name: Sneha
Enter marks for Sneha:
  Maths     : 96
  Science   : 94
  English   : 98
  History   : 92
  C Prog    : 97

============================================================
               STUDENT REPORT CARD
============================================================
Name          M1  M2  M3  M4  M5  Total    Avg  Grade
------------------------------------------------------------
Ananta        85  90  78  88  95    436    87.2    B
Priya         92  88  95  82  90    447    89.4    B
Rahul         60  55  70  65  58    308    61.6    C
Vikram        78  82  75  88  80    403    80.6    B
Sneha         96  94  98  92  97    477    95.4    A
------------------------------------------------------------
Class Topper : Sneha  (95.4 avg)
Highest Mark : 98
Lowest Mark  : 55
============================================================
how each function works
§5

Each Function Explained

Line by line

inputData() — outer loop runs 5 times (one per student). For each student: read their name with scanf("%s", names[i]), then the inner loop reads 5 marks into marks[i][0] through marks[i][4]. The local subjects[] array is just for the prompt labels.

calcTotals() — nested loop. Outer: student index i. First set totals[i] = 0. Inner: add each of the 5 subject marks. Result: totals[0] = Ananta's total, totals[1] = Priya's total, etc.

calcAverages() — simple loop. Divides each total by SUBJECTS (5). The cast (float)totals[i] is important — without it, integer division would give 87 instead of 87.2.

getGrade(float average) — the cleanest function. Takes one number, returns one character. A chain of if-else if checks which range the average falls in. Called once per student inside printReport().

findTopper() — starts by assuming student 0 is the topper (topIdx = 0). Loops through students 1–4. If any student's average beats the current best, update topIdx. Returns the index — not the name, not the average. The caller uses the index to look up whatever they need.

printReport() — the only function that prints. First finds highest and lowest marks using a nested loop. Then prints the header, then loops through each student printing a formatted row — calling getGrade() right inside printf to get the letter grade. Finally calls findTopper() for the summary.

Notice how functions call each other: printReport() calls both getGrade() and findTopper() inside itself. main() never calls getGrade or findTopper directly — it doesn't need to. This is the right way to structure a program. Each function knows only what it needs to know.
key learning points
§6

What This Project Teaches

Take away
  • Global arraysmarks[][], totals[], avg[], names[][] are declared outside all functions so every function can access them without passing parameters. This is the simplest approach for a small project.
  • void functionsinputData(), calcTotals(), calcAverages(), printReport() all use void because they work with global arrays — they don't need to return anything.
  • Functions that return valuesgetGrade() returns a char, findTopper() returns an int. These are pure utility functions — give input, get output, no side effects.
  • Functions calling functionsprintReport() calls getGrade() and findTopper(). main() stays clean and simple.
  • The (float) cast — without (float)totals[i] / SUBJECTS, C does integer division and you get 87 instead of 87.2. Always cast when you need decimals.
How to grow this project: This is a foundation. You can extend it by adding more students (change #define STUDENTS 5 to any number), adding a function to sort students by rank, saving results to a file, or adding a subject-wise class average row at the bottom. All of these are just one more function each.
checklist

Project Checklist

  • I understand why the arrays are declared globally — so all functions can share them
  • inputData() — outer loop = students, inner loop = subjects, reads marks[i][j]
  • calcTotals() — nested loop adds all 5 marks for each student into totals[i]
  • calcAverages() — (float) cast is needed to get decimal average, not integer
  • getGrade() — takes one float, returns one char. Clean single-purpose function.
  • findTopper() — starts at index 0, updates topIdx when a higher average is found
  • printReport() — calls getGrade() and findTopper() inside itself
  • I typed out the code and ran it successfully