Basic·Bài B0

C++ Template

Trong các kỳ thi tin học, lời giải thường được viết bằng C++. Bạn viết lời giải thành một tệp văn bản; máy chấm biên dịch tệp ấy thành chương trình, chạy nó trên từng bộ dữ liệu rồi so kết quả in ra với đáp án. Vì vậy mọi lời giải, từ bài in một dòng chữ cho tới bài khó của IOI, đều chung một bộ khung và chung một việc cuối cùng: in ra đúng kết quả.

Bài này dạy phần nhỏ nhất mà chương trình nào cũng có: bộ khung, lệnh in chữ và số, phép tính và biến. Các chương trình dưới đây chưa đọc dữ liệu vào mà tự in kết quả; đọc dữ liệu bằng cin là việc của bài B1. Máy không đoán ý bạn, nên ta sẽ nói tới từng dấu chấm phẩy và từng dấu cách.

Bộ khung của một chương trình

Từ ý tưởng tới một chương trình chạy được có ba bước. Viết mã nguồn (source code) vào tệp .cpp; biên dịch (compile), tức nhờ trình biên dịch g++ dịch mã nguồn thành chương trình chạy được; rồi chạy chương trình đó. Trên LQDOJ bạn chọn ngôn ngữ C++ (bản 17 trở lên) và dán mã nguồn vào ô nộp bài, hai bước sau do máy chấm làm. Trên máy cá nhân, bạn dùng một môi trường lập trình như Code::Blocks, Dev-C++ hay VS Code có cài g++, hoặc gõ g++ -std=c++17 main.cpp -o main trong cửa sổ dòng lệnh rồi chạy tệp main vừa tạo.

Đây là khung ta dùng cho cả khóa. Nó in một dòng chữ rồi dừng:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cout << "Hello, World!\n";
}
Chỉ một dòng ở giữa là lệnh thật sự của chương trình; các dòng còn lại là bộ khung dùng lại cho mọi bài.#include <bits/stdc++.h>using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << "Hello, World!\n";}thư viện, vùng tên stdmain: chạy từ đâynhập xuất nhanh (bài B1)lệnh của chương trìnhhết main
Chỉ một dòng ở giữa là lệnh thật sự của chương trình; các dòng còn lại là bộ khung dùng lại cho mọi bài.

Đọc từng dòng, từ trên xuống:

  • #include <bits/stdc++.h> nạp (include) thư viện, tức kho công cụ viết sẵn, trong đó có cout để in. Tệp này đi kèm g++ và gom gần hết thư viện chuẩn vào một dòng nên dân thi đấu hay dùng; trình biên dịch khác như Visual Studio hay clang trên macOS không có nó, khi đó viết #include <iostream>. Dòng bắt đầu bằng # không có dấu ;.
  • using namespace std; Công cụ của thư viện chuẩn nằm trong một “ngăn” tên là std. Có dòng này, ta viết cout thay vì std::cout.
  • int main() { ... } khai báo hàm (một khối lệnh có tên) main, nơi chương trình bắt đầu chạy. Các lệnh trong cặp ngoặc nhọn { } được thực hiện lần lượt từ trên xuống. Mỗi chương trình có đúng một main.
  • ios::sync_with_stdio(false); và cin.tie(0); giúp nhập xuất nhanh hơn. Chương trình này chưa đọc dữ liệu nên chưa thấy lợi; bài B1 sẽ giải thích. Cứ viết sẵn như một thói quen.
  • cout << "Hello, World!\n"; là lệnh thật sự làm việc: in dòng chữ ra màn hình.

Mọi lệnh kết thúc bằng dấu ;, như dấu chấm kết thúc câu; quên nó là lỗi người mới gặp nhiều nhất. C++ phân biệt chữ hoa và chữ thường: Cout, Main, INT đều sai. Nhiều sách còn viết return 0; trước dấu } cuối: main trả về một số nguyên cho hệ điều hành, và 0 nghĩa là chạy xong bình thường. Dòng ấy có thể bỏ vì C++ tự thêm cho main, và khóa này bỏ cho gọn.

