[Lập trình C] Cấu trúc - struct

Posted on January 9th, 2021

Trong lập trình, đôi khi bạn cần phải nhóm các loại dữ liệu liên quan lại với nhau. Để giải quyết vấn đề này, ngôn ngữ lập trình C đưa ra khái niệm cấu trúc - struct.

Vậy struct trong ngôn ngữ lập trình C được định nghĩa như thế nào, cách sử dụng struct ra sao? Mời bạn theo dõi bài viết!

Kiến thức cơ bản về cấu trúc trong lập trình C

Cấu trúc là gì?

Cấu trúc là một kiểu dữ liệu mà trong đó bao gồm một hoặc nhiều thuộc tính.

Các thuộc tính bên trong struct không nhất thiết phải có cùng kiểu dữ liệu.

Ví dụ cấu trúc về phân loại sách như sau:

struct cat {
	char bk_name[25];
	char author[20];
	int edn;
	float price;
}; 	

Một khi struct đã được định nghĩa thì ta có thể khai báo biến với struct như giống như các kiểu dữ liệu bình thường.

struct cat books1, books2;
struct cat books3;

Hoặc bạn cũng có thể khai báo biến ngay sau khi định nghĩa struct:

struct cat {
	char bk_name[25];
	char author[20];
	int edn;
	float price;
} books1, books2, books3; 

Truy cập vào phần tử trong struct

Để truy cập vào phần tử của struct, bạn sử dụng toán tử dấu chấm (.) hay còn gọi là toán tử thành viên.

Cú pháp:

struct_name.element_name

Ví dụ truy cập vào các phần tử trong struct cat trên:

books1.bk_name;
books1.author;
books1.edn;
books1.price;

Khởi tạo giá trị cho struct

Cũng giống như biến hay mảng thông thường, biến struct cũng có thể được khởi tạo giá trị tại thời điểm khai báo.

Ví dụ struct employee:

struct employee {
	int no;
	char name [20];
};

Biến emp1 và emp2 có thể được khai báo và khởi tạo như sau:

struct employee emp1 = { 346, "Abraham" };
struct employee emp2 = { 347, "John"};

Gán giá trị cho struct

Bạn có thể gán giá trị của một biến struct cho một biến struct cùng kiểu khác.

Ví dụ nếu 2 biến books1books2 có cùng kiểu struct cat, bạn có thể gán trực tiếp giá trị của books1 cho books2 như sau:

books2 = books1;

Tuy nhiên, trong trường hợp cấu trúc của struct phức tạp, việc gán trực tiếp có thể dẫn đến kết quả sai. Khi đó, bạn có thể sử dụng hàm memcpy trong thư viện string.h theo cú pháp:

memcpy(void* dest, const void* source, int nbytes);

Trong đó:

  • dest: là con trỏ đích
  • source: là con trỏ nguồn
  • nbytes: là số lượng bytes cần copy

Cụ thể câu lệnh để copy giá trị của biến books1 cho biến books2 với struct cat trên là:

memcpy(&books2, &books1, sizeof(struct cat));

Struct bên trong struct

Bạn có thể khai báo một struct bên trong một struct khác. Tuy nhiên, bên trong một struct lại không được phép chứa chính nó.

Ví dụ:

struct cat {
	char bk_name[25];
	char author[20];
	int edn;
	float price;
};

struct issue {
	char borrower [20];
	char dt_of_issue[8];
	struct cat books;
};

Trong ví dụ trên, bên trong struct issue lại chứa struct cat.

Để truy cập vào phần tử của struct loại này, bạn sử dụng toán tử (.) giống như struct thông thường, ví dụ:

struct issue iss1;
iss1.borrower;
iss1.dt_of_issue;
iss1.books;
iss1.books.author;
iss1.books.bk_name;
iss1.books.edn;
iss1.books.price;

Truyền struct vào hàm

Struct có thể là tham số để truyền vào hàm giống như các kiểu dữ liệu cơ bản khác (int, float, double, char,...).

Cách này được sử dụng khi bạn muốn truyền vào một nhóm các dữ liệu, thay vì phải truyền vào từng loại dữ liệu một.

Ví dụ struct cat là tham số để truyền vào hàm printCat như sau:

void printCat(struct cat books) {
	printf("- bk_name: %s\n", books.bk_name);
	printf("- author: %s\n", books.author);
	printf("- edn: %d\n", books.edn);
	printf("- price: %f\n", books.price);
}

