Toán tử quan hệ, logic, bitwise, misc và độ ưu tiên toán tử trong C++

Dẫn nhập

Ở bài học trước, bạn đã nắm được TOÁN TỬ SỐ HỌC, TOÁN TỬ TĂNG GIẢM VÀ TOÁN TỬ GÁN TRONG C++.

Từ bây giờ, mình sẽ chỉ dẫn về Toán tử quan hệ, logic, bitwise, misc và độ ưu tiên toán tử trong C++ (Operators).

Bài viết

Để đọc hiểu bài này tốt nhất các chúng ta nên có học thức căn bản về các phần:

Trong bài ta sẽ cùng khám phá các vấn đề:

  • Toán tử quan hệ trong C++
  • Toán tử logic trong C++
  • Toán tử trên bit trong C++
  • Các toán tử hỗn hợp trong C++
  • Độ ưu tiên toán tử trong C++

Toán tử quan hệ trong C++ (Relational operators)

Toán tử quan hệ dùng để so sánh 2 toán hạng với nhau. Sẽ trả về 2 giá trị là 1 (true) hoặc 0 (false).

Bảng bên dưới miêu tả các toán tử quan hệ trong C++, giả sử x = 6, y = 9

Lưu ý: Phân biệt toán tử gán bằng (=) và toán tử so sánh bằng (==).

Chẳng hạn:

#include <iostreamvàgt;
using namespace std;

int sum(int a, int b)
{
	return a + b;
}

int main()
{
	cout << "Enter an integer: ";
	int x;
	cin >> x;

	cout << "Enter another integer: ";
	int y;
	cin >> y;

	if (x == y)
		cout << x << " == " << y << "n";
	if (x != y)
		cout << x << " != " << y << "n";
	if (x > y)
		cout << x << " > " << y << "n";
	if (x < y)
		cout << x << " < " << y << "n";
	if (x >= y)
		cout << x << " >= " << y << "n";
	if (x <= y)
		cout << x << " <= " << y << "n";

	return 0;
}

Outputs:

Toán tử quan hệ và so sánh số chấm động?

Trong lập trình, việc so sánh trực tiếp 2 số chấm động là điều không nên và có thể cho ra những kết quả không mong chờ. Này là do lỗi làm tròn của số chấm động, vấn đề này đã được giải thích trong bài SỐ TỰ NHIÊN & SỐ CHẤM ĐỘNG TRONG C++ (Integer, Floating point).

Chẳng hạn:

#include <iostreamvàgt;
#include <iomanipvàgt;	// for std::setprecision()
using namespace std;

int main()
{
	double	d1{ 1.0 };
	double	d2{ 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 };

	if (d1 == d2)
		cout << "d1 == d2" << "n";
	else if (d1 > d2)
		cout << "d1 > d2" << "n";
	else if (d1 < d2)
		cout << "d1 < d2" << "n";

	cout << std::setprecision(20);	// show 20 digits
	cout << "d1 = " << d1 << endl;
	cout << "d2 = " << d2 << endl;

	return 0;
}

Outputs:

Trong chương trình trên, trong toán học thì 2 biến d1 == d2, nhưng trong lập trình biến d1 > d2 vì lỗi làm tròn số dấu chấm động.

Tương đương, bạn hãy thử với trường hợp 0.1 + 0.7 == 0.8 ?

Lưu ý: Không lúc nào so sánh hai giá trị dấu chấm động bằng nhau hay không. Hầu hết luôn luôn có sự độc đáo nhỏ giữa hai số chấm động. Cách thông dụng để so sánh 2 số chấm động là tính khoảng cách giữa 2 số đó, nếu khoảng cách này là rất nhỏ thì ta nghĩ rằng bằng nhau. Giá trị dùng để so sánh với khoảng cách đó thường được gọi là epsilon.

Toán tử logic trong C++ (Logical operators)

Nếu chỉ sử dụng toán tử quan hệ để so sánh biểu thức quan hệ đúng hay sai, bạn chỉ có thể kiểm soát một điều kiện tại một thời điểm. Nhưng thực tiễn, có lúc bạn sẽ cần kiểm soát nhiều điều kiện đồng thời.

Xem Thêm  Top 12 kết quả tìm kiếm download clash of clans for pc mới nhất 2022

Chẳng hạn: để trở thành một soái ca thì bạn cần phải có nhiều điều kiện như cầm, kỳ, thi, họa. Hiện tại chẳng những dễ dàng 1 điều kiện nữa.

Toán tử logic (Logical operators) sẽ kiểm soát nhiều điều kiện đồng thời giúp bạn. Có 3 toán tử logic trong C++

