Bài tập C++ cơ bản có lời giải: 20 bài từ biến, vòng lặp tới hàm và vector

Bài tập C++ cơ bản có lời giải: 20 bài từ biến, vòng lặp tới hàm và vector - Khuê Nguyễn Creator

Trong bài này chúng ta sẽ luyện tập với 20 bài tập C++ cơ bản có lời giải, bao trùm toàn bộ chương 1 và 2 của serie: nhập xuất, kiểu dữ liệu, toán tử, rẽ nhánh, vòng lặp, hàm, std::string và std::vector. Đây cũng là lời giải cho các bài tập nhỏ ở cuối mỗi bài học trước.

Bài 10 trong Serie Lập trình C++ từ A tới Z

Cách luyện bài tập C++ cơ bản hiệu quả

Mỗi bài tập gồm đề bài, gợi ý, lời giải và kết quả chạy thật. Các bạn nên làm theo thứ tự:

  1. Đọc đề và tự viết code trước, kể cả khi chưa chắc đúng.
  2. Bí quá thì đọc phần gợi ý, chưa xem code vội.
  3. Chạy thử với nhiều dữ liệu khác nhau, đặc biệt là trường hợp đặc biệt: số 0, số âm, chuỗi rỗng.
  4. Cuối cùng mới so với lời giải. Lời giải của mình chỉ là một cách, code của các bạn khác mà chạy đúng thì vẫn là đúng.

Toàn bộ lời giải biên dịch bằng g++ -std=c++17 -Wall -Wextra không có cảnh báo nào, môi trường cài đặt theo bài cài đặt C++ trên VS Code.

Bài tập nhập xuất

Kiến thức dùng trong phần này nằm ở bài Cài đặt C++ trên VS Code.

Bài 1: In thông tin cá nhân

Đề bài: Viết chương trình in ra 3 dòng: họ tên, lớp và trường của bạn.

Gợi ý: Mỗi dòng một lệnh std::cout, kết thúc bằng \n để xuống dòng.

Lời giải:

#include <iostream>