Chương trình hỏng theo ba kiểu, và biết mình gặp kiểu nào là xong nửa việc sửa:

  • Lỗi biên dịch (Compile Error): sai cú pháp, g++ từ chối dịch nên không có chương trình nào để chạy.
  • Lỗi khi chạy (Runtime Error): dịch được nhưng chương trình dừng giữa chừng, như khi chia cho 0.
  • Sai kết quả (Wrong Answer): chạy xong bình thường nhưng output khác đáp án.

Lỗi biên dịch có lời báo khá rõ; trên LQDOJ bạn đọc nó ở trang kết quả bài nộp khi nhận Compile Error. Giả sử lệnh cout << "Hello" nằm ở dòng 8 của khung trên, thiếu dấu ;, và dòng 9 là một lệnh cout khác. g++ báo:

main.cpp:8:20: error: expected ';' before 'cout'
    8 |     cout << "Hello"
      |                    ^
      |                    ;

main.cpp:8:20 là tệp, dòng và cột; sau error: là lời mô tả. Ba thói quen giúp đọc nhanh:

  • Sửa lỗi đầu tiên trước rồi biên dịch lại. Các lỗi phía sau thường chỉ là hệ quả: một dấu } thiếu có thể sinh hàng chục dòng lỗi.
  • Nhìn cả dòng được báo lẫn dòng ngay phía trên. Trình biên dịch chỉ nhận ra sai khi đọc tới chỗ vô lý, nên tùy phiên bản g++, thiếu ; có thể bị báo ở chính dòng ấy hoặc ở dòng kế tiếp.
  • Đọc lời mô tả. expected ';' before ... là thiếu ; ở cuối lệnh liền trước; 'Cout' was not declared in this scope là một cái tên chưa khai báo (gõ sai hoa thường, quên nháy kép quanh chữ, hay quên using namespace std;); expected '}' at end of input là có { mở mà chưa đóng.

Cảnh báo (warning) không chặn việc dịch nhưng đừng bỏ qua: lệnh g++ -std=c++17 -Wall main.cpp -o main bật thêm cảnh báo, chẳng hạn khi biến được dùng lúc chưa gán. Với lỗi khi chạy và sai kết quả, g++ không nói gì; ta chạy tay, hoặc chèn lệnh cout in biến giữa chừng để xem chương trình đang làm gì, rồi xóa các lệnh in đó đi.

Ví dụXin chào C++

Đề. In đúng dòng chữ Hello, C++!. Không có dữ liệu vào.

Lời giải. Dùng nguyên bộ khung, chỉ đổi xâu trong lệnh cout. Máy chấm so từng ký tự, nên dấu phẩy, dấu cách, dấu chấm than và hai dấu + phải đúng như đề, cuối dòng có \n.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cout << "Hello, C++!\n";
}

In chữ và số với cout

cout (console output) đại diện cho màn hình. Toán tử << đẩy từng mảnh vào cout, mảnh nào đẩy trước thì hiện trước. Chữ đặt trong nháy kép (xâu ký tự, hay string) được in nguyên văn; số viết thẳng, không cần nháy.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cout << "Score: " << 95 << "\n";
    cout << 1 << 2 << 3 << "\n";
    cout << 1 << " " << 2 << " " << 3 << "\n";
    cout << "Line 1\nLine 2\n";
}

Dòng đầu nối chữ và số trong một lệnh. Dòng hai in 123 dính liền: cout không tự chèn dấu cách, muốn có khoảng trắng phải đẩy " " vào như dòng ba. \n (gạch chéo ngược rồi chữ n) là ký tự xuống dòng; nó có thể nằm giữa một xâu như dòng bốn, hoặc đứng riêng trong nháy đơn '\n' (nháy đơn dành cho đúng một ký tự; bài B1 viết theo cách này, hai cách cho cùng kết quả). Nhiều ngôn ngữ khác tự xuống dòng sau mỗi lệnh in, còn cout thì không: thiếu \n, chữ in sau nối ngay vào chữ trước. Muốn in chính dấu nháy kép hay dấu \ thì viết \" và \\ trong xâu: cout << "\"Hi\"\n"; in ra "Hi". Ta cũng không dùng endl vì nó chậm khi in nhiều dòng; bài B1 nói rõ vì sao.