Mảng của struct

Struct cũng giống như kiểu dữ liệu thông thường. Vì vậy, bạn có thể định nghĩa mảng của struct như sau:

struct cat books[50];

Ví dụ trên khai báo mảng books gồm 50 phần tử kiểu struct cat.

Để truy cập vào biến author của phần tử thứ i trong mảng, bạn có thể làm như sau:

books[i].author

Để khởi tạo giá trị cho mảng struct bạn thực hiện giống với mảng thông thường, ví dụ:

struct unit {	
	char ch;
	int i;	
};

struct unit series[3] = {	
	{'a', 100},
	{'b', 200},
	{'c', 300}
};

Con trỏ struct

Bạn cũng có thể khai báo con trỏ struct bằng cách dùng toán tử (*) đứng trước tên biến, giống như khai báo các biến con trỏ thông thường.

Ví dụ:

struct cat *ptr_bk;

Để gán giá trị cho biến con trỏ, bạn có thể dùng toán tử (&):

struct cat books;
struct cat *ptr_bk = &books;

Để truy cập vào các phần tử của struct với con trỏ, bạn sử dụng toán tử (->) như sau:

struct cat books;
struct cat *ptr_bk = &books;
ptr_bk->author;
ptr_bk->bk_name;
ptr_bk->edn;
ptr_bk->price;

Chú ý: Khi truyền con trỏ struct vào hàm, bạn có thể thay đổi giá trị của các phần tử trong struct.

Từ khóa typedef

Trong các ví dụ trên, bạn có thể thấy là mỗi khi dùng đến kiểu dữ liệu struct, bạn đều phải đưa từ khóa struct phía trước.

Để tránh điều này, bạn dùng từ khóa typedef để định nghĩa tên mới cho struct, ví dụ:

typedef struct _cat {
	char bk_name[25];
	char author[20];
	int edn;
	float price;
} cat;

Hoặc tách riêng thành 2 câu lệnh:

struct _cat {
	char bk_name[25];
	char author[20];
	int edn;
	float price;
};

typedef struct _cat cat;

Lúc này bạn có thể dùng struct cat mà không cần đến từ khóa struct nữa, ví dụ:

cat books1, books2;

Bài tập thực hành về cấu trúc trong lập trình C

Bài 1

Định nghĩa một struct SinhVien bao gồm các thông tin sau:

  • Mã số: int maso
  • Tên: char ten[20]
  • Lớp: char lop[10]
  • Điểm thi môn toán: float diemToan
  • Điểm thi môn hóa: float diemHoa
  • Điểm thi môn lý: float diemLy

Trong hàm main, khai báo một mảng về SinhVien với số lượng phần tử tối đa là 20.

#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

int main() {
	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	return 0;
}

Bài 2

Viết một menu chương trình dạng sau (sử dụng struct SinhVien):

1. Nhập vào thông tin sinh viên
2. Nhập vào mã số sinh viên, hiển thị thông tin của sinh viên tương ứng
3. Nhập vào điểm, hiển thị thông tin các SV có điểm trung bình thấp hơn
4. Sắp xếp và hiển thị danh sách sinh viên theo tứ tự điểm trung bình thấp dần
5. Thoát chương trình

Sau đó, viết câu lệnh để yêu cầu người dùng nhập vào một số.

Chú ý:

  • Menu trên viết dạng không dấu.
  • Hiển thị thông tin sinh viên dạng chi tiết, bao gồm đầy đủ các thông tin trong cấu trúc
#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

void menu() {
	printf("\n");
	printf("1. Nhap thong tin sinh vien\n");
	printf("2. Nhap vao ma so, hien thi thong tin cua sinh vien tuong ung\n");
	printf("3. Nhap vao diem, hien thi thong tin cac SV co diem trung binh thap hon\n");
	printf("4. Sap xep va hien thi danh sach sinh vien theo thu tu diem trung binh thap dan\n");
	printf("5. Thoat chuong trinh\n\n");
}

void nhapLoai(int *n) {
	int kiemTra;
	while(1) {
		printf("Nhap vao mot so tu 1 den 5: ");
		kiemTra = scanf("%d", n);
		if (!kiemTra || *n < 1 || *n > 5) {
			fflush(stdin);
			continue;
		} else break;
	}
}

