Toán tử trong C++

Một toán tử là một biểu tượng, mà nói cho compiler thực hiện các thao tác toán học và logic cụ thể. C++ cung cấp nhiều toán tử có sẵn, đó là:

  • Toán tử số học
  • Toán tử quan hệ
  • Toán tử logic
  • Toán tử so sánh bit
  • Toán tử gán
  • Toán tử hỗn hợp

Toán tử số học trong C++

Bảng dưới liệt kê các toán tử số học được hỗ trợ bởi ngôn ngữ C++:

Giả sử biến A giữ giá trị 10, biến B giữ 20 thì:

Toán tửMiêu tảVí dụ
+Cộng hai toán hạngA + B kết quả là 30
-Trừ toán hạng thứ hai từ toán hạng đầuA - B kết quả là -10
*Nhân hai toán hạngA * B kết quả là 200
/Phép chiaB / A kết quả là 2
%Phép lấy số dưB % A kết quả là 0
++Toán tử tăng (++), tăng giá trị toán hạng thêm một đơn vịA++ kết quả là 11
--Toán tử giảm (--), giảm giá trị toán hạng đi một đơn vịA-- kết quả là 9

Toán tử tăng (++)

Toán tử tăng (++) cộng toán hạng thêm một đơn vị, và toán tử giảm (--) trừ một đơn vị từ toán hạng. Do vậy:

x=x+1; tương tự x++;

Tương tự như vậy:

x = x-1; tương tự x--;

Cả toán tử tăng và toán tử giảm đều có dạng tiền tố đặt trước hoặc hậu tố theo sau toán hạng. Ví dụ:

x = x+1;
có thể được viết dưới dạng
++x; // đây là dạng có tiền tố đặt trước

hoặc dạng:

x++; //dạng hậu tố

Khi một toán tử tăng hay toán tử giảm được sử dụng như là một phần của biểu thức, thì sẽ có một sự khác nhau quan trọng giữa dạng tiền tố và hậu tố. Nếu bạn sử dụng dạng tiền tố thì toán tử tăng hoặc toán tử giảm được thực hiện trước biểu thức, và nếu bạn sử dụng dạng hậu tố thì toán tử tăng hoặc toán tử giảm được thực hiện sau khi biểu thức được ước lượng.

Ví dụ

Ví dụ sau giải thích giúp bạn sự khác nhau này:

include <iostream>
using namespace std;

