Bài tập thực hành 1 - Quản lý sách
Viết chương trình quản lý thông tin sách với các yêu cầu sau:
Mã nguồn
#include <stdio.h>
#define MAX_BOOKS 15
typedef struct {
char ma_sach[20]; // Mã sách
char tieu_de[80]; // Tựa sách
char tac_gia[80]; // Tác giả
double gia_ban; // Giá bán
int so_luong_ban; // Số lượng đã bán
} Book;
void hien_thi(Book arr[], int n);
void sap_xep(Book arr[], int n);
double tinh_doanh_thu(Book arr[], int n);
int main() {
Book books[MAX_BOOKS] = {{"978-3-16-148410-0", "Giấc mơ Mỹ", "Nguyễn Nhật Ánh", 45000, 120},
{"978-0-06-112008-4", "Giết con chim nhại", "Harper Lee", 89000, 75},
{"978-0-452-28423-4", "1984", "George Orwell", 72000, 200},
{"978-0-7432-7356-5", "Dốt nát", "Stephen King", 95000, 150},
{"978-0-06-093546-7", "Đắc nhân tâm", "Dale Carnegie", 68000, 300},
{"978-0-14-028329-7", "Người giàu nhất Babylon", "George Clason", 55000, 90},
{"978-0-553-21311-7", "Chúa tể của những chiếc nhẫn", "J.R.R. Tolkien", 150000, 180},
{"978-0-385-33348-1", "Cây cam ngọt của tôi", "José Mauro, 105000, 60},
{"978-0-14-028334-1", "Bắt trẻ đồng xu", "Gary Vaynerchuk", 78000, 45},
{"978-0-06-251903-0", "Nghệ thuật chiến thắng", "Jack Welch", 92000, 85}};
int n = 10;
printf("=== DANH SÁCH SÁCH THEO THỨ TỰ SỐ LƯỢNG BÁN ===\n");
sap_xep(books, n);
hien_thi(books, n);
printf("\nTổng doanh thu: %.2f VNĐ\n", tinh_doanh_thu(books, n));
return 0;
}
void hien_thi(Book arr[], int n) {
printf("%-20s %-25s %-15s %-10s %-10s\n",
"Mã sách", "Tựa sách", "Tác giả", "Giá bán", "SL Bán");
printf("====================================================================\n");
for(int i = 0; i < n; i++) {
printf("%-20s %-25s %-15s %-10.0f %-10d\n",
arr[i].ma_sach, arr[i].tieu_de, arr[i].tac_gia,
arr[i].gia_ban, arr[i].so_luong_ban);
}
}
void sap_xep(Book arr[], int n) {
Book tam;
for(int i = 0; i < n - 1; i++) {
for(int j = 0; j < n - 1 - i; j++) {
if(arr[j].so_luong_ban < arr[j+1].so_luong_ban) {
tam = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tam;
}
}
}
}
double tinh_doanh_thu(Book arr[], int n) {
double tong = 0;
for(int i = 0; i < n; i++) {
tong += arr[i].so_luong_ban * arr[i].gia_ban;
}
return tong;
}
Kết quả chạy chương trình
Bài tập thực hành 2 - Xử lý ngày tháng
Viết chương trình xử lý ngày tháng với các hàm: nhập ngày, tính ngày thứ mấy trong năm, so sánh hai ngày.
Mã nguồn
#include <stdio.h>
typedef struct {
int nam;
int thang;
int ngay;
} Date;
void nhap_ngay(Date *pd);
int lay_ngay_trong_nam(Date d);
int so_sanh_ngay(Date d1, Date d2);
void test1() {
Date d;
printf("Nhập 3 ngày (định dạng YYYY-MM-DD):\n");
for(int i = 0; i < 3; i++) {
nhap_ngay(&d);
printf("Ngày %d-%02d-%02d là ngày thứ %d trong năm\n\n",
d.nam, d.thang, d.ngay, lay_ngay_trong_nam(d));
}
}
void test2() {
Date a, b;
printf("\nNhập ngày sinh của 2 người:\n");
for(int i = 0; i < 3; i++) {
printf("\nLần %d:\n", i + 1);
nhap_ngay(&a);
nhap_ngay(&b);
int ket_qua = so_sanh_ngay(a, b);
if(ket_qua == 0)
printf("Hai người cùng ngày sinh\n");
else if(ket_qua == -1)
printf("Người thứ nhất lớn tuổi hơn\n");
else
printf("Người thứ hai lớn tuổi hơn\n");
}
}
int main() {
printf("=== KIỂM TRA 1: Tính ngày trong năm ===\n");
test1();
printf("\n=== KIỂM TRA 2: So sánh tuổi ===\n");
test2();
return 0;
}
void nhap_ngay(Date *pd) {
scanf("%d-%d-%d", &pd->nam, &pd->thang, &pd->ngay);
}
int lay_ngay_trong_nam(Date d) {
int tong = 0;
int so_ngay_thang[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// Kiểm tra năm nhuận
if((d.nam % 4 == 0 && d.nam % 100 != 0) || d.nam % 400 == 0)
so_ngay_thang[1] = 29;
for(int i = 0; i < d.thang - 1; i++)
tong += so_ngay_thang[i];
tong += d.ngay;
return tong;
}
int so_sanh_ngay(Date d1, Date d2) {
if(d1.nam != d2.nam)
return (d1.nam < d2.nam) ? -1 : 1;
int ngay1 = lay_ngay_trong_nam(d1);
int ngay2 = lay_ngay_trong_nam(d2);
if(ngay1 < ngay2) return -1;
if(ngay1 > ngay2) return 1;
return 0;
}
Kết quả chạy chương trình
Bài tập thực hành 3 - Quản lý tài khoản
Viết chương trình quản lý tài khoản người dùng với các loại tài khoản khác nhau. Khi hiển thị, mật khẩu được thay bằng dấu *.
Mã nguồn
#include <stdio.h>
#include <string.h>
enum LoaiTaiKhoan {quan_tri, sinh_vien, giao_vien};
typedef struct {
char ten_dang_nhap[20];
char mat_khau[20];
enum LoaiTaiKhoan loai;
} Account;
void hien_thi_tai_khoan(Account ds[], int n);
int main() {
Account ds_tai_khoan[] = {{"SV001", "pass123", sinh_vien},
{"SV002", "abcxyz99", sinh_vien},
{"GV001", "math2024", giao_vien},
{"ADMIN", "admin@123", quan_tri},
{"SV003", "learnC", sinh_vien},
{"GV002", "physics01", giao_vien}};
int so_luong = sizeof(ds_tai_khoan) / sizeof(Account);
hien_thi_tai_khoan(ds_tai_khoan, so_luong);
return 0;
}
void hien_thi_tai_khoan(Account ds[], int n) {
printf("%-15s %-20s %-10s\n", "Tên đăng nhập", "Mật khẩu", "Loại tài khoản");
printf("================================================\n");
for(int i = 0; i < n; i++) {
printf("%-15s ", ds[i].ten_dang_nhap);
// Hiển thị mật khẩu dạng ****
int do_dai = strlen(ds[i].mat_khau);
for(int j = 0; j < do_dai; j++)
printf("*");
printf(" ");
switch(ds[i].loai) {
case quan_tri: printf("Quản trị viên\n"); break;
case sinh_vien: printf("Sinh viên\n"); break;
case giao_vien: printf("Giáo viên\n"); break;
default: printf("Không xác định\n");
}
}
}
Kết quả chạy chương trình
Bài tập thực hành 4 - Danh bạ điện thoại
Viết chương trình quản lý danh bạ với chức năng đánh dấu liên hệ khẩn cấp và sắp xếp theo thứ tự alphabet.
Mã nguồn
#include <stdio.h>
#include <string.h>
#define MAX_CONTACTS 10
typedef struct {
char ho_ten[20];
char so_dien_thoai[12];
int la_khau_cap; // 1 nếu là liên hệ khẩn cấp, 0 nếu không
} Contact;
void danh_dau_khau_cap(Contact ds[], int n, char ten[]);
void in_danh_ba(Contact ds[], int n);
void hien_thi_sap_xep(Contact ds[], int n);
int main() {
Contact danh_ba[MAX_CONTACTS] = {
{"Trần Văn A", "0912345678", 0},
{"Lê Thị B", "0987654321", 0},
{"Phạm Văn C", "0905123456", 0},
{"Nguyễn Thị D", "0934567890", 0},
{"Hoàng Văn E", "0978123456", 0},
{"Vũ Thị F", "0966123456", 0},
{"Đặng Văn G", "0955123456", 0},
{"Bùi Thị H", "0944123456", 0},
{"Đỗ Văn I", "0933123456", 0},
{"Ngô Thị J", "0922123456", 0}
};
int so_luong, i;
char ten[20];
printf("=== DANH BẠ BAN ĐẦU ===\n");
in_danh_ba(danh_ba, MAX_CONTACTS);
printf("\nNhập số liên hệ khẩn cấp cần thêm: ");
scanf("%d", &so_luong);
printf("Nhập %d tên liên hệ:\n", so_luong);
for(i = 0; i < so_luong; i++) {
scanf("%s", ten);
danh_dau_khau_cap(danh_ba, MAX_CONTACTS, ten);
}
printf("\n=== DANH BẾ SAU KHI SẮP XẾP ===\n");
printf("(Liên hệ khẩn cấp hiển thị trước, theo thứ tự A-Z)\n");
hien_thi_sap_xep(danh_ba, MAX_CONTACTS);
return 0;
}
void danh_dau_khau_cap(Contact ds[], int n, char ten[]) {
for(int i = 0; i < n; i++) {
if(strcmp(ds[i].ho_ten, ten) == 0) {
ds[i].la_khau_cap = 1;
break;
}
}
}
void in_danh_ba(Contact ds[], int n) {
printf("%-15s %-15s %-10s\n", "Họ tên", "Số điện thoại", "Khẩn cấp");
printf("=============================================\n");
for(int i = 0; i < n; i++) {
printf("%-15s %-15s", ds[i].ho_ten, ds[i].so_dien_thoai);
if(ds[i].la_khau_cap)
printf(" %-10s", "***");
printf("\n");
}
}
void hien_thi_sap_xep(Contact ds[], int n) {
Contact tam;
// Sắp xếp: khẩn cấp trước, sau đó theo tên A-Z
for(int i = 0; i < n - 1; i++) {
for(int j = 0; j < n - i - 1; j++) {
if(ds[j].la_khau_cap < ds[j+1].la_khau_cap ||
(ds[j].la_khau_cap == ds[j+1].la_khau_cap &&
strcmp(ds[j].ho_ten, ds[j+1].ho_ten) > 0)) {
tam = ds[j];
ds[j] = ds[j+1];
ds[j+1] = tam;
}
}
}
in_danh_ba(ds, n);
}
Kết quả chạy chương trình