int main() {
	int type;

	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	// Vong lap chuong trinh
	while(1) {
		// 2. Viet menu chuong trinh
		menu();

		// Hien thi yeu cau nguoi dung nhap vao 1 so tu 1 den 5
		nhapLoai(&type);
	}

	return 0;
}

Bài 3

Triển khai phần nhập thông tin sinh viên bên trên (giả sử nhập dữ liệu đúng kiểu, đúng giới hạn kích thước).

#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

void menu() {
	printf("\n");
	printf("1. Nhap thong tin sinh vien\n");
	printf("2. Nhap vao ma so, hien thi thong tin cua sinh vien tuong ung\n");
	printf("3. Nhap vao diem, hien thi thong tin cac SV co diem trung binh thap hon\n");
	printf("4. Sap xep va hien thi danh sach sinh vien theo thu tu diem trung binh thap dan\n");
	printf("5. Thoat chuong trinh\n\n");
}

void nhapLoai(int *n) {
	int kiemTra;
	while(1) {
		printf("Nhap vao mot so tu 1 den 5: ");
		kiemTra = scanf("%d", n);
		if (!kiemTra || *n < 1 || *n > 5) {
			fflush(stdin);
			continue;
		} else break;
	}
}

void nhapThongTinSinhVien(int *soLuong, SinhVien arr[20]) {
	int index = *soLuong;
	
	if (index < 20) {
		printf("\nNhap vao thong tin sinh vien %d:\n", index + 1);
		printf("+ Ma so: ");
		scanf("%d", &arr[index].maso);
		printf("+ Ten: ");
		scanf("%s", arr[index].ten);
		printf("+ Lop: ");
		scanf("%s", arr[index].lop);
		printf("+ Diem toan: ");
		scanf("%f", &arr[index].diemToan);
		printf("+ Diem hoa: ");
		scanf("%f", &arr[index].diemHoa);
		printf("+ Diem ly: ");
		scanf("%f", &arr[index].diemLy);
		*soLuong += 1;
	}
	else {
		printf("So luong thong tin sinh vien da qua gioi han");
	}
}

int main() {
	int type, soLuongSV = 0;

	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	// Vong lap chuong trinh
	while(1) {
		// 2. Viet menu chuong trinh
		menu();
		
		// Hien thi yeu cau nguoi dung nhap vao 1 so tu 1 den 5
		nhapLoai(&type);
		
		// Type 1: nhap thong tin sinh vien
		if (type == 1) {
			nhapThongTinSinhVien(&soLuongSV, svList);
		}
	}

	return 0;
}

Bài 4

Triển khai phần nhập vào mã số, hiển thị thông tin chi tiết của sinh viên tương ứng bên trên.

#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

void menu() {
	printf("\n");
	printf("1. Nhap thong tin sinh vien\n");
	printf("2. Nhap vao ma so, hien thi thong tin cua sinh vien tuong ung\n");
	printf("3. Nhap vao diem, hien thi thong tin cac SV co diem trung binh thap hon\n");
	printf("4. Sap xep va hien thi danh sach sinh vien theo thu tu diem trung binh thap dan\n");
	printf("5. Thoat chuong trinh\n\n");
}

void nhapLoai(int *n) {
	int kiemTra;
	while(1) {
		printf("Nhap vao mot so tu 1 den 5: ");
		kiemTra = scanf("%d", n);
		if (!kiemTra || *n < 1 || *n > 5) {
			fflush(stdin);
			continue;
		} else break;
	}
}

void nhapThongTinSinhVien(int *soLuong, SinhVien arr[20]) {
	int index = *soLuong;
	
	if (index < 20) {
		printf("\nNhap vao thong tin sinh vien %d:\n", index + 1);
		printf("+ Ma so: ");
		scanf("%d", &arr[index].maso);
		printf("+ Ten: ");
		scanf("%s", arr[index].ten);
		printf("+ Lop: ");
		scanf("%s", arr[index].lop);
		printf("+ Diem toan: ");
		scanf("%f", &arr[index].diemToan);
		printf("+ Diem hoa: ");
		scanf("%f", &arr[index].diemHoa);
		printf("+ Diem ly: ");
		scanf("%f", &arr[index].diemLy);
		*soLuong += 1;
	}
	else {
		printf("So luong thong tin sinh vien da qua gioi han");
	}
}