main()
{
int a = 21;
int c ;

// Gia tri cua a se khong duoc tang truoc khi duoc gan.
c = a++;
cout << "1, Gia tri cua a++ la: " << c << endl ;

// Sau khi gia tri cua a duoc tang thi:
cout << "2, Gia tri cua a la: " << a << endl ;

// Gia tri cua a se duoc tang truoc khi duoc gan.
c = ++a;
cout << "3, Gia tri cua ++a la: " << c << endl ;
return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Toán tử tăng

Toán tử giảm (--) trong C++

Toán tử tăng (++) cộng toán hạng thêm một đơn vị, và toán tử giảm (--) trừ một đơn vị từ toán hạng. Do vậy:

x = x+1;

la tuong tu

x++;

Tương tự như vậy:

x = x-1;

la tuong tu

x--;

Cả toán tử tăng và toán tử giảm đều có dạng tiền tố đặt trước hoặc hậu tố theo sau toán hạng. Ví dụ:

x = x+1;

co the duoc viet duoi dang

++x; // day la dang co tien to (prefix) dat truoc

hoặc dạng:

x++; // la dang voi hau to (postfix) dat sau

Khi một toán tử tăng hay toán tử giảm được sử dụng như là một phần của biểu thức, thì sẽ có một sự khác nhau quan trọng giữa dạng tiền tố và hậu tố. Nếu bạn sử dụng dạng tiền tố thì toán tử tăng hoặc toán tử giảm được thực hiện trước biểu thức, và nếu bạn sử dụng dạng hậu tố thì toán tử tăng hoặc toán tử giảm được thực hiện sau khi biểu thức được ước lượng.

Ví dụ

Ví dụ sau giải thích giúp bạn sự khác nhau này:

include <iostream>
using namespace std;

main()
{
int a = 21;
int c ;

// Gia tri cua a se khong duoc tang truoc khi duoc gan.
c = a++;
cout << "1, Gia tri cua a++ la: " << c << endl ;

// Sau khi gia tri cua a duoc tang thi:
cout << "2, Gia tri cua a la: " << a << endl ;

// Gia tri cua a se duoc tang truoc khi duoc gan.
c = ++a;
cout << "3, Gia tri cua ++a la: " << c << endl ;
return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Toán tử giảm

Toán tử quan hệ trong C++

Bảng dưới đây liệt kê các toán tử quan hệ được hỗ trợ bởi ngôn ngữ C++:

Giả sử biến A giữ giá trị 10, biến B giữ 20 thì:

Toán tửMiêu tảVí dụ
==Kiểm tra nếu 2 toán hạng bằng nhau hay không. Nếu bằng thì điều kiện là true.(A == B) là không đúng
!=Kiểm tra 2 toán hạng có giá trị khác nhau hay không. Nếu không bằng thì điều kiện là true.(A != B) là true
>Kiểm tra nếu toán hạng bên trái có giá trị lớn hơn toán hạng bên phải hay không. Nếu lớn hơn thì điều kiện là true.(A > B) là không đúng
<Kiểm tra nếu toán hạng bên trái nhỏ hơn toán hạng bên phải hay không. Nếu nhỏ hơn thì là true.(A < B) là true
>=Kiểm tra nếu toán hạng bên trái có giá trị lớn hơn hoặc bằng giá trị của toán hạng bên phải hay không. Nếu đúng là true.(A >= B) là không đúng
<=Kiểm tra nếu toán hạng bên trái có giá trị nhỏ hơn hoặc bằng toán hạng bên phải hay không. Nếu đúng là true.(A <= B) là true

Toán tử logic trong C++

Bảng dưới đây chỉ rõ tất cả các toán tử logic được hỗ trợ bởi ngôn ngữ C.

Giả sử biến A có giá trị 1 và biến B có giá trị 0:

Toán tửMiêu tảVí dụ
&&Được gọi là toán tử logic AND (và). Nếu cả hai toán tử đều có giá trị khác 0 thì điều kiện trở lên true.(A && B) là false.
||Được gọi là toán tử logic OR (hoặc). Nếu một trong hai toán tử khác 0, thì điều kiện là true.(A || B) là true.
!Được gọi là toán tử NOT (phủ định). Sử dụng để đảo ngược lại trạng thái logic của toán hạng đó. Nếu điều kiện toán hạng là true thì phủ định nó sẽ là false.!(A && B) là true.

Toán tử so sánh bit trong C++

Toán tử so sánh bit làm việc trên đơn vị bit, tính toán biểu thức so sánh từng bit. Bảng dưới đây về &, |, và ^ như sau:

pqp & qp | qp ^ q
00000
01011
11110
10011

Giả sử nếu A = 60; và B = 13; thì bây giờ trong định dạng nhị phân chúng sẽ là như sau:

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

~A = 1100 0011

Các toán tử so sánh bit được hỗ trợ bởi ngôn ngữ C++ được liệt kê trong bảng dưới đây. Giá sử ta có biến A có giá tri 60 và biến B có giá trị 13, ta có:

Toán tửMiêu tảVí dụ
&Toán tử AND (và) nhị phân sao chép một bit tới kết quả nếu nó tồn tại trong cả hai toán hạng.(A & B) sẽ cho kết quả là 12, tức là 0000 1100
|Toán tử OR (hoặc) nhị phân sao chép một bit tới kết quả nếu nó tồn tại trong một hoặc hai toán hạng.(A | B) sẽ cho kết quả là 61, tức là 0011 1101
^Toán tử XOR nhị phân sao chép bit mà nó chỉ tồn tại trong một toán hạng mà không phải cả hai.(A ^ B) sẽ cho kết quả là 49, tức là 0011 0001
~Toán tử đảo bit (đảo bit 1 thành bit 0 và ngược lại).(~A ) sẽ cho kết quả là -61, tức là 1100 0011.
<<Toán tử dịch trái. Giá trị toán hạng trái được dịch chuyển sang trái bởi số các bit được xác định bởi toán hạng bên phải.A << 2 sẽ cho kết quả 240, tức là 1111 0000 (dịch sang trái hai bit)
>>Toán tử dịch phải. Giá trị toán hạng trái được dịch chuyển sang phải bởi số các bit được xác định bởi toán hạng bên phải.A >> 2 sẽ cho kết quả là 15, tức là 0000 1111 (dịch sang phải hai bit)

Toán tử gán trong C++

Dưới đây là những toán tử gán được hỗ trợ bởi ngôn ngữ C++:

Toán tửMiêu tảVí dụ
=Toán tử gán đơn giản. Gán giá trị toán hạng bên phải cho toán hạng trái.C = A + B sẽ gán giá trị của A + B vào trong C
+=Thêm giá trị toán hạng phải tới toán hạng trái và gán giá trị đó cho toán hạng trái.C += A tương đương với C = C + A
-=Trừ đi giá trị toán hạng phải từ toán hạng trái và gán giá trị này cho toán hạng trái.C -= A tương đương với C = C - A
*=Nhân giá trị toán hạng phải với toán hạng trái và gán giá trị này cho toán hạng trái.C *= A tương đương với C = C * A
/=Chia toán hạng trái cho toán hạng phải và gán giá trị này cho toán hạng trái.C /= A tương đương với C = C / A
%=Lấy phần dư của phép chia toán hạng trái cho toán hạng phải và gán cho toán hạng trái.C %= A tương đương với C = C % A
<<=Dịch trái toán hạng trái sang số vị trí là giá trị toán hạng phải.C <<= 2 tương đương với C = C << 2
>>=Dịch phải toán hạng trái sang số vị trí là giá trị toán hạng phải.C >>= 2 tương đương với C = C >> 2
&=Phép AND bitC &= 2 tương đương với C = C & 2
^=Phép OR loại trừ bitC ^= 2 tương đương với C = C ^ 2
|=Phép OR bit.C |= 2 tương đương với C = C | 2

Các toán tử hỗn hợp trong C++

Dưới đây là một số toán tử hỗn hợp quan trọng được hỗ trợ bởi ngôn ngữ C++.

Toán tửMiêu tả
sizeofToán tử sizeof trong C++ trả về kích cỡ của một biến. Ví dụ: sizeof(a), với a là integer, sẽ trả về 4
Điều kiện ? X : YToán tử điều kiện trong C++. Nếu Condition là true ? thì nó trả về giá trị X : nếu không thì trả về Y
,Toán tử Comma trong C++ làm cho một dãy hoạt động được thực hiện. Giá trị của toàn biểu thức comma là giá trị của biểu thức cuối cùng trong danh sách được phân biệt bởi dấu phảy
. (dot) và -> (arrow)Toán tử thành viên trong C++ được sử dụng để tham chiếu các phần tử đơn của các lớp, các cấu trúc, và union
CastToán tử ép kiểu (Casting) trong C++ biến đổi một kiểu dữ liệu thành kiểu khác. Ví dụ: int(2.2000) sẽ trả về 2
&Toán tử con trỏ & trong C++ trả về địa chỉ của một biến. Ví du: &a; sẽ trả về địa chỉ thực sự của biến này
*Toán tử con trỏ * trong C++ là trỏ tới một biến. Ví dụ: *var sẽ trỏ tới một biến var

Toán tử sizeof trong C++

sizeof là một từ khóa trong C++, nhưng nó là một toán tử compile-time mà quyết định kích cỡ, bằng giá trị byte, của một biến hoặc kiểu dữ liệu.

Toán tử sizeof có thể được sử dụng để lấy kích cỡ của lớp, cấu trúc, union và bất kỳ kiểu dữ liệu tự định nghĩa khác (user-defined) trong C++.

Cú pháp để sử dụng toán tử sizeof trong C++ như sau:

sizeof (kieu du lieu)

Tại đây, data type là kiểu dữ liệu gồm lớp, cấu trúc, union và bất kỳ kiểu dữ liệu tự định nghĩa khác (user-defined) trong C++.

Bạn thử ví dụ sau để hiểu cách sử dụng toán tử sizeof trong C++. Copy và paste chương trình sau trong tệp test.cpp, sau đó biên dịch và chạy chương trình.

include <iostream>
using namespace std;

int main()
{
cout << "Kich co cua char : " << sizeof(char) << endl;
cout << "Kich co cua int : " << sizeof(int) << endl;
cout << "Kich co cua short int : " << sizeof(short int) << endl;
cout << "Kich co cua long int : " << sizeof(long int) << endl;
cout << "Kich co cua float : " << sizeof(float) << endl;
cout << "Kich co cua double : " << sizeof(double) << endl;
cout << "Kich co cua wchar_t : " << sizeof(wchar_t) << endl;
return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Toán tử sizeof trong C++

Toán tử điều kiện ? : trong C++

Cú pháp của toán tử điều kiện ? : trong C++ là:

bieu_thuc_1 ? bieu_thuc_2 : bieu_thuc_3;

Ở đây, bieu_thuc_1, bieu_thuc_2 và bieu_thuc_3 là các biểu thức. Bạn chú ý sự sử dụng và vị trí của dấu hai chấm. Giá trị của một biểu thức ? được quyết định như sau: bieu_thuc_1 được ước lượng. Nếu nó là true, thì bieu_thuc_2 được ước lượng và trở thành giá trị của toàn bộ biểu thức ?. Nếu bieu_thuc_1 là false, thì bieu_thuc_3 được ước lượng và giá trị của nó trở thành giá trị của biểu thức ?.

Biểu thức ? được xem như là một toán tử tam phân bởi vì nó yêu cầu ba toán hạng và có thể được sử dụng để thay thế lệnh if-else, có form sau:

if(dieu_kien){
var = X;
}else{
var = Y;
}
Bạn xét code sau:

if(y < 10){
var = 30;
}else{
var = 40;
}

Code trên có thể được viết lại như thế này:

var = (y < 10) ? 30 : 40;

Ở đây, x được gán giá trị 30 nếu y nhỏ hơn 10 và được gán 40 nếu không nhỏ hơn 10. Bạn có thể thử ví dụ sau:

#include <iostream>
using namespace std;

int main ()
{
// Khai bao bien cuc bo:
int x, y = 10;

x = (y < 10) ? 30 : 40;

cout << "Gia tri cua x la: " << x << endl;

return 0;
}

Khi code trên được biên dịch và thực thi, nó cho kết quả sau:

Gia tri cua x la: 40

Toán tử comma trong C++

Mục đích của toán tử comma trong C++ là để xâu chuỗi một số biểu thức cùng nhau. Giá trị của một danh sách biểu thức được phân biệt bởi dấu phảy là giá trị của biểu thức cuối cùng bên phải. Về cơ bản, hiệu quả của dấu phảy là để làm cho một dãy các hoạt động để được thực hiện.

Các giá trị của các biểu thức khác sẽ bị loại bỏ. Nghĩa là, biểu thức cuối cùng bên phải sẽ trở thành giá trị của toàn bộ biểu thức được phân biệt bởi dấu phảy. Ví dụ:

var = (biendem=19, incr=10, biendem+1);

Tại đây, đầu tiên gán cho biendem giá trị 19, gán cho incr giá trị 10, sau đó thêm 1 tới biendem, và cuối cùng, gán cho var giá trị của biểu thức cuối cùng bên phải, biểu thức biendem+1, là 20. Dấu ngoặc đơn là cần thiết bởi vì toán tử comma có độ ưu tiên thấp hơn toán tử gán.

Để xem hiệu quả của toán tử comma, bạn thử chạy ví dụ sau:

#include <iostream>
using namespace std;

int main()
{
int i, j;

j = 10;
i = (j++, j+100, 999+j);

cout << i;

return 0;
}

Khi code trên được biên dịch và thực thi, nó cho kết quả sau:

1010

Thủ tục mà giá trị của i được ước lượng là: j bắt đầu với giá trị 0. Sau đó j được tăng tới 11. Tiếp đó, j được cộng với 100. Cuối cùng, j (vẫn chứa 11) được cộng với 999, mà sẽ cho kết quả là 1010.

Toán tử thành viên (. và ->) trong C++

Toán tử thành viên dot (.) và arrow (->) được sử dụng để tham chiếu các thành viên riêng lẻ của lớp, cấu trúc struct và union trong C++.

Toán tử dot được áp dụng cho đối tượng thực sự. Toán tử arrow được sử dụng với một con trỏ tới một đối tượng. Ví dụ, bạn xét cấu trúc sau:

struct sinhvien {
char ten[16];
int diemthi;
} sv;

Toán tử dot (.) trong C++

Để gán giá trị "hoang" cho thành viên ten của đối tượng sinhvien, bạn viết:

strcpy(sinhvien.ten, "hoang");

Toán tử arrow (->) trong C++

Nếu p_sv là một con trỏ tới đối tượng của kiểu sinhvien, thì để gán giá trị "hoang" tới thành viên ten của đối tượng sinhvien, bạn viết:

strcpy(p_sv->ten, "hoang");

Có thể nói đơn giản rằng: Để truy cập các thành viên của một cấu trúc, sử dụng toán tử dot trong C++. Để truy cập các thành viên của một cấu trúc thông qua một con trỏ, sử dụng toán tử arrow.

Toán tử ép kiểu (casting) trong C++

Toán tử ép kiểu (một cast) trong C++ là một toán tử đặc biệt mà làm một kiểu dữ liệu này biến đổi thành kiểu dữ liệu khác. Toán tử ép kiểu là một toán tử một ngôi và có cùng độ ưu tiên như bất kỳ toán tử một ngôi nào khác trong C++.

Cú pháp được sử dụng thường xuyên của toán tử ép kiểu trong C++ là:

(kieu_du_lieu) bieu_thuc 

Ở đây, kieu_du_lieu là kiểu dữ liệu bạn muốn. Dưới đây là một số toán tử ép kiểu được hỗ trợ bởi C++:

const_cast<kieu_du_lieu> (bieu_thuc): Toán tử const_cast được sử dụng để ghi đè const và/hoặc volatile. Kiểu dữ liệu bạn muốn phải giống như kiểu dữ liệu nguồn ngoại trừ sự sửa đổi của các thuộc tính const hoặc volatile trong một cast. Dạng ép kiểu này thao tác thuộc tính const của đối tượng đã truyền: hoặc được thiết lập hoặc gỡ bỏ.

dynamic_cast<kieu_du_lieu> (bieu_thuc): Toán tử dynamic_cast trong C++ thực hiện một ép kiểu tại runtime mà thẩm tra tính hợp lệ của cast. Nếu cast không thể được tạo ra, cast này thất bại và biểu thức ước lượng là null. Một toán tử dynamic_cast thực hiện các cast trên các kiểu đa hình và có thể ép một con trỏ A* thành một con trỏ B* chỉ khi đối tượng đang được trỏ tới thực sự là một đối tượng B.

reinterpret_cast<kieu_du_lieu> (bieu_thuc): Toán tử reinterpret_cast trong C++ thay đổi một con trỏ tới bất kỳ kiểu con trỏ khác. Nó cũng cho phép ép kiểu từ con trỏ tới một kiểu integer và ngược lại.

static_cast<kieu_du_lieu> (bieu_thuc): Toán tử static_cast trong C++ thực hiện một cast không có tính đa hình. Ví dụ, nó có thể được sử dụng để ép kiểu một con trỏ lớp cơ sở thành một con trỏ lớp kế thừa.

Tất cả toán tử ép kiểu trên sẽ được sử dụng trong khi làm việc với lớp và đối tượng. Bây giờ, bạn thử ví dụ sau để hiểu toán tử ép kiểu đơn giản trong C++. Copy và paste chương trình C++ sau trong tệp test.cpp, sau đó biên dịch và chạy chương trình:

include <iostream>
using namespace std;

main()
{
double a = 15.65653;
float b = 9.02;
int c ;

c = (int) a;
cout << "Dong 1: Gia tri cua (int)a la: " << c << endl ;

c = (int) b;
cout << "Dong 1: Gia tri cua (int)b la: " << c << endl ;

return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Toán tử ép kiểu (casting) trong C++

Toán tử con trỏ trong C++

C++ cung cấp hai toán tử con trỏ là: toán tử & (toán tử address of) và toán tử * (toán tử indirection).

Một con trỏ là một biến mà chứa địa chỉ của biến khác hoặc bạn có thể nói rằng một biến chứa địa chỉ của biến khác là được xem như là trỏ tới biến khác. Một biến có thể là bất kỳ kiểu dữ liệu nào, gồm đối tượng, cấu trúc, hoặc chính con trỏ.

Toán tử . (dot) và toán tử -> (arrow) được sử dụng để tham chiếu tới các thành viên riêng rẽ của lớp, cấu trúc, và union.

Toán tử & trong C++

Toán tử & là một toán tử một ngôi trong C++ mà trả về địa chỉ bộ nhớ của toán hạng của nó. Ví dụ, nếu var là một biến integer, thì &var là địa chỉ của nó. Toán tử này có cùng độ ưu tiên và thứ tự từ phải qua trái như các toán tử một ngôi khác trong C++.

Bạn nên đọc toán tử & là "address of", nghĩa là &var sẽ được đọc là "địa chỉ của var".

Toán tử * trong C++

Toán tử con trỏ thứ hai là toán tử * trong C++, và nó một sự bổ sung cho toán tử &. Đây là toán tử một ngôi mà trả về giá trị của biến được đặt tại địa chỉ đã được xác định bởi toán hạng của nó.

Sau đây là chương trình minh họa cho hai loại toán tử con trỏ trong C++:

#include <iostream>

using namespace std;

int main ()
{
int var;
int *ptr;
int val;

var = 3000;

// lay dia chia cua bien var
ptr = &var;

// Lay gia tri co san tai ptr
val = *ptr;
cout << "Gia tri cua var la: " << var << endl;
cout << "Gia tri cua ptr la: " << ptr << endl;
cout << "Gia tri cua val la: " << val << endl;

return 0;
}

Chạy chương trình C++ trên sẽ cho kết quả như hình sau:

Toán tử con trỏ trong C++

Thứ tự ưu tiên toán tử trong C++

Thứ tự ưu tiên toán tử trong C++ xác định cách biểu thức được tính toán. Ví dụ, toán tử nhân có quyền ưu tiên hơn toán tử cộng, và nó được thực hiện trước.

Ví dụ, x = 7 + 3 * 2; ở đây, x được gán giá trị 13, chứ không phải 20 bởi vì toán tử * có quyền ưu tiên cao hơn toán tử +, vì thế đầu tiên nó thực hiện phép nhân 3 * 2 và sau đó thêm với 7.

Bảng dưới đây liệt kê thứ tự ưu tiên của các toán tử. Các toán tử với quyền ưu tiên cao nhất xuất hiện trên cùng của bảng, và các toán tử có quyền ưu tiên thấp nhất thì ở bên dưới cùng của bảng. Trong một biểu thức, các toán tử có quyền ưu tiên cao nhất được tính toán đầu tiên.

LoạiToán tửThứ tự ưu tiên
Postfix() [] -> . ++ - -Trái sang phải
Unary+ - ! ~ ++ - - (type)* & sizeofPhải sang trái
Tính nhân* / %Trái sang phải
Tính cộng+ -Trái sang phải
Dịch chuyển<< >>Trái sang phải
Quan hệ< <= > >=Trái sang phải
Cân bằng== !=Trái sang phải
Phép AND bit&Trái sang phải
Phép XOR bit^Trái sang phải
Phép OR bit|Trái sang phải
Phép AND logic&&Trái sang phải
Phép OR logic||Trái sang phải
Điều kiện?:Phải sang trái
Gán= += -= *= /= %=>>= <<= &= ^= |=Phải sang trái
Dấu phảy,Trái sang phải

Theo Tutorialspoint

Bài trước: Lớp lưu trữ (Storage Class) trong C/C++

Bài tiếp: Vòng lặp trong C++

Thứ Năm, 09/04/2020 11:36
4,68 👨 100.333
0 Bình luận
Sắp xếp theo