C - Toán tử: Cánh cửa Đến Vùng Đất Ma thuật Lập trình

Xin chào các nhà lập trình tương lai! ? Mình rất vui được làm hướng dẫn cho các bạn trong cuộc hành trình thú vị vào thế giới lập trình C. Hôm nay, chúng ta sẽ khám phá vùng đất ma thuật của các toán tử trong C. Đừng lo nếu bạn chưa từng viết một dòng mã trước đây – chúng ta sẽ bắt đầu từ đầu và học tập cùng nhau.

C - Operators

Toán tử Định lý: Các Bộ phép Cơ bản

Hãy bắt đầu với những bộ phép đơn giản nhất trong cuốn sách ma thuật lập trình của chúng ta – các toán tử định lý. Những điều này là các khối xây dựng của hầu hết các phép toán trong C.

Nhóm Năm Toán tử Định lý

Dưới đây là những toán tử định lý cơ bản:

Toán tử Tên Ví dụ
+ Cộng 5 + 3 = 8
- Trừ 7 - 2 = 5
* Nhân 4 * 6 = 24
/ Chia 10 / 2 = 5
% Chia lấy dư 7 % 3 = 1

Hãy xem các toán tử này hoạt động như thế nào:

#include <stdio.h>

int main() {
int a = 10, b = 3;

printf("Cộng: %d\n", a + b);
printf("Trừ: %d\n", a - b);
printf("Nhân: %d\n", a * b);
printf("Chia: %d\n", a / b);
printf("Chia lấy dư: %d\n", a % b);

return 0;
}

Khi chạy mã này, bạn sẽ thấy:

Cộng: 13
Trừ: 7
Nhân: 30
Chia: 3
Chia lấy dư: 1

Nhận ra rằng phép chia cho chúng ta một giá trị nguyên thay vì 3.33? Điều đó xảy ra vì khi chúng ta chia hai số nguyên trong C, chúng ta nhận được một kết quả nguyên. Toán tử chia lấy dư (%) cho chúng ta phần dư sau phép chia.

Toán tử So sánh: So sánh Quả Táo Với Cam

Bây giờ đã biết cách thực hiện các phép toán cơ bản, hãy học cách so sánh các điều. Các toán tử so sánh như những giám khảo trong một buổi biểu diễn nghệ thuật – họ so sánh hai giá trị và nói về mối quan hệ giữa chúng.

Dưới đây là các toán tử so sánh của chúng ta:

Toán tử Ý nghĩa Ví dụ
== Bằng 5 == 5 là đúng
!= Không bằng 5 != 3 là đúng
> Lớn hơn 7 > 3 là đúng
< Nhỏ hơn 2 < 8 là đúng
>= Lớn hơn hoặc bằng 5 >= 5 là đúng
<= Nhỏ hơn hoặc bằng 4 <= 4 là đúng

Hãy thử các toán tử này:

#include <stdio.h>

int main() {
int x = 5, y = 8;

printf("x == y: %d\n", x == y);
printf("x != y: %d\n", x != y);
printf("x > y: %d\n", x > y);
printf("x < y: %d\n", x < y);
printf("x >= y: %d\n", x >= y);
printf("x <= y: %d\n", x <= y);

return 0;
}

Kết quả sẽ là:

x == y: 0
x != y: 1
x > y: 0
x < y: 1
x >= y: 0
x <= y: 1

Trong C, 0 có nghĩa là sai, và bất kỳ giá trị khác không (thường là 1) đều có nghĩa là đúng. Do đó, chúng ta có thể thấy rằng 5 thực sự không bằng 8 và nó nhỏ hơn 8.

Toán tử Logic: Những Người Quyết định

Các toán tử logic như những người cựu của ngôi làng lập trình của chúng ta. Họ giúp chúng ta đưa ra những quyết định phức tạp bằng cách kết hợp các điều kiện đơn giản hơn.

Dưới đây là các toán tử logic của chúng ta:

Toán tử Ý nghĩa Ví dụ
&& (5 > 3) && (4 < 7) là đúng
|| HOẶC (5 > 8) || (4 < 7) là đúng
! KHÔNG !(5 > 8) là đúng

Hãy xem các toán tử này hoạt động như thế nào:

#include <stdio.h>

int main() {
int a = 5, b = 3, c = 8;

printf("(a > b) && (c > a): %d\n", (a > b) && (c > a));
printf("(a > b) || (a > c): %d\n", (a > b) || (a > c));
printf("!(a > b): %d\n", !(a > b));

return 0;
}

Kết quả sẽ là:

(a > b) && (c > a): 1
(a > b) || (a > c): 1
!(a > b): 0

Toán tử AND (&&) chỉ trả về đúng khi cả hai điều kiện đều đúng. Toán tử OR (||) chỉ cần một điều kiện đúng để trả về đúng. Toán tử NOT (!) lật ngược giá trị đúng/sai.

Toán tử Nhị phân: Những Phù thủy Nhị phân

Bây giờ, chúng ta đang bước vào vùng đất ma thuật nhị phân. Các toán tử nhị phân làm việc trực tiếp với các biểu diễn nhị phân của các số. Họ như những kính micro của thế giới lập trình, cho phép chúng ta thấy và thao tác các bit riêng lẻ.

Dưới đây là các toán tử nhị phân của chúng ta:

Toán tử Tên Ví dụ
& AND nhị phân 5 & 3 = 1
| OR nhị phân 5 | 3 = 7
^ XOR nhị phân 5 ^ 3 = 6
~ NOT nhị phân ~5 = -6
<< Dịch trái 5 << 1 = 10
>> Dịch phải 5 >> 1 = 2

