Java Bài 5: Toán Tử (Operator)

Posted by

Được chỉnh sửa ngày 1/9/2017.

Chào mừng các bạn quay trở lại với bài học Java số 5 trong chuỗi bài viết về lập trình ngôn ngữ Java của Yellow Code Books.

Nếu như ở bài trước các bạn đã làm quen với việc khai báo và sử dụng các biến và hằng trong Java. Thì đến bài hôm nay chúng ta cùng học cách vận dụng các biến và hằng này vào các logic tính toán trong chương trình, thông qua việc tìm hiểu về các Toán Tử.

Trước khi vào làm quen với các Toán Tử, mình muốn nói về khái niệm Biểu Thức cái đã.

Biểu Thức

Bạn nên biết là lập trình không khác gì làm toán cả, tất cả chúng ta, những Lập Trình Viên, chỉ đơn giản là đang vận dụng các phép toán mà chúng ta đã từng được học vào trong việc lập trình ra các ứng dụng mà thôi. Và để làm quen lại với kiến thức toán, chúng ta cùng quay về với khái niệm Biểu Thức. Trong toán học định nghĩa rằng Biểu Thức là sự kết hợp giữa các Toán Tử (Operator) và các Toán Hạng (Operand) theo đúng một trật tự nhất định. Trong đó mỗi Toán Hạng có thể là một Hằng, một Biến hoặc một Biểu Thức khác.

Mình xin minh họa một Biểu Thức như sau.

Operator - Minh họa

Qua đó * + là các Toán Tử. 2, y5 là các Toán Hạng, trong đó 25 là các Hằng, còn y là Biến.

Cũng giống như trong toán học, bạn có thể dùng cặp dấu ngoặc đơn () để gom nhóm các Biểu Thức lại, và khi đó thì Biểu Thức trong dấu ngoặc đơn này sẽ được ưu tiên thực hiện trước.

Ví dụ minh họa cho một Biểu Thức có dấu ngoặc đơn.

2 * (y + 5)

Toán Tử Gán

Giờ chúng ta cùng ra xa khỏi toán học một chút để đi sâu vào kiến thức lập trình. Thì ngoài các Toán Tử cộng, trừ, nhân chia trong toán học ra, chúng ta còn có nhiều Toán Tử đặc thù khác của lập trình, một trong những Toán Tử chúng ta làm quen đầu tiên hôm nay đó là Toán Tử Gán.

Trong Java, Toán Tử Gán được thực hiện thông qua ký hiệu “=”. Quen lắm phải không nào, vì bài trước bạn đã thực hành khai báo một biến như sau int count = 5; thì dấu “=” ở đây chính là một phép gán. Phép gán được định nghĩa cụ thể thông qua cú pháp.

tên_biến = biểu_thức

Khi đó kết quả của một biểu_thức (biểu_thức này có thể là một Biểu Thức gồm nhiều Toán Tử và Toán Hạng, hay có thể chỉ là một con số như các ví dụ ở bài trước) sẽ được gán vào tên_biến. Tức là tên_biến sẽ chứa đựng giá trị bằng với biểu_thức mang đến thông qua phép gán này.

Bài Thực Hành Số 1

Với bài thực hành này, bạn hãy thực hiện phép gán sau đây và cho biết kết quả in ra log sau khi gán giá trị cho biến thisYear là gì nhé.

final int THIS_YEAR = 2016;
int thisYear = 2000;
thisYear = THIS_YEAR;

System.out.println("This year is " + thisYear);

Kết quả như sau, bạn nên thử chạy bằng Eclipse, hoặc tự đoán kết quả trước khi click vào bên dưới.

This year is 2016

Gán Cho Nhiều Biến Cùng Lúc

Trong trường hợp bạn có một giá trị giống nhau được gán cho nhiều biến khác nhau, thay vì như ví dụ dưới đây bạn phải gán giá trị đó cho từng biến một.

int x = 10;
int y = 10;
int z = 10;