void hienThiThongTin(SinhVien sv) {
	printf("\nThong tin sinh vien la:\n");
	printf("+ Ma so: %d\n", sv.maso);
	printf("+ Ten: %s\n", sv.ten);
	printf("+ Lop: %s\n", sv.lop);
	printf("+ Diem toan: %g\n", sv.diemToan);
	printf("+ Diem hoa: %g\n", sv.diemHoa);
	printf("+ Diem ly: %g\n", sv.diemLy);
}

void nhapMaSoHienThiThongTin(int soLuong, SinhVien arr[20]) {
	int maSo;
	printf("\nNhap ma so sinh vien: ");
	scanf("%d", &maSo);
	
	// Tim kiem sinh vien theo ma so
	int i;
	for (i = 0; i < soLuong; i++) {
		if (maSo == arr[i].maso) {
			hienThiThongTin(arr[i]);
			return;
		}
	}
	
	printf("\nKhong tim thay sinh vien voi ma so: %d\n", maSo);
}

int main() {
	int type, soLuongSV = 0;

	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	// Vong lap chuong trinh
	while(1) {
		// 2. Viet menu chuong trinh
		menu();
		
		// Hien thi yeu cau nguoi dung nhap vao 1 so tu 1 den 5
		nhapLoai(&type);
		
		// Kiem tra type
		if (type == 1) { 		// Type 1: nhap thong tin sinh vien
			nhapThongTinSinhVien(&soLuongSV, svList);
		}
		else if (type == 2) { 	// Type 2: nhap ma so, hien thi thong tin
			nhapMaSoHienThiThongTin(soLuongSV, svList);
		}
	}

	return 0;
}

Bài 5

Triển khai phần nhập vào giá trị điểm, tìm và hiển thị thông tin chi tiết của các SV có điểm trung bình thấp hơn bên trên.

#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

void menu() {
	printf("\n");
	printf("1. Nhap thong tin sinh vien\n");
	printf("2. Nhap vao ma so, hien thi thong tin cua sinh vien tuong ung\n");
	printf("3. Nhap vao diem, hien thi thong tin cac SV co diem trung binh thap hon\n");
	printf("4. Sap xep va hien thi danh sach sinh vien theo thu tu diem trung binh thap dan\n");
	printf("5. Thoat chuong trinh\n\n");
}

void nhapLoai(int *n) {
	int kiemTra;
	while(1) {
		printf("Nhap vao mot so tu 1 den 5: ");
		kiemTra = scanf("%d", n);
		if (!kiemTra || *n < 1 || *n > 5) {
			fflush(stdin);
			continue;
		} else break;
	}
}

void nhapThongTinSinhVien(int *soLuong, SinhVien arr[20]) {
	int index = *soLuong;
	
	if (index < 20) {
		printf("\nNhap vao thong tin sinh vien %d:\n", index + 1);
		printf("+ Ma so: ");
		scanf("%d", &arr[index].maso);
		printf("+ Ten: ");
		scanf("%s", arr[index].ten);
		printf("+ Lop: ");
		scanf("%s", arr[index].lop);
		printf("+ Diem toan: ");
		scanf("%f", &arr[index].diemToan);
		printf("+ Diem hoa: ");
		scanf("%f", &arr[index].diemHoa);
		printf("+ Diem ly: ");
		scanf("%f", &arr[index].diemLy);
		*soLuong += 1;
	}
	else {
		printf("So luong thong tin sinh vien da qua gioi han");
	}
}

void hienThiThongTin(SinhVien sv) {
	printf("\nThong tin sinh vien la:\n");
	printf("+ Ma so: %d\n", sv.maso);
	printf("+ Ten: %s\n", sv.ten);
	printf("+ Lop: %s\n", sv.lop);
	printf("+ Diem toan: %g\n", sv.diemToan);
	printf("+ Diem hoa: %g\n", sv.diemHoa);
	printf("+ Diem ly: %g\n", sv.diemLy);
}

void nhapMaSoHienThiThongTin(int soLuong, SinhVien arr[20]) {
	int maSo;
	printf("\nNhap ma so sinh vien: ");
	scanf("%d", &maSo);
	
	// Tim kiem sinh vien theo ma so
	int i;
	for (i = 0; i < soLuong; i++) {
		if (maSo == arr[i].maso) {
			hienThiThongTin(arr[i]);
			return;
		}
	}
	
	printf("\nKhong tim thay sinh vien voi ma so: %d\n", maSo);
}

