Viết chương trình nhập vào 2 số nguyên a và b từ bàn phím sau đó tính c a,b in ra kết quả của c
Loading Preview Show
Sorry, preview is currently unavailable. You can download the paper by clicking the button above. Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu về kiểu dữ liệu, hằng và biến - những khái niệm cơ sở của mọi ngôn ngữ lập trình. I. Kiểu dữ liệuCác bài toán trong thực tế thường sẽ có dữ liệu đầu vào và kết quả ra thuộc những kiểu dữ liệu quen thuộc như số nguyên, số thực,...Việc sử dụng các kiểu dữ liệu có liên quan mật thiết đến các phép toán có thể thao tác trên dữ liệu và bộ nhớ cấp phát cho dữ liệu đó. Mỗi ngôn ngữ lập trình sẽ cung cấp cho người dùng một số kiểu dữ liệu và cho biết phạm vi lưu trữ cũng như các phép toán có thể tác động lên dữ liệu kiểu đó. Đối với ngôn ngữ C++, người dùng được cung cấp sẵn 777 kiểu dữ liệu nguyên thủy (Primitive Type) dưới đây: 2. Phạm vi của các kiểu dữ liệuMỗi kiểu dữ liệu đều có một phạm vi lưu trữ nhất định. Ngoài ra, người dùng có thể thêm vào một số modifier ở phía trước dữ liệu để thay đổi khoảng giá trị của kiểu. Có 444 loại modifier:
Bảng dưới đây thống kê phạm vi lưu trữ cũng như bộ nhớ tiêu tốn của các kiểu dữ liệu dạng số trong C++ kèm theo modifier của chúng: Ngoài ra, C++ cung cấp một số từ khóa để đưa ra giá trị nhỏ nhất và lớn nhất lưu trữ được của một kiểu dữ liệu, thể hiện trong bảng dưới đây: Riêng với kiểu dữ liệu char, kiểu này có thể lưu được cả số lẫn kí tự. Đối với kí tự, kiểu char lưu trữ được toàn bộ 256256256 kí tự thuộc bảng mã ASCII - là bảng kí tự và mã kí tự sử dụng trong tin học và một số lĩnh vực khác. II. Khai báo hằng và biếnĐịnh nghĩa: Hằng là giá trị cố định, không thể thay đổi trong suốt chương trình sau khi đã khai báo. Khai báo hằng thường được sử dụng cho các giá trị xuất hiện nhiều lần trong chương trình. Cú pháp khai báo: const {Kiểu_dữ_liệu} {Tên_hằng} = {Giá_trị};Ví dụ: const double pi = 3.14;Sử dụng: Sau khi được khai báo, hằng số có thể được sử dụng trong các câu lệnh, đi kèm với các toán tử trong C++. Thông thường, khai báo hằng số được đặt ngay sau phần khai báo thư viện và không gian tên của chương trình. Dưới đây là ví dụ đưa ra diện tích của một hình tròn có bán kính bằng 2.52.52.5 sử dụng hằng số pi=3.14\text{pi} = 3.14pi=3.14: #include2. Khai báo và sử dụng biếnĐịnh nghĩa: Biến là giá trị sử dụng trong chương trình, có thể thay đổi tùy ý người sử dụng. Các biến trong chương trình cũng đều phải được đặt tên và khai báo cho chương trình dịch biết. Cú pháp khai báo: {Kiểu_dữ_liệu} {Danh_sách_biến} = {Giá_trị_ban_đầu_nếu_có};Ví dụ: int x, y; int index = 1;Sử dụng: Sau khi được khai báo, biến có thể được sử dụng trong các câu lệnh, đi kèm với các toán tử trong C++. Dưới đây là ví dụ đưa ra tổng của hai số 101010 và 151515: #include3. Lưu ý khi khai báo và sử dụng hằng, biếnCác tên biến, tên hằng, tên của các hàm,...đều được gọi chung là các định danh (identifier). Các định danh do người dùng đặt ra cần tuân theo một số quy tắc chung sau đây:
III. Biến tự động (automatic variables)Định nghĩa: Biến tự động là một phát triển rất tiện lợi của phiên bản C++11, nó cho phép người dùng sử dụng từ khóa auto để khai báo một biến mà không cần biết trước kiểu dữ liệu của biến đó. Từ khóa auto sẽ tự động chọn kiểu phù hợp cho biến. Điều này có thể không cần thiết đối với những kiểu dữ liệu nguyên thủy, tuy nhiên sẽ rất thuận lợi khi cần dùng các kiểu dữ liệu phức tạp sau này, hay thậm chí là tự động chọn kiểu trả về cho một hàm. Ngoài ra bạn có thể kiểm tra kiểu trả về của biến bằng cú pháp: typeid({Tên_biến}).name();Ví dụ: int main() { auto x = 6.5F; auto y = 7.1; auto k = 10; cout << x << endl; cout << "Kiểu của x: " << typeid(x).name() << endl; cout << y << endl; cout << "Kiểu của y: " << typeid(y).name() << endl; cout << k << endl; cout << "Kiểu của k: " << typeid(k).name(); return 0; }Kết quả: III. Câu lệnh nhập - xuất cơ bản trong C++C++ cung cấp hai câu lệnh nhập xuất dữ liệu nằm trong thư viện Đối với câu lệnh cin, bạn chỉ được phép sử dụng nó để nhập vào giá trị cho các biến. Ví dụ, các câu lệnh cin >> a;, cin >> x >> y;,...là các câu lệnh hợp lệ; ngược lại cin >> 4;, cin >> int x;, cin >> "number";,...là không hợp lệ và sẽ báo lỗi. Đối với câu lệnh cout, bạn chỉ được phép sử dụng nó để in ra giá trị của các biến - biểu thức có giá trị, hoặc các hằng số, hoặc các kí tự và chuỗi kí tự. Khi đưa ra một kí tự thì đặt kí tự đó trong cặp dấu '', còn khi đưa ra một chuỗi thì đặt chuỗi đó trong cặp dấu "". Ví dụ, cout << 5;, cout << a + b;, cout << "Hello World";,...là các câu lệnh hợp lệ; ngược lại các câu lệnh cout << a = 5;, cout << int g = a + b;,...là không hợp lệ và sẽ báo lỗi. Các lệnh cin và cout cũng có thể được áp dụng với nhiều biến, biểu thức hoặc hằng phía sau Khi cần nhập hay xuất nhiều đối tượng liên tiếp, chỉ cần phân tách chúng bằng các dấu >> hoặc << tương ứng. Đối với lệnh cin, khi sử dụng để nhập giá trị cho nhiều biến thì phân tách chúng trong khi nhập bằng dấu cách hoặc dấu xuống dòng. Chẳng hạn: cin >> a >> b; hay cout << "Tổng các số từ 1 tới " << N << " là: " << S;. Ví dụ: Chương trình dưới đây cho phép nhập vào hai số nguyên aaa và bbb từ bàn phím sau đó đưa ra tổng của hai số đó: int main() { int a, b; cin >> a >> b; cout << a + b; }IV. Ép kiểu cho biến và hằngTrong khi tính toán, có nhiều trường hợp kết quả của biểu thức cần tính sẽ có kiểu dữ liệu khác với các toán hạng trong biểu thức. Đơn cử một trường hợp như khi phải tính giá trị thập phân của một số hữu tỉ ab,\frac{a}{b},ba, với a,b∈(Z)a, b \in \mathbb(Z)a,b∈(Z). Theo tư duy thông thường, nhiều bạn sẽ viết chương trình như thế này: int main() { int a, b; cin >> a >> b; cout << "Giá trị thập phân là: " << a / b; }Nếu chạy chương trình này với a=5,b=4,a = 5, b = 4,a=5,b=4, điều gì sẽ xảy ra? Có phải kết quả là 1.251.251.25 hay không? Không may là không! Kết quả của chương trình sẽ đưa ra như sau: Giá trị thập phân là: 1Lí giải cho điều này, đó là do aaa và bbb đều có kiểu dữ liệu số nguyên, mà kết quả của toán tử / trong C++ sẽ phụ thuộc vào kiểu của hai toán hạng. Vì thế, kết quả của phép tính a / b sẽ tự động chọn kiểu là số nguyên, mà số nguyên thì chỉ có thể lấy giá trị phần nguyên của số 1.251.251.25 thôi. Những trường hợp kiểu như vậy xuất hiện khá nhiều trong các phép tính, khi đó chúng ta cần sử dụng ép kiểu. Tựu chung lại, có 333 trường hợp cần sử dụng tới ép kiểu:
2. Cách ép kiểu cho biến và hằngĐể ép kiểu cho biến trong C++, ta sử dụng cú pháp: ({Kiểu_dữ_liệu_mới}) {Tên_biến}Toàn bộ cụm biến đã được ép kiểu có thể được sử dụng vào các phép tính như bình thường, nhưng sẽ có kiểu dữ liệu khác so với ban đầu khai báo (chỉ trong phép tính đó). Việc ép kiểu có thể làm thay đổi khoảng giá trị biểu diễn của một biến, ví dụ như từ số thực trở thành số nguyên, hoặc từ số nguyên sang số thực, từ kí tự sang mã của kí tự,...Điều này có khá nhiều tác dụng trong lập trình thi đấu nói riêng và lập trình nói chung, bởi trong nhiều thời điểm chúng ta sẽ cần những giá trị ở kiểu khác nhau của biến. Ví dụ 1: Đưa ra bình phương của số thực NNN và giá trị làm tròn của số thực NNN: int main() { double N = 7.5; cout << N * N << endl; cout << (int)N; }Kết quả 1: 56.25 7Ví dụ 2: Đưa ra vị trí của kí tự xxx trong bảng kí tự ASCII: int main() { char x = 'A'; cout << (int)x; }Kết quả 2: Lưu ý:
V. Biểu diễn số thực trong C++Trong toán học, để biểu diễn các số thực rất nhỏ hoặc rất lớn, thông thường người ta sử dụng kí hiệu khoa học, đó là biểu diễn các số dựa trên lũy thừa cơ số 10. Ví dụ, khối lượng của một electron là 9.1093822×10−31,9.1093822 \times 10^{-31},9.1093822×10−31, hay mol\text{mol}mol - một đơn vị đo lường trong hóa học có giá trị là 6.022×1023,...6.022 \times 10^{23},...6.022×1023,... Trong C++, ta sử dụng kí tự eee để thay cho giá trị (×10)(\times 10)(×10) khi biểu diễn số thực. Ví dụ:
2. Độ chính xác của kiểu số thựcNhư ta đã biết, có hai kiểu dữ liệu hỗ trợ biểu diễn số thực trong C++ ở dạng dấu chấm động là float và double. Mặc định một hằng số thực trong C++ luôn luôn có kiểu là double, còn nếu muốn sử dụng kiểu float thì ta thêm hậu tố f vào sau hằng số thực (chẳng hạn 3.5f). Các số thực có dạng hữu hạn và dạng vô hạn. Đối với dạng vô hạn, sẽ có vô số chữ số phía sau dấu chấm thập phân, tuy nhiên bộ nhớ máy tính và kích thước kiểu dữ liệu thì lại hữu hạn. Các biến kiểu thực chỉ có thể lưu được một số lượng chữ số nhất định phía sau dấu chấm thập phân, và phần còn lại sẽ bị bỏ đi. Trong C++, câu lệnh cout mặc định sẽ có độ chính xác là 666 chữ số đối với số thực kể cả phần thực lẫn phần phân. Những số ngoài phạm vi sẽ bị cắt bỏ và làm tròn lên 1 đơn vị nếu số bị cắt sau nó lớn hơn 5, hoặc số đó có thể được chuyển sang ký hiệu khoa học trong vài trường hợp tùy vào từng trình biên dịch. Cùng xem ví dụ sau: #includeBiên dịch và chạy chương trình trên với CodeBlocks, ta thu được kết quả: 9.87654 9.87654e+006 9.87654e-005 1.23457Đối với kiểu float, độ chính xác sẽ là 777 chữ số phần phân, còn với kiểu double, độ chính xác lên tới 161616 chữ số phần phân. Do đó, khi cần sử dụng tới số thực với độ chính xác cao, kiểu double nên được ưu tiên để tránh sai số ở mức tối đa. 3. Làm tròn số thựcBạn có thể làm tròn được các số thực tới số lượng chữ số mà mình mong muốn bằng cách sử dụng hàm setprecision trong thư viện Sử dụng hàm này, chúng ta có thể điều chỉnh số chữ số sẽ xuất hiện sau dấu chấm động của một hằng hoặc biến kiểu thực, đồng thời chương trình cũng sẽ tự làm tròn lên 111 đơn vị cho chữ số cuối cùng nếu như chữ số đầu tiên trong phần bị cắt đi lớn hơn 555. Chẳng hạn, khi viết ra số thực 9.876543219.876543219.87654321 với 333 chữ số phần phân, ta viết như sau: #includeKết quả thu được sẽ là: 9.877Tuy nhiên, như đã nói ở trên, kiểu dữ liệu số thực trong C++ chỉ cung cấp độ chính xác tối đa tới 161616 chữ số, nên nếu như bạn cố viết ra các số thực với độ chính xác nhiều hơn 161616 chữ số, sẽ dẫn đến kết quả bị sai số nhất định. Điều này hầu như sẽ không xảy ra trong các bài toán lập trình thi đấu, nên chúng ta không cần quá lo lắng về nó! 4. So sánh bằng nhau giữa hai số thựcTrong C++, khi so sánh giữa hai số thực, nếu như chúng đều là các số thực hữu hạn thì không có gì đáng lưu tâm cả. Tuy nhiên, nếu so sánh những số thực vô hạn, thì sẽ không bao giờ xảy ra trường hợp chúng bằng nhau hoàn toàn được cả, vì số chữ số chính xác của kiểu dữ liệu là hữu hạn. Lấy ví dụ, số 1.01.01.0 khi chia cho 333 bằng 0.333333...,0.333333...,0.333333..., nhưng nếu đem 333 giá trị 0.333333...0.333333...0.333333... cộng với nhau thì chỉ thu được kết quả là 0.999999...,0.999999...,0.999999..., rõ ràng khác với 1.01.01.0. Cùng xem một ví dụ sau để hiểu kĩ hơn: #includeKết quả của đoạn chương trình trên sẽ là: 0.1 0.1000000000000000555Mặc dù cùng là số d=0.1,d = 0.1,d=0.1, nhưng khi làm tròn tới 202020 chữ số thì ta lại thu được một giá trị lớn hơn 0.10.10.1. Lí do là vì, dữ liệu kiểu double chỉ có thể cho độ chính xác tới 161616 chữ số, nếu người dùng muốn làm tròn ngoài khoảng đó thì sẽ xảy ra lỗi làm tròn dấu chấm động. Bởi thế, khi so sánh giữa hai số thực trong C++, ta chỉ có thể sử dụng các phép toán <, >, <= và >= thôi, còn riêng với phép toán ==, thì cần sử dụng đến một khái niệm là độ chính xác epsilon. Cụ thể, với hai số thực aaa và b,b,b, muốn biết chúng có bằng nhau hay không, người ta sẽ lựa chọn một giá trị thật nhỏ (thông thường là 10−610^{-6}10−6), đặt nó làm giá trị epsilon. Sau đó, xét hiệu ∣a−b∣,|a - b|,∣a−b∣, nếu hiệu này nhỏ hơn hoặc bằng epsilon thì sẽ coi rằng aaa và bbb bằng nhau. Ngược lại thì aaa và bbb sẽ khác nhau. Chi tiết về cài đặt các bạn sẽ hiểu rõ hơn khi học tới bài Cấu trúc rẽ nhánh. VI. Tài liệu tham khảo |