Hãy xem các toán tử này hoạt động như thế nào:

#include <stdio.h>

int main() {
unsigned int a = 5, b = 3;  // 5 là 101 trong nhị phân, 3 là 011

printf("a & b = %u\n", a & b);   // 101 & 011 = 001
printf("a | b = %u\n", a | b);   // 101 | 011 = 111
printf("a ^ b = %u\n", a ^ b);   // 101 ^ 011 = 110
printf("~a = %d\n", ~a);         // ~101 = ...11111010 (dạng hai)
printf("a << 1 = %u\n", a << 1); // 101 trở thành 1010
printf("a >> 1 = %u\n", a >> 1); // 101 trở thành 10

return 0;
}

Kết quả sẽ là:

a & b = 1
a | b = 7
a ^ b = 6
~a = -6
a << 1 = 10
a >> 1 = 2

Những toán tử này rất hữu ích khi bạn làm việc với lập trình cấp độ thấp hoặc cần tối ưu hóa mã của mình.

Toán tử Gán: Những Người Thay đổi Giá trị

Các toán tử gán như những người scribe của thế giới lập trình của chúng ta. Họ ghi (hoặc gán) giá trị vào các biến. Hãy gặp gỡ các toán tử gán của chúng ta:

Toán tử Ví dụ Tương đương với
= x = 5 x = 5
+= x += 3 x = x + 3
-= x -= 2 x = x - 2
*= x *= 4 x = x * 4
/= x /= 2 x = x / 2
%= x %= 3 x = x % 3
<<= x <<= 2 x = x << 2
>>= x >>= 1 x = x >> 1
&= x &= 3 x = x & 3
^= x ^= 5 x = x ^ 5
|= x |= 3 x = x | 3

Dưới đây là một ví dụ nhanh:

#include <stdio.h>

int main() {
int x = 10;

x += 5;  // x bây giờ là 15
printf("After x += 5: %d\n", x);

x *= 2;  // x bây giờ là 30
printf("After x *= 2: %d\n", x);

x %= 7;  // x bây giờ là 2 (30 % 7 = 2)
printf("After x %%= 7: %d\n", x);

return 0;
}

Kết quả sẽ là:

After x += 5: 15
After x *= 2: 30
After x %= 7: 2

Những toán tử này là các phím tắt giúp mã của chúng ta ngắn gọn hơn và thường dễ đọc hơn.

Toán tử Khác: Những Đội Quân Đặc Nhiệm

Bây giờ, hãy gặp những toán tử đặc biệt không phải vào bất kỳ danh mục nào khác.

Toán tử sizeof

Toán tử sizeof cho chúng ta biết kích thước của một biến hoặc kiểu dữ liệu trong byte. Nó như một cân đo cho dữ liệu của chúng ta.

#include <stdio.h>

int main() {
int x;
char c;
float f;

printf("Size of int: %zu bytes\n", sizeof(x));
printf("Size of char: %zu bytes\n", sizeof(c));
printf("Size of float: %zu bytes\n", sizeof(f));

return 0;
}

Kết quả có thể là (tùy thuộc vào hệ thống của bạn):

Size of int: 4 bytes
Size of char: 1 byte
Size of float: 4 bytes

Toán tử Ba ngôi

Toán tử ba ngôi như một đoạn mã if-else nhỏ gọn. Nó được viết như condition ? value_if_true : value_if_false.

#include <stdio.h>

int main() {
int x = 10;
int y = (x > 5) ? 1 : 0;

printf("y = %d\n", y);

return 0;
}

Kết quả sẽ là:

y = 1

Vì x lớn hơn 5, y được gán giá trị 1.

Thứ tự ưu tiên của Toán tử trong C: Hệ thống Phân cấp

Giống như trong toán học, C có một hệ thống phân cấp của các phép toán. Hệ thống này xác định các phép toán nào sẽ được thực hiện trước khi có nhiều toán tử được sử dụng trong một biểu thức duy nhất.

Dưới đây là bảng ưu tiên đơn giản hóa, từ cao đến thấp:

Ưu tiên Toán tử
1 () [] -> .
2 ! ~ ++ -- + - * & (type) sizeof
3 * / %
4 + -
5 << >>
6 < <= > >=
7 == !=
8 &
9 ^
10 |
11 &&
12 ||
13 ?:
14 = += -= *= /= %= &= ^= |= <<= >>=
15 ,

Nếu bạn có nghi ngờ, hãy sử dụng dấu ngoặc để làm rõ ý tưởng của bạn!

Các Toán tử Khác trong C: Những Đá quý Bị Ẩn

Có một số toán tử nữa trong C mà chúng ta chưa bao giờ bảo:

  1. Toán tử phẩy (,): Nó cho phép bạn sử dụng nhiều biểu thức nơi chỉ cần một biểu thức.
  2. Toán tử địa chỉ (&): Nó trả về địa chỉ bộ nhớ của một biến.
  3. Toán tử truy cập (*): Nó truy cập giá trị tại một địa chỉ bộ nhớ cụ thể.
  4. Toán tử thành phần cấu trúc (.): Nó truy cập các thành phần của một cấu trúc.
  5. Toán tử con trỏ (->): Nó truy cập các thành phần của một cấu trúc thông qua một con trỏ.

Chúng ta sẽ khám phá những toán tử này khi chúng ta bước vào con pointers và cấu trúc trong các bài học tương lai.

Và đó là tất cả, các nhà lập trình tương lai! Chúng ta đã hành trình qua vùng đất của các toán tử trong C, từ những bộ phép cơ bản đến những phép bitwise phức tạp. Hãy nhớ rằng tập trung và thực hành là chìa khóa

Credits: Image by storyset