Phân Tích Chi Tiết Đề Thi Chứng Chỉ Lập Trình C++ GESP Cấp Độ 1 Tháng 9/2024

Phần Trắc Nghiệm Khách Quan

Mỗi câu hỏi đúng được 2 điểm, tổng cộng 30 điểm.

Câu 1

Theo tài liệu lưu trữ, máy tính DJL-1 do Đại học Sơn Đông nghiên cứu thành công năm 1972 và đưa vào vận hành năm 1973, có hiệu năng tổng hợp đứng thứ ba toàn quốc thời bấy giờ. Bộ phận điều khiển运算 của máy tính DJL-1 sử dụng linh kiện lưu trữ lõi từ tính được cấu tạo từ các hạt lõi từ, với chu kỳ lưu trữ thiết kế là 2μs (micro giây). Linh kiện lưu trữ lõi từ này tương đương với thành phần nào trong máy tính hiện đại?

A. Bộ nhớ trong (RAM)
B. Ổ đĩa cứng
C. Bộ xử lý trung tâm (CPU)
D. Màn hình hiển thị

Đáp án: A

  • Phân tích: Linh kiện lõi từ là công nghệ lưu trữ sớm, cho phép đọc và ghi dữ liệu. Chu kỳ 2 micro giây chỉ thời gian cho một thao tác đọc/ghi. Chức năng chính là lưu trữ tạm thời để CPU truy xuất nhanh, tương đương với RAM hiện nay. Ổ đĩa dùng lưu trữ dài hạn, CPU xử lý lệnh, màn hình hiển thị kết quả.

Câu 2

Khi chương trình C++ gặp lỗi, phương pháp debug nào ít được sử dụng phổ biến nhất?

A. Đọc lại mã nguồn
B. Debug từng bước (Step-by-step)
C. In ra kết quả trung gian
D. Theo dõi mã hợp ngữ (Assembly)

Đáp án: D

  • Phân tích: Đọc code, debug từng bước và in log là các phương pháp tiêu chuẩn. Theo dõi mã hợp ngữ đòi hỏi kiến thức sâu về底层 và thường chỉ dùng cho tối ưu hóa hiệu năng hoặc lỗi rất phức tạp, không phải cách debug thông thường.

Câu 3

Trong C++, biểu thức nào sau đây là sai cú pháp?

A. cout << "Hello,GESP!" << endl;
B. cout << 'Hello,GESP!' << endl;
C. cout << """Hello,GESP!""" << endl; 
D. cout << "Hello,GESP!' << endl;

Đáp án: D

  • Phân tích:
    • A: Đúng, chuỗi ký tự hợp lệ.
    • B: Sai về ngữ nghĩa (dùng đơn cho chuỗi) nhưng một số compiler có thể cảnh báo, tuy nhiên D sai cú pháp rõ ràng hơn.
    • C: Đúng, compiler có thể xử lý nhiều dấu nháy kép liên tiếp tùy ngữ cảnh cụ thể hoặc coi là chuỗi rỗng nối tiếp, nhưng D là lỗi cú pháp rõ ràng do không đóng ngoặc kép đúng cách.
    • D: Sai, chuỗi bắt đầu bằng " nhưng kết thúc bằng ', không khớp cặp dấu nháy.

Câu 4

Giá trị của biểu thức C++ 10 - 3 * 2 là bao nhiêu?

A. 14
B. 4 
C. 1 
D. 0

Đáp án: B

  • Phân tích: Ưu tiên phép nhân trước: 3 * 2 = 6. Sau đó thực hiện phép trừ: 10 - 6 = 4.

Câu 5

Giả sử N là số nguyên dương 10, lệnh cout << (N / 3 + N % 3) sẽ xuất ra giá trị nào?

A. 6
B. 4.3 
C. 4 
D. 2

Đáp án: C

  • Phân tích:
    1. Phép chia nguyên: 10 / 3 = 3 (loại bỏ phần thập phân).
    2. Phép chia lấy dư: 10 % 3 = 1.
    3. Tổng: 3 + 1 = 4.

Câu 6

Kết quả xuất ra màn hình sau khi thực hiện lệnh printf("6%2={%d}", 6%2); là gì?

A. "6%2={6%2}"
B. 6%2={6%2} 
C. 0=0
D. 6%2={0}

Đáp án: D

  • Phân tích: %d là ký tự định dạng cho số nguyên. Giá trị 6%2 bằng 0. Chuỗi ký tự % đầu tiên trong printf cần được escape nếu muốn in ra ký tự %, nhưng ở đây 6%2 trong chuỗi định dạng sẽ được hiểu là in ra ký tự '%' nếu viết đúng cách, tuy nhiên trong ngữ cảnh câu hỏi này, %d thay thế bằng 0. Kết quả là 6%2={0}.

Câu 7

Nếu lần lượt nhập 5 và 2 từ bàn phím cho đoạn mã sau, kết quả là gì?

cin >> a;
cin >> b;
cout << a + b;
A. Xuất ra số nguyên 7
B. Xuất ra 52, không có khoảng trắng
C. Xuất ra 5 và 2, có khoảng trắng
D. Kết quả không xác định do thiếu khai báo kiểu dữ liệu

