Giáo trình C#

35
1. Chương 1. Làm quen với C# Bắt đầu làm quen với một ngôn ngữ lập trình nào đó với sinh viên là một việc khá khó khăn và bỡ ngỡ, với những bạn có khả năng và tư duy tốt thì sẽ ít gặp trở ngại hơn nhưng chúng ta đều gặp vấn đề chung là không biết phải bắt đầu nó từ đâu, học sao cho đúng. Hôm nay Khoaimon mạn phép viết bài này hướng dẫn cho các bạn mới bắt đầu với ngôn ngữ lập trình C# cách làm quen và định hướng nó đúng đắn hơn. Ps: Tớ viết theo những gì đã học và trải nghiệm có gì sai sót mọi người góp ý. Bắt đầu nào. Học C# nên bắt đầu từ đâu? Có rất nhiều người và cả tôi cũng gặp phải thắc mắc này. Có người nói nên học từ C, C++ rồi mới sang C# còn theo tớ chúng ta nên bắt đầu với việc học C# trên Console (ý kiến riêng tớ thui nhé). Các bạn bật visual lên và chọn Project -> New -> ConsoleApplication. Ở đây tớ dùng visual 2005. Tớ xin giới thiệu một chút về ngôn ngữ C#: C# là một sản phẩm của Microsoft, là một ngôn ngữ hướng đối tượng khá thân thiện, mềm dẻo và chúng ta có thể dùng nó để tạo nên những ứng dụng trên desktop hay web. Ngoài ra C# còn có sẵn một khối thư viện khổng lồ với các hàm hỗ trợ mạnh trong việc lập trình. Chúng ta nên chú ý một vài nguyên tắc sau: C# là ngôn ngữ phân biệt hoa thường . Quy tắc đặt tên trong C# . Quy tắc viết chú thích. Cách khai báo các thư viện dùng trong chương trình. <những cái này các bạn sẽ hiểu hơn khi chính thức bắt tay vào từng dòng code>. Chương trình đầu tiên là gì? Chúng ta sẽ bắt đầu với việc in ra dòng chữ “Hello World”, nó sẽ tạo ra sự thân thiện trong việc tiếp xúc ngôn ngữ. Vd: Visual C# Code: Select All | Show/Hide 1. using System; 2. using System.Collections.Generic; 3. using System.Text; 4.

description

Giáo trình C#

Transcript of Giáo trình C#

Page 1: Giáo trình C#

1.Chương 1. Làm quen với C#

Bắt đầu làm quen với một ngôn ngữ lập trình nào đó với sinh viên là một việc khá khó khăn và bỡ ngỡ, với những bạn có khả năng và tư duy tốt thì sẽ ít gặp trở ngại hơn nhưng chúng ta đều gặp vấn đề chung là không biết phải bắt đầu nó từ đâu, học sao cho đúng. Hôm nay Khoaimon mạn phép viết bài này hướng dẫn cho các bạn mới bắt đầu với ngôn ngữ lập trình C# cách làm quen và định hướng nó đúng đắn hơn.Ps: Tớ viết theo những gì đã học và trải nghiệm có gì sai sót mọi người góp ý.Bắt đầu nào.Học C# nên bắt đầu từ đâu?Có rất nhiều người và cả tôi cũng gặp phải thắc mắc này. Có người nói nên học từ C, C++ rồi mới sang C# còn theo tớ chúng ta nên bắt đầu với việc học C# trên Console (ý kiến riêng tớ thui nhé). Các bạn bật visual lên và chọn Project -> New -> ConsoleApplication. Ở đây tớ dùng visual 2005.

Tớ xin giới thiệu một chút về ngôn ngữ C#: C# là một sản phẩm của Microsoft, là một ngôn ngữ hướng đối tượng khá thân thiện, mềm dẻo và chúng ta có thể dùng nó để tạo nên những ứng dụng trên desktop hay web. Ngoài ra C# còn có sẵn một khối thư viện khổng lồ với các hàm hỗ trợ mạnh trong việc lập trình.Chúng ta nên chú ý một vài nguyên tắc sau:

C# là ngôn ngữ phân biệt hoa thường .

Quy tắc đặt tên trong C# .

Quy tắc viết chú thích. 

Cách khai báo các thư viện dùng trong chương trình.

<những cái này các bạn sẽ hiểu hơn khi chính thức bắt tay vào từng dòng code>.Chương trình đầu tiên là gì?Chúng ta sẽ bắt đầu với việc in ra dòng chữ “Hello World”, nó sẽ tạo ra sự thân thiện trong việc tiếp xúc ngôn ngữ.Vd:

Visual C# Code:Select All | Show/Hide

1. using System;

2. using System.Collections.Generic;

3. using System.Text;

4.  

5. namespace khoaimon

6. {

7.     class Program

8.     {

9.         static void Main(string[] args)

10.         {

11.             //xuat ra man hinh dong chu "Hello World"

12.             Console.WriteLine("Hello World ");

13.             Console.ReadLine();

14.         }

15.     }

Page 2: Giáo trình C#

16. }

Sau khi viết xong chúng ta lưu nó lại với đuôi .cs (mặc định trong visual đã có) sau đó ấn F6 để biên dịch và ấn F5 để chạy chương trình. Kết quả xuất hiện trên màn hình dòng chữ “Hello World”.