Lưu ý: Luôn sử dụng dấu ngoặc đơn () khi thực hiện với các mệnh đề quan hệ để trổ tài cụ thể ý nghĩa dòng lệnh và giới hạn sai sót. Với phương pháp này, bạn thậm chí không cần nhớ nhiều về độ ưu tiên toán tử.

Chẳng hạn:

#include <iostreamvàgt;
#include <iomanipvàgt;	// for std::setprecision()
using namespace std;

int main()
 (value == 100))
		cout << value << " == 1 or "<< value <<" == 100" << endl;
	else
		cout << value << " != 1 or " << value << " != 100" << endl;

	return 0;

Outputs:

Toán tử trên bit trong C++ (Bitwise operators)

Toán tử trên bit dùng để thao tác với các bit trên một biến.

Vì sao cần thao tác trên bit? Trong dĩ vãng, bộ nhớ lưu trữ laptop chưa lớn mạnh, vấn đề về làm chủ bộ nhớ lưu trữ là rất quan trọng. Chính vì thế, người lập trình cần tận dụng tối đa các bit trong bộ nhớ lưu trữ.

Chẳng hạn: Các biến được lưu trong bộ nhớ lưu trữ ở một địa chỉ duy nhất, những địa chỉ này được xác nhận với nhà cung cấp nhỏ đặc biệt là byte. Xét kiểu dữ liệu bool, nó chỉ nắm giữ 2 giá trị true (1) hoặc false (0). Kiểu bool chỉ cần 1 bit để lưu trữ dữ liệu, nhưng nó lại chiếm giữ 1 byte trong bộ nhớ lưu trữ, vậy 7 bit sót lại sẽ là phung phí. Sử dụng toán tử trên bit giúp bạn có thể chứa 8 biến kiểu bool vào 1 byte duy nhất, và tiết kiệm bộ nhớ lưu trữ đáng kể.

Trong dĩ vãng, sử dụng toán tử trên bit rất được ưu chuộng. Ngày nay, bộ nhớ lưu trữ laptop đã lớn mạnh và tiết kiệm hơn, lập trình viên thường quan tâm đến tính dễ hiểu và dễ cải tiến của mã nguồn. Cho nên, việc thao tác trên bit không còn được ưu chuộng, ngoại trừ những trường hợp cần tối ưu tối đa tốc độ, bộ nhớ lưu trữ (những chương trình thao tác big data, những game lớn, lập trình nhúng …).

Vì các toán tử trên bit ít gặp nên mình chỉ giới thiệu qua cho các bạn xem qua, bạn có thể tự tham khảo thêm nếu mong muốn nâng cao hơn.

Xem Thêm  Top 7 Phần Mềm Làm Nhạc Beat Miễn Phí Tốt Nhất Để Tạo Nhạc Từ Android - phần mềm tạo nhạc beat android

Bảng bên dưới gồm 6 toán tử thao tác trên bit

Bảng bên dưới gồm 5 toán tử gán trên bit

Các toán tử hỗn hợp trong C++ (Misc Operators)

Sizeof operator

Để xác nhận kích cỡ của một kiểu dữ liệu trên một laptop rõ ràng và cụ thể, C++ phân phối cho bạn toán tử sizeof. Toán tử sizeof là toán tử một ngôi, nhận vào một kiểu dữ liệu hoặc một biến, và trả về kích cỡ (byte) của kiểu dữ liệu hoặc biến đó. Toán tử này sizeof đã được giải thích cụ thể trong bài Số tự nhiên và Số chấm động trong C++ (Integer, Floating point).

Comma operator

Các biểu thức đặt cách nhau bằng dấu phẩy (,), các biểu thức con lần lượt được tính từ trái

sang phải. Biểu thức mới thu được là giá trị của biểu thức bên phải cùng.

Chẳng hạn:

x = (a++, b = b + 2);

// Tương tự với
a++; b = b + 2; x = b;

hoặc

int x = 0;
int y = 2;
int z = (++x, ++y); // increment x and y

// Tương tự với
int x = 0;
int y = 2;
++x;
++y;
int z = y;

Lưu ý: Dấu phẩy có ưu tiên thấp nhất trong toàn bộ các toán tử. 

Chính vì thế, hai dòng code sau đây sẽ cho kết quả khác nhau:

z = (a, b); // z = b
z = a, b;   // z = a, và b bị bỏ qua

Lưu ý: Tránh sử dụng các toán tử dấu phẩy (,), loại trừ trường hợp dùng trong vòng lặp. Vấn đề về vòng lặp sẽ được chỉ dẫn cụ thể trong bài VÒNG LẶP FOR TRONG C++ (For statements).

Conditional operator

Toán tử điều kiện ( ?: ) là toán tử 3 ngôi duy nhất trong C++ (có 3 toán hạng), tương tự với câu điều kiện ( if/else statements ).