Thì bạn có thể thực hiện việc gán chỉ với một dòng như dưới đây. Đảm bảo đúng.

Đúng
int x;
int y;
int z;
x = y = z = 10;

Hoặc bạn có thể viết ngắn gọn hơn, cách viết này gom các khai báo biến với cùng một kiểu dữ liệu vào cùng một dòng.

Đúng
int x, y, z;
x = y = z = 10;

Nhưng lưu ý bạn không thể viết như vậy được.

Sai
int x = int y = int z = 10;

Toán Tử Số Học

Chúng ta làm quen với Toán Tử thứ hai của lập trình, Toán Tử này thì hoàn toàn giống với toán học, đó là các phép toán cộng, trừ, nhân, chia. Các phép toán này được gom lại chung vào một Toán Tử, gọi là Toán Tử Số Học. Cụ thể về các Toán Tử Số Học được mình liệt kê ở bảng sau.

Toán Tử Ý Nghĩa
+ Toán Tử Cộng, có thể cộng các số, và còn có thể cộng Chuỗi sẽ được mình nói cụ thể ở bài học chuỗi sau.
Toán Tử Trừ.
* Toán Tử Nhân.
/ Toán Tử Chia lấy phần nguyên, ví dụ 5/2 sẽ bằng 2, phần dư bị loại bỏ.
% Toán Tử Chia lấy phần dư, ví dụ 5%2 sẽ bằng 1, đó chính là số dư của phép chia.

Bài Thực Hành Số 2

Bạn hãy thử code để biết kết quả in ra của phép gán từ một Biểu Thức tới biến age với các Toán Tử Số Học như sau.

int age;
int thisYear = 2016;
int yearOfBirth = 1990;
age = thisYear - yearOfBirth;
System.out.println("I am " + age + " years old");

Bạn có thể xem kết quả bằng cách click vào mục dưới đây.

I am 26 years old

Bài Thực Hành Số 3

Bạn thử đoán xem kết quả in ra của các các so1, so2, và so3 như ví dụ bên dưới, và xem kết quả có đúng với bạn đoán không nhé.

int so1;
int so2;
float so3;

so1 = 15 / 6;
so2 = 15 % 6;
so3 = 15 / 6;

System.out.println("Ket qua so1 la " + so1 + ", so2 la " + so2 + ", so3 la " + so3);

Và kết quả.

Ket qua so1 la 2, so2 la 3, so3 la 2.0

Toán Tử Một Ngôi

Một Toán Tử đặc trưng của lập trình nữa, đó là Toán Tử Một Ngôi. Với Toán Tử này, thì chỉ cần một Toán Tử kết hợp với một Toán Hạng thôi là đã có thể cho ra kết quả. Các bạn hãy nhìn vào bảng sau.

Toán Tử Ý Nghĩa
+ Toán Tử Cộng, toán tử cộng này khác với toán tử cộng ở bảng Số Học trên, toán tử này biểu diễn số dương. Vì các số dương bình thường không cần phải hiển thị toán tử này, nên bạn cũng sẽ không thấy công dụng của nó.
Toán Tử Trừ, ngược lại với toán tử cộng ở trên, toán tử trừ này biểu diễn số âm.
++ Toán Tử Tăng, toán tử này sẽ làm tăng giá trị của toán hạng lên 1 đơn vị.
– – Toán Tử Giảm, toán tử này sẽ làm giảm giá trị của toán hạng đi 1 đơn vị.
! Toán Tử Phủ định logic. Toán tử này sẽ đảo ngược giá trị của biến biểu thức logic. Nếu biểu thức logic đang là true thì sẽ bị đảo ngược thành false và ngược lại

Bài Thực Hành Số 4

Bạn hãy nhìn biểu thức dưới đây, soGi sẽ được gán bằng một Biểu Thức, mà ở đó soDuong được cộng với một Toán Tử Một Ngôi biểu thị số âm.