float tinhDiemTb(SinhVien sv) {
	return (float)(sv.diemToan + sv.diemHoa + sv.diemLy) / 3;
}

void nhapDiemHienThiDanhSachDiemTbThapHon(int soLuong, SinhVien arr[20]) {
	float diem;
	printf("\nNhap gia tri diem: ");
	scanf("%f", &diem);
	
	// Tim kiem sinh vien co diem trung binh thap hon
	printf("\nDanh sach sinh vien co diem trung binh thap hon %g la:\n", diem);
	int i;
	for (i = 0; i < soLuong; i++) {
		float tb = tinhDiemTb(arr[i]);
		if (tb < diem) {
			hienThiThongTin(arr[i]);
		}
	}
}

int main() {
	int type, soLuongSV = 0;

	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	// Vong lap chuong trinh
	while(1) {
		// 2. Viet menu chuong trinh
		menu();
		
		// Hien thi yeu cau nguoi dung nhap vao 1 so tu 1 den 5
		nhapLoai(&type);
		
		// Kiem tra type
		if (type == 1) { 	  // Type 1: nhap thong tin sinh vien
			nhapThongTinSinhVien(&soLuongSV, svList);
		}
		else if (type == 2) { // Type 2: nhap ma so, hien thi thong tin
			nhapMaSoHienThiThongTin(soLuongSV, svList);
		}
		else if (type == 3) { // Type 3: nhap diem, hien thi cac sv co diem tb thap hon
			nhapDiemHienThiDanhSachDiemTbThapHon(soLuongSV, svList);
		}
	}

	return 0;
}

Bài 6

Triển khai phần sắp xếp và hiển thị danh sách sinh viên theo tứ tự điểm trung bình thấp dần bên trên.

#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

void menu() {
	printf("\n");
	printf("1. Nhap thong tin sinh vien\n");
	printf("2. Nhap vao ma so, hien thi thong tin cua sinh vien tuong ung\n");
	printf("3. Nhap vao diem, hien thi thong tin cac SV co diem trung binh thap hon\n");
	printf("4. Sap xep va hien thi danh sach sinh vien theo thu tu diem trung binh thap dan\n");
	printf("5. Thoat chuong trinh\n\n");
}

void nhapLoai(int *n) {
	int kiemTra;
	while(1) {
		printf("Nhap vao mot so tu 1 den 5: ");
		kiemTra = scanf("%d", n);
		if (!kiemTra || *n < 1 || *n > 5) {
			fflush(stdin);
			continue;
		} else break;
	}
}

void nhapThongTinSinhVien(int *soLuong, SinhVien arr[20]) {
	int index = *soLuong;
	
	if (index < 20) {
		printf("\nNhap vao thong tin sinh vien %d:\n", index + 1);
		printf("+ Ma so: ");
		scanf("%d", &arr[index].maso);
		printf("+ Ten: ");
		scanf("%s", arr[index].ten);
		printf("+ Lop: ");
		scanf("%s", arr[index].lop);
		printf("+ Diem toan: ");
		scanf("%f", &arr[index].diemToan);
		printf("+ Diem hoa: ");
		scanf("%f", &arr[index].diemHoa);
		printf("+ Diem ly: ");
		scanf("%f", &arr[index].diemLy);
		*soLuong += 1;
	}
	else {
		printf("So luong thong tin sinh vien da qua gioi han");
	}
}

void hienThiThongTin(SinhVien sv) {
	printf("\nThong tin sinh vien la:\n");
	printf("+ Ma so: %d\n", sv.maso);
	printf("+ Ten: %s\n", sv.ten);
	printf("+ Lop: %s\n", sv.lop);
	printf("+ Diem toan: %g\n", sv.diemToan);
	printf("+ Diem hoa: %g\n", sv.diemHoa);
	printf("+ Diem ly: %g\n", sv.diemLy);
}

void nhapMaSoHienThiThongTin(int soLuong, SinhVien arr[20]) {
	int maSo;
	printf("\nNhap ma so sinh vien: ");
	scanf("%d", &maSo);
	
	// Tim kiem sinh vien theo ma so
	int i;
	for (i = 0; i < soLuong; i++) {
		if (maSo == arr[i].maso) {
			hienThiThongTin(arr[i]);
			return;
		}
	}
	
	printf("\nKhong tim thay sinh vien voi ma so: %d\n", maSo);
}