Cấu tạo câu điều kiện if/else:

if (condition)     // nếu condition là true
     expression1;  // thực thi câu lệnh này
else
     expression2;  // nếu condition là false, thực thi câu lệnh này

Hoặc :

if (condition)     // nếu condition là true
     x = value1;   // x = value 1
else
     x = value2;   // nếu condition là false, x = value 2

Viết lại dưới dạng toán tử điều kiện ( ?: ):

(condition) ? expression1 : expression2;

Hoặc:

x = (condition) ? value1 : value2;

Chẳng hạn:

#include <iostreamvàgt;
using namespace std;

int main()
{
int x{ 6 }, y{ 9 }, max;
	if (x > y)
	{
		max = x;
	}
	else
	{
		max = y;
	}
	cout << "Max = " << max << endl;

	// Tương tự với
	max = (x > y) ? x : y;
	cout << "Max = " << max << endl; 

	return 0;
}

Outputs:

Lưu ý: Chỉ sử dụng toán tử điều kiện với những câu điều kiện dễ dàng.

Chẳng hạn:

#include <iostreamvàgt;
using namespace std;

int main()
{
int a{ 3 }, b{ 2 }, c{ 4 }, max;

	// Khó hiểu, dễ sai => Không nên
	max = a > b ? (a > c ? a : c) : (b > c ? b : c);
	cout << "Max = " << max << endl;

	// Dễ hiểu => Nên
	max = a;
	if (max < b)
	{
		max = b;
	}
	if (max < c)
	{
		max = c;
	}
	cout << "Max = " << max << endl; 

	return 0;
}

Outputs:

Xem Thêm  two IFrames

Lưu ý: Toán tử điều kiện ( ?: ) có thể là một biểu thức (expression), trong khi câu điều kiện ( if/else ) chỉ là một câu lệnh (statements).

Chẳng hạn:

bool bIsVip = true;

// Initializing a const variable
const double dPrice = bIsVip ? 1000 : 500;

Trong chẳng hạn trên, chẳng thể dùng câu điều kiện ( if/else ) để thay thế. Vì một hằng số phải được khởi tạo giá trị tại thời điểm khai báo.

Một số toán tử khác

Độ ưu tiên và nguyên tắc phối hợp toán tử trong C++

Để nhận xét đúng một biểu thức như 6 + 9 * 8, bạn cần tinh thông ý nghĩa mỗi toán tử trong biểu thức đó, và thứ tự thực hiện của nó. Thứ tự thực hiện của các toán tử trong 1 biểu thức gọi là độ ưu tiên của toán tử (operator precedence).

Khi vận dụng độ ưu tiên toán tử, biểu thức bên trên sẽ tương tự với 6 + ( 9 * 8 ) = 78. Phép nhân (*) có độ ưu tiên cao hơn phép cộng (+), compiler sẽ auto hiểu và thực hiện đúng theo độ ưu tiên của từng toán tử.

Khi 2 toán tử có cùng độ ưu tiên trong 1 biểu thức, các nguyên tắc phối hợp (associativity rules) sẽ nói cho compiler biết nên thực hiện từ trái sang phải (L->R) hay từ phải sang trái (R->L).

Chẳng hạn: bạn có biểu thức 6 * 9 / 8. Trong biểu thức này, phép nhân (*) và chia (/) cùng độ ưu tiên, nhưng nó có nguyên tắc phối hợp từ trái sang phải (L->R). Chính vì thế nó sẽ tương tự (6 * 9) / 8.

Bảng độ ưu tiên (operator precedence) và nguyên tắc phối hợp (associativity rules) các toán tử trong C++

Có thể bạn sẽ không hiểu phần nhiều những toán tử trong bảng trên ở thời điểm này, bạn chỉ cần quan tâm đến những toán tử vừa học ở phần trên. Những toán tử sót lại bạn có thể tự khám phá nếu bạn có nhu cầu đặt biệt nào đó.

Tổng kết

Qua bài học này, bạn đã nắm được Toán tử quan hệ, logic, bitwise, misc và độ ưu tiên toán tử trong C++ (Operators).

Ở bài kế đến, bạn sẽ được học về CƠ BẢN VỀ CHUỖI KÝ TỰ TRONG C++ (String), là tiền đề để bạn có thể giải được các bài toán trong lập trình.

Cảm ơn các bạn đã theo dõi nội dung. Hãy để lại comment hoặc phản hồi của mình để lớn mạnh nội dung tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.

Luận bàn

Nếu bạn có bất kỳ khổ cực hay khúc mắc gì về khóa học, đừng ngần ngại đặt thắc mắc trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để thu được sự trợ giúp từ cộng đồng.

Viết một bình luận