int soDuong = 4;
int soGi = soDuong + -10;
System.out.println("Ket qua la " + soGi);

Và kết quả như sau chắc bạn cũng dễ dàng đoán được.

Ket qua la -6

Bài Thực Hành Số 5

Bạn hãy chú ý vào các Toán Tử “++”“- -“ sau đây, như đã nói, các Toán Tử này sẽ làm Toán Hạng đứng sau nó tăng lên hoặc giảm đi 1 rồi mới thực hiện các phép toán khác.

int so1 = 4;
int so2 = 10;
int soKetQua = ++so1 + --so2;
System.out.println("So1 la " + so1 + ", so2 la " + so2 + ", ket qua la " + soKetQua);

Và kết quả là.

So1 la 5, so2 la 9, ket qua la 14

Mình xin giải thích một chút ở Bài Thực Hành Số 5 trên đây, vì Toán Tử Một Ngôi dạng này sẽ hơi lạ với các bạn mới làm quen với lập trình. Với việc thực hiện Biểu Thức soKetQua = ++so1 + – -so2; hệ thống sẽ thực hiện biểu thức ++so1 trước và so1 sau đó mang giá trị là 5 (++so1 lúc bấy giờ tương tự như biểu thức so1 = so1 + 1; vậy), rồi hệ thống cũng thực hiện tiếp – -so2 ra giá trị 9 (tương tự thì – -so2 cũng sẽ giống như so2 = so2 – 1;), sau cùng thì tiến hành cộng hai số này lại và gán cho biến soKetQua.

Có bạn nào thắc mắc là hai cách viết ++so1 và so1++ có khác nhau không? Câu trả lời là Có. Cũng giống như C/C++, khi bạn viết ++so1, Java sẽ thực hiện việc tăng giá trị của so1 trước khi lấy giá trị đó dùng vào trong Biểu Thức. Còn nếu viết so1++, Java sẽ lấy giá trị của so1 dùng vào trong Biểu Thức trước khi tăng giá trị của nó.

Để hiểu rõ hơn bạn thử sửa code trên lại một chút như sau và chạy lại nhé.

int so1 = 4;
int so2 = 10;
int soKetQua = so1++ + so2;
System.out.println("So1 la " + so1 + ", so2 la " + so2 + ", ket qua la " + soKetQua);

Kết quả in ra là.

So1 la 5, so2 la 10, ket qua la 14

Với thử nghiệm trên, bạn thấy so1++ không hề được áp dụng tăng giá trị của so1 vào biểu thức, mà so1 vẫn mang giá trị 4 rồi cộng với so210 ra kết quả 14. Sau khi thự hiện xong Biểu Thức thì so1 mới được tăng giá trị và vì vậy bạn thấy in ra so15.

Toán Tử Quan Hệ

Toán Tử Quan Hệ sẽ so sánh các Biểu Thức với nhau để cho ra một giá trị boolean, tức là cho ra một trong hai giá trị là true hay false. Bạn hãy nhìn vào bảng để xem các Toán Tử Quan Hệ sau.

Toán Tử Ý Nghĩa
== Bằng
!= Không bằng (khác)
> Lớn hơn
>= Lớn hơn hoặc bằng
< Nhỏ hơn
<= Nhỏ hơn hoặc bằng

Chú ý rằng kết quả của Toán Tử này luôn trả về một giá trị boolean nhé.

Bài Thực Hành Số 6

Bạn thử ngẫm xem kết quả in ra sẽ là giá trị true hay false nhé.

double weight = 71.23;
int height = 191;
boolean married = false;
boolean attached = false;
char gender = 'm';

System.out.println("Ket qua 1: " + (!married == attached));
System.out.println("Ket qua 2: " + (gender != 'f'));
System.out.println("Ket qua 3: " + (height >= 180));
System.out.println("Ket qua 4: " + (weight > 90));

Bạn đã có kết quả của riêng mình chưa? Nếu có rồi thì click vào kết quả bên dưới để so sánh nhé.