float tinhDiemTb(SinhVien sv) {
	return (float)(sv.diemToan + sv.diemHoa + sv.diemLy) / 3;
}

void nhapDiemHienThiDanhSachDiemTbThapHon(int soLuong, SinhVien arr[20]) {
	float diem;
	printf("\nNhap gia tri diem: ");
	scanf("%f", &diem);
	
	// Tim kiem sinh vien co diem trung binh thap hon
	printf("\nDanh sach sinh vien co diem trung binh thap hon %g la:\n", diem);
	int i;
	for (i = 0; i < soLuong; i++) {
		float tb = tinhDiemTb(arr[i]);
		if (tb < diem) {
			hienThiThongTin(arr[i]);
		}
	}
}

void hoanDoiSV(SinhVien *sv1, SinhVien *sv2) {
	SinhVien temp = *sv1;
	*sv1 = *sv2;
	*sv2 = temp;
}

void sapXepHienThiDiemTbThapDan(int soLuong, SinhVien arr[20]) {
	// Sap xep sinh vien theo thu tu diem tb thap dan
	int i, j;
	for (i = 0; i < soLuong - 1; i++) {
		for (j = i + 1; j < soLuong; j++) {
			float tb1 = tinhDiemTb(arr[i]);
			float tb2 = tinhDiemTb(arr[j]);
			if (tb1 < tb2) {
				hoanDoiSV(&arr[i], &arr[j]);
			}
		}
	}
	
	// In ra danh sach sau khi sap xep
	printf("\nDanh sach sinh vien sau khi sap xep la:\n");
	for (i = 0; i < soLuong; i++) {
		hienThiThongTin(arr[i]);
	}
}

int main() {
	int type, soLuongSV = 0;

	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	// Vong lap chuong trinh
	while(1) {
		// 2. Viet menu chuong trinh
		menu();
		
		// Hien thi yeu cau nguoi dung nhap vao 1 so tu 1 den 5
		nhapLoai(&type);
		
		// Kiem tra type
		if (type == 1) { 	  // Type 1: nhap thong tin sinh vien
			nhapThongTinSinhVien(&soLuongSV, svList);
		}
		else if (type == 2) { // Type 2: nhap ma so, hien thi thong tin
			nhapMaSoHienThiThongTin(soLuongSV, svList);
		}
		else if (type == 3) { // Type 3: nhap diem, hien thi cac sv co diem tb thap hon
			nhapDiemHienThiDanhSachDiemTbThapHon(soLuongSV, svList);
		} 
		else if (type == 4) { // Type 4: sap xep va hien thi theo diem tb thap dan
			sapXepHienThiDiemTbThapDan(soLuongSV, svList);
		}
	}

	return 0;
}

Bài 7

Triển khai phần thoát chương trình bên trên.

#include <stdio.h>

typedef struct _SinhVien {
	int maso;
	char ten[20];
	char lop[10];
	float diemToan;
	float diemHoa;
	float diemLy;
} SinhVien;

void menu() {
	printf("\n");
	printf("1. Nhap thong tin sinh vien\n");
	printf("2. Nhap vao ma so, hien thi thong tin cua sinh vien tuong ung\n");
	printf("3. Nhap vao diem, hien thi thong tin cac SV co diem trung binh thap hon\n");
	printf("4. Sap xep va hien thi danh sach sinh vien theo thu tu diem trung binh thap dan\n");
	printf("5. Thoat chuong trinh\n\n");
}

void nhapLoai(int *n) {
	int kiemTra;
	while(1) {
		printf("Nhap vao mot so tu 1 den 5: ");
		kiemTra = scanf("%d", n);
		if (!kiemTra || *n < 1 || *n > 5) {
			fflush(stdin);
			continue;
		} else break;
	}
}