Bốn chỗ hay sai:

  • Quên nháy kép: cout << Hello; làm g++ đi tìm một biến tên Hello rồi báo lỗi.
  • Gõ /n thay cho \n: máy in hẳn hai ký tự /n. Dấu \ nằm gần phím Enter.
  • Máy chấm so output với đáp án, nên một chữ thừa, một dấu cách thiếu hay một dòng nhắc như Ket qua: đều có thể thành Wrong Answer. Đề viết “không in thêm lời nhắc” vì thế.
  • Chỉ in chữ không dấu: chữ có dấu hiển thị tùy bảng mã của hệ thống, còn đề thi thường chỉ đòi ký tự ASCII.

Hỏi nhanh

Chương trình chỉ có ba lệnh: cout << 1; rồi cout << 2; rồi cout << 3;, không lệnh nào in \n. Màn hình hiện gì?

Ví dụMột hàng số

Đề. In các số 1,2,31, 2, 3 trên một dòng, cách nhau bởi một dấu cách.

Lời giải. cout không tự chèn dấu cách, nên đẩy " " vào giữa các số; thiếu nó thì máy in 123. Kết thúc dòng bằng \n.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cout << 1 << " " << 2 << " " << 3 << "\n";
}

Phép tính với số nguyên

Số nguyên thông thường trong C++ có kiểu int. Năm phép tính là +, -, * (nhân), / (chia) và % (lấy phần dư). Chương trình sau thử từng phép, kèm vài chỗ dễ nhầm:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cout << 8 + 6 << "\n";
    cout << "8 + 6" << "\n";
    cout << 8 - 11 << "\n";
    cout << 8 * 6 << "\n";
    cout << 7 / 2 << "\n";
    cout << 7 % 2 << "\n";
    cout << -7 / 2 << " " << -7 % 2 << "\n";
    cout << 7 / 2.0 << "\n";
    cout << 1 + 2 * 5 << "\n";
    cout << (1 + 2) * 5 << "\n";
    cout << 100 / 5 * 2 << "\n";
    cout << 100 / (5 * 2) << "\n";
}

Dòng một không có nháy kép nên máy tính ra 14; dòng hai có nháy kép nên chỉ in lại chữ 8 + 6.

Chia hai số nguyên cho kết quả nguyên: 7 / 2 là 3, phần lẻ bị bỏ chứ không làm tròn. % cho phần dư của chính phép chia ấy, nên 7 % 2 là 1. Hai phép luôn khớp nhau: a == (a / b) * b + a % b với mọi số nguyên a và b khác 0 (ở đây / là phép chia nguyên của C++), chẳng hạn 7=3⋅2+17 = 3 \cdot 2 + 1. Với số âm, thương bỏ phần lẻ về phía 0 và phần dư mang dấu của số bị chia: -7 / 2 là -3, -7 % 2 là -1. Muốn giữ phần lẻ thì ít nhất một số phải viết dạng số thực (kiểu double, bài B1 nói kỹ), có dấu chấm thập phân: 7 / 2.0 là 3.5. Chia số nguyên cho 0 thường làm chương trình dừng giữa chừng vì lỗi khi chạy.

Thứ tự tính giống toán học: *, /, % trước, +, - sau, nên 1 + 2 * 5 là 11. Dấu ngoặc tròn đổi thứ tự: (1 + 2) * 5 là 15. Các phép cùng mức tính từ trái sang phải, nên 100 / 5 * 2 là (100 / 5) * 2, bằng 40 chứ không phải 10. Phép tính C++ chỉ dùng ngoặc tròn; [ ] và { } mang nghĩa khác. Khi không chắc, cứ thêm ngoặc.

Ô viền cam là phép máy tính tiếp theo; gõ biểu thức khác để thử, chẳng hạn 100 / 5 * 2 hay -7 % 2.

Hỏi nhanh

Giá trị của biểu thức 23 / 4 * 4 + 23 % 4 trong C++ là bao nhiêu?

Ví dụChia kẹo cố định

Đề. Chia đều 17 viên kẹo cho 5 bạn, mỗi bạn nhận một số nguyên viên như nhau; in số kẹo mỗi bạn nhận và số kẹo còn dư trên một dòng, cách nhau một dấu cách.

