Lập trình C: Bài tập thực hành về Struct và Enum

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

Kết quả bài tập 1

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

Kết quả bài tập 2

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

Kết quả bài tập 3

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

Kết quả bài tập 4

Thẻ: C programming struct enum Data Structures Sorting Algorithms

Đăng vào ngày 30 tháng 5 lúc 02:09