Đáp án: D

  • Phân tích: Biến ab chưa được khai báo kiểu dữ liệu (int, char, float...). Nếu là int thì tổng là 7, nếu là char thì là tổng mã ASCII. Do thiếu thông tin này, kết quả không thể xác định chính xác.

Câu 8

Đoạn mã C++ dưới đây xuất ra giá trị nào?

int tong = 0;
for(int idx = 0; idx < 10; idx++) 
	tong += idx;
cout << tong;
A. 55 
B. 45 
C. 10 
D. 9

Đáp án: B

  • Phân tích: Vòng lặp cộng dồn các số từ 0 đến 9. Tổng dãy số này là 45.

Câu 9

Đoạn mã C++ dưới đây xuất ra giá trị nào?

int dem = 0;
for(int idx = 0; idx < 10; idx++) 
	dem += 1;
cout << dem;
A. 55
B. 45 
C. 10 
D. 9

Đáp án: C

  • Phân tích: Vòng lặp chạy 10 lần, mỗi lần tăng biến đếm lên 1. Kết quả cuối cùng là 10.

Câu 10

Đoạn mã C++ dưới đây xuất ra giá trị nào?

int dem = 0; 
for(int idx = 1; idx < 10; idx += 2){
	if (idx % 2 == 1)
	    continue;
	dem += 1;
}
cout << dem;
A. 5 
B. 4 
C. 2 
D. 0

Đáp án: D

  • Phân tích: Vòng lặp bắt đầu từ 1, bước nhảy 2 nên idx luôn là số lẻ (1, 3, 5...). Điều kiện idx % 2 == 1 luôn đúng, lệnh continue luôn được thực hiện, bỏ qua lệnh tăng biến dem. Kết quả dem giữ nguyên bằng 0.

Câu 11

Nhập vào 14+7, đoạn mã sau xuất ra gì?

int P; 
printf("Nhap so nguyen duong P: "); 
scanf("%d", &P); 
if(P % 3 || P % 7)
	printf("Dong 5: %d, %d", P % 3, P % 7); 
else
	printf("Dong 7: %2d", P % 3 && P % 7);
A. Dong 5: 2, 0 
B. Dong 5: 1, 0 
C. Dong 7: 1 
D. Dong 7: 0

Đáp án: A

  • Phân tích: scanf chỉ đọc số nguyên đầu tiên là 14, bỏ qua phần sau. 14 % 3 = 2 (khác 0, true), 14 % 7 = 0 (false). Biểu thức if dùng OR (||) nên đúng. In ra giá trị dư tương ứng là 2 và 0.

Câu 12

Kết quả xuất ra của đoạn mã sau là gì?

int count= 0, i, s;
for(i = 0, s = 0;i < 20; i++, count++) 
	s += i++;
cout << s << " " <<count;
A. 190 20 
B. 95 10 
C. 90 19 
D. 90 10

Đáp án: D

  • Phân tích: Trong vòng lặp, i tăng 2 lần (một lần trong thân loop i++, một lần trong biểu thức update i++). Vòng lặp thực chất chạy 10 lần. Các giá trị cộng vào s là 0, 2, 4..., 18. Tổng là 90. Biến count tăng 10 lần.

Câu 13

Đoạn mã sau dự tính đếm số chữ số của số nguyên N. Đâu là nhận định đúng?

int N, N0, rc = 0;
cout << "Nhap so nguyen:"; 
cin >> N;
N0 = N; 
while (N){
	rc++;
	N /= 10;
}
printf("%d la %d chu so\n", N, rc); // L11
A. Biến N0 thừa, có thể xóa
B. Code đúng với mọi số nguyên
C. Sửa dòng L11 có thể cho kết quả đúng với số dương
D. Định dạng xuất ở L11 sai

Đáp án: C

  • Phân tích: Sau vòng lặp, N bằng 0. Dòng in cần dùng N0 để hiển thị số gốc. Sửa thành printf("%d la %d chu so\n", N0, rc); sẽ đúng cho số dương.

Câu 14

Đoạn mã tính tổng chữ số hàng trăm của các số nguyên dương 5 chữ số liên tiếp. Nhận định nào sai?

int M, Tong = 0, rc = 0;
cout << "Nhap so nguyen:"; 
cin >> M;
while (M){
    M = (M / 100 % 10); // L6
    Tong += M;
    rc++;
    cin >> M;
}
cout << rc << " so nguyen duong 5 chu so, tong chu so hang tram la " << Tong;
A. Nhập 23221 23453 12345 11111 0, Tong cuối cùng là 10
B. Nhập số không đủ 5 chữ số, program vẫn chạy
C. Đổi L6 thành M = (M % 1000 / 100); vẫn đúng
D. Đổi L6 thành M = (M % 100 / 10); vẫn đúng

Đáp án: D

  • Phân tích: Công thức M % 100 / 10 lấy chữ số hàng chục, không phải hàng trăm. Do đó D sai.

Câu 15

Số nguyên dương N gọi là "số anh em" nếu N = X * (X + 1). Điền vào chỗ trống để kiểm tra điều kiện này, có bao nhiêu cách điền đúng?