Lời giải. Số kẹo mỗi bạn nhận là thương nguyên của 17 chia 5, số kẹo dư là phần dư của phép chia ấy: đúng là / và % ở trên. Thương nhân số bạn cộng phần dư trả lại số kẹo ban đầu, 5⋅3+2=175 \cdot 3 + 2 = 17, và phần dư nhỏ hơn số bạn nên không đủ chia thêm mỗi bạn một viên. Cất 17 và 5 vào hai biến có tên để sau này đổi số chỉ sửa một chỗ.

Kéo số kẹo và số bạn: mỗi bạn nhận a / b viên, phần còn lại a % b luôn ít hơn số bạn.

Chỗ dễ sai là quên " " giữa hai số (máy in 32), đảo thứ tự hai số, hay viết 17.0 / 5 làm thương thành 3.4.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int candies = 17, kids = 5;
    cout << candies / kids << " " << candies % kids << "\n";
}

Biến: ô nhớ có tên

Muốn dùng lại một kết quả, ta cất nó vào biến (variable): một ô nhớ có tên, chứa một giá trị. Câu int a = 10; tạo ô kiểu số nguyên tên a và bỏ số 10 vào đó.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a = 10;
    int b = a + 5;
    a = a * 2;
    b += 3;
    cout << a << " " << b << "\n";
}

Dòng một tạo ô a và bỏ 10 vào. Dòng hai lấy giá trị trong a, cộng 5, bỏ vào ô b. Dòng ba đọc a, nhân 2, ghi lại vào a. Dòng bốn là cách viết gọn của b = b + 3. Dấu = là phép gán (assignment), không phải so sánh (so sánh dùng ==, bài B2): máy tính vế phải trước rồi ghi kết quả vào biến bên trái, đè lên giá trị cũ. Vì thế a = a * 2; hợp lệ, đọc là “lấy a, nhân 2, ghi lại vào a”, dù trong toán học a=2aa = 2a chỉ đúng khi a=0a = 0. Các phép gán gộp +=, -=, *=, /=, %= viết gọn hơn, còn a++ nghĩa là a += 1. Gán chỉ chép giá trị tại lúc đó: sau int b = a + 5;, biến b sống riêng, a đổi về sau không kéo b theo, khác với ô công thức trong bảng tính.

Hỏi nhanh

Máy chạy lần lượt int a = 4; int b = a; a = 10; rồi in cout << a << " " << b;. Màn hình hiện gì?

Tên biến gồm chữ cái, chữ số và dấu _, không bắt đầu bằng chữ số, không trùng từ khóa như int, return; total và Total là hai biến khác nhau. Hãy đặt tên theo nghĩa (candies, price) thay vì x1, x2.

Khai báo mà chưa gán giá trị là chỗ sai kinh điển:

C++
int c;
cout << c << "\n";

Biến khai báo trong main mà chưa gán chứa giá trị tùy ý còn sót trong bộ nhớ: hôm nay in 0, mai in một số lạ, nên lỗi lúc có lúc không và rất khó tìm. Luôn gán giá trị đầu ngay khi khai báo, như int c = 0;.

Một int chỉ chứa được các số nguyên từ -2147483648 đến 2147483647, tức cỡ hai tỷ về mỗi phía. Phép tính vượt khỏi khoảng đó không báo lỗi mà trả số sai: đó là tràn số (overflow). Kiểu long long chứa được số lớn hơn nhiều, tới khoảng 9223372036854775807 (số có 19 chữ số):

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    long long a = 50000;
    long long area = a * a;
    cout << area << "\n";
}

Nếu a là int thì tích a * a vẫn tính trong int và tràn ngay, dù kết quả sau đó được cất vào biến long long; máy thường in một số âm vô nghĩa như -1794967296. Vì vậy phải khai báo long long cho chính các biến tham gia phép tính. Quy tắc nhớ: số nào có thể vượt hai tỷ thì dùng long long.

Hỏi nhanh

Ta muốn in đúng tích 50000 * 50000, bằng 2500000000 (hai tỷ rưỡi, vượt int). Cách nào làm được?

Ví dụBiến đầu tiên

Đề. Khai báo một biến số nguyên có giá trị 10, tăng nó thêm 3, rồi in giá trị của biến.

