[Programming in C#] Bài 3: Các lệnh và toán tử trong C#

1. Vào ra dữ liệu trong C# (trong môi trường Console)
- C# hỗ trợ vào ra dữ liệu trong môi trường Console thông qua đối tượng Console. Đối tượng này nằm trong thư viện (namespace) có tên: System.
- Để khai báo thư viện sử dụng dòng lệnh:

using System;
- Để xuất dữ liệu (ra – output) chúng ta sử dụng 2 phương thức:

* Write: phương thức này cho phép in dữ liệu ra màn hình Console theo định dạng. Dữ liệu có thể là các hằng số, các biến, các biểu thức.

Có tất cả 18 quá tải phương thức (overloadding method) để cho phép chúng ta có thể thực hiện in ra giá trị của các kiểu hằng số, biến khác nhau.

Trong đó có hàm tổng và thường được sử dụng nhất là:

Cú pháp:
Console.Write(“chuỗi định dạng”,”danh sách các đối số”);
Trong đó:
“Chuỗi định dạng”: là chuỗi kí tự chỉ ra dạng hiển thị (trình bày của dữ liệu).
Chuỗi định dạng có thể là:

* Các kí tự: kí tự số (0,2,3,4….9) hoặc các kí tự chữ ‘a’, ‘z’,’A’,’X’….’%’.
* Các kí tự thoát (escape sequence): các kí tự thoát bắt đầu với dấu % hoặc dấu \. VD: kí tự điều khiển xuống dòng là \n hoặc kí tự điều khiển nhẩy 1 Tab là \t.
* Kí tự giữ chỗ (placeholder): các kí tự giữ chỗ này có dạng {n}. Trong đó n là số nguyên chỉ ra số thứ tự của đối số.

“danh sách các đối số”: là danh sách các biến hoặc các hằng số hoặc các biểu thức cách nhau bởi dấu phẩy (,). VD: -7, ‘a’, (a+b)*c, x…

VD: sử dụng lệnh Write để in ra giá trị tương ứng của các biến a, b, c và giá trị của biểu thức (a+b)*c.

int a, b, c;

a = 3;
b = -5;
c = 9;

Console.Write("a = {0}, b = {1}, c = {2}, fx = {3}",a,b,c,(a+b)*c);

Chú ý:

* Số lượng các placeholder trong chuỗi định dạng bằng với số lượng các đối số trong danh sách các đối số.
* Giá trị số của các placeholder bắt đầu được đánh số thứ tự từ 0.
* Thứ tự của các đối số sẽ tương ứng với thứ tự của các placeholder.

* WriteLine: hàm thực hiện in dữ liệu và chuyển con trỏ đến dòng tiếp theo trên màn hình Console.

- Hàm nhập dữ liệu (input): để nhập dữ liệu cho ứng dụng Console chúng ta có thể sử dụng các hàm sau:

* Read: hàm read cho phép đọc 1 số nguyên từ vùng đệm bàn phím trong ứng dụng Console. Hàm này trả về 1 số nguyên.
* ReadKey: hàm này cho phép đọc 1 phím từ bàn phím.
* ReadLine: hàm này cho phép nhập 1 chuỗi kí tự.

Một số hàm liên quan đến quá trình nhập liệu khác:

* Parse: hàm này thực hiện phân tích và chuyển đổi 1 kiểu dữ liệu thành một kiểu dữ liệu khác.

VD1: để chuyển 1 chuỗi kí tự thành 1 số nguyên thì dùng dòng lệnh.

int a;
a = int.Parse(Console.ReadLine());

VD2: để chuyển 1 chuỗi kí tự thành 1 số thực decimal thì dùng dòng lệnh.

decimal n;
n = decimal.Parse(Console.ReadLine());

* Đối tượng Convert: là đối tượng cho phép biến đổi 1 kiểu dữ liệu bất kì thành 1 kiểu dữ liệu khác. Đối tượng này chứa các phương th��c tĩnh tương ứng cho việc chuyển đổi các kiểu dữ liệu dữ liệu sang một kiểu dữ liệu nào đó. VD: để chuyển đổi sang số nguyên chúng ta có thể dùng các hàm ToInt16, ToInt32, ToInt64, chuyển sang số thực dùng các hàm ToFloat, ToDouble, ToDecimal…

VD:

a = Convert.ToInt32(Console.ReadLine());

2. Lệnh và các biểu thức
- Định nghĩa: lệnh là một nhóm logic các biến, các toán tử và các từ khóa để thực hiện 1 công việc cụ thể nào đó.
VD: lệnh để khai báo 1 hằng số thực PI có giá trị bằng 3.14.
const float PI = 3.14f;
- Các lệnh trong C# đều kết thúc bởi dấu chấm phẩy (.
- Định nghĩa: khối lệnh (block) là một nhóm các câu lệnh thực hiện 1 nhiệm vụ cụ thể nào đó. Các khối lệnh nằm trong cặp dấu
VD: khối lệnh tính diện tích hình tròn.

float banKinh;
float dienTich;

Console.Write("Nhap ban kinh: ");
banKinh = float.Parse(Console.ReadLine());

dienTich = banKinh * banKinh * Math.PI;
Console.WriteLine("Dien tich: {0}", dienTich);

Console.ReadLine();


3. Các kiểu lệnh
Có 7 kiểu lệnh trong C#:
- Các lệnh lựa chọn (Selection Statements): là những lệnh tạo ra quyết định một đoạn mã lệnh nào đó có được thực hiện hay ko dựa vào một điều kiện. Một số lệnh thuộc nhóm này: if, switch.
- Các lệnh lặp (Iteration Statements): là cấu trúc lệnh giúp chúng ta thực hiện lặp đi lặp lại một đoạn mã lệnh cho đến khi thỏa mãn một điều kiện nào đó. Các lệnh thuộc nhóm này: for, foreach, do, while.
- Các lệnh nhảy (Jump Statements): là các lệnh giúp chúng ta chuyển luồng thực hiện của chương trình (flow of program) từ một đoạn mã lệnh này sang một đoạn mã lệnh khác. Các lệnh thuộc nhóm này: break, continue, return, goto, default, yield.
- Các lệnh xử lý ngoại lệ (Exception Handling Statements): là các lệnh được sử dụng để kiểm soát những tình huống ko mong muốn xảy ra trong ứng dụng của chúng ta và làm cho ứng dụng hoạt động sai hoặc bị phá vỡ. Các lệnh thuộc nhóm này: try, catch, finally, throw.
- Các lệnh được kiểm tra và ko được kiểm tra (Checked and UnChecked Statements): những lệnh ko được kiểm tra là những lệnh sẽ được bỏ qua bởi trình quản lý code (CLR) còn những lệnh được kiểm tra là những lệnh sẽ được kiểm soát bởi CLR. Và để chỉ ra những lệnh nào là được kiểm tra và ko được kiểm tra thì chúng ta sử dụng các từ khóa tương ứng là: checked và unchecked. Mặc định các lệnh đều thuộc nhóm checked.
- Các lệnh fixed: các lệnh fixed được sử dụng để chỉ ra cho GC (trình thu gom rác – Garbage Collector) là sẽ bỏ qua việc thu hồi bộ nhớ được sử dụng bởi các đối tượng trong đoạn lệnh fixed này. Các từ được sử dụng là: fixed và unsafe.
- Các lệnh khóa (Lock Statements): là các lệnh giúp cho việc khóa các đoạn code quan trọng để đảm bảo rằng các tiến trình (process) hoặc các tuyến đoạn (thread) khác có thể can thiệp vào bộ nhớ mà đang được sử dụng bởi đoạn lệnh nào đó. Các lệnh này được sử dụng để đảm bảo tính bảo mật và chỉ hoạt động trên các kiểu dữ liệu tham chiếu. Từ khóa được sử dụng là lock.

8. Các biểu thức

- Biểu thức (expression) là một sự kết hợp của các toán tử (operators) và các toán hạng (operands).
- Toán tử là một kí hiệu để chỉ ra thao tác trên dữ liệu. VD: + để chỉ ra thao tác tính tổng 2 số…
- Toán hạng có thể là các hằng số, các biến hoặc các hàm. VD: -7, x, Sin(PI/180)…
- Một số VD về biểu thức:
x+y
(x-y)/(x+y)
Sin(x*x)/2+5*y
- Để gán giá trị của một biểu thức vào một biến chúng ta sử dụng toán tử gán (assignment operator). Cú pháp:
[tên biến] = [biểu thức];

9. Các kiểu toán tử
Có 6 kiểu toán tử:
- Toán tử toán học (Arithmetic Operators): là các toán tử được sử dụng để thực hiện các thao tác tính toán toán học ví dụ như: tính tổng, hiểu, tích, thương, lấy phần dư….
Một số các toán tử toán học:
+ : tính tổng
- : tính hiệu
* : tính tích
/ : tính thương
% : lấy phần dư của phép chia a cho b
- : toán tử âm.
- Toán tử quan hệ (Relational Operators): là những toán tử được sử dụng để kiểm tra mối quan hệ giữa các toán hạng.
> : kiểm tra lớn hơn
< : kiểm tra nhỏ hơn
= = : kiểm tra bằng nhau
!= : kiểm tra khác nhau
>= : kiểm tra lớn hơn hoặc bằng
<= : kiểm tra nhỏ hơn hoặc bằng
- Toán tử logic (Logical Operators): là những toán tử được sử dụng để liên kết các toán hạng, các biểu thức với nhau.
&& : toán tử VÀ.
|| : toán tử HOẶC.
! : toán tử PHỦ ĐỊNH.
- Các toán tử trên bit (Bitwise Operators): là các toán tử thực hiện các thao tác logic trên bit.
& : và logic trên bit.
| : hoặc logic trên bit.
^ : toán tử lấy phần bù.
- Các toán tử tăng và giảm (Increment and Decrement Operators): các toán tử này được sử dụng để tăng hoặc giảm giá trị của biến.
-- : giảm giá trị của biến xuống 1 đơn vị.
++ : tăng giá trị của biến lên 1 đơn vị.
- Toán tử gán (Assignment Operator): được sử dụng để gán giá trị của một hằng số hoặc một biến hoặc 1 biểu thức cho một biến.
Toán tử gán sử dụng dấu =.

10. Chuyển đổi dữ liệu trong C#
- Trong quá trình xây dựng chương trình thì cần có sự chuyển đổi linh hoạt giữa các loại dữ liệu được sử dụng trong chương trình.
- Sự chuyển đổi này có 2 loại:
Chuyển đổi ngầm định (Implicit conversion): chuyển đổi ngầm định được sử dụng trong trường hợp chúng ta chuyển dữ liệu từ một kiểu dữ liệu có phạm vi lưu trữ thấp sang một kiểu dữ liệu có phạm vi lưu trữ lớn hơn.
VD: chuyển dữ liệu từ kiểu số nguyên sang kiểu số thực.

int x = -7;
float y = x; // implicit conversion.

Chuyển đổi ép buộc - rõ ràng (Explicit conversion): kiểu chuyển đổi được sử dụng trong trường hợp chúng ta muốn chuyển dữ liệu từ một kiểu dữ liệu có phạm vi lưu trữ lớn hơn về một kiểu dữ liệu có phạm vi lưu trữ nhỏ hơn.
VD: chuyển dữ liệu từ kiểu số thực về số nguyên.

float x1 = -3.76f;
int x2 = (int)x1; // explicit conversion.

- Một hình thức chuyển đổi kiểu dữ liệu khác đó là chuyển đổi dữ liệu từ kiểu dữ liệu tham trị sang kiểu dữ liệu tham chiếu và ngược lại.
Nếu chúng ta chuyển từ kiểu dữ liệu tham trị sang tham chiếu thì gọi là Boxing. Boxing ko sử dụng toán tử ép kiểu.
VD:

int n1 = -9; // value type.
object o1 = n1; // value type -> reference type: Boxing.

Nếu chúng ta chuyển kiểu dữ liệu từ kiểu tham chiếu sang kiểu tham trị thì gọi là UnBoxing. Để thực hiện UnBoxing thì phải ép kiểu.
VD:

int n1 = -9; // value type.
object o1 = n1; // value type -> reference type: Boxing.
int n2 = (int)o1; // reference type -> value type: UnBoxing.