Nhìn vào đây các bạn sẽ thắc mắc và không hiểu cấu trúc nó như thế nào. Vì thế tớ sẽ giải thích từng phần một ở bên dưới.Ví dụ trên đây là sự thể hiện ứng dụng console. Hiểu đơn giản ứng dụng console là giao tiếp với người dùng bằng bàn phím và không có giao diện người dùng. Bây giờ chúng ta sẽ cùng nhau khai phá ví dụ này nhé.Namespace: trong ví dụ trên namespace được khai báo như sauNamespace : khoaimon{//nơi chứa đựng các class ()}Trong đó: namespace là từ khóa khai báo.khoaimon là tên của namespace.Các bạn để ý thì class program được chứa trong namespace và trong namespace có thể chứa được nhiều class. Việc sử dụng namespace nhằm giải quyết xung đột tên class trong cùng một project. Ta có thể hiểu namespace là một gói những thực thể có thuộc tính và hành vi độc lập với bên ngoài và có 2 ưu điểm như sau:., Tránh được sự trùng lặp tên giữa các class.., Cho phép tổ chức mã nguồn một cách có khoa học và hợp lý.

Từ khóa using: để làm cho chương trình gọn hơn và nhất cần phải viết từng namespace cho từng đối tượng, C# cung cấp từ khóa “using”. Ta có thể sử dụng dòng lệnh “using System” ở ngay đầu chương trình, trước định nghĩa lớp và khi chúng ta dùng tới đối tượng console thay vì phải viết là “System.Console” thì chỉ cần viết Console thôi. Việc này sẽ làm cho code ngắn gọn, rõ ràng hơn.Toán tử “.”: dùng để truy cập đến dữ liệu hay phương thức trong cùng một lớp, và ngăn cách giữa tên lớp đến một namespace theo chiều từ trên xuống.Hàm Main(): trong C# hàm Main() được quy định ký tự đầu viết hoa và hàm có thể trả về giá trị void hay int và luôn khai báo là static.Chú thích (comment): //xuat ra man hinh dong chu "Hello World"Trong một project việc chú thích là vô cùng quan trọng và không thể thiếu nó làm cho chương trình dễ hiểu, rõ ràng và chúng ta không bị gặp trở ngại khi quay lại xem code. Trước mình làm project kỳ 2 điểm cho phần chú thích code chiếm khá cao vì thế mọi người nên chú ý nhé. Chúng ta có thể chú thích code bằng những cách như sau:Cách 1: sử dụng ký tự “//”. Khi gặp ký tự này trình biên dịch sẽ bó qua cả dòng đó vì thế nó thích hợp nhất khi chúng ta muốn chú thích trong 1 dòng.Cách 2: chúng ta khai báo “/*” ở đầu phần chú thích và “*/” ở cuối phần chú thích vì thế mà thích hợp cho việc chú thích trong nhiều dòng hay một khối.Cách 3: chú thích XML ghi chép tài liệu cho một lớp hoặc phương thức bằng cách sử dụng 1 phần XML (cái này các bạn sẽ tự nghiên cứu sau khi nào đã hiểu hết được về C# để tránh tẩu hỏa nhập ma).Trong ví dụ trên để viết ra dòng chữ “Hello World” chúng ta sử dụng phương thức WriteLine() và phương thức ReadLine() giúp chúng ta dừng lại màn hình để cho nó không bị chạy mất tiêu sau 1, 2 giây xuất hiện. (Cái này có nhiều bạn hỏi trên diễn đàn mà không chịu để ý nè).

Trên đây là 1 ví dụ để các bạn làm quen và tớ đã mổ xẻ nó nhưng chắc chắn vẫn còn nhiều thứ chưa mổ hết. Sang phần sau tớ sẽ giới thiệu tổng quan và đi vào chi tiết từng

Page 3: Giáo trình C#

phần của ngôn ngữ C# cho các bạn hiểu rõ hơn.

Tiếp theo chúng ta sẽ nghiên cứu tổng quan về ngôn ngữ C#

Chương 2: Biến và kiểu dữ liệu (Variables and Data Types).

!> Biến

1. Định nghĩa: Biến là một vùng nhớ được đặt tên , được sử dụng để lưu trữ dữ liệu trong chương trình.2. Cấu trúc: Để khai báo biến chúng ta có cấu trúc như sau:<kiểu dữ liệu><tên biến>;Vd: để khai báo 1 biến a kiểu một số nguyên ta làm như sau:Int a;Nếu các bạn muốn gán giá trị cho biến a là một giá trị xác định, ở đây tôi vd gán giá trị cho a bằng 3.a = 3;Cấu trúc: <tên biến> = <biểu thức>;Từ 2 ví dụ trên chúng ta có thể khai báo gộp như sau:Int a = 3;Ví dụ sau sẽ minh họa cách sử dụng biến:

Visual C# Code:Select All | Show/Hide

17. using System;

18. using System.Collections.Generic;

19. using System.Text;

20. namespace SuDungBien

21. {

22.     class MinhHoa

23.     {

24.         static void Main()

25.         {

26.             int bien1 = 3; // khai báo và khởi tạo giá trị cho một biến

27.             Console.WriteLine("Sau khi khoi tao: bien1 ={0}", bien1);

28.             bien1 = 10; // gán giá trị cho biến

29.             Console.WriteLine("Sau khi gan: bien1 ={0}", bien1);

30.             Console.ReadLine();

31.         }

32.     }

33. }

Bây giờ nếu bạn có nhiều biến với cùng 1 kiểu dữ liệu thì có thể khai báo chung được không và nếu gán cho chúng cùng giá trị như nhua thì sao? Dĩ nhiên câu trả lời là có và chúng ta có thể gộp chung việc khai báo các biến cùng kiểu và cùng giá trị.Chúng ta có cấu trúc như sau: <kiểu dữ liệu><biến 1><biến 2>,…,<biến n>;Vd: int a,b,c;Gán cùng một giá trị cho nhiều biến(cái này người ta gọi là “đa gán”).Vd: gán giá trị 3 cho 3 biến a, b,c;a = b = c = 3;

Page 4: Giáo trình C#

Chú ý: a, trong C# yêu cầu các biến phải được khởi tạo trước khi sử dụng.b, tên biến trong C# phân biệt chữ hoa, chữ thường.c, tên biến chỉ có thể bắt đầu với ký tự hoặc dấu _ chứ không thể bắt đầu với chữ số.d, tên biến không được chưa các ký tự đặc biệt như $,#,%,^…e, tên biến không đươc trùng với từ khóa nhưng nếu muốn đặt trùng tên với từ khóa thì dùng @ ở đằng trước.Và cuối cùng hãy nhớ đặt tên biến sao cho nó phả ánh được ý nghĩa mà chúng ta sử dụng nó để thuận lợi hơn trong việc kiểm tra lại code.Ngoài ra hằng (constant) cũng được coi là biến nhưng tớ sẽ nhắc tới nó vào phần sau.Từ nãy đến giờ nhắc đến “kiểu dữ liệu” chắc các bạn đang thắc mắc nó là gì đúng hem? Sẽ không để các bạn phải chờ lâu nữa.

!!> Kiểu dữ liệu (data type)

C# chia thành hai tập hợp kiểu dữ liệu chính: Kiểu xây dựng sẵn (built- in) mà ngôn ngữ cung cấp cho người lập trình và kiểu được người dùng định nghĩa(user-defined) do người lập trình tạo ra. C# phân tập hợp kiểu dữ liệu này thành hai loại: Kiểu dữ liệu giá trị (value) và kiểu dữ liệu tham chiếu (reference).1. Kiểu dữ liệu giá trị: là các kiểu dữ liệu lưu trữ các thông tin thức tế.

Các kiểu dữ liệu xây dựng sẵn

byte: số nguyên dương không dấu từ 0-255

char: ký tự Unicode

int: số nguyên có dấu –2.147.483.647 và 2.147.483.647 

float: kiểu dấu chấm động, giá trị xấp xỉ từ 3,4E-38 đến 3,4E+38, với 7 chữ số có nghĩa..

sbyte : số nguyên có dấu ( từ -128 đến 127)

short: số nguyên có dấu giá trị từ -32768 đến 32767.

ushort: số nguyên không dấu 0 – 65.535

uint: số nguyên không dấu 0 – 4.294.967.295

double: kiểu dấu chấm động có độ chính xác gấp đôi, giá trị xấp xỉ từ 1,7E-308 đến 1,7E+308,với 15,16 chữ số có nghĩa.

decimal: Có độ chính xác đến 28 con số và giá trị thập phân, được dùng trong tính toán tài chính, kiểu này đoi hỏi phải có hậu tố “m” hay “M” theo sau giá trị.

long: kiểu số nguyên có dấu có giá trị trong khoảng :-9.223.370.036.854.775.808 đến 9.223.372.036.854.775.807

ulong: Số nguyên không dấu từ 0 đến 0xffffffffffffffff

bool: Giá trị logic true/ false

2. Kiểu dữ liệu tham chiếu: 

Page 5: Giáo trình C#

object: đây là kiểu dữ liệu cơ sở chứa tất cả các kiểu dữ liệu khác trong C#.string: kiểu dữ liệu chuỗi ký tự.class: kiểu dữ liệu class.delegate: kiểu dữ liệu chuyển giao.interface: kiểu dữ liệu giáo tiếp.array: kiểu dữ liệu mảng.

 tiếp phần 2.

Tớ định viết tách 1 phần riêng để nói về “hằng” (const) nhưng hằng lại là trường hợp đặc biệt của biến và theo yêu cầu của một số mem muốn nói rõ hơn về vấn đề này nên tớ sẽ tách nó ra để mọi người theo dõi.I. Hằng là gì? Như trên tớ đã nói thì chúng ta có thể khái quát lại như sau: hằng là một biến nhưng giá trị của nó không thay đổi.Từ định nghĩa các bạn phải chú ý 1 điều: trong suốt chương trình phải đảm bảo giá trị của nó không đổi. (Đừng làm liều nghe.hihi.)II. Phân loại: hằng được phân thành 3 loại: 

Bây giờ chúng ta sẽ đi phân tích chi tiết từng loại 1 nhé.Đầu tiên sẽ là cấu trúc khai báo hằng<const><kiểu dữ liệu><tên hằng> = <giá trị>;Vd: const int a = 20; 1. Giá trị hằng: từ ví dụ trên thì giá trị 20 chính là giá trị hằng và giá trị 20 là không đổi.2. Biểu tượng hằng: một biểu tượng hằng phải tượng khởi tạo trước khi khai báo và chỉ duy nhất một lần trong suốt quá trình và không được thay đổi. Trong ví dụ trên thì a chính là biểu tượng hằng có kiểu số nguyên. (các bạn nên đặt biểu tượng hằng có ý nghĩa nó sẽ giúp chúng ta dễ dàng hơn khi xem lại).

Visual C# Code:Select All | Show/Hide

34. class khoaimon

35.     {

36.         static void Main()

37.         {

38.         const int diemmax = 10; // Điểm cao nhất

39.         const int diemliet = 0; // Điểm liệt

40.         System.Console.WriteLine( “diem thi cao nhat la {0}”, diemmax );

41.         System.Console.WriteLine( “diem liet la {0}”, diemliet );

42.         }

43.     }

3. Kiểu liệt kê: kiểu liệt kê là tập hợp các tên hằng có giá trị không đổi (danh sách liệt kê).3.1. Cách khai báo và sử dụngTrong ví dụ trên ta có:const int diemmax = 10;

Page 6: Giáo trình C#

cost int diemliet = 0;

Bây giờ theo yêu cầu mở rộng của bài toán chúng ta thêm một số hằng khác vào danh sách trên:const int diemtb = 5; //điểm trung binhconst int diemkha = 7; //điểm khá

Và dĩ nhiên các biểu tượng hằng trên đều có ý nghĩa quan hệ với nhau, chúng cùng nhắc đến các mốc điểm để đánh giá điểm thi. Một vấn đề đặt ra nếu chúng ra để riêng lẻ từng hằng trên thì chương trình nhìn sẽ không đẹp mắt và cồng kềnh. Lúc này đây C# cung cấp cho người lập trình một giải pháp để giải quyết vấn đề trên đó là kiểu liệt kê:

Cú pháp:

Visual C# Code:Select All | Show/Hide

44. enum  [kiểu cơ sở]

45. {

46.     Danh sách các thành phần liệt kê

47. };

Vd:

Visual C# Code:Select All | Show/Hide

48. enum  diemthi : int

49. {

50. diemmax = 10,

51. diemliet = 0,

52. diemtb = 5,

53. diemkha = 7,

54. };

Chú ý: mỗi kiểu liệt kê đều có một kiểu dữ liệu cơ sở có thể là bất kỳ kiểu dữ liệu nào như int, short, long…tuy nhiên kiểu dữ liệu liệt kê không chấp nhận kiểu ký tự và nếu chúng ta bỏ qua phần này thì trình biên dịch sẽ gán giá trị mặc định là kiểu nguyên (int). Kiểu liệt kê là một kiểu hình thức do đó bắt buộc phải thực hiện phép chuyển đổi tường minh với các kiểu giá trị nguyên:

Visual C# Code:Select All | Show/Hide

55. using System;

56. using System.Collections.Generic;

57. using System.Text;

58.  

59. namespace khoaimon

60. {

61.  

62.     class KieuEnum

63.     {

64.  

65.         enum diemthi : int

Page 7: Giáo trình C#

66.         {

67.  

68.             diemmax = 10,

69.             diemliet = 0,

70.             diemtb = 5,

71.             diemkha = 7,

72.  

73.  

74.         };

75.  

76.         static void Main()

77.         {

78.  

79.             System.Console.WriteLine("diem cao nhat:

{0}", (int)diemthi.diemmax);

80.  

81.             System.Console.WriteLine("diem liet:

{0}", (int)diemthi.diemliet);

82.  

83.             System.Console.WriteLine("diem trung binh

{0}", (int)diemthi.diemtb);

84.  

85.             System.Console.WriteLine("diem kha:

{0}", (int)diemthi.diemkha);        

86.  

87.            

88.  

89.             Console.ReadLine();

90.  

91.         }

92.  

93.     }

94.  

95. }

Chú ý: Mỗi thành phần trong kiểu liệt kê tương ứng với một giá trị số, trong trường hợp này là mộtsố nguyên. Nếu chúng ta không khởi tạo cho các thành phần này thì chúng sẽ nhận các giá trị tiếp theo với thành phần đầu tiên là 0.

vd:

Visual C# Code:Select All | Show/Hide

96. using System;

97. using System.Collections.Generic;

98. using System.Text;

99.  

100. namespace ConsoleApplication18

Page 8: Giáo trình C#

101. {

102.     class Program

103.     {

104.         enum diemthi : int

105.         {

106.  

107.             diemmax,

108.             diemliet,

109.             diemtb,

110.             diemkha,

111.  

112.  

113.         };

114.  

115.         static void Main(string[] args)

116.         {

117.             System.Console.WriteLine("diem cao nhat:

{0}", (int)diemthi.diemmax);

118.  

119.             System.Console.WriteLine("diem liet:

{0}", (int)diemthi.diemliet);

120.  

121.             System.Console.WriteLine("diem trung binh

{0}", (int)diemthi.diemtb);

122.  

123.             System.Console.WriteLine("diem kha:

{0}", (int)diemthi.diemkha);

124.  

125.  

126.  

127.             Console.ReadLine();

128.  

129.  

130.         }

131.     }

132. }

Khi đó giá trị thứ nhất là 0, các giá trị sau sẽ là 1; 2; 3.(đây là trường hợp với số nguyên).

Chúng ta sẽ tiếp tục bước sang chương 3.Chương 3: Statements (cấu trúc lệnh).

Trong C# tớ chia ra cấu trúc lệnh thành 3 loại:

còn một vài kiểu lệnh nữa nhưng các bạn đừng nên quan tâm quá nhiều

Page 9: Giáo trình C#

tránh gây nhầm lẫn.

I. Cấu trúc điều khiển: C# cung cấp hai cấu trúc điều khiển thực hiện việc lựa chọn điều kiện thực thi chương trình đó là cấu trúc if và switch...case.I.I. Cấu trúc ifCấu trúc if trong C# được mô tả như sau:

Visual C# Code:Select All | Show/Hide

133. if (biểu thức điều kiện)

134. {

135. // câu lệnh thực thi nếu biểu thức điều kiện đúng

136. }

137. else

138. {

139. // câu lệnh thực thi nếu biểu thức điều kiện sai

140. }

Đây là câu lệnh dùng để kiểm tra điều kiện Ví dụ:

Visual C# Code:Select All | Show/Hide

141. using System;

142. using System.Collections.Generic;

143. using System.Text;

144.  

145. namespace ConsoleApplication19

146. {

147.     class Program

148.     {

149.         static void Main(string[] args)

150.         {

151.             Console.WriteLine("Hay nhap vao mot ten khoaimon");

152.             string input;

153.             input = Console.ReadLine();

154.             if (input == "khoaimon")

155.             {

156.                 Console.WriteLine("khoaimon kute hihi");

157.             }

158.             else

159.             {

160.                 Console.WriteLine("ban chua nhap dung");

161.             }

162.            

163.             Console.WriteLine("Ban vua go " + input);

164.  

165.             Console.ReadLine();

166.         }

Page 10: Giáo trình C#

167.     }

168. }

Trong ví dụ trên câu lệnh if kiểm tra giá trị của input được nhập vào có trùng với từ “khoaimon” hay không? Nếu đúng thì in ra dòng chữ “khoaimon kute hihi” còn nhập sẽ chương trình sẽ báo lỗi bạn chưa nhập đúng. Câu lệnh này khá đơn giản và chắc chắn các bạn sẽ hiểu được nó sau một vài ví dụ. Trong cấu trúc câu lệnh if này tớ sẽ giới thiệu thêm một trường hợp các câu lệnh if lồng nhau. Trường hợp các câu lệnh if lồng nhau dùng để cho việc xử lý các câu lệnh điều kiện phức tạp.Cấu trúc:

Visual C# Code:Select All | Show/Hide

169. if(điều kiện 1)

170. if(điều kiện 2){

171. }else{

172. }else{

173. }

Hoặc

Visual C# Code:Select All | Show/Hide

174. if(điều kiện 1){

175. }

176. else{

177. if(điều kiện 2){

178. }

179. else{

180. }

181. }

I.II. Cấu trúc switch … case

Các câu lệnh if nằm lồng nhau rất khó đọc, khó gỡ rối. Khi chúng ta có một loạt lựa chọn phức tạp thì nên sử dụng câu lênh switch.Cấu trúc swtich….case có cú pháp như sau:

Visual C# Code:Select All | Show/Hide

182. // switch ... case

183. switch (Biến điều kiện)

184. {

185. case giá trị 1:

186. Câu lệnh thực thi

187. break;

188. case giá trị 2:

189. Câu lệnh thực thi

190. break;

Page 11: Giáo trình C#

191. case giá trị 3:

192. Câu lệnh thực thi

193. break;

194. default:

195. Câu lệnh thực thi

196. break;

197. }

Cũng tương tự như câu lệnh if, biểu thức để so sánh được đặt sau từ khóa switch, tuy nhiên giá trị so sánh lại được đặt sau mỗi các từ khóa case. Trong câu lệnh này phải có một câu lệnh nhảy như break, gôt để điều khiển nhảy qua các case khác. Nếu không thì chương trình sẽ thực hiện tất cả các case theo sau.

II. Cấu trúc lặp

C# cung cấp các cấu trúc vòng lặp chương trìnhWhile Do… whileForForeachCho phép chúng ta thực hiện một đoạn mã lặp lại đến khi đúng điều kiện lặp.Sau đây, tôi xin giới thiệu công thức và ví dụ sử dụng các vòng lặp trênVòng lặp While Cấu trúc vòng lặp while

Visual C# Code:Select All | Show/Hide

198. while (biểu thức điều kiện)

199. {

200. // câu lệnh

201. }

202. Thực thi câu lệnh hoặc một loạt những câu lệnh đến khi điều kiện

không thỏa mãn.

Ví dụ:

Visual C# Code:Select All | Show/Hide

203. using System;

204. using System.Collections.Generic;

205. using System.Text;

206.  

207. namespace ConsoleApplication19

208. {

209.     class Program

210.     {

211.         static void Main(string[] args)

212.         {

213.            int diem = 0;

214.            while ( diem < 10 )

215.                 {

Page 12: Giáo trình C#

216.                     Console.WriteLine(" diem: {0} ",diem);

217.                     diem++;

218.                 }

219.                 Console.ReadLine();

220.            

221.         }

222.     }

223. }

Vòng lặp do…whileCấu trúc vòng lặp do…while

Visual C# Code:Select All | Show/Hide

224. do

225. {

226. // câu lệnh

227. }

228. While (biểu thức điều kiện)

Chú ý: Ở đây có sự khác biệt quan trọng giữa vòng lặp while và vòng lặp do...while là khi dùng vòng lặp do...while thì tối thiểu sẽ có một lần các câu lệnh trong do...while được thực hiện. Điều này cũng dễ hiểu vì lần đầu tiên đi vào vòng lặp do...while thì điều kiện chưa được kiểm tra.

Ví dụ:

Visual C# Code:Select All | Show/Hide

229. using System;

230. using System.Collections.Generic;

231. using System.Text;

232.  

233. namespace ConsoleApplication19

234. {

235.     class Program

236.     {

237.         static void Main(string[] args)

238.         {

239.            int diem = 10;

240.            do

241.            {

242.                Console.WriteLine(" diem: {0} ", diem);

243.                diem++;

244.            } while (diem < 10);

245.            Console.ReadLine();

246.            

247.         }

248.     }

Page 13: Giáo trình C#

249. }

Ở trong ví dụ này chúng ta sẽ thấy mặc dù diem = 10 là vi phạm điều kiện nhưng chương trình vẫn ra in kết quả diem = 10. Vì trong câu lệnh này nó thực hiện câu lệnh in ra diem = 10 rồi sau đó mới kiểm tra điều kiện rằng 10 không thỏa mãn và sau đó mới dừng chương trình.

Vòng lặp forCấu trúc vòng lặp for

Visual C# Code:Select All | Show/Hide

250. for ([ phần khởi tạo] ; [biểu thức điều kiện]; [bước lặp])

251. {

252. // thực thi câu lệnh

253. }

Ví dụ:

Visual C# Code:Select All | Show/Hide

254. using System;

255. using System.Collections.Generic;

256. using System.Text;

257.  

258. namespace ConsoleApplication19

259. {

260.     class Program

261.     {

262.         static void Main(string[] args)

263.         {

264.             for (int diem = 0; diem <= 10; diem++)

265.             Console.WriteLine(diem);

266.             Console.ReadLine();

267.  

268.         }

269.     }

270. }

Vòng lặp foreach

Câu lệnh foreach cho phép chúng ta lặp qua tất cả các mục trong một mảng hay trong một tập hợp. Cú pháp sử dụng lệnh lặp foreach như sau: 

Visual C# Code:Select All | Show/Hide

271. foreach ( in )

272. {

273. // thực hiện thông qua tương ứng với

274. // từng mục trong mảng hay tập hợp

Page 14: Giáo trình C#

275. }

Ở đây chúng ta sẽ chỉ quan tâm đến vòng lặp foreach sử dụng với mảng. Bạn hãy xem ví dụ sau để hiểu cách sử dụng của vòng lặp foreach truy cập đến từng phần tử của mảng.

Visual C# Code:Select All | Show/Hide

276. using System;

277. using System.Collections.Generic;

278. using System.Text;

279.  

280. namespace ConsoleApplication19

281. {

282.     class Program

283.     {

284.         static void Main(string[] args)

285.         {

286.             int[] intArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

287.             foreach (int item in intArray)

288.             {

289.                 Console.Write("{0} ", item);

290.             }

291.             Console.ReadLine();

292.  

293.  

294.         }

295.     }

296. }

III. Các lệnh break, goto và continue III.I. Câu lệnh nhảy goto:Lệnh nhảy goto là một lệnh nhảy đơn giản, cho phép chương trình nhảy vô điều kiện tới một vị trí trong chương trình thông qua tên nhãn. Goto giúp chương trình của bạn được linh hoạt hơn nhưng trong nhiều trường hợp nó sẽ làm mất đi cấu trúc thuật toán và gây rối chương trình.Cách sử dụng lệnh goto:Tạo một nhãngoto đến nhãnNhãn là một định danh theo sau bởi dấu hai chấm ( . Thường thường một lệnh goto gắn vớimột điều kiện nào đó.Nhưng trong lập trình người ta tránh dùng nó vì việc sử dụng câu lệnh này sẽ khiến chương trình bị rối và gây ra tình trạng khó kiểm soát. Vì thế tớ sẽ không đi sâu vào nó.III.II. Câu lệnh nhảy break Ta dùng câu lệnh break khi muốn ngưng ngang việc thi hành và thoát khỏi vòng lặp và tiếp tục thực hiện các lệnh tiếp ngay sau vòng lặp.

III.III. Câu lệnh nhảy continue

Câu lệnh continue được dùng trong vòng lặp khi bạn muốn khởi động lại một vòng lặp nhưng lại không muốn thi hành phần lệnh còn lại trong vòng lặp, ở một điểm nào đó trong thân vòng lặp.

Page 15: Giáo trình C#

Ngoài ra còn có một vài câu lệnh nhảy nữa như return, yield, default. Chúng ta sẽ hiểu hơn về chúng khi làm những bài tập về sau này. 

Chương 4: Toán Tử (Operators).

I. Định nghĩa: C# có một tập hợp các toán tử phong phú. Toán tử là công cụ dùng để thao tác dữ liệu . Một toán tử là một ký hiệu dùng để đại diện cho một thao tác cụ thể nào đó được thực hiện trên dữ liệu. 

II. Phân loại:

Với toán tử tớ sẽ chia nó ra thành 5 loại cơ bản như sau:

II.I. Toán tử số học: Ngôn ngữ C# cung cấp cho chúng ta 5 toán tử toán học là: 

Các phép toán này không thể thiếu trong bất cứ ngôn ngữ lập trình nào, C# cũng không ngoại lệ, các phép toán số học đơn giản nhưng rất cần thiết bao gồm: phép cộng (+), phép trừ (-), phép nhân (*), phép chia (/) nguyên.Để tìm phần dư của phép chia nguyên, chúng ta sử dụng toán tử chia lấy dư (%).Vd khi ta thực hiện phép chia 5/2 thì kết quả sẽ thu được là 1 (đây là phần dư còn lại của phép chia nguyên). Trong vòng lặp thì điều này là rất hữu dụng khi muốn thực hiện một công việc nào đó cách khoảng n lần, ta chỉ cần kiểm tra phép chia dư n, nếu kết quả bằng 0 thì thực hiện công việc. Để hiểu rõ hơn về phép chia lấy phần dư này tớ sẽ có một vd sau đây:Vd:

Visual C# Code:Select All | Show/Hide

297. using System;

298. using System.Collections.Generic;

299. using System.Text;

300.  

301. namespace ConsoleApplication20

302. {

303.     class Program

304.     {

305.         static void Main(string[] args)

306.         {

307.             for (int i = 0; i < 4; i++)

308.             {

309.                 if (i %2 ==0)

310.                 {

311.                     Console.WriteLine(" so i chia het cho 2 la: {0}

", i);

312.                 }

Page 16: Giáo trình C#

313.                 else

314.                 {

315.                     //không in ra

316.                 }

317.             }

318.             Console.ReadLine();

319.         }

320.     }

321. }

Trong chương trình nó tìm xem trong khoảng i từ 0 đến 3 có số nào chia cho 2 dư 0 thì sẽ in ra còn những số chia cho 2 có dư khác 0 sẽ không được in ra.

II.II. Toán tử quan hệ: 

Toán tử quan hệ được dùng để kiểm tra mối quan hệ giữa hai biến, hay giữa một biến và một hằng. Ví dụ việc xét số lớn hơn của hai số a và b được thực hiện thông qua dấu lớn hơn (>) giữa hai toán hạng a và b là (a>b). Bây giờ ta so sánh lớn hơn giữa 4 và 3. Ta có 4 > 3 là đúng thì sẽ trả về giá trị là true trong khi 3> 4 là sai thì trả về giá trị là false. Chúng ta sẽ cùng xem các toán tử quan hệ và ý nghĩa của chúng qua hình sau đây.

II.III. Toán tử tăng và giảm:

Khi sử dụng các biến số ta thường có thao tác là cộng một giá trị vào biến, trừ đi một giá trị từ biến đó, hay thực hiện các tính toán thay đổi giá trị của biến sau đó gán giá trị mới vừa tính toán cho chính biến đó.Đối với toán tử này tớ sẽ chia ra làm 2 loại:a. Tính toán và gán trở lạiChúng ta sẽ có bảng mô tả các phép toán tự gán như sau:

Ví dụ ta có một biến nguyên a có giá trị bằng 5. Giờ chúng ta muốn giảm giá trị của biến a bằng 3 ta làm như sau:a = a – 2;Trong câu lênh này phép trừ được thực hiện trước lấy giá trị của a là 5 trừ đi 2 bằng 3 và sau đó gán giá trị 3 cho biến a. Lúc này biến a sẽ có giá trị bằng 5. Các kiểu khác cũng tương tự. Và việc tăng hay giảm giá trị của một biến trong tính toán thương rất hay xảy ra. 

Chú ý: chúng ta rất hay gặp một biến có giá trị được tăng hay giảm 1 và nó rất phổ biến trong lập trình và C# cung cấp cho chúng ta 2 toán tử đặc biết là tăng một (++) hay giảm một (--).b. Toán tử tăng giảm tiền tố và tăng giảm hậu tố

Trong trường hợp chúng ta sử dụng các phép toán kết hợp như tăng một giá trị cho biến và sau đó gán giá trị của biến cho biến thứ 2. Vậy làm thế nào để xác định được việc nào thực hiện trước, việc nào thực hiện sau?Để giải quyết yêu cầu trên C# cung cấp thứ tự thực hiện phép toán tăng/giảm với phép toán gán, thứ tự này được gọi là tiền tố (prefix) hay hậu tố (postfix).

Page 17: Giáo trình C#

Vd ta có: var1 = var2++; // Hậu tố.var1 = ++var2; //Tiền tố.Trong trường hợp tiền tố phép tăng sẽ được thực hiện trước và sau đó phép gán mới thực hiện. Và nó ngược lại với trường hợp hậu tố.Để hiểu rõ hơn ta sẽ có một ví dụ nhỏ như sau:

Visual C# Code:Select All | Show/Hide

322. using System;

323. using System.Collections.Generic;

324. using System.Text;

325.  

326. namespace ConsoleApplication20

327. {

328.     class Program

329.     {

330.         static void Main(string[] args)

331.         {

332.             int a = 5;

333.             int b;

334.             b = a++;

335.             Console.WriteLine("Thuc hien tang sau: {0}, {1}",

336.             a, b);

337.             a = 5;

338.             b = ++a;

339.             Console.WriteLine("Thuc hien tang truoc: {0}, {1}",

340.             a, b);

341.             Console.ReadLine();

342.         }

343.     }

344. }

II.IV. Toán tử gán:Đến lúc này toán tử gán khá quen thuộc với chúng ta, hầu hết các chương trình minh họa từ đầu đều đã sử dụng phép gán. Toán tử gán hay phép gán làm cho toán hạng bên trái thay đổi giá trị bằng với giá trị của toán hạng bên phải. Toán tử gán là toán tử hai ngôi. Đây là toán tử đơn giản nhất thông dụng nhất và cũng dễ sử dụng nhất. ví dụ a = b;II.V. Toán tử logic:C# cung cấp cho chúng ta một tập hợp toán tử logic để phục vụ cho người lập trình.Các bạn xem trong hình sau:

Đôi khi chúng ta muốn kết hợp nhiều điều kiện với nhau như: bắt buộc cả hai hay nhiều điều kiện phải đúng hoặc chỉ cần một trong các điều kiện đúng là đủ hoặc không có điều kiện nào đúng...thì chúng ta phải dùng tới toán tử này.

Ngoài ra chúng ta cần biết thêm tới một loại toán tử nữa là toán tử ba ngôi(? .Toán tử này sẽ xác định giá trị của một biểu thức điều kiện, và biểu thức điều kiện này phải trả về một giá trị kiểu bool. Có nghĩa là nếu điều kiện đúng thì làm công việc thứ

Page 18: Giáo trình C#

nhất, còn ngược lại điều kiện sai thì làm công việc thứ hai.Vd: Visual C# Code:

Select All | Show/Hide

345. using System;

346. using System.Collections.Generic;

347. using System.Text;

348.  

349. namespace ConsoleApplication20

350. {

351.     class Program

352.     {

353.         static void Main(string[] args)

354.         {

355.             int a;

356.             int b;

357.             int max;

358.             a = 5;

359.             b = 8;

360.             max = a > b ? a : b;

361.             Console.WriteLine("gia tri lon nhat {0}", max);

362.             Console.ReadLine();

363.         }

364.     }

365. }

Đây là bài toán tìm giá trị lớn nhất trong 2 số. Nếu a lớn hơn b thì giá trị lớn nhất là a còn sai thì b là giá trị lớn nhất. Đó là ý nghĩa của toán tử này.

Chương 5: Chuyển đổi các kiểu dữ liệu trong C#

Trong C# cung cấp cho chúng ta rất nhiều cách ép kiểu nhưng ở đây tớ chỉ xin giới thiệu tới mọi người 4 cách: 

1. Parse Phương thức Parse là phương thức được sử dụng khá phổ biến khi chúng ta muốn chuyển đổi một chuỗi sang một kiểu dữ liệu tương ứng.Mỗi kiểu dữ liệu cơ bản trong C# đều có phương thức Parse để chuyển đổi sang kiểu dữ liệu đó. Một số ví dụ các câu lệnh minh họa cho việc chuyển đổi sử dụng phương thức Parse 

PHP Code:int a = Int32.Parse("123"); //a sẽ mang giá trị 123float b = Float.Parse("20.7"); //b sẽ mang giá trị 20.7bool c = Boolean.Parse("true"); //c sẽ mang giá trị true  

Page 19: Giáo trình C#

Nếu như chuỗi chúng ta truyền vào là rỗng, không đúng định dạng hoặc vượt quá giá trị cho phép thì chúng ta sẽ nhận được các Exception tương ứng. Ví dụ: 

PHP Code:int a = Int32.Parse(“Hello”); //sai định dạng, FormatExceptionbyte b = Byte.Parse(“10000000000”); //quá giới hạn, OverflowExceptionbool c = Boolean.Parse(null); //tham số là null, ArgumentNullException  

2. TryParse Giống như Parse, TryParse cũng là phương thức được tích hợp sẵn trong các lớp kiểu dữ liệu cơ bản của C#. Tuy nhiên, cú pháp của TryParse có phần khác với Parse. Cụ thể, tham số thứ nhất của TryParse là chuỗi cần chuyển đổi và tham số thứ hai là biến sẽ chứa giá trị đã được chuyển đổi, biến thứ hai này phải được đánh dấu là out . Để hiểu hơn về out các bạn tra MSDN nhé.

Một số ví dụ minh họa 

PHP Code:int a;Int32.TryParse(“123”, out a); //a sẽ mang giá trị 123  bool b;Boolean.TryParse(“false”, out b); //b sẽ mang giá trị false  

Điểm khác biệt thứ hai của TryParse so với Parse là phương thức TryParse không ném ra các ngoại lệ như Parse mà sẽ trả về các giá trị true (chuyển đổi thành công) hoặc false (chuyển đổi thất bại, biến mang giá trị mặc định). 

PHP Code:int a;Int32.TryParse("hello", out a); //trả về giá trị false, a mang giá trị 0bool b;Boolean.TryParse("", out b); //trả về giá trị false, b mang giá trị False  

Chú ý: Ngoài ra, phương thức TryParse sẽ thực thi nhanh hơn phương thức Parse vì TryParse không ném ra ngoại lệ

3. Convert Lớp Convert là một lớp tiện ích trong C# cung cấp cho chúng ta rất nhiều phương thức tĩnh khác nhau để chuyển đổi từ một kiểu dữ liệu này sang kiểu dữ liệu khác. Tham số mà các phương thức trong Convert nhận không nhất thiết phải là chuỗi mà có thể ở nhiều kiểu dữ liệu khác nhau (int, bool, double…). Ví dụ: 

PHP Code:int a = Convert.ToInt32("123"); //chuyển chuỗi 123 sang số nguyênbool b = Convert.ToBoolean(13); //chuyển số 13 sang kiểu bool  

Các phương thức trong lớp Convert sẽ trả về giá trị mặc định nếu như tham số truyền vào là null. Còn trong các trường hợp sai định dạng hoặc vượt quá giới hạn thì các phương thức đó sẽ ném ra các ngoại lệ tương tự như phương thức Parse. Ví dụ:

PHP Code:bool a = Convert.ToBoolean("khoaimon"); //FormatExceptionint b = Convert.ToInt32("123456787654"); //OverflowExceptiondouble d = Convert.ToDouble(null); //trả về giá trị mặc định  

4. Casting (Ép kiểu) Ép kiểu là cách chúng ta có thể sử dụng khi muốn chuyển đổi giữa các kiểu dữ liệu có tính chất tương tự nhau (thường là số). Ví dụ :

PHP Code:int a = 100;float b = a; //chuyển đổi ngầm định, b = 100

Page 20: Giáo trình C#

int c = (int)b; //chuyển đổi rõ ràng, c = 100int a = 100;  

Ngoài ra, đối với các giá trị được lưu trong kiểu tổng quát Object (bằng cách boxing) thì chúng ta có thể ép kiểu đưa về kiểu dữ liệu ban đầu (Tìm hiểu về Boxing và Unboxing) 

PHP Code:object b = a; //boxing, b là kiểu tham chiếu chứa giá trị 100int c = (int)b; //unboxing, c mang giá trị 100  

Ép kiểu chỉ được sử dụng khi chúng ta biết rõ rằng đối tượng đó chứa kiểu dữ liệu tương ứng với kiểu mà ta cần chuyển tới. Ví dụ như các trường hợp sau sẽ là các lỗi cú pháp trong lập trình: 

PHP Code:string a = "1234";int b = (int)a; //lỗi, không thể ép kiểu chuỗi sang kiểu sốbool c = true;double d = (double)c; //lỗi, không thể ép kiểu bool sang kiểu double  

Chú ý: Việc sử dụng cách nào là do tùy chương trình và còn phụ thuộc vào sự quan hệ giữa các kiểu dữ liệu vì thế các bạn nên chú ý nhé.

Lần trước có một mem hỏi tớ về toán tử "as". Và tiện đây tớ xin chia sẻ thêm. Ngoài việc sử dụng casting thuần túy, chúng ta có thể sử dụng toán tử “as”.Nhược điểm của việc sử dụng casting thuần túy là nếu việc casting thất bại thì chúng ta sẽ nhận được một exception cho việc thất bại đó. Tuy nhiên, nếu sử dụng toán tử “as”, nếu việc casting không thành công thì chúng ta sẽ nhận về một giá trị null thay vì là một exception.vd: 

PHP Code:var myObject = existingObject as MyObject;  

Giả định rằng nếu việc chuyển đổi trên sẽ thất bại thì myObject lúc này sẽ mang giá trị null.

chương 6: Mảng (arrays) trong C#

Với những bạn đã được làm quen với các ngôn ngữ khác thì việc nhắc đến mảng không có gì là mới lạ nhưng trong tài liệu này điều mà mình muốn hướng là cả những bạn chưa từng làm quen với ngôn ngữ lập trình nào cả và các bạn khác nên tìm hiểu để rút ra nhận sét và so sánh sự giống và khác nhau của mảng trong từng ngôn ngữ. Mảng trong C# là một vấn đề rất quan trọng và nó sẽ là bước đệm phục vụ tốt hơn cho chúng ta khi bước tiếp vào phần sau.

I. Mảng là gì?Một ngày nào đó bạn gặp một chương trình mà cần lưu trữ hàng loạt các biến có cùng kiểu dữ liệu và cách làm bây giờ là khai báo từng biến một. Thật dài dòng và rắc rối đúng hem. Và thật tuyệt vời khi C# cung cấp cho chúng ta một kiểu cấu trúc dữ liệu cho phép quản lý các biến cùng tên đó đó là mảng(arrays). Vậy mảng là gì? Có lẽ nhìn vào ví dụ trên các bạn cũng đã định nghĩa được cho mình về khái niệm này.Mảng là một tập hợp hữu hạn các phần tử có cùng kiểu dữ liệu.II. Cách khai báo:Để khai báo một mảng trong C# chúng ta sử dụng cú pháp như sau:

PHP Code:

Page 21: Giáo trình C#

< DataType >[]< ArrayName >;  

Trong đó:DataType: kiểu dữ liệu như int, float….ArrayName: tên mảng (hãy đặt tên nào đó có ý nghĩa và mang tính chất gợi mở nhé).[]: cặp dấu ngoặc vuông này chỉ ra cho trình biên dịch biết chúng ta đang khai báo một mảng. Vd:PHP Code:int[]x;  

Bây giờ là vấn đề khởi tạo mảng tức là quá trình khai báo số lượng các phần tử của mảng và gán giá trị cho các phần tử đó.Tớ sẽ tóm tắt cho mọi người 4 cách như sau để khởi tạo giá trị của mảng:C1: Khai báo và chỉ ra số phần tử của mảng.

Cú pháp:

PHP Code:[DataType] [ ] [ArrayName] = new [DataType] [number of elements];  

number of elements: số phần tử của mảng.VD: khai báo một mảng số nguyên lưu trữ 5 phần tử.

PHP Code:int[] a = new int[5]  

C2: Khai báo sau đó mới khởi tạo số phần tử của mảng.

[DataType] [ ] [ArrayName];[ArrayName] = new [DataType] [number of elements];VD: khai báo một mảng số nguyên lưu trữ 5 phần tử.

PHP Code:Int[]  a;a = new int[5];  

C3: Khai báo, chỉ ra số lượng các phần tử mảng và gán các giá trị ban đầu cho các phần tử mảng.

PHP Code:int[] a = new int[5] {1, -1, 3, 4, 5};  

gán giá trị cho các phần tử của mảng.

- Truy cập các phần tử mảng: một mảng là một danh sách các phần tử có cùng kiểu dữ liệu, các phần tử đó được đánh số thứ tự bắt đầu từ 0 đến n-1 (Trong đó n là số phần tử của mảng).Như vậy để truy cập đến 1 phần tử của mảng thì chúng ta sử dụng một số nguyên để chỉ ra số thứ tự của phần tử đó trong mảng, phần tử nguyên này được gọi là chỉ số (index).Cú pháp tổng quát để truy cập đến phần tử thứ i của mảng là:

PHP Code:[tên mảng] [i-1];  

VD: gán giá trị 5 cho phần tử thứ 3 của mảng.

PHP Code:a[2] = 5;  

- Duyệt qua các phần tử mảng.Kể từ khi mảng là một tập hợp các hữu hạn phần tử do đó để duyệt qua các phần tử

Page 22: Giáo trình C#

mảng thường chúng ta sử dụng vòng lặp for.VD: in danh sách các phần tử mảng a ở trên.

PHP Code:Console.WriteLine("Danh sach cac phan tu trong mang:");for (int i = 0; i < 5; i++)    Console.Write(a[i] + "\t");  

III. Các kiểu mảng:Mảng trong C# được chia thành 3 loại: 

Mảng 1 chiều (single-dimension array): mảng 1 chiều là một mảng các phần tử. Mảng 1 chiều được khai báo chỉ bao gồm 1 cặp dấu [ ].Tất cả những ví dụ trên tớ đều minh họa mạng 1 chiều nên tớ sẽ không lấy thêm ví dụ ở đây nữa.- Mảng nhiều chiều (multi-dimension array): mảng nhiều chiều là mảng có số chiều từ 2 trở lên (có từ 2 cặp [ ] trở lên).Vd: chúng ta có 1 đối tượng học sinh vừa tổng kết điểm từng môn xong và bạn ấy có 2 môn mỗi môn lại có 3 điểm. Vậy chúng ta sẽ cùng hiểu hơn để đến với ví dụ này nhé.

Visual C# Code:Select All | Show/Hide

366. using System;

367. using System.Collections.Generic;

368. using System.Text;

369.  

370. namespace ConsoleApplication22

371. {

372.     class Program

373.     {

374.         static void Main(string[] args)

375.         {

376.             // Khai báo một mảng 2 chiều 2 dòng và 3 cột để lưu

377.             // trữ danh sách bảng điểm của 1 sinh viên.

378.             float[,] diem = new float[2, 3];

379.  

380.             // Nhập danh sách điểm cho sinh viên.

381.             Console.WriteLine("Nhap diem cho sinh vien");

382.             for (int i = 0; i < 2; i++)

383.             {

384.                 Console.WriteLine("Nhap diem cho mon thu {0}",

i + 1);

385.                 for (int j = 0; j < 3; j++)

386.                 {

387.                     Console.Write("Nhap diem thu {0}: ", j + 1);

388.                     diem[i, j] = float.Parse(Console.ReadLine());

389.                 }

390.             }

391.             // In danh sách điểm cho sinh viên

392.             Console.WriteLine("\n\tDiem1\tDiem2\tDiem3\n");

393.             for (int i = 0; i < 2; i++)

394.             {

Page 23: Giáo trình C#

395.                 Console.Write("Mon{0}\t", i + 1);

396.                 for (int j = 0; j < 3; j++)

397.                     Console.Write(diem[i, j] + "\t");

398.                 Console.WriteLine();

399.             }

400.             Console.ReadLine();

401.         }

402.     }

403. }

Và loại cuối cùng mà tớ thấy có một vài bài trên diễn đàn đã thắc mắc về nó.Mảng nhọn (jagged array): mảng nhọn là một mảng của các mảng, trong đó kích thước của mỗi một mảng có thể khác nhau. Vd: chúng ta có 1 đối tượng học sinh vừa thi xong học kỳ 2 môn và mỗi môn lại có số điểm thành phần khác nhau, môn thứ nhất thi 2 lần và có 2 lần điểm, môn thứ hai lại thi tới 5 lần và có 5 lần điểm. Vậy nếu chúng ta sử dụng mảng nhiều chiều thì môn thứ nhất lại không sử dụng hết bộ nhớ đã khai báo. Vậy làm thế nào để tiết kiệm bộ nhớ thì mảng jagged là một lựa chọn hoàn hảo.

Visual C# Code:Select All | Show/Hide

404. using System;

405. using System.Collections.Generic;

406. using System.Text;

407.  

408. namespace ConsoleApplication22

409. {

410.     class Program

411.     {

412.         static void Main(string[] args)

413.         {

414.             float[][] diem = new float[2][];

415.             diem[0] = new float[] {9, 4};

416.             diem[1] = new float[] { 3, 4, 6, 8, 7 };

417.  

418.             // Duyệt qua các phần tử của mảng jagged.

419.             for (int i = 0; i < 2; i++)

420.             {

421.                 for (int j = 0; j < diem[i].Length; j++)

422.                     Console.Write(diem[i][j] + "\t");

423.                 Console.WriteLine();

424.             }

425.  

426.             Console.ReadLine();

427.          

428.         }

429.     }

430. }

Page 24: Giáo trình C#

Chú ý: Mảng trong ngôn ngữ C# có một vài sự khác biệt so với mảng trong ngôn ngữ C++ vàmột số ngôn ngữ khác, bởi vì chúng là những đối tượng. Điều này sẽ cung cấp cho mảng sửdụng các phương thức và những thuộc tính.Ngôn ngữ C# cung cấp cú pháp chuẩn cho việc khai báo những đối tượng Array. Tuynhiên, cái thật sự được tạo ra là đối tượng của kiểu System.Array. Mảng trong ngôn ngữ C#kết hợp cú pháp khai báo mảng theo kiểu ngôn ngữ C và kết hợp với định nghĩa lớp do đó thểhiện của mảng có thể truy cập những phương thức và thuộc tính của System.Array.

Chương 7: Classes and Methods (phần 1)

I. Giới thiệu về lớp (class) và đối tượng (object)

Theo mình nghĩ lập trình hướng đối tượng là nền tảng trong lập trình C# trong đó các đối tượng (object) và các lớp (class) đóng vai trò vô cùng quan trọng không thể thiếu để tạo nên tính hướng đối tượng của C#. Class mô tả tất cả các thuộc tính của một tập hợp các đối tượng cụ thể, nó như một khuôn mẫu bao gồm một tập hợp các đối tượng có tính chất tương tự nhau.

II. Các thực thể trong thế giới thực như là các đối tượng

Để mọi người dễ hiểu hơn chúng ta sẽ cùng nhau tìm hiểu ví dụ sau: 

Tớ có 1 tập hợp các hình sau mà chúng ta đều nhìn thấy ở quanh mình như: Chó, mèo,ô-tô (car), ngôi nhà, bông hoa…Chúng ta đều thấy điểm chung ở các ví dụ đó là chúng là những vật hữu hình, chúng ta có thể sờ mó được vào nó và người ta gọi đó là đối tượng trong thế giới thực.Mỗi một đối tượng chúng đều có các thuộc tính hoặc tính chất để mô tả nó và giúp chúng ta phân biệt đối tượng đó với đối tượng khác.Ví dụ với đối tượng là con chó các thuộc tính của nó như: 

Và ngoài ra đối tượng con chó còn được thể hiện bằng cách hành động như:

Page 25: Giáo trình C#

Vậy từ các ví dụ trên chúng ta rút ra được nhận xét sau:Hai yếu tố quan trọng nhất của đối tượng trong thể giới thực là: thuộc tính (attribute) và hành động (action). Đối tượng có các thuộc tính và hành động hoàn toàn xác định.Bây giờ quay lại với thế giới phần mềm, các đối tượng cũng được mô tả theo trạng thái và hành vi của nó. Trạng thái được định nghĩa như các thuộc tính và hành vi được định nghĩa như các hành động, hoạt động của một đối tượng phần mềm. Các hành vi được xem như là các phương thức, giống như các hàm trong ngôn ngữ lập trình. Một phương thức là một chuỗi các câu lệnh được đặt tên nhằm thực hiện các tác vụ cụ thể nào đó.Sự thuận lợi khi sử dụng đối tượng (object) là:+, Nó giúp chúng ta hiểu hơn về thế giới thực.+, Nó ánh xạ các thuộc tính và các hành động của các đối tượng trong thế giới thực thành trạng thái và hành vi của các đối tượng phần mềm.

III. Class (lớp)Như chúng ta biết trong thế giới thực có nhiều loài động vật khác nhau như gà, lợn, mèo, chim…Và như chúng ta đã xét chó là một đối tượng của thế giới thực vì vậy chó chỉ là một thể hiện của lớp động vật.Bây giờ chúng ta có một số đối tượng có các thuộc tính và hành động chung và chúng ta nhóm nó lại thành một đơn vị và đơn vị này được dùng để tạo ra một đại diện của loại tương ứng gọi là lớp (class). Mỗi một lớp mô tả một tập hợp các đối tượng riêng lẻ. Tất cả các thể hiện của lớp được gọi là đối tượng, sẽ có chung các trạng thái và hành vi.

Chú ý: Các thuộc tính và hành động có thể được gán chỉ sau khi một đối tượng được tạo ra. Khi một đối tượng được tạo ra, lúc đó ta mới có một đại diện thật sự của một thực thể.

IV. So sánh giữa lớp (class) và đối tượng (object)

Như trên mình đã phân tích thì một lớp (class) mô tả một thực thể, trong khi đó thì một đối tượng (object) là một thực thể thực sự. Điều này không khác gì việc bạn so sánh giữa khái niệm loài chó và một con chó Nhật. Chúng ta không thể đụng chạm hay đùa giỡn với khái niệm loài chó nhưng có thể thực hiện điều đó được với con chó Nhật, nó là một thực thể sống động, chứ không trừu tượng như khái niệm họ loài chó.

Trong phần này tớ chú trọng hoàn toàn vào lý thuyết để mọi người thực sự hiểu về lớp (class) và đối tượng (object). Sang phần sau tớ sẽ đi vào các ví dụ minh họa và triển khai các ý tiếp theo.

Page 26: Giáo trình C#

chương 7 (phần 2)

Trong phần trước chúng ta đã nắm bắt được định nghĩa và hiểu được lớp (class) và đối tượng (object), trong phần 2 này để củng cố cho mọi người hiểu sâu hơn sẽ là những cấu trúc và ví dụ cụ thể.Trước khi bước sang phần 2 tớ xin trích 1 câu ngắn gọn từ phần 1 để mọi người không bị nhầm lấn giữa lớp (class) và đối tượng (object):

“Như trên mình đã phân tích thì một lớp (class) mô tả một thực thể, trong khi đó thì một đối tượng (object) là một thực thể thực sự. Điều này không khác gì việc bạn so sánh giữa khái niệm loài chó và một con chó Nhật.”

I. Định nghĩa lớp: Chúng ta đã hiểu được định nghĩa của lớp là gì, bây giờ mình sẽ nêu ra cấu trúc khai báo một lớp (class). Khai báo một lớp bằng cách sử dụng từ khóa class, cú pháp đầy đủ:

PHP Code:[thuộc tính] [bổ sung truy cập] class định danh lớp [: lớp cơ sở]{        <phần thân của lớp: bao gồm định nghĩa, thuộc tính, phương thức>}  

Nhìn vào cái kia chắc sẽ khó hiểu, tớ sẽ giải thích cho mọi người từng phần một.Dấu []: có thể có hoặc không.[thuộc tính]: thuộc tính của đối tượng chúng ta sẽ tìm hiểu ở phần sau.[bổ sung truy cập]: cái này tớ sẽ nói ngay cuối phần 2 mọi người theo dõi.Định danh lớp: chính là tên lớp do người lập trình tự đặt, nó giống như chúng ta mỗi người đều có một tên vậy nhưng trong lập trình người ta thường đặt những tên mang tính chất gợi mở để thuận tiện cho việc đọc lại code về sau hay khắc phục lỗi.[lớp cơ sở]: là lớp mà đối tượng sẽ kế thừa. Như trên đầu mình có nói thì các bạn sẽ hiểu được nó kỹ hơn ở phần 3 trong bài liên quan đến kế thừa (inheritance).Tất cả các thành viên của lớp được định nghĩa ở bên trong thân của lớp trong cặp dấu {}.

Chú ý: Trong C# kết thúc của lớp không có dấu ; giống như C++, tuy nhiên có cũng hem sao chỉ báo lỗi thôi nhưng vấn chạy bình thường. Nhưng mà tốt nhất là không cho gì vào cả.

Ví dụ: tớ sẽ cho mọi người 1 ví dụ thật đơn giản như hằng ngày chúng ta vẫn thấy

Visual C# Code:Select All | Show/Hide

431. public class Khoaimon

432. {

433.     public static void Main (string[] args)

434. {

435.     //viết các câu lệnh…

436. }

437. }

Nhìn vào ví dụ trên chúng ta thấy hoàn toàn chưa tạo bất cứ thể hiện nào của lớp, lớp Khoaimon chưa có đối tượng gì cả. 

Page 27: Giáo trình C#

Bây giờ chúng ta sẽ tới ví dụ tiếp theo để tìm hiểu cách tạo một lớp và tạo các thể hiện của chúng.

Visual C# Code:Select All | Show/Hide

438. using System;

439. using System.Collections.Generic;

440. using System.Text;

441.  

442. namespace ConsoleApplication23

443. {

444.     public class khoaimon

445.     {

446.         public void khoailang()

447.         {

448.             Console.WriteLine("khoaimon kute");

449.         }

450.  

451.         public class khoaitay

452.         {

453.             static void Main(string[] args)

454.             {

455.                 khoaimon k = new khoaimon();

456.                 k.khoailang();

457.                 Console.ReadLine();

458.                

459.             }

460.         }

461.     }

462. }

Lớp khoaimon chỉ có 1 phương thức là khoailang(), phần thân của phương thức này được định nghĩa bên trong lớp khoaimon. Sau khi đã định nghĩa lớp khoaimon tớ sang định nghĩa tiếp lớp khoaitay, lớp này chứa một hàm Main(). Bên trong hàm Main chứa một thể hiện của lớp khoaimon được tạo ra và gán giá trị cho đối tượng k. Như các bạn thấy trong hàm Main() này có câu lệnh sau:k.khoailang();Sở dĩ có câu lệnh này là vì k là thể hiện của đối tượng khoaimon nên nó có thể sử dụng tất cả các phương thức của k.Từ khóa new dùng để tạo một đối tượng.Đến đây có lẽ chúng ta đã nắm bắt được cú pháp để khai báo và cách sử dụng lớp(class). Từ những ví dụ của mình từ đầu tới giờ có không ít những từ như public, private cả khi khai báo trong class tớ cũng dùng nó vậy nó có nghĩa là gì? Vì phần này liên quan đến class và cách tham chiếu từ class hay method này tới class, method khác nên tớ sẽ giới thiệu cho mọi người hiểu hơn về nó. 

II. Thuộc tính truy cập

Thuộc tính truy cập quyết định khả năng các phương thức của lớp (class) bao gồm việc các phương thức của lớp khác có thể nhìn thấy và sử dụng các thành viên hay những phương thức bên trong lớp.

Page 28: Giáo trình C#

Sau đây là tổng hợp các thuộc tính truy cập của một lớp trong C#:

+, public: không hạn chế. Những thành viên được đánh dấu public có thể được dùng bởi bất kỳ các phương thức của lớp bao gồm những lớp khác.+, private: riêng tư chỉ có phạm vi hoạt động trong lớp mà nó khai báo. Các phương thức bên ngoài lớp không thể truy xuất đến nó.+, protected: các thành viên trong lớp được khai báo bằng protected thì chỉ có các phương thức bên trong lớp và các lớp dẫn xuất từ lớp đó mới có thể truy cập đến nó.+, internal: các phươn thức, các biến thành viên được khai báo bằng từ khóa internal có thể được truy cập bởi tất cả những phương thức của bất kỳ lớp (class) nào trong cùng một khối hợp ngữ với lớp (class) đó.+, protected internal: các biến thành viên được khai báo bằng từ khóa trong một lớp A bất kỳ có thể được truy xuất bởi các phương thức thuộc lớp A và các phương thức của lớp dẫn xuất từ lớp A và bất cứ lớp nào trong cùng một khối hợp ngữ với lớp A.

Chú ý: +, Các thuộc tính truy cập được áp dụng cho thuộc tính, phương thức của lớp và bản thân lớp. Khi định nghĩa thuộc tính truy cập của lớp là internal, protected chỉ được định nghĩa trong lớp lồng nhau mà thôi.+, Khi lập trình hãy tạo cho mình một thói quen là khai báo tường minh các thuộc tính truy cập của biến thành viên hay các phương thức trong một lớp. Việc này sẽ giúp chương trình của chúng ta dễ hiểu hơn.+, Mặc định các thành viên của lớp được khai báo là private.Hết chương 7 (phần 2).

Các thuộc tính chính yếu của ngôn ngữ lập trình hướng đối tượng mà C# không phải là ngoại lệ đó là tính trừu tượng (abstraction), đóng gói (encapsulation), kế thừa (inheritance) và đa hình (polymorphism), đó là các thuộc tính vô cùng quan trọng mà khoaimon sẽ trình bày nó ở phần sau.

chương 7 (phần 3):Như đã nói ở Chương 7: phần 2, trong phần 3 này Khoaimon sẽ tập trung vào các thuộc tính chính yếu của hướng đối tượng trong C# là tính trừu tượng (abstraction), đóng gói (encapsulation), kế thừa (inheritance) và đa hình (polymorphism).

1. tính trừu tượng (abstraction):Là lớp có ít nhất một phương thức trừu tượng. Khi xây dựng lớp trừu tượng thì mọi thành viên được định nghĩa trong lớp trừu tượng đều sử dụng từ khoá abstract.

Phương thức trừu tượng không có sự thực thi. Phương thức này chỉ đơn giản tạo ra một tên phương thức và kí hiệu phương thức. Nó không định nghĩa phần thân, thay vào đó chúng được cài đặt trong phương thức ghi đè của lớp dẫn xuất.Để khai báo lớp trừu tượng bạn sử dụng từ khoáabstract trước từ khoá class như cú pháp sau:abstract class baseclass{// Code of members}

2. tính đóng gói (encapsulation): Tính đóng gói là một cách mô phỏng đời thật của lập trình hướng đối tượng. Trong cuộc

Page 29: Giáo trình C#

sống thật, khi bạn có một cái máy, bạn biết cách khởi động nó, bạn biết cách nhấn nút để điều khiển trò chơi nhưng bạn không cần quan tâm xem bên trong cái máy ấy có những linh kiện gì và cũng không biết các linh kiện ấy hoạt động, tương tác với nhau như thế nào. Trong lập trình cũng vậy. Giả như bạn tạo ra một lớp trong C# tên là Khoaimon. Bạn khai báo các biến đối tượng, nhưng bạn không để lộ thông tin đó ra bên ngoài. Người dùng lớp Khoaimon mà bạn tạo, không biết được là bạn tạo cái lớp Khoaimon đó thế nào (và thực sự là người ta cũng không cần biết). Cái người ta cần biết là khi tạo ra một lớp, bạn phải cung cấp một tài liệu về cách sử dụng cái lớp đó (cách tạo đối tượng từ lớp đó, cách gọi phương thức từ lớp đó ...v...v...). Sau đó người ta chỉ việc gọi phương thức từ lớp đó thôi chứ không cần biết lớp đó đã được tạo thế nào. Gọi phương phương thức mà không cần biết nó được tạo ra như thế nào cũng giống như việc chơi CF mà không cần biết bên trong hoạt động ra sao. --> tính đóng gói giúp bảo mật thông tin, tránh những can thiệp không cần thiết, giảm hỏng hóc, kiểm soát được trạng thái của đối tượng.3. tính kế thừa (inheritance):Một lớp con được thừa hưởng tất cả các thuộc tính và phương thức của lớp cha, như thế gọi là kế thừa. Tại sao phải kế thừa? Vì không có kế thừa thì không có đa hình (polymorphism). Kế thừa giúp tiết kiệm code, giúp chương trình dễ dàng bảo trì, nâng cấp, nhờ đó mà tiết kiệm được chi phí. Nếu lớp B là lớp được kế thừa từ lớp A thì toàn bộ các thành phần của lớp A cũng có mặt trong lớp B mà không cần phải khai báo trong lớp B. Lớp A được gọi là lớp cơ sở hay lớp cha, còn lớp B được gọi là lớp dẫn xuất hay lớp con. Như vậy chúng ta không cần viết đi viết lại các đoạn code giống nhau nữa, mà chỉ cần viết những đoạn code khác nhau ở các lớp con thôi. Còn những đoạn code giống nhau thì lớp con nào cũng có, vì nó đã được kế thừa từ lớp cha. --> đây là một biểu hiện của việc dùng lại code.Kế thừa có hai loại: Đơn kế thừa và đa kế thừa trong đó đơn kế thừa là một lớp dẫn xuất chỉ được kế thừa từ một lớp cơ sở, còn đa kế thừa là một lớp dẫn xuất được kế thừa từ nhiều lớp cơ sở.

Cách khai báo:lớp dẫn xuất kế thừa một lớp cơ sở :Tên lớp dẫn xuất : Tên lớp cơ sở.

ví dụ:

Visual C# Code:Select All | Show/Hide

463. using System;

464. using System.Collections.Generic;

465. using System.Text;

466.  

467. namespace ConsoleApplication26

468. {

469.     class Person

470.     {

471.         public void Talk()

472.         {

473.             Console.WriteLine("Khoaimon kute");

474.         }

475.     }

476.     class A : Person

477.     {

478.         public void Say()

479.         {

480.             Console.WriteLine("Khoaimon baby");

481.         }

Page 30: Giáo trình C#

482.  

483.         public static void Main(string[] args)

484.         {

485.             A a = new A();            

486.             a.Talk();

487.             a.Say();

488.             Console.ReadLine();

489.         }

490.     }

491.  

492. }

493.

4. tính đa hình (polymorphism):Polymorphism (đa hình): Đa hình chính là mục tiêu lớn nhất của kế thừa (inheritance). Việc override hoặc overload một phương thức là biểu hiện của đa hình.Phương thức là đa hình có từ khoá Virtual ở trước và phương thức này phải được ghi đè ở lớp dẫn xuất.Cho phép cài đặt phương thức của lớp dẫn xuất trong khi thi hành .

ví dụ:

Visual C# Code:Select All | Show/Hide

494. using System;

495. using System.Collections.Generic;

496. using System.Text;

497.  

498. namespace ConsoleApplication26

499. {

500.     class Shape

501.     {

502.         public virtual void ShapeType()

503.         {

504.             Console.WriteLine("phuong thuc nay se duoc su dung");

505.         }

506.         public int CalculateArea(int side)

507.         {

508.             return side*side;

509.         }

510.      

public double CalculateArea(double baseBreadth, double height)

511.         {

512.             return 0.5 * baseBreadth * height;

513.         }

514.  

515.     }

516.  

Page 31: Giáo trình C#

517.     class Square : Shape

518.     {

519.         public override void ShapeType()

520.         {

521.             Console.WriteLine("A square is a polygon");

522.         }

523.         static void Main(string[] args)

524.         {

525.             Square sq = new Square();

526.             sq.ShapeType();

527.             Shape sh = new Shape();

528.             Console.WriteLine("Are is: " + sq.CalculateArea(6));

529.             Console.ReadLine();

530.         }

531.     }

532. }