Ket qua 1: false
Ket qua 2: true
Ket qua 3: true
Ket qua 4: false

Toán Tử Điều Kiện

Các Toán Tử Điều Kiện sẽ so sánh các Biểu Thức mang giá trị truefalse với nhau. Toán Tử này còn được gọi là Toán Tử Logic. Bạn cứ tưởng tượng toán tử này sẽ hoạt động theo kiểu câu nói “nếu trời không mưa và tôi có tiền thì tôi sẽ đi chơi hôm nay”, trong đó ” nếu trời không mưa” mang một giá trị boolean, “tôi có tiền” cũng là một giá trị boolean, hai giá trị này được so sánh bởi Toán Tử “và”. Vậy nếu “trời không mưa” “tôi có tiền” đều mang giá trị true thì kết quả so sánh sẽ là true, tức “tôi sẽ đi chơi hôm nay” true, tức là tôi sẽ đi chơi. Ngược lại nếu một trong hai vế đầu là false thì kết quả sẽ là false, tức tôi sẽ không đi chơi. Các Toán Tử Điều Kiện được nêu trong bảng sau.

Toán Tử Ý Nghĩa
&& So sánh AND.
|| So sánh OR.
?: So sánh theo điều kiện, sẽ được nhắc đến khi chúng ta học đến cách viết điều kiện if..else..bài học sau.

Sau đây là Bảng chân trị, tức các kết quả so sánh điều kiện của các Toán Tử &&|| như sau.

p q p && q p || q
false false false false
false true false true
true false false true
true true true true

Bài Thực Hành Số 7

Bạn thử gõ các câu lệnh sau và ngẫm kết quả của nó nhé.

int age = 18;
double weight = 71.23;
int height = 191;
boolean married = false;
boolean attached = false;
char gender = 'm';

System.out.println(!married && !attached && (gender == 'm'));
System.out.println(married && (gender == 'f'));
System.out.println((height >= 180) && (weight >= 65) && (weight <= 80));
System.out.println((height >= 180) || (weight >= 90));

Kết quả như sau.

true
false
true
true

Chúng ta thử giải nghĩa dòng in log thứ nhất để hiểu rõ hơn. Đầu tiên biến married có giá trị false, !married đảo ngược giá trị thành true. Tương tự attchedfalse!attachedtrue, (gender == ‘m’) sẽ là true. Tóm lại chúng ta có true && true && true, và kết quả cuối cùng theo bảng chân trị là true.

Dòng thứ hai, ưu tiên biểu thức trong ngoặc đơn trước (gender == ‘f’) sẽ cho kết quả false. Biến married được khai báo là false. false && false kết quả theo bảng chân trị là false.

Bạn cứ giải nghĩa tương tự cho các dòng còn lại.

Toán Tử Bitwise

Toán Tử Bitwise là Toán Tử sẽ tương tác trực tiếp đến các bit của Toán Hạng. Để hiểu về việc làm việc với các bit là gì thì dài dòng lắm, có thể mình sẽ nói rõ hơn ở các bài khác. Nhưng bạn có thể hiểu là bản chất của tất cả dữ liệu mà máy tính có thể hiểu và làm việc chính là các dữ liệu dạng nhị phân được biểu diễn chỉ bởi hai giá trị là 01. Mỗi một giá trị 0 hay 1 như vậy là một bit, do đó có thể nói Toán Tử Bitwise là Toán Tử tương tác trực tiếp đến các bit là vậy.

Lưu ý là Toán Tử Bitwise này sẽ không làm việc được với các dữ liệu thuộc kiểu số thực (floatdouble).

Bảng sau là Toán Tử Bitwise.

Toán Tử Ý Nghĩa
& AND
| OR
^ XOR
~ NOT, đảo ngược bit 0 thành 1, và ngược lại 1 thành 0.
>> Dịch phải
<< Dịch trái