Lời giải. Đề muốn in giá trị của biến, nên in a chứ không in thẳng số 13. a += 3 cộng 3 vào chính a.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a = 10;
    a += 3;
    cout << a << "\n";
}

Bảng theo dõi biến

Chương trình thực hiện từng lệnh theo thứ tự từ trên xuống, và mỗi lệnh chỉ đổi vài biến. Muốn hiểu một đoạn code, hay tìm chỗ sai trong nó, ta chạy tay: kẻ một bảng, mỗi cột một biến, mỗi hàng sau một lệnh, rồi ghi giá trị mới.

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int x = 6;
    int y = x * 2;
    x = x + y;
    y = y - x;
    cout << x << " " << y << "\n";
}
Bấm chạy hoặc dùng mũi tên: dòng tô màu là lệnh vừa chạy, chữ đậm là biến vừa đổi.

Ở lệnh x = x + y;, vế phải dùng giá trị đang có là 6 và 12, rồi kết quả 18 ghi đè lên x; giá trị 6 cũ biến mất. Vì vậy ở lệnh sau, y - x là 12−18=−612 - 18 = -6 chứ không phải 12−612 - 6. Giá trị đã bị ghi đè là mất hẳn, và chính điều này khiến bài hoán đổi ở dưới cần thêm một biến tạm.

Hỏi nhanh

Máy chạy lần lượt int u = 2; int v = u + 3; u = v * 2; v = u - v; rồi in cout << u << " " << v;. Màn hình hiện gì?

Ví dụĐổi giá trị

Đề. Hai biến số nguyên có giá trị lần lượt là 4 và 9; hoán đổi giá trị của hai biến rồi in giá trị mới của chúng trên một dòng, theo thứ tự ban đầu của hai biến.

Lời giải. Viết a = b; b = a; không được: sau lệnh đầu cả hai biến đều là 9, giá trị 4 đã bị ghi đè và mất, đúng như ta thấy ở bảng theo dõi biến. Cần một chỗ cất tạm giá trị cũ của a trước khi ghi đè nó, là biến tạm t: muốn đổi nước giữa hai ly thì phải có ly thứ ba. Ba lệnh theo thứ tự: t = a; rồi a = b; rồi b = t;.

Chạy từng lệnh để thấy 4 được cất vào t trước khi a bị ghi đè. Bấm “Thử bỏ biến tạm” để xem cách sai.

Gọi giá trị ban đầu của a và b là pp và qq. Sau t = a; thì t giữ pp; sau a = b; thì a bằng qq, còn pp vẫn nằm trong t; sau b = t; thì b bằng pp. Đúng là hoán đổi, với mọi giá trị chứ không riêng 4 và 9.

Code đầy đủ
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int a = 4, b = 9;
    int t = a;
    a = b;
    b = t;
    cout << a << " " << b << "\n";
}

Thư viện có sẵn hàm swap(a, b); làm đúng việc này trong một lệnh. Tự viết ba lệnh một lần để hiểu vì sao cần biến tạm; từ các bài sau ta dùng swap cho gọn.

Khi đi thi

  • Dán khung mẫu trước rồi mới nghĩ lời giải; chạy thử trên ví dụ của đề và so output từng ký tự: dấu cách, xuống dòng, không lời nhắc.
  • Gặp lỗi biên dịch thì sửa lỗi đầu tiên, nhìn cả dòng được báo lẫn dòng phía trên nó, rồi biên dịch lại trước khi sửa tiếp.
  • Gán giá trị đầu cho mọi biến, dùng long long khi số có thể vượt hai tỷ, và nhớ / giữa hai số nguyên bỏ phần lẻ.

Tóm tắt

  • Khung: #include <bits/stdc++.h>, using namespace std;, int main() { ... }; mỗi lệnh kết thúc bằng ;, chữ hoa và chữ thường khác nhau.
  • cout << a << b in lần lượt từng mảnh, không tự chèn dấu cách hay xuống dòng; xuống dòng bằng \n.
  • / giữa hai số nguyên bỏ phần lẻ, % lấy phần dư, và a == (a / b) * b + a % b. *, /, % tính trước +, -; cùng mức thì từ trái sang phải.
  • = là phép gán: ghi đè giá trị cũ và chỉ chép giá trị. Luôn gán giá trị đầu; int chứa tới khoảng hai tỷ, vượt thì dùng long long.
  • Hoán đổi hai biến cần một biến tạm; muốn kiểm một đoạn code thì chạy tay bằng bảng theo dõi biến.