void nhapThongTinSinhVien(int *soLuong, SinhVien arr[20]) {
	int index = *soLuong;
	
	if (index < 20) {
		printf("\nNhap vao thong tin sinh vien %d:\n", index + 1);
		printf("+ Ma so: ");
		scanf("%d", &arr[index].maso);
		printf("+ Ten: ");
		scanf("%s", arr[index].ten);
		printf("+ Lop: ");
		scanf("%s", arr[index].lop);
		printf("+ Diem toan: ");
		scanf("%f", &arr[index].diemToan);
		printf("+ Diem hoa: ");
		scanf("%f", &arr[index].diemHoa);
		printf("+ Diem ly: ");
		scanf("%f", &arr[index].diemLy);
		*soLuong += 1;
	}
	else {
		printf("So luong thong tin sinh vien da qua gioi han");
	}
}

void hienThiThongTin(SinhVien sv) {
	printf("\nThong tin sinh vien la:\n");
	printf("+ Ma so: %d\n", sv.maso);
	printf("+ Ten: %s\n", sv.ten);
	printf("+ Lop: %s\n", sv.lop);
	printf("+ Diem toan: %g\n", sv.diemToan);
	printf("+ Diem hoa: %g\n", sv.diemHoa);
	printf("+ Diem ly: %g\n", sv.diemLy);
}

void nhapMaSoHienThiThongTin(int soLuong, SinhVien arr[20]) {
	int maSo;
	printf("\nNhap ma so sinh vien: ");
	scanf("%d", &maSo);
	
	// Tim kiem sinh vien theo ma so
	int i;
	for (i = 0; i < soLuong; i++) {
		if (maSo == arr[i].maso) {
			hienThiThongTin(arr[i]);
			return;
		}
	}
	
	printf("\nKhong tim thay sinh vien voi ma so: %d\n", maSo);
}

float tinhDiemTb(SinhVien sv) {
	return (float)(sv.diemToan + sv.diemHoa + sv.diemLy) / 3;
}

void nhapDiemHienThiDanhSachDiemTbThapHon(int soLuong, SinhVien arr[20]) {
	float diem;
	printf("\nNhap gia tri diem: ");
	scanf("%f", &diem);
	
	// Tim kiem sinh vien co diem trung binh thap hon
	printf("\nDanh sach sinh vien co diem trung binh thap hon %g la:\n", diem);
	int i;
	for (i = 0; i < soLuong; i++) {
		float tb = tinhDiemTb(arr[i]);
		if (tb < diem) {
			hienThiThongTin(arr[i]);
		}
	}
}

void hoanDoiSV(SinhVien *sv1, SinhVien *sv2) {
	SinhVien temp = *sv1;
	*sv1 = *sv2;
	*sv2 = temp;
}

void sapXepHienThiDiemTbThapDan(int soLuong, SinhVien arr[20]) {
	// Sap xep sinh vien theo thu tu diem tb thap dan
	int i, j;
	for (i = 0; i < soLuong - 1; i++) {
		for (j = i + 1; j < soLuong; j++) {
			float tb1 = tinhDiemTb(arr[i]);
			float tb2 = tinhDiemTb(arr[j]);
			if (tb1 < tb2) {
				hoanDoiSV(&arr[i], &arr[j]);
			}
		}
	}
	
	// In ra danh sach sau khi sap xep
	printf("\nDanh sach sinh vien sau khi sap xep la:\n");
	for (i = 0; i < soLuong; i++) {
		hienThiThongTin(arr[i]);
	}
}

int main() {
	int type, soLuongSV = 0;

	// 1. Khai bao mang sinh vien gom toi da 20 phan tu
	SinhVien svList[20];

	// Vong lap chuong trinh
	while(1) {
		// 2. Viet menu chuong trinh
		menu();
		
		// Hien thi yeu cau nguoi dung nhap vao 1 so tu 1 den 5
		nhapLoai(&type);
		
		// Kiem tra type
		if (type == 1) { 	  // Type 1: nhap thong tin sinh vien
			nhapThongTinSinhVien(&soLuongSV, svList);
		}
		else if (type == 2) { // Type 2: nhap ma so, hien thi thong tin
			nhapMaSoHienThiThongTin(soLuongSV, svList);
		}
		else if (type == 3) { // Type 3: nhap diem, hien thi cac sv co diem tb thap hon
			nhapDiemHienThiDanhSachDiemTbThapHon(soLuongSV, svList);
		} 
		else if (type == 4) { // Type 4: sap xep va hien thi theo diem tb thap dan
			sapXepHienThiDiemTbThapDan(soLuongSV, svList);
		}
		else if (type == 5) { // Type 5: thoat chuong trinh
			break;
		}
	}

	return 0;
}