Bạn nên nhớ AND ở Toán Tử Bitwise chỉ có một dấu &, còn AND ở Toán Tử Điều Kiện có hai dấu &&. Và một điều khác nhau nữa là && chỉ so sánh các Biểu Thức boolean với nhau, còn & so sánh dựa trên các bit, và vì vậy & có thể làm việc với mọi kiểu dữ liệu nguyên thủy trong Java trừ kiểu số thực đã nói ở trên. Tương tự cho khác nhau giữa |||.

Vậy trước khi đi vào bài thực hành Toán Tử Bitwise, bạn hãy xem qua Bảng chân trị cho Bitwise như sau.

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

Bài Thực Hành Số 8

Ở bài thực hành này chúng ta cùng code thử các Toán Tử Bitwise như sau, mình sẽ giải thích kết quả tại sao ở bên dưới bài thực hành này.

byte so1 = 5;
byte so2 = 12;

System.out.println("Toan tu &: " + (so1 & so2));
System.out.println("Toan tu |: " + (so1 | so2));
System.out.println("Toan tu ^: " + (so1 ^ so2));
System.out.println("Toan tu ~: " + (so1 & ~so2));
System.out.println("Toan tu <<: " + (so1<<1));
System.out.println("Toan tu >>: " + (so2>>2));

Kết quả ở dưới đây.

Toan tu &: 4
Toan tu |: 13
Toan tu ^: 9
Toan tu ~: 1
Toan tu <<: 10
Toan tu >>: 3

Giờ hãy cùng nhau giải thích ý nghĩa của các phép toán. Chúng ta đều biết kiểu dữ liệu byte được hệ thống cấp phát cho 1 byte bộ nhớ, và 1 byte = 8 bits, vậy hai biến so1so2 có giá trị lần lượt là 512 sẽ được biểu diễn dạng bit như sau.

5   = 0000 0101
12 = 0000 1100

so1 & so2: nếu bạn lấy 0000 0101 & 0000 1100, bạn hãy áp dụng bảng chân trị vào so sánh từng bit với nhau, bạn sẽ có kết quả là 0000 0100, đây là biểu diễn bit của số 4, và là kết quả của dòng log đầu tiên.

so1 | so2: tương tự như trên 0000 0101 | 0000 1100 sẽ là 0000 1101, là dạng bit của số 13.

so1 ^ so2: 0000 0101 ^ 0000 1100 sẽ là 0000 1001, là dạng bit của số 9.

so1 & ~so2: ta xét từ ~so2, ~ là toán tử NOT, nó sẽ đảo ngược các bit của so2 thành 1111 0011, vậy so1 & ~so2 sẽ là 0000 0101 & 1111 0011, sẽ là 0000 0001, là dạng bit của số 1.

so1<<1: tức là lấy dãy bit của so1 dịch trái đi 1 bit, sẽ thành 0000 1010, là dạng bit của số 10.

so2>>2: tức là lấy dãy bit của so2 dịch phải đi 2 bit, sẽ thành 0000 0011, là dạng bit của số 3.

Chúng ta vừa mới đi qua bài học về các Toán Tử trong Java, qua bài học hôm nay bạn đã hiểu rõ hơn ngôn ngữ Java hơn rồi đúng không nào. Các Toán Tử hôm nay sẽ được ứng dụng khá nhiều vào các kiến thức và bài thực hành sau này. Bạn hãy cố gắng theo dõi các bài học thú vị phía trước nhé.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy đánh giá 5 sao nếu thấy thích bài viết, hãy comment bên dưới nếu có thắc mắc, hãy để lại địa chỉ email của bạn để nhận được thông báo mới nhất khi có bài viết mới, và nhớ chia sẻ các bài viết của Yellow Code Books đến nhiều người khác nữa nhé.

Bài Kế Tiếp

Bạn sẽ cùng nhau xem qua cách thức ép kiểu, và cách ghi chú vào source code nhé.

Advertisements
Rating: 5.0/5. From 10 votes.
Please wait...

Gửi phản hồi