Bài tập

1
Lời chào lớp họccanucbasic0e01 · Basic 0 · LuyệnMột dòng chữ có dấu cách giữa các từ; so từng ký tự với đề, kể cả dấu +.
LQDOJ
2
Hai lời chàocanucbasic0l02 · Basic 0 · HọcHai dòng chữ: đặt \n giữa hai từ.
LQDOJ
3
Ba ngày họccanucbasic0e02 · Basic 0 · LuyệnBa dòng, mỗi từ kết thúc bằng \n.
LQDOJ
4
Cột sốcanucbasic0l04 · Basic 0 · HọcNgược với bài trước: mỗi số kết thúc bằng \n.
LQDOJ
5
Nhãn và sốcanucbasic0e03 · Basic 0 · LuyệnChữ và số nối với nhau bằng <<; để ý dấu cách sau dấu hai chấm.
LQDOJ
6
Hình vuông nhỏcanucbasic0e04 · Basic 0 · LuyệnBa lệnh in giống nhau, mỗi lệnh in một dòng ***.
LQDOJ
7
Bậc thang ba tầngcanucbasic0e05 · Basic 0 · LuyệnNhư bài hình vuông nhưng mỗi dòng dài hơn dòng trước một dấu *.
LQDOJ
8
Phép cộng đầu tiêncanucbasic0l05 · Basic 0 · HọcMuốn máy tính tổng thì viết 7 + 5 mà không đặt trong nháy kép.
LQDOJ
9
Ba phép tínhcanucbasic0l06 · Basic 0 · HọcBa kết quả, mỗi kết quả một dòng, đúng thứ tự tổng, hiệu, tích.
LQDOJ
10
Dấu ngoặccanucbasic0l07 · Basic 0 · HọcDấu ngoặc đổi thứ tự tính; thử bỏ ngoặc để thấy kết quả thay đổi ra sao.
LQDOJ
11
Đọc thứ tự phép tínhcanucbasic0e07 · Basic 0 · LuyệnNhân tính trước, trừ tính sau; tự tính tay ra đáp án rồi đối chiếu với chương trình.
LQDOJ
12
Chu vi cố địnhcanucbasic0e06 · Basic 0 · LuyệnChu vi là hai lần tổng chiều dài và chiều rộng; chú ý dấu ngoặc khi viết biểu thức.
LQDOJ
13
Hóa đơn nhỏcanucbasic0e10 · Basic 0 · LuyệnMỗi loại hàng là số lượng nhân đơn giá, rồi cộng hai loại lại.
LQDOJ
14
Chiếc hộp nhỏcanucbasic0l10 · Basic 0 · HọcThể tích là tích ba cạnh; lưu ba cạnh vào ba biến có tên rõ nghĩa.
LQDOJ
15
Theo dõi biếncanucbasic0e09 · Basic 0 · LuyệnGán lại chính biến sau mỗi bước, như a = a * 3;, theo đúng thứ tự đề bài.
LQDOJ

Đọc thêm

  • Hello, World!OI WikiChọn môi trường lập trình, cài trình biên dịch, biên dịch bằng dòng lệnh g++ và chương trình đầu tiên, viết cho người thi đấu (tiếng Trung).
  • Tôi đã học tin học như thế nào? Phần 2VNOI WikiKinh nghiệm của một cựu tuyển thủ: vì sao chọn C++, dùng công cụ nào, biên dịch bằng g++ ra sao và nên làm những bài nào trước.
  • Structure of a programcplusplus.comGiải thích từng dòng của chương trình đầu tiên, vùng tên std, chú thích và dấu chấm phẩy.
  • Arithmetic operatorsLearn C++Phép chia nguyên và chia cho 0, những chỗ dễ nhầm của toán tử số học.
  • Signed integersLearn C++Khoảng giá trị của từng kích thước số nguyên và điều xảy ra khi vượt khỏi khoảng đó.
  • Uninitialized variables and undefined behaviorLearn C++Vì sao biến chưa gán giá trị gây lỗi lúc có lúc không.