int N;
cin >> N; 
for(int i = 0; i <= N; i++)
	if(________)
		cout << N << " la so anh em\n";
i) N == i * (i + 1)  
ii) N == i * (i - 1)  
iii) N / (i + 1) == i  
iv) N / (i - 1) == i
A. 1 
B. 2 
C. 3 
D. 4

Đáp án: B

  • Phân tích:
    • i) Đúng theo định nghĩa.
    • ii) Sai công thức.
    • iii) Đúng về mặt toán học (biến đổi từ i).
    • iv) Sai công thức.
    Có 2 cách đúng là i và iii.

Phần Đúng/Sai

Mỗi câu đúng 2 điểm, tổng 20 điểm.

  1. C++ là ngôn ngữ hướng đối tượng và thuộc nhóm ngôn ngữ bậc cao.
    Đáp án: Đúng. C++ hỗ trợ OOP và trừu tượng hóa cao so với mã máy.
  2. Biểu thức 10/4 và 10%4 cùng bằng 2 nên có thể thay thế nhau.
    Đáp án: Sai. Ý nghĩa khác nhau (chia lấy nguyên vs chia lấy dư), kết quả chỉ trùng hợp ở số liệu này.
  3. scanf("%d", &N) sẽ lỗi nếu input chứa chữ cái.
    Đáp án: Sai. scanf sẽ đọc phần số hợp lệ đầu tiên và dừng lại, phần còn lại lưu trong buffer.
  4. Đoạn code vòng lặp cộng dồn sau sẽ xuất ra 45.
    Đáp án: Sai. Biến tổng chưa được khởi tạo, giá trị rác có thể làm kết quả sai.
  5. Biểu thức (X++, X+1) / 10 với X=20.24 (int) ra 2.124.
    Đáp án: Sai. Phép chia nguyên lấy phần nguyên, kết quả là 2.
  6. Vòng lặp for(i=1; i<10; i+=3) lần cuối xuất ra 10.
    Đáp án: Sai. Lần cuối thỏa mãn điều kiện là i=7. Khi i=10 vòng lặp dừng.
  7. break thường dùng với if.
    Đáp án: Sai. break thường dùng trong vòng lặp hoặc switch để thoát khối.
  8. Không thể đặt tên biến là five-star.
    Đáp án: Đúng. Ký tự '-' không được phép trong tên biến.
  9. Các kiểu int, float, char, bool đều so sánh được lớn nhỏ.
    Đáp án: Đúng. Chúng đều có thể quy đổi về số để so sánh.
  10. Với a=5,b=4,c=3 thì (a<b<c) là false.
    Đáp án: Sai. a<b ra 0 (false), sau đó 0<c (0<3) ra 1 (true).

Phần Lập Trình

Bài 1: Tính Toán Ngân Sách Mua Sắm

Mô tả: Bạn có tổng cộng n đồng. Giá商品 A là a, giá商品 B là b. Cần mua số lượng A và B bằng nhau. Tính số lượng tối đa mỗi loại có thể mua.

Dữ liệu vào: 3 dòng lần lượt là n, a, b.

Dữ liệu ra: Một số nguyên duy nhất.

Ví dụ: Input: 12, 1, 2. Output: 4. (Vì 4*1 + 4*2 = 12).

#include <iostream>

using namespace std;

int main() {
    // Tối ưu hóa tốc độ I/O
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int nganSach, giaA, giaB;
    if (cin >> nganSach >> giaA >> giaB) {
        int tongGiaMotCap = giaA + giaB;
        // Tránh chia cho 0 nếu giá trị không hợp lệ (mặc dù đề bài bảo số dương)
        if (tongGiaMotCap > 0) {
            int soLuongToiDa = nganSach / tongGiaMotCap;
            cout << soLuongToiDa << endl;
        } else {
            cout << 0 << endl;
        }
    }
    return 0;
}

Bài 2: Đếm Số Đẹp

Mô tả: Cho n số nguyên dương. Một số được gọi là "đẹp" nếu nó chia hết cho 9 nhưng không chia hết cho 8. Đếm số lượng số đẹp.

Dữ liệu vào: Dòng 1 là n. Dòng 2 là n số nguyên.

Dữ liệu ra: Số lượng số đẹp tìm được.

Ví dụ: Input: 3 \n 1 9 72. Output: 1. (Chỉ có 9 thỏa mãn).

#include <iostream>
#include <vector>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int soLuongSo;
    cin >> soLuongSo;

    int demSoDep = 0;
    for (int idx = 0; idx < soLuongSo; ++idx) {
        int giaTri;
        cin >> giaTri;
        
        bool chiaHetCho9 = (giaTri % 9 == 0);
        bool chiaHetCho8 = (giaTri % 8 == 0);

        if (chiaHetCho9 && !chiaHetCho8) {
            demSoDep++;
        }
    }

    cout << demSoDep << endl;

    return 0;
}

Thẻ: gesp c++-level-1 lap-trinh-co-ban ky-thi-lap-trinh

Đăng vào ngày 17 tháng 05 lúc 07:13