int main()
{
    std::cout << "Ho ten: Nguyen Van An\n";
    std::cout << "Lop:    DTVT 01\n";
    std::cout << "Truong: Dai hoc Bach Khoa\n";
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ cơ bản 1: In thông tin cá nhân

Bài 2: Chào hỏi kèm quê quán

Đề bài: Nhập tên và quê quán từ bàn phím, in ra câu “Xin chao …, ban den tu …”.

Gợi ý: Tên và quê quán có thể có dấu cách nên phải dùng std::getline, không dùng std::cin >>.

Lời giải:

#include <iostream>
#include <string>

int main()
{
    std::string ten, queQuan;

    std::cout << "Nhap ten cua ban: ";
    std::getline(std::cin, ten);
    std::cout << "Ban den tu dau: ";
    std::getline(std::cin, queQuan);

    std::cout << "Xin chao " << ten << ", ban den tu " << queQuan << "!\n";
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 2: Chào hỏi kèm quê quán

Bài tập cú pháp cơ bản

Kiến thức dùng trong phần này nằm ở bài Cú pháp C++ cơ bản.

Bài 3: Chu vi và diện tích hình chữ nhật

Đề bài: Nhập chiều dài, chiều rộng, in ra chu vi và diện tích hình chữ nhật.

Gợi ý: Dùng double để nhập được cả số lẻ. std::cin >> dai >> rong đọc 2 số cách nhau bởi dấu cách.

Lời giải:

#include <iostream>

int main()
{
    double dai, rong;
    std::cout << "Nhap chieu dai va chieu rong: ";
    std::cin >> dai >> rong;

    std::cout << "Chu vi:    " << (dai + rong) * 2 << '\n';
    std::cout << "Dien tich: " << dai * rong << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 3: Chu vi và diện tích hình chữ nhật

Bài tập kiểu dữ liệu

Kiến thức dùng trong phần này nằm ở bài Các kiểu dữ liệu trong C++.

Bài 4: Lưu số lượt xem 3 tỷ

Đề bài: Một video có 3 tỷ lượt xem. Chọn kiểu dữ liệu phù hợp để lưu, cộng thêm 1 lượt và in ra.

Gợi ý: int chỉ lưu tới khoảng 2,1 tỷ nên phải dùng long long (8 byte). Hậu tố LL báo hằng số có kiểu long long.

Lời giải:

#include <iostream>

int main()
{
    long long luotXem = 3000000000LL;   // 3 ty, vuot gioi han cua int
    luotXem += 1;
    std::cout << "Luot xem: " << luotXem << '\n';
    std::cout << "sizeof(long long) = " << sizeof(luotXem) << " byte\n";
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 4: Lưu số lượt xem 3 tỷ

Bài 5: Điểm trung bình 3 môn

Đề bài: Nhập điểm 3 môn (số nguyên), in ra điểm trung bình có phần thập phân.

Gợi ý: Chia cho 3.0 chứ không phải 3: tổng 3 số int chia cho int sẽ mất phần thập phân như bài kiểu dữ liệu đã chỉ ra.

Lời giải:

#include <iostream>

int main()
{
    int toan, ly, hoa;
    std::cout << "Nhap diem Toan, Ly, Hoa: ";
    std::cin >> toan >> ly >> hoa;

    double trungBinh = (toan + ly + hoa) / 3.0;   // 3.0 de chia so thuc
    std::cout << "Diem trung binh: " << trungBinh << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 5: Điểm trung bình 3 môn

Bài tập hằng và biến

Kiến thức dùng trong phần này nằm ở bài Hằng và biến C++.

Bài 6: Chu vi và diện tích hình tròn

Đề bài: Nhập bán kính, in ra chu vi và diện tích hình tròn. Số pi khai báo bằng constexpr.

Gợi ý: Số pi là hằng số biết sẵn lúc biên dịch nên dùng constexpr double PI.

Lời giải:

#include <iostream>

int main()
{
    constexpr double PI = 3.14159265358979;
    double banKinh;

    std::cout << "Nhap ban kinh: ";
    std::cin >> banKinh;

    std::cout << "Chu vi:    " << 2 * PI * banKinh << '\n';
    std::cout << "Dien tich: " << PI * banKinh * banKinh << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 6: Chu vi và diện tích hình tròn

Bài tập toán tử

Kiến thức dùng trong phần này nằm ở bài Toán tử trong C++.

Bài 7: Đổi số giây sang giờ:phút:giây

Đề bài: Nhập một số giây, in ra dạng giờ:phút:giây. Ví dụ 3725 giây là 1:2:5.

Gợi ý: 1 giờ = 3600 giây. Số giờ là tongGiay / 3600, phần dư tongGiay % 3600 chia tiếp cho 60 ra số phút, còn số giây là tongGiay % 60.

Lời giải:

#include <iostream>

int main()
{
    int tongGiay;
    std::cout << "Nhap so giay: ";
    std::cin >> tongGiay;

    int gio = tongGiay / 3600;
    int phut = tongGiay % 3600 / 60;
    int giay = tongGiay % 60;

    std::cout << tongGiay << " giay = " << gio << ":" << phut << ":" << giay << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 7: Đổi số giây sang giờ:phút:giây

Bài 8: Kiểm tra chẵn lẻ bằng 2 cách

Đề bài: Nhập một số nguyên, in ra chẵn hay lẻ bằng toán tử % và bằng toán tử bit &. Thử với số âm.

Gợi ý: Với số âm, -7 % 2 ra -1 nên phải kiểm tra != 0 chứ không phải == 1. Cách dùng bit: số lẻ luôn có bit thấp nhất bằng 1, đúng cả với số âm.

Lời giải:

#include <iostream>

int main()
{
    int n;
    std::cout << "Nhap so nguyen: ";
    std::cin >> n;

    // Cach 1: chia lay du, dung != 0 de dung ca voi so am
    std::cout << "Cach 1 (%): " << (n % 2 != 0 ? "le" : "chan") << '\n';

    // Cach 2: bit thap nhat cua so le luon bang 1
    std::cout << "Cach 2 (&): " << ((n & 1) ? "le" : "chan") << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 8: Kiểm tra chẵn lẻ bằng 2 cách

Bài 9: Kiểm tra năm nhuận

Đề bài: Nhập năm, kiểm tra có phải năm nhuận không: chia hết cho 4 nhưng không chia hết cho 100, hoặc chia hết cho 400.

Gợi ý: Viết điều kiện trên một dòng bằng && và ||, thêm ngoặc tròn cho rõ thứ tự. Năm 1900 chia hết cho 4 nhưng không phải năm nhuận vì chia hết cho 100.

Lời giải:

#include <iostream>

int main()
{
    int nam;
    std::cout << "Nhap nam: ";
    std::cin >> nam;

    bool nhuan = (nam % 4 == 0 && nam % 100 != 0) || nam % 400 == 0;
    std::cout << nam << (nhuan ? " la nam nhuan\n" : " khong phai nam nhuan\n");
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 9: Kiểm tra năm nhuận

Bài tập rẽ nhánh

Kiến thức dùng trong phần này nằm ở bài Lệnh rẽ nhánh C++.

Bài 10: Số lớn nhất trong 3 số

Đề bài: Nhập 3 số nguyên, in ra số lớn nhất chỉ dùng if.

Gợi ý: Giả sử số đầu là lớn nhất, rồi so lần lượt với 2 số còn lại. Cách này mở rộng được cho n số.

Lời giải:

#include <iostream>

int main()
{
    int a, b, c;
    std::cout << "Nhap 3 so nguyen: ";
    std::cin >> a >> b >> c;

    int lonNhat = a;
    if (b > lonNhat)
        lonNhat = b;
    if (c > lonNhat)
        lonNhat = c;

    std::cout << "So lon nhat: " << lonNhat << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 10: Số lớn nhất trong 3 số

Bài 11: Số ngày trong tháng

Đề bài: Nhập tháng (1–12), dùng switch in ra số ngày của tháng đó (coi tháng 2 có 28 ngày).

Gợi ý: Gộp các case có cùng số ngày bằng cách viết liền nhau, chỉ đặt break ở cuối nhóm.

Lời giải:

#include <iostream>

int main()
{
    int thang;
    std::cout << "Nhap thang (1-12): ";
    std::cin >> thang;

    switch (thang)
    {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        std::cout << "Thang " << thang << " co 31 ngay\n";
        break;
    case 4: case 6: case 9: case 11:
        std::cout << "Thang " << thang << " co 30 ngay\n";
        break;
    case 2:
        std::cout << "Thang 2 co 28 ngay\n";
        break;
    default:
        std::cout << "Thang khong hop le\n";
        break;
    }
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 11: Số ngày trong tháng

Bài tập vòng lặp

Kiến thức dùng trong phần này nằm ở bài Vòng lặp trong C++.

Bài 12: In các số chẵn từ 1 tới 50

Đề bài: In các số chẵn từ 1 tới 50 trên cùng một dòng.

Gợi ý: Bắt đầu từ 2 và tăng mỗi lần 2 đơn vị (i += 2), không cần kiểm tra chẵn lẻ trong vòng lặp.

Lời giải:

#include <iostream>

int main()
{
    for (int i = 2; i <= 50; i += 2)
        std::cout << i << ' ';
    std::cout << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 12: In các số chẵn từ 1 tới 50

Bài 13: Tổng các chữ số

Đề bài: Nhập một số nguyên dương, in ra tổng các chữ số. Ví dụ 2026 thì in ra 10.

Gợi ý: x % 10 lấy chữ số cuối, x / 10 bỏ chữ số cuối. Lặp tới khi x bằng 0. Chưa biết số có mấy chữ số nên dùng while.

Lời giải:

#include <iostream>

int main()
{
    int n;
    std::cout << "Nhap so nguyen duong: ";
    std::cin >> n;

    int tong = 0;
    int x = n;
    while (x > 0)
    {
        tong += x % 10;   // lay chu so cuoi
        x /= 10;          // bo chu so cuoi
    }
    std::cout << "Tong cac chu so cua " << n << " la " << tong << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 13: Tổng các chữ số

Bài 14: Điểm trung bình, nhập -1 để kết thúc

Đề bài: Nhập điểm của nhiều sinh viên, nhập -1 để kết thúc, in ra điểm trung bình.

Gợi ý: Không biết trước số lần lặp nên dùng while (true) và break khi gặp -1. Nhớ kiểm tra trường hợp chưa nhập điểm nào để không chia cho 0.

Lời giải:

#include <iostream>

int main()
{
    double diem;
    double tong = 0;
    int soSinhVien = 0;

    std::cout << "Nhap diem tung sinh vien, nhap -1 de ket thuc\n";
    while (true)
    {
        std::cout << "Diem: ";
        std::cin >> diem;
        if (diem == -1)
            break;
        tong += diem;
        soSinhVien++;
    }

    if (soSinhVien > 0)
        std::cout << "Trung binh cua " << soSinhVien << " sinh vien: " << tong / soSinhVien << '\n';
    else
        std::cout << "Chua nhap diem nao\n";
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 14: Điểm trung bình, nhập -1 để kết thúc

Bài tập hàm và tham chiếu

Kiến thức dùng trong phần này nằm ở bài Hàm, nạp chồng hàm và tham chiếu của serie.

Bài 15: Hàm kiểm tra năm nhuận

Đề bài: Viết hàm bool laNamNhuan(int nam) và dùng nó in các năm nhuận từ 2000 tới 2030.

Gợi ý: Tách điều kiện ở bài tập 9 thành hàm riêng, main chỉ còn vòng lặp và lời gọi hàm, đọc dễ hơn hẳn.

Lời giải:

#include <iostream>

bool laNamNhuan(int nam)
{
    return (nam % 4 == 0 && nam % 100 != 0) || nam % 400 == 0;
}

int main()
{
    std::cout << "Cac nam nhuan tu 2000 toi 2030:";
    for (int nam = 2000; nam <= 2030; nam++)
    {
        if (laNamNhuan(nam))
            std::cout << ' ' << nam;
    }
    std::cout << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 15: Hàm kiểm tra năm nhuận

Bài 16: Hàm hoán đổi 2 số

Đề bài: Viết hàm void hoanDoi(int& a, int& b) đổi giá trị 2 biến. Thử bỏ dấu & và giải thích.

Gợi ý: Tham số là tham chiếu nên hàm sửa thẳng x, y của main. Bỏ dấu & thì hàm chỉ đổi 2 bản sao, x và y giữ nguyên.

Lời giải:

#include <iostream>

void hoanDoi(int& a, int& b)
{
    int tam = a;
    a = b;
    b = tam;
}

int main()
{
    int x = 3, y = 8;
    std::cout << "Truoc: x = " << x << ", y = " << y << '\n';
    hoanDoi(x, y);
    std::cout << "Sau:   x = " << x << ", y = " << y << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 16: Hàm hoán đổi 2 số

Bài 17: Nạp chồng hàm tính diện tích

Đề bài: Nạp chồng hàm tinhDienTich cho hình vuông (1 tham số int), hình chữ nhật (2 tham số) và hình tròn (1 tham số double). Hình vuông và hình tròn cùng 1 tham số thì có vấn đề gì?

Gợi ý: Nạp chồng hợp lệ vì kiểu tham số khác nhau. Nhưng dòng cuối cho thấy cái bẫy: gọi tinhDienTich(2) với số nguyên thì trình biên dịch chọn bản hình vuông, ra 4 chứ không phải diện tích hình tròn. Muốn tính hình tròn phải truyền 2.0. Đây là lý do không nên nạp chồng các hàm có ý nghĩa khác nhau, đặt tên riêng dienTichHinhVuong, dienTichHinhTron sẽ an toàn hơn.

Lời giải:

#include <iostream>

constexpr double PI = 3.14159265358979;

int tinhDienTich(int canh)                  // hinh vuong
{
    return canh * canh;
}

int tinhDienTich(int dai, int rong)         // hinh chu nhat
{
    return dai * rong;
}

double tinhDienTich(double banKinh)         // hinh tron
{
    return PI * banKinh * banKinh;
}

int main()
{
    std::cout << "Hinh vuong canh 4:        " << tinhDienTich(4) << '\n';
    std::cout << "Hinh chu nhat 4 x 6:      " << tinhDienTich(4, 6) << '\n';
    std::cout << "Hinh tron ban kinh 2.0:   " << tinhDienTich(2.0) << '\n';
    std::cout << "Hinh tron ban kinh 2 (?): " << tinhDienTich(2) << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 17: Nạp chồng hàm tính diện tích

Bài tập string và vector

Kiến thức dùng trong phần này nằm ở bài String và vector trong C++ của serie.

Bài 18: Đếm từ và tìm từ dài nhất

Đề bài: Nhập một câu, đếm số từ (các từ cách nhau bởi dấu cách) và in ra từ dài nhất.

Gợi ý: Duyệt từng ký tự, gom vào tuHienTai cho tới khi gặp dấu cách. Thêm một dấu cách vào cuối câu để từ cuối cùng cũng được xử lý. Kiểm tra empty() để nhiều dấu cách liền nhau không bị đếm thành từ.

Lời giải:

#include <iostream>
#include <string>

int main()
{
    std::string cau;
    std::cout << "Nhap mot cau: ";
    std::getline(std::cin, cau);

    int soTu = 0;
    std::string tuHienTai, tuDaiNhat;
    for (char c : cau + " ")              // them dau cach o cuoi de xu ly tu cuoi cung
    {
        if (c == ' ')
        {
            if (!tuHienTai.empty())
            {
                soTu++;
                if (tuHienTai.size() > tuDaiNhat.size())
                    tuDaiNhat = tuHienTai;
                tuHienTai.clear();
            }
        }
        else
        {
            tuHienTai += c;
        }
    }
    std::cout << "So tu: " << soTu << ", tu dai nhat: " << tuDaiNhat << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 18: Đếm từ và tìm từ dài nhất

Bài 19: Chuỗi đảo ngược và chuỗi đối xứng

Đề bài: Nhập một chuỗi, in ra chuỗi đảo ngược và kiểm tra có phải chuỗi đối xứng không.

Gợi ý: Duyệt ngược từ cuối về đầu. Biến đếm kiểu std::size_t không âm được, nên viết i > 0 và lấy s[i - 1], tránh lỗi vòng lặp vô hạn với số unsigned ở bài vòng lặp.

Lời giải:

#include <iostream>
#include <string>

int main()
{
    std::string s;
    std::cout << "Nhap chuoi: ";
    std::getline(std::cin, s);

    std::string daoNguoc;
    for (std::size_t i = s.size(); i > 0; i--)
        daoNguoc += s[i - 1];

    std::cout << "Dao nguoc: " << daoNguoc << '\n';
    std::cout << (s == daoNguoc ? "La chuoi doi xung\n" : "Khong phai chuoi doi xung\n");
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 19: Chuỗi đảo ngược và chuỗi đối xứng

Bài 20: Điểm cao hơn trung bình

Đề bài: Nhập điểm của n sinh viên vào std::vector<double>, in ra điểm trung bình và các điểm cao hơn trung bình.

Gợi ý: std::vector<double> diem(n) tạo sẵn n phần tử. Phải lưu hết điểm vào vector vì cần duyệt lại lần thứ hai sau khi đã tính xong trung bình.

Lời giải:

#include <iostream>
#include <vector>

int main()
{
    int n;
    std::cout << "So sinh vien: ";
    std::cin >> n;

    std::vector<double> diem(n);
    double tong = 0;
    for (int i = 0; i < n; i++)
    {
        std::cout << "Diem sinh vien " << i + 1 << ": ";
        std::cin >> diem[i];
        tong += diem[i];
    }

    double trungBinh = tong / n;
    std::cout << "Trung binh: " << trungBinh << '\n';
    std::cout << "Cac diem cao hon trung binh:";
    for (double d : diem)
        if (d > trungBinh)
            std::cout << ' ' << d;
    std::cout << '\n';
    return 0;
}

Kết quả:

Kết quả chạy bài tập C++ 20: Điểm cao hơn trung bình

Kết

20 bài tập C++ cơ bản ở trên đi qua toàn bộ nền tảng của ngôn ngữ: nhập xuất, chọn kiểu dữ liệu, toán tử, rẽ nhánh, vòng lặp, hàm, chuỗi và vector. Làm được hết mà không cần xem lời giải là các bạn đã sẵn sàng sang phần con trỏ và lập trình hướng đối tượng.

Khi làm bài mà quên cú pháp hay tên hàm, các bạn tra nhanh trên cppreference, trang tài liệu C++ mà lập trình viên nào cũng dùng.

Lưu ý: Đừng chỉ chạy với dữ liệu trong ví dụ. Thử nhập số âm, số 0, chữ thay vì số, chuỗi rỗng. Phần lớn lỗi của chương trình thật nằm ở những trường hợp này, và tập thói quen thử chúng ngay từ bây giờ sẽ giúp các bạn rất nhiều khi đi làm.

Các bạn đã quen với C có thể luyện thêm với bài tổng hợp bài tập lập trình C cơ bản, rồi thử viết lại bằng C++ với std::string và std::vector. Bài tiếp theo chúng ta sang chương 3 với mảng và con trỏ trong C++. Có cách giải hay hơn thì các bạn để lại bình luận để mọi người cùng tham khảo nhé.

Rate this post

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *