Tập bài giảng Lập trình cơ bản

MỤC LỤC DANH MỤC CÁC BẢNG .............................................................................................iv DANH MỤC CÁC HÌNH ..............................................................................................vi

LỜI NÓI ĐẦU ................................................................................................................. x

CHƢƠNG 1: TỔNG QUAN VỀ .NET VÀ C# .............................................................. 1 1.1. Giới thiệu .NET .................................................................................................... 1

1.1.1. Tổng quan về .NET Framework .................................................................... 1

1.1.2. Giới thiệu Visual Studio .NET ...................................................................... 2

1.2. Ngôn ngữ C# ........................................................................................................ 3 1.2.1. Giới thiệu C# ................................................................................................. 3

1.2.2. Các bƣớc chuẩn bị cho chƣơng trình ............................................................. 5

1.2.3. Xây dựng chƣơng trình C# đơn giản ............................................................. 6

1.2.4. Chú thích trong chƣơng trình C# ................................................................... 9

1.2.5. Namespace ................................................................................................... 10

CHƢƠNG 2: CƠ SỞ LẬP TRÌNH TRONG C# ........................................................... 11

2.1. Tên ...................................................................................................................... 11

2.2. Từ khóa ............................................................................................................... 12

2.3. Hằng và Biến ...................................................................................................... 12

2.3.1. Các kiểu dữ liệu cơ sở ................................................................................. 12

2.3.2. Biến .............................................................................................................. 14

2.3.3. Hằng ............................................................................................................ 16

2.4. Biểu thức ............................................................................................................. 17

2.4.1. Biểu thức...................................................................................................... 17 2.4.2. Lệnh gán và biểu thức ................................................................................. 17

2.4.3. Các phép toán số học ................................................................................... 18

2.4.4. Các phép toán quan hệ và logic ................................................................... 19

2.4.5. Phép toán tăng giảm .................................................................................... 20 2.4.6. Thứ tựƣu tiên các phép toán ........................................................................ 22 2.4.7. Chuyển đổi kiểu giá trị ................................................................................ 24 2.4.8. Lớp Math ..................................................................................................... 26 2.5. Câu lệnh rẽ nhánh ............................................................................................... 27 2.5.1. Câu lệnh if ................................................................................................... 27 2.5.2. Câu lệnh switch ........................................................................................... 31

2.6. Câu lệnh lặp ........................................................................................................ 34

i

Tập bài giảng Lập trình cơ bản

2.6.1. Câu lệnh while ............................................................................................. 34

2.6.2. Câu lệnh do...while ...................................................................................... 35

2.6.3. Câu lệnh for ................................................................................................. 37

2.7. Câu lệnh nhảy ..................................................................................................... 39 2.7.1. Câu lệnh break và continue ......................................................................... 39

2.7.2. Câu lệnh goto ............................................................................................... 40

2.7.3. Câu lệnh return ............................................................................................ 41 2.8. Xử lý ngoại lệ ..................................................................................................... 41

Bài tập ........................................................................................................................ 45

CHƢƠNG 3: MỘT SỐ CẤU TRÚC DỮ LIỆU ........................................................... 50

3.1. Mảng ................................................................................................................... 50 3.1.1. Mảng một chiều ........................................................................................... 51

3.1.2. Mảng đa chiều ............................................................................................. 56

3.2. Xâu ký tự. ........................................................................................................... 61

3.3. Xử lý tập tin ........................................................................................................ 71

3.4. Lớp ...................................................................................................................... 80

3.5. Cấu trúc............................................................................................................. 100

Bài tập ...................................................................................................................... 103

CHƢƠNG 4: LẬP TRÌNH TRÊN FORM .................................................................. 116

4.1. Giới thiệu về lập trình trên Form ...................................................................... 116

4.2. Làm việc với Form ........................................................................................... 116

4.2.1. Một số khái niệm ....................................................................................... 116

4.2.2. Các loại Form ............................................................................................ 123

4.2.3. Thuộc tính của Form ................................................................................. 124

4.2.4. Sự kiện trên Form ...................................................................................... 125 4.2.5. Phƣơng thức của Form .............................................................................. 125

4.3. Một số điều khiển thông dụng .......................................................................... 128

4.3.1. Các thuộc tính và sự kiện chung................................................................ 128

4.3.2. Nhóm điều khiển Label ............................................................................. 129 4.3.3. Nhóm điều khiển TextBox ........................................................................ 131 4.3.4. Nhóm điều khiển ComboBox, ListBox ..................................................... 138 4.3.5. Nhóm điều khiển CheckBox, RadioButtom .............................................. 146 4.3.6. Điều khiển Button ...................................................................................... 154 4.4. Một số điều khiển đặc biệt ................................................................................ 155 4.4.1 Nhóm điều khiển Menu .............................................................................. 155

4.4.2. Điều khiển Container ................................................................................. 158

ii

Tập bài giảng Lập trình cơ bản

4.4.3. Điều khiển Dialog ...................................................................................... 160

Bài tập .................................................................................................................. 167

TAI LIỆU THAM KHẢO ........................................................................................... 197

iii

Tập bài giảng Lập trình cơ bản

DANH MỤC CÁC BẢNG Bảng 1.1: Từ khóa của ngôn ngữ C#. .............................................................................. 5

Bảng 2.1: Mô tả các kiểu dữ liệu xây dựng sẵn ............................................................ 13

Bảng 2.2: Các kiểu ký tự đặc biệt. ................................................................................. 14 Bảng 2.3: Các phép toán số học hai ngôi ...................................................................... 18

Bảng 2.4: Các toán tử so sánh (giả sử value1 = 100 và value2 = 50). .......................... 20

Bảng 2.5: Các toán tử logic (giả sử x = 5, y = 7). ......................................................... 20 Bảng 2.6: Mô tả các phép toán tự gán. .......................................................................... 20

Bảng 2.7: Một số các phép toán khác có trong C# ........................................................ 22

Bảng 2.8: Thứ tự ƣu tiên các phép toán. ....................................................................... 23

Bảng 2.9: Một số phƣơng thức của lớp Math. ............................................................... 27 Bảng 2.10: Một số lớp ngoại lệ ..................................................................................... 44

Bảng 3.1: Các phƣơng thức và thuộc tính của System.Array. ...................................... 51

Bảng 3.2: Phƣơng thức và thuộc tính của lớp String .................................................... 63

Bảng 3.3: Một số phƣơng thức mở tập tin ..................................................................... 73

Bảng 3.4: Giá trị của FileMode ..................................................................................... 77

Bảng 3.5: Các phƣơng thức đọc của BinaryReader. ..................................................... 80

Bảng 3.6: Thuộc tính truy cập. ...................................................................................... 83

Bảng 3.7: Giá trị mặc định của kiểu dữ liệu cơ bản. ..................................................... 85

Bảng 4.1: Một số thuộc tính của Form ........................................................................ 125

Bảng 4.2: Một số sự kiện của Form ............................................................................ 125

Bảng 4.3: Một số phƣơng thức của Form .................................................................... 126

Bảng 4.4: Một số thuộc tính chung của các điều khiển ............................................... 128

Bảng 4.5: Một số sự kiện chung của các điều khiển ................................................... 129

Bảng 4.6: Một số thuộc tính của Label........................................................................ 129 Bảng 4.7: Các thuộc tính của LinkLabel ..................................................................... 130

Bảng 4.8: Các sự kiện của LinkLabel ......................................................................... 130

Bảng 4.9: Một số thuộc tính của TextBox ................................................................... 131

Bảng 4.10: Một số sự kiện của TextBox ..................................................................... 132 Bảng 4.11: Một số thuộc tính của MaskedTextBox .................................................... 136 Bảng 4.12: Một số sự kiện của MaskedTextBox ........................................................ 137 Bảng 4.13: Một số thuộc tính của ComboBox ............................................................ 139 Bảng 4.14: Một số sự kiện của ComboBox ................................................................. 139 Bảng 4.15: Một số thuộc tính của ListBox .................................................................. 142 Bảng 4.16: Một số sự kiện của ListBox ...................................................................... 142

Bảng 4.17: Một số thuộc tính của CheckBox .............................................................. 146

iv

Tập bài giảng Lập trình cơ bản

Bảng 4.18: Một số sự kiện của CheckBox .................................................................. 146

Bảng 4.19: Một số thuộc tính của CheckedListBox .................................................... 150

Bảng 4.20: Một số sự kiện của CheckedListBox ........................................................ 150

Bảng 4.21: Một số thuộc tính của RadioButton .......................................................... 152 Bảng 4.22: Một số sự kiện của RadioButton ............................................................... 152

Bảng 4.23: Một số thuộc tính của Button .................................................................... 155

Bảng 4.24: Một số sự kiện của Button ........................................................................ 155 Bảng 4.25: Một số thuộc tính của MenuStrip ............................................................. 155

Bảng 4.26: Một số thuộc tính của ToolStripMenuItem ............................................... 156

Bảng 4.27: Một số sự kiện của ToolStripMenuItem ................................................... 156

Bảng 4.28: Một số thuộc tính của GroupBox .............................................................. 158 Bảng 4.29: Một số thuộc tính của TabControl ............................................................ 159

Bảng 4.30: Một số thuộc tính của điều khiển ColorDialog ......................................... 163

Bảng 4.31: Một số thuộc tính của điều khiển SaveFileDialog .................................... 164

Bảng 4.32: Một số thuộc tính của điều khiển OpenFileDialog ................................... 166

v

Tập bài giảng Lập trình cơ bản

DANH MỤC CÁC HÌNH Hình 1.1: Cấu trúc của .Net Framework.......................................................................... 2

Hình 1.2: Các bƣớc lựa chọn một Project mới Visual Studio 2010 ................................ 7

Hình 1.3: Tập tin Program.cs .......................................................................................... 8 Hình 1.4: Kết quả chƣơng trình Vidu 1.1 ........................................................................ 8

Hình 1.5: Kết quả chƣơng trình ví dụ 1.2. ..................................................................... 10

Hình 2.1: Kết quả chƣơng trình ví dụ 2.3 ...................................................................... 15 Hình 2.2: Kết quả chƣơng trình ví dụ 2.6. ..................................................................... 17

Hình 2.3: Kết quả chƣơng trình ví dụ 2.7 ...................................................................... 19

Hình 2.4: Kết quả chƣơng trình ví dụ 2.8. ..................................................................... 22

Hình 2.5: Kết quả chƣơng trình ví dụ 2.9 ...................................................................... 24 Hình 2.6: Hoạt động của câu lệnh if không đầy đủ ....................................................... 27

Hình 2.7: Kết quả chƣơng trình ví dụ 2.10 .................................................................... 28

Hình 2.8: Hoạt đông của câu lệnh if đầy đủ .................................................................. 29

Hình 2.9: Kết quả chƣơng trình ví dụ 2.11 .................................................................... 29

Hình 2.10: Kết quả chƣơng trình ví dụ 2.12. ................................................................. 31

Hình 2.11: Kết quả chƣơng trình ví dụ 2.13. ................................................................. 33

Hình 2.12: Hoạt động của vòng lặp while ..................................................................... 34

Hình 2.13: Kết quả chƣơng trình ví dụ 2.14. ................................................................. 35

Hình 2.14: Hoạt động của vòng lặp do … while. .......................................................... 36

Hình 2.15: Kết quả chƣơng trình ví dụ 2.15. ................................................................. 37

Hình 2.16: Hoạt động của vòng lặp for. ........................................................................ 37

Hình 2.17: Kết quả chƣơng trình ví dụ 2.16 .................................................................. 38

Hình 2.18: Kết quả chƣơng trình ví dụ 2.18. ................................................................. 39

Hình 2.19: Kết quả chƣơng trình 2.19 ........................................................................... 41 Hình 2.20: Kết quả chƣơng trình ví dụ 2.20 .................................................................. 43

Hình 2.21: Kết quả chƣơng trình ví dụ 2.21 .................................................................. 45

Hình 2.22: Kết quả chƣơng trình bài 2.1. ...................................................................... 46

Hình 2.23: Kết quả chƣơng trình bài 2.5 ....................................................................... 48 Hình 3.1: Kết quả chƣơng trình ví dụ 3.1. ..................................................................... 54 Hình 3.2. Kết quả chƣơng trình ví dụ 3.2. ..................................................................... 56 Hình 3.3: Kết quả chƣơng trình ví dụ 3.3 ...................................................................... 58 Hình 3.4: Kết quả chƣơng trình ví dụ 3.4. ..................................................................... 61 Hình 3.5: Kết quả chƣơng trình ví dụ 5 ......................................................................... 65 Hình 3.6: Kết quả chƣơng trình ví dụ 3.6. ..................................................................... 70

Hình 3.7: Kết quả chƣơng trình ví dụ 3.7 ...................................................................... 71

vi

Tập bài giảng Lập trình cơ bản

Hình 3.8: Kết quả chƣơng trình ví dụ 3.8 ...................................................................... 74

Hình 3.9: Kết quả chƣơng trình ví dụ 3.9. ..................................................................... 75

Hình 3.10: Nội dung tập tin tapnhiphan.data đƣợc mở bằng WordPad. ....................... 76

Hình 3.11: Kết quả chƣơng trình ví dụ 3.11 .................................................................. 78 Hình 3.12: Kết quả chƣơng trình ví dụ 3.12. ................................................................. 82

Hình 3.13: Kết quả chƣơng trình ví dụ 3.13 .................................................................. 84

Hình 3.14: Kết quả chƣơng trình ví dụ 3.14 .................................................................. 86 Hình 3.15: Kết quả chƣơng trình ví dụ 3.15. ................................................................. 89

Hình 3.16: Kết quả chƣơng trình ví dụ 3.16 .................................................................. 91

Hình 3.17: Kết quả chƣơng trình ví dụ 3.17 .................................................................. 94

Hình 3.18: Kết quả chƣơng trình ví dụ 3.18. ................................................................. 97 Hình 3.19: Kết quả chƣơng trình ví du 3.19. ................................................................. 99

Hình 3.20: Kết quả chƣơng trình ví dụ 3.20. ............................................................... 103

Hình 3.21: Kết quả chƣơng trình bài 3.1 ..................................................................... 105

Hình 3.22: Kết quả chƣơng trình bài 3.3 ..................................................................... 107

Hình 3.23: Kết quả chƣơng trình bài 3.4 ..................................................................... 109

Hình 3.24: Kết quả chƣơng trình bài 3.7 ..................................................................... 112

Hình 3.25: Kết quả chƣơng trình bài 3.9 ..................................................................... 115

Hình 4.1: Giao diện ví dụ 4.1 ...................................................................................... 117

Hình 4.2: Các bƣớc tạo ứng dụng Windows Forms Application ................................ 118

Hình 4.3: Giao diện ứng dụng Windows Forms Application sau khi tạo. .................. 118

Hình 4.4: Cửa sổ Toolbox. .......................................................................................... 119

Hình 4.5: Cửa sổ Solution Explorer. ........................................................................... 119

Hình 4.6: Cửa sổ Properties của Form1. ..................................................................... 120

Hình 4.7: Thêm điều khiển Label vào Form1. ............................................................ 120 Hình 4.8: Thay đổi thuộc tính Text của điều khiển label1. ......................................... 121

Hình 4.9: Kết quả sau khi thay đổi thuộc tính Text của điều khiển label1 ................. 121

Hình 4.10: Cửa sổ Font................................................................................................ 121

Hình 4.11: Thay đổi Font và màu chữ của điều khiển label1. .................................... 122 Hình 4.12: Chọn sự kiện Click .................................................................................... 123 Hình 4.13: Phƣơng thức btThoat_Click ...................................................................... 123 Hình 4.14: Màu nền của MDI Form. ........................................................................... 123 Hình 4.15: Form sau khi thay đổi một số thuộc tính theo ví dụ 4.4. ........................... 125 Hình 4.16: Giao diện Form ví dụ 4.5........................................................................... 126 Hình 4.17: Sử dụng điều khiển Label. ......................................................................... 129

Hình 4.18: Ví dụ về điều khiển LinkLabel. ................................................................. 130

vii

Tập bài giảng Lập trình cơ bản

Hình 4.19: Hiển thị trang https://www.google.com.vn/ trên trình duyệt web ............. 130

Hình 4.20: Ví dụ về điều khiển TextBox .................................................................... 132

Hình 4.21: Giao diện ví dụ 4.8. ................................................................................... 134

Hình 4.22: Một số định dạng cho thuộc tính Mask ..................................................... 136 Hình 4.23: Ví dụ về điều khiển MaskedTextBox ........................................................ 137

Hình 4.24: Ví dụ về điều khiển ComboBox ................................................................ 139

Hình 4.25: Cửa sở String Collection Editor ................................................................ 140 Hình 4.26: Ví dụ về điều khiển ListBox...................................................................... 143

Hình 4.27: Ví dụ về điều khiển CheckBox.................................................................. 147

Hình 4.28: Ví dụ về điều khiển CheckedListBox ....................................................... 150

Hình 4.29: Ví dụ về điều khiển RadioButton .............................................................. 153 Hình 4.30: Ví dụ về điều khiển MenuStrip ................................................................. 155

Hình 4.31: Giao diện ví dụ 4.15 .................................................................................. 156

Hình 4.32: Ví dụ về điểu khiển GroupBox.................................................................. 159

Hình 4.33: Ví dụ về điều khiển TabControl ................................................................ 160

Hình 4.34: Hộp thoại MessageBox ............................................................................. 160

Hình 4.35: Hộp thoại MessageBox chỉ có nội dung .................................................... 160

Hình 4.36: Hộp thoại MessageBox có thêm tiều đề .................................................... 161

Hình 4.37: Hộp thoại MessageBox có thêm tùy chỉnh nút bấm.................................. 161

Hình 4.38: Hộp thoại MessageBox có thêm tùy chỉnh biểu tƣợng ............................. 161

Hình 4.39: Hộp thoạiMessageBox .............................................................................. 162

Hình 4.40: Xuất hiện hộp thoại MessageBox khi click chọn nút Yes. ....................... 162

Hình 4.41: Giao diện ví dụ 4.16 .................................................................................. 163

Hình 4.42: Giao diện ví dụ 4.17 và tập tin songuyen.txt đƣợc tạo ra .......................... 165

Hình 4.43: Giao diện ví dụ 4.18 .................................................................................. 166 Hình 4.44: Giải bất phƣơng trình ................................................................................ 167

Hình 4.45: Kết quả chạy chƣơng trình giải bất phƣơng trình ..................................... 169

HInh 4.46: Giao diện ví dụ bài tập 2 ........................................................................... 170

Hình 4.47: Ứng dụng từ điển đơn giản ........................................................................ 170 HÌnh 4.48: Giao diện bài tập Xếp Ô ............................................................................ 170 Hình 4.49: Giao diện bài tập Bàn phím ký tự .............................................................. 171 Hình 4.50: Giao diện ví dụ Lucky Seven .................................................................... 171 Hình 4.51: Bài tập mảng một chiều ............................................................................. 172 Hình 4.52: Kết quả thiết kế Form bài tập mảng một chiều ......................................... 176 Hình 4.53:Kết quả chạy chƣơng trình khi kích vào nút bổ sung ................................. 182

Hình 4.54: Kết quả chạy chƣơng trình khi kích vào nút loại bỏ ................................. 182

viii

Tập bài giảng Lập trình cơ bản

Hình 4.55: Kết quả chạy chƣơng trình khi kích vào nút tìm kiếm .............................. 183

Hình 4.56: Bài tập về mảng hai chiều ......................................................................... 184

Hình 4.57: Kết quả thiết kế Form bài tập mẫu về mảng hai chiều .............................. 186

Hình 4.58: Kết quả chạy chƣơng trình bài tập mẫu về mảng hai chiều ...................... 190 Hình 4.59: Chƣơng trình xử lý chuỗi .......................................................................... 191

Hình 4.60: Kết quả thiết kế Form chƣơng trình xử lý xâu ......................................... 193

Hình 4.61: Kết quả chạy chƣơng trình xử lý xâu ........................................................ 196 Hình 4.62: Chuẩn hóa và đếm từ trong xâu ................................................................. 196

ix

Tập bài giảng Lập trình cơ bản

LỜI NÓI ĐẦU

Ngôn ngữ C# là một ngôn ngữ đƣợc dẫn xuất từ C và C++, nhƣng đƣợc tạo từ nền

tảng phát triển hơnvà thêm vào những đặc tính mới để làm cho ngôn ngữ này dễ sử

dụng hơn. Những đặc tính này có thể đƣợc tóm tắt nhƣ sau: C# là ngôn ngữ đơn giản, hiện đại, ngôn ngữ hƣớng đối tƣợng, ngôn ngữ mạnh mẽ và mềm dẻo, có ít từ khóa,

hƣớng module. Ngay từ khi mới xuất hiện, C# đã có sức lôi cuốn, thu hút nhiều ngƣời

và đƣợc sử dụng ở nhiều lĩnh vực khác nhau. Vì vậy, nhu cầu nghiên cứu, học tập môn học này ngày càng cao. Ở Việt Nam, mặc dù đã có một vài tài liệu hƣớng dẫn giảng

dạy về C# nhƣng hầu nhƣ mới dừng lại ở mức độ lý thuyết trừu tƣợng, chƣa phù hợp

với trình độ sinh viên trƣờng Đại học sự phạm Kỹ thuật Nam Định, vì vậy việc biên

soạn tập bài giảng về ngôn ngữ C# và cụ thể tập bài giảng Lập trình cơ bản là một nhu cầu cấp thiết.

Tập bài giảng đƣợc chia làm 4 chƣơng:

Chƣơng 1: Tổng quan về .NET và C#

Chƣơng 2: Cơ sở lập trình trong C#

Chƣơng 3: Một số cấu trúc dữ liệu nâng cao

Chƣơng 4: Lập trình trên Form

Mỗi chƣơng trong tập bài giảng đều hệ thống hóa các kiến thức cơ bản, cần

thiết. Tƣơng ứng với mỗi nội dung kiến thức đều có các ví dụ minh họa cụ thể, gắn với

các ứng dụng thực tiễn. Đặc biệt, cuối tập bài giảng, tác giả đƣa ra một hệ thống các

bài tập thực tế để sinh viên vận dụng củng cố lại kiến thức và kỹ năng.

Với phần lý thuyết chi tiết, đầy đủ đƣợc trình bày một cách khoa học, logic và

phần bài tập để củng cố kiến, hy vọng rằng tập bài giảng này sẽ mang lại cho sinh viên

nhiều kiến thứchữu ích.

Trong quá trình biên soạn, tập bài giảng không tránh khỏi những sai sót, rất mong đồng nghiệp và các em sinh viên góp ý kiến để tập bài giảng ngày càng đƣợc

hoàn thiện hơn. Mọi sự đóng góp ý kiến xin gửi về Văn phòng Khoa Công nghệ thông

tin-Trƣờng Đại học Sƣ phạm Kỹ thuật Nam Định-Phƣờng Lộc Hạ-Tp Nam Định.

Nhóm biên soạn

Nguyễn Thế Vinh – Nguyễn Thi ̣ Thu Thủy

x

Tập bài giảng Lập trình cơ bản

CHƢƠNG 1: TỔNG QUAN VỀ .NET VÀ C#

1.1. Giới thiệu .NET

1.1.1. Tổng quan về .NET Framework Microsoft .NET Framework là một thành phần có thể đƣợc cài thêm hoặc đã có sẵn trong các hệ điều hành Windows. Nó cung cấp những giải pháp đã đƣợc lập trình

sẵn cho những yêu cầu thông thƣờng của chƣơng trình quản lý việc thực thi các

chƣơng trình viết trên framework, cần phải cài framework để có thể chạy các chƣơng trình đƣợc phát triển bằng các ngôn ngữ trong họ .NET. .NET Framework do

Microsoft đƣa ra và đƣợc sử dụng trong hầu hết các ứng dụng viết trên nền Windows.

Những giải pháp đƣợc lập trình sẵn hình thành nên một thƣ viện các lớp của

Framework, đƣợc sử dụng trong nhiều lĩnh vực của lập trình nhƣ: giao diện ngƣời dùng, truy cập dữ liệu, kết nối cơ sở dữ liệu, mã hoá, phát triển những ứng dụng

website, các giải thuật số học và giao tiếp mạng. Thƣ viện lớp của Framework đƣợc

lập trình viên sử dụng, kết hợp với chƣơng trình của chính mình để tạo nên các ứng

dụng.

Kiến trúc của .NET Framework Microsoft tổ chức .NET Framework thành nhiều tầng, quá trình biên dịch và

thực thi một chƣơng trình viết trên nền .NET Framework đƣợc thực hiện từng bƣớc từ

phần mã nguồn đến phần mã máy. Mã nguồn của chƣơng trình sau khi biên dịch sẽ

thành ngôn ngữ trung gian (Common Intermediate Language - CIL). Ngôn ngữ này

biên dịch phần lớn các thƣ viện đƣợc viết trên nền .NET thành các thƣ viện liên kết

động (Dynamic Linked Library - DLL). Với giải pháp này, các ngôn ngữ đƣợc .NET

Framework hỗ trợ sẽ dễ dàng sử dụng lại lẫn nhau. Một chƣơng trình đƣợc viết bằng

ngôn ngữ C# có thể sử dụng các lớp, các thuộc tính đã đƣợc viết trƣớc đó bằng ngôn

ngữ VB.NET hoặc J#. Tầng dƣới cùng của cấu trúc phân tầng của .NET Framework là Common Language Runtime – còn đƣợc gọi là CLR. Đây là thành phần quan trọng

nhất của .NET Framework. Tầng này thực hiện biên dịch mã của CIL thành mã máy

và thực thi.

1

Tập bài giảng Lập trình cơ bản

Hình 1.1: Cấu trúc của .Net Framework

Các ngôn ngữ thuộc họ .Net Hiện tại các lập trình viên có thể sử dụng nhiều ngôn ngữ khác nhau để lập trình,

có ngƣời thân thiện với ngôn ngữ này, có ngƣời thân thiện với ngôn ngữ khác. Có ngƣời làm việc rất tốt với ngôn ngữ Basic, trong khi đó, một số ngƣời khác thân thiện

với ngôn ngữ Java. Những lập trình viên với khả năng thông thạo những ngôn ngữ

khác nhau dƣờng nhƣ không thể cùng xây dựng một ứng dụng vì sự không tƣơng thích

giữa các mã lệnh biên dịch. Để khắc phục tình trạng này, Microsoft đã đƣa ra giải pháp

.Net Framework. Với .Net Framework, các lập trình viên có thể lập trình ở những

ngôn ngữ khác nhau, sau khi biên dịch, kết quả thu đƣợc sẽ là các thƣ viện liên kết

động .dll (dynamic linked library). Các thƣ viện này sẽ đƣợc các lập trình viên khác kế

thừa và sử dụng lại. Visual Studio và Microsoft .Net Framework hỗ trợ các ngôn ngữ

lập trình: Visual C++, Visual Basic .NET, Visual C#, Visual J#. Các ngôn ngữ lập

trình trên đƣợc gọi chung là họ ngôn ngữ .NET.

Các thƣ viện có sẵn của .Net Framework Thƣ viện lớp cơ sở của .NET là một tập hợp lớn các lớp đƣợc viết bởi

Microsoft, những lớp này cho phép thao tác rất nhiều các tác vụ sẵn có trong Windows

và có thể tạo các lớp của mình từ các lớp có sẵn trong thƣ viện lớp cơ sở của .NET dựa trên cơ chế thừa kế đơn. Thƣ viện lớp cơ sở của .NET rất trực quan và rất dễ sử dụng.

1.1.2. Giới thiệu Visual Studio .NET Microsoft Visual Studio là một môi trƣờng phát triển tích hợp (IDE) từ Microsoft. Nó đƣợc sử dụng để phát triển chƣơng trình máy tính cho Microsoft Windows, cũng nhƣ các trang web, các ứng dụng web và các dịch vụ web. Visual Studio sử dụng nền tảng phát triển phần mềm của Microsoft nhƣ Windows API, Windows Forms, Windows Presentation Foundation, Windows Store và Microsoft Silverlight.

2

Tập bài giảng Lập trình cơ bản

Visual Studio bao gồm một trình soạn thảo mã hỗ trợ IntelliSense cũng nhƣ cải

tiến mã nguồn. Trình gỡ lỗi tích hợp hoạt động cả về trình gỡ lỗi mức độ mã nguồn và

gỡ lỗi mức độ máy. Công cụ tích hợp khác bao gồm một mẫu thiết kế các hình thức

xây dựng giao diện ứng dụng, thiết kế web, thiết kế lớp và thiết kế giản đồ cơ sở dữ liệu.

Visual Studio hỗ trợ nhiều ngôn ngữ lập trình khác nhau và cho phép trình biên

tập mã và gỡ lỗi hỗ trợ (mức độ khác nhau) hầu nhƣ mọi ngôn ngữ lập trình. Các ngôn ngữ tích hợp gồm có Visual C++, VB.NET (Visual Basic.NET), Visual C# và Visual

F#. Ngoài ra Visual Studio còn hỗ trợ cho các ngôn ngữ khác nhƣ J++/J thăng, Python

và Ruby thông qua dịch vụ cài đặt riêng rẽ. Nó cũng hỗ trợ XML/XSLT,

HTML/XHTML, JavaScript và CSS.

Hiện nay, một hệ thống thông tin thƣờng có những dạng ứng dụng sau: Ứng

dụng Console phục vụ xử lý các vấn đề liên quan đến hệ thống và giao tiếp vào ra;

Ứng dụng Desktop phục vụ xây dựng các phần mềm ứng dụng với giao diện thân

thiện; Ứng dụng Internet phục vụ việc xây dựng các website; Đối với mỗi dạng ứng

dụng khác nhau, Visual Studio cung cấp các dạng Project khác nhau. Các dạng Project

đƣợc Visual Studio cung cấp gồm có:

- Console Application: Cung cấp template cho ứng dụng Console - Windows Application: Cung cấp template cho ứng dụng Desktop - Class Library: Cung cấp template cho việc xây dựng thƣ viện liên kết động - ASP.NET Website: Cung cấp template cho việc xây dựng Website - ASP.NET Web Service: Cung cấp template cho việc xây dựng Web Service

1.2. Ngôn ngữ C#

1.2.1. Giới thiệu C# Ngôn ngữ C# đƣợc phát triển bởi đội ngũ kỹ sƣ của Microsoft, ngƣời đứng đầu là Anders Hejlsberg và Scott Wiltamuth. Trong đó Anders Hejlsberg đƣợc biết đến là

tác giả của Turbo Pascal, một ngôn ngữ lập trình trên máy tính phổ biến. Và ông đứng

đầu nhóm thiết kế Borland Delphi, một trong những thành công đầu tiên của việc xây

dựng môi trƣờng phát triển tích hợp (IDE) cho lập trình client/server.

Ngôn ngữ C# là một ngôn ngữ đƣợc dẫn xuất từ C và C++, nhƣng nó đƣợc tạo từ nền tảng phát triển hơn và thêm vào những đặc tính mới để làm cho ngôn ngữ này dễ sử dụng hơn. Nhiều trong số những đặc tính này khá giống với những đặc tính có trong ngôn ngữ Java. Không dừng lại ở đó, Microsoft đƣa ra một số mục đích khi xây dựng ngôn ngữ này. Những mục đích này đƣợc đƣợc tóm tắt nhƣ sau:

- C# là ngôn ngữ đơn giản

- C# là ngôn ngữ hiện đại

3

Tập bài giảng Lập trình cơ bản

- C# là ngôn ngữ hƣớng đối tƣợng

- C# là ngôn ngữ mạnh mẽ và mềm dẻo

- C# là ngôn ngữ có ít từ khóa

- C# là ngôn ngữ hƣớng module

C# là ngôn ngữ đơn giản C# loại bỏ một số sự phức tạp của những ngôn ngữ nhƣ Java và C++, bao gồm

việc loại bỏ những macro, những template, đa kế thừa và lớp cơ sở ảo (virtual base class). Chúng là những nguyên nhân gây ra sự nhầm lẫn hay dẫn đến những vấn đề

cho các ngƣời phát triển C++. Nếu là ngƣời học ngôn ngữ C# đầu tiên thì chắc chắn là

sẽ không trải qua thời gian tìm hiểu về những vấn đề trên. Nhƣng khi đó sẽ không biết

đƣợc hiệu quả của ngôn ngữ C# khi loại bỏ những vấn đề đó.

Ngôn ngữ C# đơn giản vì nó dựa trên nền tảng C và C++. Nếu đãquen với C và

C++ hoặc thậm chí là Java, sẽ thấy C# khá giống về diện mạo, cú pháp, biểu thức,

toán tử và những chức năng khác đƣợc lấy trực tiếp từ ngôn ngữ C và C++, nhƣng nó

đã đƣợc cải tiến để làm cho ngôn ngữ đơn giản hơn. Một vài trong các sự cải tiến là

loại bỏ các dƣ thừa, hay là thêm vào những cú pháp thay đổi. Ví dụ nhƣ, trong C++ có

ba toán tử làm việc với các thành viên là ::, . và ->. Để biết khi nào dùng ba toán tử

này cũng phức tạp và dễ nhầm lẫn. Trong C#, chúng đƣợc thay thế với một toán tử duy

nhất gọi là . (dot). Đối với ngƣời mới học thì điều này và những việc cải tiến khác làm

bớt nhầm lẫn và đơn giản hơn.

C# là ngôn ngữ hiện đại Điều gì làm cho một ngôn ngữ hiện đại? Những đặc tính nhƣ là xử lý ngoại lệ,

thu gom bộ nhớ tự động, những kiểu dữ liệu mở rộng và bảo mật mã nguồn là những

đặc tính đƣợc mong đợi trong một ngôn ngữ hiện đại. C# chứa tất cả những đặc tính

trên. Nếu là ngƣời mới học lập trình có thể sẽ cảm thấy những đặc tính trên phức tạp và khó hiểu. Tuy nhiên, cũng đừng lo lắng sẽ dần dần đƣợc tìm hiểu những đặc tính

qua các chƣơng trong tập bài giảng này.

C# là ngôn ngữ hƣớng đối tƣợng Những đặc điểm chính của ngôn ngữ hƣớng đối tƣợng (Object-oriented language) là sự đóng gói (encapsulation), sự kế thừa (inheritance) và đa hình (polymorphism). C# hỗ trợ tất cả những đặc tính trên.

C# là ngôn ngữ mạnh mẽ và cũng mềm dẻo Nhƣ đã đề cập trƣớc, với ngôn ngữ C# chỉ bị giới hạn ở chính bởi bản thân hay là trí tƣởng tƣợng của lập trình viên. Ngôn ngữ này không đặt những ràng buộc lên những việc có thể làm. C# đƣợc sử dụng cho nhiều các dự án khác nhau nhƣ là tạo ra

4

Tập bài giảng Lập trình cơ bản

ứng dụng xử lý văn bản, ứng dụng đồ họa, bảng tính, hay thậm chí những trình biên

dịch cho các ngôn ngữ khác.

C# là ngôn ngữ ít từ khóa C# là ngôn ngữ sử dụng giới hạn những từ khóa. Nhiều ngƣời có thể nghĩ rằng một ngôn ngữ có nhiều từ khóa thì sẽ mạnh hơn. Điều này không phải sự thật, ít nhất

là trong trƣờng hợp ngôn ngữ C#, có thể thấy rằng ngôn ngữ này có thể đƣợc sử dụng

abstract

as

base

bool

break

byte

case

catch

char

checked

class

const

continue

decimal

default

delegate

do

double

else

enum

event

explicit

extern

false

finally

fixed

float

for

foreach

goto

if

implicit

in

int

interface

internal

is

lock

long

namespace

new

null

object

operator

out

override

params

private

protected

public

readonly

ref

return

sbyte

sealed

short

sizeof

stackalloc

static

string

struct

switch

this

throw

true

try

typeof

uint

ulong

unchecked

unsafe

ushort

using

virtual

void

volatile

while

Bảng 1.1: Từ khóa của ngôn ngữ C#.

để xây dựng bất cứ ứng dụng nào.

C# là ngôn ngữ hƣớng module Mã nguồn C# có thể đƣợc viết trong lớp, những lớp này chứa các phƣơng thức thành viên của nó. Lớp và những phƣơng thức có thể đƣợc sử dụng lại trong ứng dụng hay các chƣơng trình khác. Bằng cách truyền các mẫu thông tin đến lớp hay phƣơng thức có thể tạo ra những mã nguồn dùng lại có hiệu quả.

1.2.2. Các bƣớc chuẩn bị cho chƣơng trình Thông thƣờng, trong việc phát triển phần mềm, ngƣời phát triển phải tuân thủ theo quy trình phát triển phần mềm một cách nghiêm ngặt và quy trình này đã đƣợc

chuẩn hóa. Tuy nhiên trong phạm vi là tìm hiểu một ngôn ngữ mới và viết những

5

Tập bài giảng Lập trình cơ bản

chƣơng trình nhỏ thì không đòi hỏi khắt khe việc thực hiện theo quy trình. Nhƣng để

giải quyết đƣợc những vấn đề thì cũng cần phải thực hiện đúng theo các bƣớc sau:

- Xác định mụctiêu của chƣơngtrình. - Xác định những phƣơng pháp giải quyếtvấn đề. - Tạo mộtchƣơngtrình để giảiquyếtvấn đề.

- Thựcthi chƣơng trình để xemkết quả. Ví dụ để viết chƣơng trình xử lý văn bản đơn giản, mục tiêu chính là xây dựng

chƣơng trình cho phép soạn thảo và lƣu trữ những chuỗi ký tự hay văn bản. Nếu không có mục tiêu thì không thể viết đƣợc chƣơng trình hiệu quả.

Bƣớc thứ hai là quyết định đến phƣơng pháp để viết chƣơng trình. Bƣớc này xác định những thông tin nào cần thiết đƣợc sử dụng trong chƣơng trình, các hình thức nào đƣợc sử dụng. Từ những thông tin này rút ra đƣợc phƣơng pháp để giải quyết vấn

đề.

Bƣớc thứ ba là cài đặt, bƣớc này có thể dùng các ngôn ngữ khác nhau để cài

đặt, Trong phạm vi của tập bài giảng này là dùng C#.

Và bƣớc cuối cùng là phần thực thi chƣơng trình để xem kết quả.

1.2.3. Xây dựng chƣơng trình C# đơn giản Yêu cầu: Xây dựng ứng dụng Console thực hiện các công việc sau: - Hiển thị chuỗi thông báo ―Chao mung den voi C# 2010‖ ra màn hình; - Thực hiện nhập hai số thực từ bàn phím và hiển thị số lớn nhất trong hai số Hướng dẫn thực hiện

- Bƣớc1: Khởi động Visual Studio 2010

Chọn Start | All Programs | Microsoft Visual Studio 2010 | Microsoft

Visual Studio 2010.

- Bƣớc 2: Tạo một Project mới

Chọn menu File | New | Project

- Bƣớc 3: Thiết lập lựa chọn và thực hiện khai báo nhƣ hình 1.2 theo các bƣớc

sau.

Bƣớc 3.1: Chọn ngôn ngữ là Visual C# và kiểu Template là Windows. Bƣớc 3.2: Chọn kiểu ứng dụng Console Application. Bƣớc 3.3: Đặt tên cho Project Bƣớc 3.4: Đƣờng dẫn tới thƣ mục chứa Project Bƣớc 3.5: Kích chuột vào nút Ok để tạo Project mới

6

Tập bài giảng Lập trình cơ bản

3.1

1

3.2

3.3

3.4

3.5

Hình 1.2: Các bước lựa chọn một Project mới Visual Studio 2010

Ghi chú: Nếu muốn tạo một Project sử dụng ngôn ngữ khác thì có thể chọn ngôn ngữ đó trong mục Other Languages. Như ở trên hình 1.2, có thể chọn

Visual Basic hoặc Visual C++.

// Xuat ra man hinh chuoi thong bao 'Chao mung ban den voi C# 2010'

Console.WriteLine("Chao mung ban den voi C# 2010");

// Nhập hai số thực a, b từ bàn phím

//Thực hiện hai báo hai biến thực a, b

float a, b;

//Thực hiện nhập a

Console.Write("Nhap a = "); a = float.Parse(Console.ReadLine());

//Thực hiện nhập a

Console.Write("Nhap b = "); b = float.Parse(Console.ReadLine());

//Khai báo biến max và tìm số lớn nhất trong hai số a, b

float max;

max = a;

if (max < b) max = b;

Console.WriteLine("So lon nhat = {0}", max);

System.Console.ReadLine();

- Bƣớc 4: Sau khi tạo xong Project mới, chọn tập tin Program.cs trong cửa sổ Solution Explorer nhƣ hình 1.3. Trong phƣơng thức Main, thêm đoạn mã lệnh sau:

7

Tập bài giảng Lập trình cơ bản

Hình 1.3: Tập tin Program.cs

- Bƣớc 5: Để chạy chƣơng trình, nhấn F5 hoặc ấn vào nút . Kết quả hình 1.4.

Hình 1.4: Kết quả chương trình Vidu1.1

Ví dụ đơn giản trên đƣợc gọi là ứng dụng Console, ứng dụng này đƣợc giao tiếp

thông qua bàn phím và không có giao diện ngƣời dùng (User Interface), nhƣ các ứng

dụng thƣờng thấy trong Windows. Trong các chƣơng xây dựng các ứng dụng nâng cao

trên Windows hay Web thì mới dùng các các giao diện đồ họa. Còn để tìm hiểu về

ngôn ngữ C# thuần tuý thì cách tốt nhất là viết các ứng dụng Console.

Trong ứng dụng đơn giản trên,có sử dụng phƣơng thức WriteLine() của lớp Console. Phƣơng thức này sẽ xuất ra màn hình chuỗi tham số đƣa vào, cụ thể là chuỗi ―Chao mung ban den voi C# 2010‖ và sau đó đƣa con trỏ màn hình xuống đầu dòng tiếp theo, ngoài ra có thể sử dụng phƣơng thức Write() để hiển thị chuỗi nhƣng không

float a, b;

//Thực hiện nhập a

Console.Write("Nhap a = "); a = float.Parse(Console.ReadLine());

//Thực hiện nhập a

đƣa con trỏ xuống đầu dòng tiếp theo. Tiếp theo là thực hiện khai báo hai số thực là a, b và thực hiện nhập dữ liệu cho hai biến thức này.

8

Console.Write("Nhap b = "); b = float.Parse(Console.ReadLine());

Tập bài giảng Lập trình cơ bản

Phƣơng thức ReadLine() trả về một chuỗi đƣợc nhập từ bàn phím và phƣơng

thức phƣơng thức float.Parse() trả về một số thực tƣơng ứng với chuỗi nhập vào. Sau

đó là đoạn mã đƣợc dùng để tìm số lớn nhất trong hai biến a, b và hiển thị kết quả ra

float max;

max = a;

if (max < b) max = b;

Console.WriteLine("So lon nhat = {0}", max);

màn hình.

Sau khi khai báo biến max và gán giá trị của biến a cho max, câu lệnh if sẽ thực

hiện so sánh max với b, nếu max nhỏ hơn b thì giá trị của b cho max và hiển thị ra

thông báo số lớn nhất.

Câu lệnh cuối cùng Console.ReadLine() cuối chƣơng trình đƣợc dùng với mục

đích đợi sau khi ấn phím Enter sẽ đóng lại chƣơng trình đang chạy.

1.2.4. Chú thích trong chƣơng trình C# Một chƣơng trình đƣợc viết tốt thì cần phải có chú thích các đoạn mã đƣợc viết. Các đoạn chú thích này sẽ không đƣợc biên dịch và cũng không tham gia vào chƣơng

trình. Mục đích chính là làm cho đoạn mã nguồn rõ ràng và dễ hiểu.

Trong ví dụ 1.1 có một dòng chú thích:

// Xuat ra man hinh chuoi thong bao 'Chao mung ban den voi C# 2010'

Một chuỗi chú thích trên một dòng thì bắt đầu bằng ký tự ―//‖. Khi trình biên

dịch gặp hai ký tự này thì sẽ bỏ qua dòng đó.

Ngoài ra C# còn cho phép kiểu chú thích cho một hay nhiều dòng và phải khai

báo ―/*‖ ở phần đầu chú thích và kết thúc chú thích là ký tự ―*/‖.

namespace Vidu1_2

{

class Program

{

static void Main(string[] args)

{

/* Xuat ra man hinh chuoi ‘chao mung’

Su dung ham WriteLine cua lop System.Console

*/

System.Console.WriteLine("Chao mung ban den voi C# 2010");

System.Console.ReadLine();

}}}

Ví dụ 1.2: Minh họa dùng chú thích trên nhiều dòng.

Kết quả thực thi chƣơng trình:

9

Tập bài giảng Lập trình cơ bản

Hình 1.5: Kết quả chương trình ví dụ 1.2.

1.2.5. Namespace

Mã nguồn bên trong Framework đƣợc tổ chức bên trong namespace. Có hàng

trăm namespace bên trong Framework đƣợc sử dụng để tổ chức hàng ngàn lớp đối

tƣợng và các kiểu dữ liệu khác.Một vài namespace thì đƣợc lƣu trữ bên trong namespace khác. 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. Những ƣu điểm của namespace đƣợc liệt kê nhƣ sau:

- Tránh đƣợc sự trùng lặp tên giữa các lớp. - Cho phép tổ chức mã nguồn một cách có khoa học và hợp lý. Khai báo một Namespace

namespace NamespaceName

{

// nơi chứa đựng tất cả các class

}

Trong đó,

namespace CSharpProgram

{

class Basic

{

}

class Advanced

{

}

}

- namespace: là từ khóa khai báo một NameSpace - NamespaceName: là tên của một Namespace Ví dụ:

10

Tập bài giảng Lập trình cơ bản

CHƢƠNG 2: CƠ SỞ LẬP TRÌNH TRONG C#

Chƣơng này sẽ thảo luận về hệ thống kiểu dữ liệu, phân biệt giữa kiểu dữ liệu xây dựng sẵn (nhƣ int, bool, string…) với kiểu dữ liệu do ngƣời dùng định nghĩa (lớp

hay cấu trúc do ngƣời lập trình tạo ra...). Một số khái niệm cơ bản khác về lập trình

nhƣ tạo và sử dụng biến dữ liệu hay hằng cũng đƣợc đề cập cùng với cách xây dựng

biểu thức với các toán tử nhƣ phép gán, phép toán logic, phép toán quan hệ và toán

học... và các cấu trúc điều khiển nhƣ if, switch, for, while, do…while.

Nhƣ đã biết C# là một ngôn ngữ hƣớng đối tƣợng rất mạnh và công việc của

ngƣời lập trình là kế thừa để tạo và khai thác các đối tƣợng. Do vậy để nắm vững và

phát triển tốt ngƣời lập trình cần phải đi từ những bƣớc đi dầu tiên tức là đi vào tìm hiểu những phần cơ bản và cốt lõi nhất của ngôn ngữ.

2.1. Tên Têndùng để xác định cácthành phầnkhác nhau trong một chƣơng trình. Trong

C#, tên là một dãy ký tự bắt đầu bằng một chữ cái hoặc dấu gạch nối ( _ ), sau đó là

các chữ cái, chữ số hoặc dấu gạch nối.

Ví dụ 2.1: Đặt tên trong C#.

a_1 delta x1 _step GAMA

Các tên đúng: Các tên sai:

Tên sai Giải thích

3MN Ký tự đầu tiên là chữ số

m#2 Sử dụng ký tự #

f(x) Sử dụng dấu ()

do Trùng với từ khóa

11

Tập bài giảng Lập trình cơ bản

te ta Sử dụng dấu cách (white space)

Y-3 Sử dụng dấu -

Ghi chú: C# là ngôn ngữ phân biệt chữ cái thường và in hoa. Do dó, delta và

Delta là hai tên khác nhau.

2.2. Từ khóa Nhƣ đã giới thiệu ở chƣơng 1, bảng 1.1, ngôn ngữ C# có khoảng 77 từ khóa,

mỗi từ khóa có một ý nghĩa đặc biệt và khôngđƣợc sử dụng các từ khóa cho việc đặt tên các đại lƣợng khác trong chƣơng trình. Ví dụ class, do, using là các từ khóa. Ý

nghĩa của hầu hết các từ khóa sẽ đƣợc giới thiệu trong tập bài giảng.

Ghi chú: Trong cửa sổ Code and Text Editor của Visual Studio 2010, từ khóa

sẽ có màu xanh lam khi gõ đúng.

2.3. Hằng và Biến

2.3.1. Các kiểu dữ liệu cơ sở C# là ngôn ngữ lập trình mạnh về kiểu dữ liệu, một ngôn ngữ mạnh về kiểu dữ

liệu là phải khai báo kiểu của mỗi đối tƣợng khi tạo (kiểu số nguyên, số thực, kiểu

chuỗi, ...) và trình biên dịch sẽ giúp cho ngƣời lập trình không bị lỗi khi chỉ cho phép

một loại kiểu dữ liệu có thể đƣợc gán cho các kiểu dữ liệu khác. 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). Việc phân chia này do sự khác nhau khi lƣu kiểu

dữ liệu giá trị và kiểu dữ liệu tham chiếu trong bộ nhớ. Đối với một kiểu dữ liệu giá trị

thì sẽ đƣợc lƣu giữ kích thƣớc thật trong bộ nhớ đã cấp phát là stack. Trong khi đó thì

địa chỉ của kiểu dữ liệu tham chiếu thì đƣợc lƣu trong stack nhƣng đối tƣợng thật sự

thì lƣu trong bộ nhớ heap. Trong chƣơng này chỉ tập trung giới thiệu kiểu dữ kiểu cơ bản hay kiểu xây dựng sẵn.

Ngôn ngữ C# đƣa ra các kiểu dữ liệu xây dựng sẵn rất hữu dụng, phù hợp với

một ngôn ngữ lập trình hiện đại, mỗi kiểu dữ liệu đƣợc ánh xạ đến một kiểu dữ liệu đƣợc hỗ trợ bởi hệ thống xác nhận ngôn ngữ chung (Common Language Specification: CLS) trong MS.NET.

Việc ánh xạ các kiểu dữ liệu nguyên thuỷ của C# đến các kiểu dữ liệu của .NET sẽ đảm bảo các đối tƣợng đƣợc tạo ra trong C# có thể đƣợc sử dụng đồng thời với các đối tƣợng đƣợc tạo bởi bất cứ ngôn ngữ khác đƣợc biên dịch bởi .NET, nhƣ VB.NET. Mỗi kiểu dữ liệu có một miền giá trị và kích thƣớc không thay đổi, không giống

nhƣ C++, int trong C# luôn có kích thƣớc là 4 byte bởi vì nó đƣợc ánh xạ từ kiểu Int32 trong .NET.

12

Tập bài giảng Lập trình cơ bản

Kiểu C# Số byte Kiểu .NET Miền giá trị

Số nguyên từ 0 đến 255 byte Byte 1

Ký tự Unicode char Char 2

Boolean {true, false} bool 1

sbyte Sbyte 1 Số nguyên từ -128 đến 127

short Int16 2 Số nguyên từ -32768 đến32767.

ushort Uịnt16 2 Số nguyên không dấu từ 0 – 65535

int Int32 4

Số nguyên từ –2.147.483.647 đến 2.147.483.647

uint Uint32 4 Số nguyên từ 0 đến 4.294.967.295

float Single 4 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.

double 8 Double Số nguyên từ 0 đến 4.294.967.295

decimal 8 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 đòi hỏi phải có hậu tố ―m‖ hay ―M‖

theo sau giá trị.

long 8 Int64 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 8 Uint64 Số nguyên từ 0 -18,446,744,073,709,551,615

Bảng 2.1: Mô tả các kiểu dữ liệu xây dựng sẵn

Chọn kiểu dữ liệu Thông thƣờng để chọn một kiểu dữ liệu nguyên để sử dụng nhƣ short, int hay

long thƣờng dựa vào độ lớn của giá trị muốn sử dụng. Ví dụ, một biến ushort có thể

lƣu giữ giá trị từ 0 đến 65.535, trong khi biến ulong có thể lƣu giữ giá trị từ 0 đến

4.294.967.295, do đó tùy vào miền giá trị của phạm vi sử dụng biến mà chọn các kiểu

dữ liệu thích hợp nhất. Kiểu dữ liệu int thƣờng đƣợc sử dụng nhiều nhất trong lập trình vì với kích thƣớc 4 byte của nó cũng đủ để lƣu các giá trị nguyên cần thiết.

Kiểu float, double và decimal đƣa ra nhiều mức độ khác nhau về kích thƣớc cũng nhƣ độ chính xác.Với thao tác trên các phân số nhỏ thì kiểu float là thích hợp nhất. Tuy nhiên lƣu ý rằng trình biên dịch luôn luôn hiểu bất cứ một số thực nào cũng là một số kiểu double trừ khi khai báo rõ ràng. Để gán một số kiểu float thì số phải có ký tự f theo sau.

float soFloat = 24f;

13

Tập bài giảng Lập trình cơ bản

Kiểu dữ liệu ký tự thể hiện các ký tự Unicode, bao gồm các ký tự đơn giản, ký

tự theo mã Unicode và các ký tự thoát khác đƣợc bao trong những dấu nháy đơn. Ví

dụ, A là một ký tự đơn giản trong khi \u0041 là một ký tự Unicode. Ký tự thoát là

những ký tự đặc biệt bao gồm hai ký tự liên tiếp trong đó ký tự đầu tiên là dấu chéo ‗\‘. Ví dụ, \t là dấu tab. Bảng 3.2 liệt kê một số ký tự đặc biệt.

Ký tự Ý nghĩa

\‘ Dấu nháy đơn

\‖ Dấu nháy kép

\\ Dấu chéo

\0 Ký tự null

\a Alert

\b Backspace

\f Sang trang Form feed

\n Dòng mới

\r Đầu dòng

\t Tab ngang

\v Tab dọc

Bảng 2.2: Các kiểu ký tự đặc biệt.

2.3.2. Biến Một biến đƣợc khai báo theo cú pháp sau:

Kiểu_dữ_liệu tên_biến;

Trong đó Kiểu_dữ_liệu có thể là kiểu dữ liệu đã đƣợc xây dựng sẵn hoặc là

kiểu dữ liệu do ngƣời dùng định nghĩa, tên_biến do ngƣời dùng tự đặt và tuân thủ theo

quy tắc đặt tên.

Ví dụ 2.2: Khai báo biến

int a; //khai báo một biến nguyên có tên là a

float b,c;//khai báo hai biến thực b và c

Ghi chú: Trong một câu lệnh cho phép khai báo nhiều biến cùng kiểu, giữa các

biến này được phân cách nhau bới dấu “,”. Biến có thể đƣợc khởi tạo giá trị ngay khi đƣợc khai báo, hay nó cũng có thể đƣợc gán một giá trị mới vào bất cứ lúc nào trong chƣơng trình. Ví dụ 2.3 sau minh

họa sử dụng biến.

namespace Vidu2_3{

class Program

Ví du 2.3: Khởi tạo và gán giá trị đến một biến.

14

{

static void Main(string[] args)

{

int x = 9;

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

Console.Write("Nhap gia tri moi = ");

x = int.Parse(Console.ReadLine());//chuyển đổi chuỗi nhập từ bàn phím sang kiểu

số nguyên

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

System.Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.1: Kết quả chương trình ví dụ 2.3

Chƣơng trình trên thực hiện khai báo biến x và khởi gán giá trị ban đầu bằng 9,

khi hiển thị x thì x có giá trị là 9, sau đó thực hiện phép gán biến x với giá trị mới là 15

thì biến sẽ có giá trị là 15 và xuất kết quả là 15.

Gán giá trị xác định cho biến C# đòi hỏi các biến phải đƣợc khởi tạo trƣớc khi đƣợc sử dụng. Để kiểm tra luật

này, thực hiện thay đổi dòng lệnh khởi tạo biến bien1 trong ví dụ 2.3 nhƣ sau:

namespace Vidu2_4

{

class Program

{

static void Main(string[] args)

{

int x;

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

x = int.Parse(Console.ReadLine());//chuyển đổi chuỗi nhập từ bàn phím sang kiểu

số nguyên

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

System.Console.ReadLine();

}

}

}

Ví dụ 2.4: Sử dụng một biến không khởi tạo.

15

Tập bài giảng Lập trình cơ bản

Khi biên dịch chƣơng trình trên thì trình biên dịch C# sẽ thông báo một lỗi sau:

Use of unassigned local variable ‗x

Việc sử dụng biến khi chƣa đƣợc khởi tạo là không hợp lệ trong C#.Tuy nhiên

không nhất thiết lúc nào cũng phải khởi tạo biến nhƣng để dùng đƣợc thìbắt buộc phải gán cho chúng một giá trị trƣớc khi có một lệnh nào sử dụng đến biến đó.

namespace Vidu2_5

{

class Program

{

static void Main(string[] args)

{

int x;

x = 9;

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

x = 15;

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

System.Console.ReadLine();

}

}

}

Ví dụ 2.5: Biến không đƣợc khi tạo nhƣng sau đó đƣợc gán giá trị.

Tầm hoạt động của biến Tầm hoạt động của một biến là vùng mã lệnh mà trong đó biến có thể truy xuất.

Nói chung, tầm hoạt động của biến đƣợc xác định theo các quy tắc sau:

- Một trƣờng dữ liệu (field), còn đƣợc gọi là một biến thành phần của một lớp đối

tƣợng sẽ có tầm hoạt động trong phạm vi lớp chứa nó.

- Một biến cục bộ sẽ có tầm hoạt động trong khối khai báo nó (trong cặp dấu

ngoặc

nhọn { })

- Một biến cục bộ đƣợc khai báo trong các lệnh lặp for, while, … sẽ có tầm hoạt

động trong thân vòng lặp

Lƣu ý, trong cùng phạm vi hoạt động, các biến không đƣợc phép trùng tên.

2.3.3. Hằng Để khai báo một hằng sử dụng từ khóa const và cú pháp sau:

const kiểu_dữ_liệu tên_hằng = giá_trị;

namespace Vidu2_6

{

class Program

{

Ví dụ 2.6: Sử dụng hằng.

16

static void Main(string[] args)

{

const int DoSoi = 100; // Độ C

const int DoDong = 0; // Độ C

System.Console.WriteLine( "Do dong cua nuoc {0}", DoDong );

System.Console.WriteLine( "Do soi cua nuoc {0}", DoSoi );

System.Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.2: Kết quả chương trình ví dụ 2.6.

Ghi chú: Trong chương trình nếu có một câu lệnh làm thay đổi giá trị của hằng thì trình biên dịch sẽ phát sinh lỗi: “The left-hand side of an assignment must

be a variable, property or indexer”

2.4. Biểu thức

2.4.1. Biểu thức Biểu thức đƣợc tạo nên bằng sự kết hợp giữa các toán hạng và toán tử. Toán

hạng gồm: hằng, biến, hàm,… Trong các phần tiếp theo dƣới đây, sẽ nói đến các toán

tử.Ngoài ra, biểu thức đƣợc phân loại theo kiểu giá trị ví dụ nhƣ nguyên hoặc thực.

Trong các mệnh đề logic, biểu thức đƣợc phân thành đúng (true) và sai (false).

v=e

2.4.2. Lệnh gán và biểu thức Biểu thức gán là biểu thức có dạng: Trong đó v là một biến, e là một biểu thức cùng kiểu với v. Giá trị của biểu thức

Biểu thức gán có thể sử dụng trong các phép toán và các câu lệnh nhƣ các biểu

gán là giá trị của e, kiểu của nó là kiểu của v. Nếu đặt dấu; vào sau biểu thức gán sẽ thu đƣợc phép toán gán có dạng: v=e; thức khác. Ví dụ nhƣ khi viết a=b=5;

thì điều đó có nghĩa là gán giá trị của biểu thức b=5 cho biến a. Kết qủa là b=5 và a=5.

17

Tập bài giảng Lập trình cơ bản

Hoàn toàn tƣơng tự nhƣ:

a=b=c=d=6; //gán 6 cho cả a, b, c và d

z=(y=2)*(x=6); //ở đây * là phép toán nhân, gán 2 cho y, 6 cho x và

//nhân hai biểu thức sẽ cho z=12.

2.4.3. Các phép toán số học Các phép toán hai ngôi số học là:

Phép toán

Ý nghĩa

Ví dụ

+ Phép cộng a+b

- Phép trừ a-b

* Phép nhân a*b

/ Phép chia a/b

Khi chia hai số nguyên thì C# sẽ bỏ phần

phân số, hay bỏ phần dƣ. Khi chia cho số thực có kiểu nhƣ float, double, hay decimal thì kết quả chia đƣợctrả về là một số thực.

% Phép lấy phần dƣ a%b

(Cho phần dƣ của phép chia a cho b)

Bảng 2.3: Các phép toán số học hai ngôi

Có phép toán một ngôi (-), ví du -(a+b) sẽ đảo giá trị của phép cộng (a+b).

namespace Vidu2_7

{

class Program

{

static void Main(string[] args)

{

int i1, i2;

float f1, f2;

double d1, d2;

decimal dec1, dec2;

i1 = 17;

i2 = 4;

f1 = 17f;

f2 = 4f;

d1 = 17;

d2 = 4;

dec1 = 17;

dec2 = 4;

Console.WriteLine("i1 + i2 = \t{0}", i1 + i2);

Console.WriteLine("i1 - i2 = \t{0}", i1 - i2);

Ví dụ 2.7: Minh họa sử dụng các phép toán các số nguyên, thực...

18

Console.WriteLine("i1 * i2 = \t{0}", i1 * i2);

Console.WriteLine("\nCac phep chia:");

Console.WriteLine(" Integer: i1/i2 = \t{0}", i1/i2);

Console.WriteLine(" Float: f1/f2 = \t{0}", f1 / f2);

Console.WriteLine(" Double: d1/d2 = \t{0}", d1 / d2);

Console.WriteLine(" Decimal: dec1/dec2 = \t{0}", dec1 / dec2);

Console.WriteLine("\nPhep toan lay du: i1%i2 = \t{0}", i1%i2);

Console.ReadLine();

}

}

} Kết quả chƣơng trình:

Tập bài giảng Lập trình cơ bản

Hình 2.3: Kết quả chương trình ví dụ 2.7

2.4.4. Các phép toán quan hệ và logic

Các phép toán quan hệ Những toán tử quan hệ đƣợc dùng để so sánh giữa hai giá trị và trả về kết quả là một giá trị logic kiểu bool (true hay false). Các toán tử quan hệ trong ngôn ngữ C#

đƣợc trình bày trong bảng 2.4. Các toán tử trong bảng đƣợc minh họa với hai biến là

value1 và value2, trong đó value1 có giá trị là 100 và value2 có giá trị là 50.

Phép toán

Ý nghĩa

Biểu thức so sánh

Kết quả so sánh

So sánh bằng ==

value1 == 100 value1 == 50 true false

Không bằng !=

value2 != 100 value2 != 90 false true

Lớn hơn >

value1 > value2 value2 > value1 true false

Lớn hơn hay bằng value2 >= 50 >= true

value1 < value2 Nhỏ hơn < false

value2 < value1 true

19

Tập bài giảng Lập trình cơ bản

<= Nhỏ hơn hay bằng value1 <= value2 false

Bảng 2.4: Các toán tử so sánh (giả sử value1 = 100 và value2 = 50).

Nhƣ trong bảng 2.4 trên lƣu ý toán tử so sánh bằng (==), toán tử này đƣợc ký

hiệu bởi hai dấu bằng (=) liền nhau và cùng trên một hàng, không có bất kỳ khoảng trống nào xuất hiện giữa chúng. Trình biên dịch C# xem hai dấu này nhƣ một toán tử.

Phép toán logic Bảng 2.5 liệt kệ ba phép toán logic, bảng này cũng sử dụng hai biến minh họa là

x và y trong đó x có giá trị là 5 và y có giá trị là 7

Tên toán tử Ký hiệu

Biểu thức logic

Giá trị

Logic

Và && (x == 3) && (y ==7) false Cả hai điều kiện

phải đúng

Hoặc (x == 3) || (y == 7) true ||

Chỉ cần một điều kiện đúng

! Phủ định ! (x == 3 ) true Biểu thức trong

ngoặc phải sai.

Bảng 2.5: Các toán tử logic (giả sử x = 5, y = 7).

2.4.5. Phép toán tăng giảm Tính toán và gán trở lại Do việc tăng hay giảm giá trị của một biến rất thƣờng xảy ra trong khi tính toán

nên C# cung cấp các phép toán tự gán (self- assignment). Bảng 2.6 sau liệt kê các phép

toán tự gán.

Tên toán tử

Ý nghĩa

+= Cộngthêm giá trị toán hạng bên phải vào giá trị toán

hạng bên trái

-= Toán hạng bên trái đƣợc trừ bớt đi một lƣợng bằng giá

trị của toán hạng bên phải

*= Toán hạng bên trái đƣợc nhân với một lƣợng bằng giá

trị của toán hạng bên phải.

/=

Toán hạng bên trái đƣợc chia với một lƣợng bằng giá trị của toán hạng bên phải.

%=

Toán hạng bên trái đƣợc chia lấy dƣ với một lƣợng bằng giá trị của toán hạng bên phải.

Bảng 2.6: Mô tả các phép toán tự gán.

Ví dụ có biến nguyên a với giá trị ban đầu bằng 5, để cộng thêm 10 vào giá trị

của biến a thì hai cách viết sau là tƣơng đƣơng:

20

Tập bài giảng Lập trình cơ bản

a = a + 10;

hoặc sử dụng phép toán tự gán:

a+=10;

Do việc tăng hay giảm 1 rất phổ biến trong lập trình, C# cung cấp hai toán tử đặc biệt là tăng một (++) hay giảm một (--). Để tăng giá trị của một biến bienDem lên

1 có thể viết nhƣ sau:

bienDem++; Ví dụ vớin=5, khi thực hiện:

++n sẽ cho n=6

--n sẽ cho n=4

Có thể viết phép toán ++ và -- trƣớc hoặc sau toán hạng nhƣ sau : ++n, n++, --

n, n--.

Sự khác nhau của ++n và n++ ở chỗ: trong phép n++ thì tăng sau khi giá trị của

nó đã đƣợc sử dụng, còn trong phép ++n thì n đƣợc tăng trƣớc khi sử dụng. Sự khác

nhau giữa n-- và --n cũng nhƣ vậy.

Ví dụ với n = 5, khi thực hiện:

x=++n sẽ cho x=6 và n=6

x=n++ sẽ chon x=5 và n=6

namespace Vidu2_8

{

class Program

{

static void Main(string[] args)

{

int a = 10;

int b;

b= a++;

Console.WriteLine("Thuc hien tang sau: {0}, {1}", a, b);

a= 20;

b= ++a;

Console.WriteLine("Thuc hien tang truoc: {0}, {1}", a, b);

Console.ReadLine();

}

}

}

Ví dụ 2.8: Minh hoạ sử dụng toán tử tăng trƣớc và tăng sau khi gán.

Kết quả chƣơng trình:

21

Tập bài giảng Lập trình cơ bản

Hình 2.4: Kết quả chương trình ví dụ 2.8.

Các phép toán khác Bảng 2.7 mô tả một số các phép toán khác có trong C#

Phép toán

Mô tả

Ví dụ

sizeof() Trả lại kích thƣớc của một sizeof(int), trả về 4.

kiểu dữ liệu

typeof() Trả lại kiểu của một lớp nào typeof(int), trả về

đó System.Int32

Biểu thức điều kiện (Điều kiện)?X:Y, trả về X ? :

nếu Điều kiện đúng và trả

về Y nếu Điều kiện là sai.

Xác định xem một đối tƣợng is

có phải có kiểu nào đó hay

không

Chuyển đổi không phát sinh as

lỗi nếu chuyển đổi sai

Bảng 2.7: Một số các phép toán khác có trong C#

2.4.6. Thứ tựƣu tiên các phép toán Trình biên dịch phải xác định thứ tự thực hiện các toán tử trong trƣờng hợp một

biểu thức có nhiều phép toán. Bảng 2.8 liệt kê thứ tự độ ƣu tiên các phép toán trong

C#.

Thứ

STT

Loại toán tử

Toán tử

tự

1 Phép toán cơ bản Trái

(x) x.y f(x) a[x] x++ x—new typeof sizeof checked unchecked

2 Phép toán một ngôi + - ! ~ ++x --x (T)x Trái

3 Phép nhân * / % Trái

4 Phép cộng + - Trái

22

Tập bài giảng Lập trình cơ bản

Trái 5 Dịch bit <<>>

Trái 6 Quan hệ <><= >= is as

Phải 7 So sánh bằng == !=

Trái 8 Phép toán logicAND &

Trái 9 Phép toán logicXOR ^

Trái 10 Phép toán logic OR |

Trái 11 Điều kiện AND &&

Trái 12 Điều kiện OR ||

Phải 13 Điều kiện ?:

14 Phép gán = *= /= %= += -= <<= >>= &= Phải

^= |=

Bảng 2.8: Thứ tự ưu tiên các phép toán.

Các phép toán đƣợc liệt kê cùng loại sẽ có thứ tự theo mục thứ tự của bảng: thứ

tự trái tức là độ ƣu tiên của các phép toán từ bên trái sang, thứ tự phải thì các phép

toán có độ ƣu tiên từ bên phải qua trái. Các toán tử khác loại thì có độ ƣu tiên từ trên

xuống dƣới, do vậy các toán tử loại cơ bản sẽ có độ ƣu tiên cao nhất và phép toán gán

sẽ có độ ƣu tiên thấp nhất trong các toán tử.

Biểu thức điều kiện Hầu hết các toán tử đòi hỏi có một toán hạng nhƣ toán tử (++, --) hay hai toán

hạng nhƣ (+,-,*,/,...). Tuy nhiên, C# còn cung cấp thêm một toán tử có ba toán hạng

(?:). Toán tử này có cú pháp sử dụng nhƣ sau:

? : Toán tử này sẽ xác định giá trị của 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. Khi điều kiện đúng thì sẽ đƣợc thực hiện, còn ngƣợc lại điều kiện sai thì sẽ đƣợc thực hiện. Có thể diễn giải theo ngôn ngữ tự nhiên thì toán tử này có ý nghĩa: ―Nếu điều kiện đúng thì làm công việc thứ nhất, còn ngƣợc lại điều kiện sai thì làm công việc thứ hai‖. Cách sử dụng toán tử ba ngôi này đƣợc minh họa trong ví dụ 2.9 sau.

Ví dụ 2.9: Lập chƣơng trình tìm số lớn nhất của hai số

23

namespace Vidu2_9

{

class Program

{

static void Main(string[] args)

{

int so1;

int so2;

int max;

so1 = 10;

so2 = 20;

max = so1 > so2 ? so1 : so2;

Console.WriteLine("Gia tri thu nhat {0}, gia tri thu hai {1}, gia

tri lon nhat {2}", so1, so2, max);

short x;

int i = 345;

x = (short)i;

Console.WriteLine("x = "+x.ToString());

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết qủa chƣơng trình:

Hình 2.5: Kết quả chương trình ví dụ 2.9

Trong ví dụ minh họa trên toán tử ba ngôi đƣợc sử dụng để kiểm tra xem giá trị

củaso1 có lớn hơn giá trị của so2, nếu đúng thì trả về giá trị của so1, tức là gán giá trị

so1 cho biến max, còn ngƣợc lại thì gán giá trị so2 cho biến max.

2.4.7. Chuyển đổi kiểu giá trị Những đối tƣợng của một kiểu dữ liệu này có thể đƣợc chuyển sang những đối tƣợng của một kiểu dữ liệu khác thông qua cơ chế chuyển đổi tƣờng minh hay ngầm định.

Chuyển đổi ngầm định Chuyển đỗi ngầm định xảy ra khi: - Ép từ kiểu nhỏ qua kiểu lớn - Ép từ lớp dẫn xuất qua lớp cơ sở

24

Tập bài giảng Lập trình cơ bản

Ví dụ, có thể gán ngầm định một số kiểu short (2 byte) vào một số kiểu int (4

byte) một cách ngầm định. Sau khi gán hoàn toàn không mất dữ liệu vì bất cứ giá trị

nào của short cũng thuộc về int:

short x = 10; int y = x; // chuyển đổi ngầm định

Tuy nhiên, nếu thực hiện chuyển đổi ngƣợc lại, chắc chắn sẽ bị mất thôngtin.

Nếu giá trị của số nguyên đó lớn hơn 32.767 thì nó sẽ bị cắt khi chuyển đổi. Trình biêndịch sẽ không thực hiện việc chuyển đổi ngầm định từ số kiểu int sang số kiểu

short:

short x;

int y = 100; x = y; // Không biên dịch, lỗi!!!

Chuyển đổi tƣờng minh:

- Do lập trình viên chỉ định - Xảy ra khi: Ép từ kiểu lớn qua kiểu nhỏ (có thể mất giá trị), Ép từ lớp cơ

sở qua lớp dẫn xuất

Để thực hiện chuyển đổi tƣờng minh ta có thể sử dụng một trong ba cách sau:

- Để không bị lỗi phải dùng lệnh gán tƣờng minh

Ví dụ:

short x;

int y = 500;

x = (short) y; // Ép kiểu tường minh, trình biên dịch không báo lỗi.

- Sử dụng phƣơng thức Parse, TryParse

Trong mỗi kiểu dữ liệu trên đều có hai phƣơng thức sẽ thƣờng xuyên đƣợc sử

dụng trong tập bài giảng này đó là Parse và TryParse, đƣợc dùng để chuyển đổi một đối tƣợng bất kỳ sang kiểu dữ liệu gọi các phƣơng thức này. Sự khác biệt giữa hai

phƣơng thức đó là TryParse sẽ kiểm tra tính hợp lệ của dữ liệu chuyển đổi trƣớc khi

chuyển đổi còn phƣơng thức Parse thì không. Ví dụ với câu lênh:

int x = int.Parse(”123”);

thực hiện chuyển đổi chuỗi 123 sang số nguyên và gán cho biến x. Nếu tham số truyền vào không phải là số nguyên thì khi chạy chƣơng trình sẽ phát sinh ngoại lệ. Để tránh điều này có thể sử dụng phƣơng thức TryParse nhƣ sau: bool kt = int.TryParse(”123”, out x)

Câu lệnh trên sẽ thực hiện chuyển đổi chuỗi 123 sang số nguyên, nếu thành công thì sẽ gán giá trị 123 cho biến x, phƣơng thức sẽ trả về giá trị true, ngƣợc lại phƣơng

thức sẽ trả về giá trị false còn biến x sẽ không đƣợc gán giá trị mới.

25

Tập bài giảng Lập trình cơ bản

- Sử dụng lớp Convert

C# cung cấp lớp Convert để thực hiện chuyển đổi kiểu dữ liệu. Ví dụ câu lệnh:

int y = Convert. ToInt32(“32”)

thực hiện chuyển đổi chuỗi ―32‖ thành số và gán cho biến y. Trong lớp Convert còn có rất nhiều các phƣơng thức chuyển đổi đối tƣợng bất kỳ sang các kiểu dữ liệu nhƣ

short, float, double, …sinh viên tự tìm hiểu thêm.

2.4.8. Lớp Math Để xây dựng các công thức toán học, ngoài các phép toán cơ bản đã đƣợc giới

thiệu còn cần rất nhiều các hàm toán học mà chƣa đƣợc đề cập tới. Trong C# có lớp

Math là lớp chứa các phƣơng thức hay thuộc tính liên quan tới các hàm toán học nhƣ

tính sin, cos, logarit,…. Bảng 2.9 sau liệt kê một số phƣơng thức có trong lớp Math.

Phƣơng thức Mô tả

Ví dụ

Abs Trả về trị tuyệt đối của một số Math.Abs(x) ≈ |x|

Ceiling Trả về giá trị nhỏ nhất hay bằng của một số Math.Ceiling(123.456

) = 124

Exp thực Trả về giá trị e với mũ là tham số đầu vào Math.Exp(x) ≈ ex

Floor Trả về giá trị lớn nhất hay bằng của một số Math.Floor(123.456) =

thực 123

Log Trả về giá trị logarit của một số Math.Log(x) ≈ ln(x)

Log10 Trả về giá trị logarit cơ số 10 của một số ≈

Math.Log10(x) log10(x) Max(3,7) = 7 Max Trả về số lớn nhất trong hai số

Min Trả về số nhỏ nhất trong hai số Min(3,7) = 3

Pow Trả về giá trị mũ của hai số = Math.Pow(x,y) ≈ xy

Round Trả về giá trị đƣợc làm tròn của một số thực Math.Round(123.456)

= 123

Sign Trả về dấu của một số, -1 nếu số âm và 1 Math.Sign(3) = 1

nếu số dƣơng

Sqrt Trả về căn bậc hai của một số Math.Sqrt(x) ≈ 𝑥

Cos Trả về giá trị cosin của một góc Math.Cos(x) ≈ cos(x)

26

Tập bài giảng Lập trình cơ bản

Sin Trả về giá trị sin của một góc Math.Sin(x) ≈ sin(x)

Tan Trả về giá trị tang của một góc Math.Tan(x) ≈ tan(x)

Bảng 2.9: Một số phương thức của lớp Math.

Ngoài thuộc ra, tính PI, E, trong đó PI =

lớp Math có hai 3.14159265358979323846 vàE = 2.7182818284590452354.

2.5. Câu lệnh rẽ nhánh

2.5.1. Câu lệnh if

1. Câu lệnh if không đầy đủ

Cú pháp:

if ()

{;}

Hoạt động: Tính biểu thức logic. Nếu biểu thức logic nhận giá trị true thì thực hiện lệnh

hoặc khối lệnh. Ngƣợc lại bỏ qua lệnh hoặc khối lệnh và kết thúc câu lệnh if.

Cụ thể hoạt động của câu lệnh trên đƣợc mô tả trong hình sau:

Hình 2.6: Hoạt động của câu lệnh if không đầy đủ

Ví dụ 2.10: Lập trình tìm và hiển thị số lớn nhất của hai số thực đƣợc nhập vào

namespace Vidu_2_10

{

class Program

{

static void Main(string[] args)

{ float a, b;

từ bàn phím.

27

Console.Write("Nhap a = "); a = float.Parse(Console.ReadLine());

Console.Write("Nhap b = "); b = float.Parse(Console.ReadLine());

float max = a;

if(max < b) max = b;

Console.WriteLine("So lon nhat: {0} ", max);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.7: Kết quả chương trình ví dụ 2.10

Trong trƣờng hợp lệnh hoặc khối lệnh là một lệnh thì có thể bỏ cặp dấu{ }.

2. Câu lệnh if đầy đủ

Cú pháp:

if ()

{;}

else

{;}

Hoạt động: Trƣớc hết tính biểu thức logic. Nếu biểu thức nhận giá trị true thì thực hiện lệnh

hoặc khối lệnh 1. Ngƣợc lại thực hiện lệnh hoặc khối lệnh 2 và kết thúc câu lệnh if.

Cụ thể hoạt động của câu lệnh trên đƣợc mô tả trong hình sau:

28

Tập bài giảng Lập trình cơ bản

Hình 2.8: Hoạt đông của câu lệnh if đầy đủ

Ví dụ 2.11: Lập chƣơng trình giải phƣơng trình bậc nhất ax + b = 0, với a, b là

namespace Vidu_2_11

{

class Program

{

static void Main(string[] args)

{

float a, b, c;

Console.Write("Nhap a = "); a = float.Parse(Console.ReadLine());

Console.Write("Nhap b = "); b = float.Parse(Console.ReadLine());

if (a != 0) Console.WriteLine("Phuong trinh co nghiem duy nhat x =

" + (-b / a).ToString());

else if (b != 0) Console.WriteLine("Phuong trinh vo nghiem");

else Console.WriteLine("Phuong trinh vo so nghiem");

Console.ReadLine();

}

}

}

các số thực nhập từ bàn phím.

Kết quả chƣơng trình:

Hình 2.9: Kết quả chương trình ví dụ 2.11

29

Tập bài giảng Lập trình cơ bản

3. Câu lệnh if lồng nhau Các câu lệnh if trên chỉ cho phép rẽ 1 hoặc 2 nhánh, trong trƣờng hợp rẽ nhiều

hơn 2 nhánh thì có thể sử dụng câu lệnh if lồng nhau.

Cú pháp: if ()

{;}

else if ()

{;}

......

else if ()

{;} else

{;}

Hoạt động: Bƣớc 1: Thực hiện tính biểu thức logic 1, nếu biếu thức logic 1 là đúng thì thực

hiện lệnh hoặc khối lệnh 1 và kết thúc câu lệnh if lồng nhau. Ngƣợc lại lệnh hoặc khối

lệnh 1 bị bỏ qua.

Bƣớc 2: Thực hiện tính biểu thức logic 2, nếu biếu thức logic 2 là đúng thì thực

hiện lệnh hoặc khối lệnh 2 và kết thúc câu lệnh if lồng nhau. Ngƣợc lại lệnh hoặc khối

lệnh 2 bị bỏ qua.

Bƣớc n-1: Thực hiện tính biểu thức logic n-1, nếu biếu thức logic n-1 là đúng

thì thực hiện lệnh hoặc khối lệnh n-1 và kết thúc câu lệnh if lồng nhau. Ngƣợc lại lệnh

hoặc khối lệnh n - 1 bị bỏ qua.

Bƣớc n: Thực hiện lệnh hoặc khối lệnh n và kết thúc câu lệnh if lồng nhau. Ví dụ 2.12: Lập chƣơng trình giải phƣơng trình bậc hai ax2 + bx + c = 0 với a,

namespace Vidu2_12

{

class Program

{

static void Main(string[] args)

{

double a, b, c, delta, x1, x2;

Console.Write("Nhap a = ");

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

Console.Write("Nhap b = ");

b = double.Parse(Console.ReadLine());

Console.Write("Nhap c = ");

b, c là các số thực nhập từ bàn phím.

30

c = double.Parse(Console.ReadLine());

if (a == 0)

if (b == 0)

if (c == 0) Console.WriteLine("Phuong trinh vo so nghiem");

else Console.WriteLine("Phuong trinh vo nghiem");

else Console.WriteLine("Phuong trinh co nghiem duy nhat {0}", -

c / b);

else

{

delta = b * b - 4 * a * c;

if (delta < 0) Console.WriteLine("Phuong trinh vo nghiem");

else if (delta == 0) Console.WriteLine("Phuong trinh co nghiem

kep x1 = x2 = {0}", -b / 2 * a);

else

{

Console.WriteLine("Phuong trinh co hai nghiem");

x1 = (-b - Math.Sqrt(delta)) / 2 * a;

x2 = (-b + Math.Sqrt(delta)) / 2 * a;

Console.WriteLine("x1 = {0}", x1);

Console.WriteLine("x2 = {0}", x2);

}

}

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.10: Kết quả chương trình ví dụ2.12.

2.5.2. Câu lệnh switch Cú pháp:

switch () {

case :

; break;

31

Tập bài giảng Lập trình cơ bản

case :

; break;

...

case :

; break;

[default:

; break;]

}

Hoạt động: Bƣớc 0: Tính giá trị biểu thức nguyên.

Bƣớc 1: Nếu giá trị biểu thứcnguyên bằng giá trị 1 thì thực hiện lệnh hoặc khối lệnh 1 và kết thúc switch. Ngƣợc lại lệnh hoặc khối lệnh 1 và câu lệnh break bị bỏ qua.

Bƣớc 2: Nếu giá trị biểu thứcnguyên bằng giá trị2 thì thực hiện lệnh hoặc khối

lệnh 2 và kết thúc switch. Ngƣợc lại lệnh hoặc khối lệnh 2 và câu lệnh break bị bỏ qua.

Bƣớc n: Nếu giá trị biểu thứcnguyên bằng giá trịn thì thực hiện lệnh hoặc khối

lệnh nvà kết thúc switch. Ngƣợc lại lệnh hoặc khối lệnh n và câu lệnh break bị bỏ qua

và kết thúc switch nếu không có tùy chọn default: < Lệnh hoặc khối lệnh n + 1>;

break;. Nếu có tùy chọn default: < Lệnh hoặc khối lệnh n + 1>; break; thì lệnh hoặc

khối lệnh n + 1 đƣợc thực hiện rồi kết thúc câu lệnh switch.

Ví dụ 2.13: Lập chƣơng trình nhập vào một số nguyên là tháng của năm 2015.

namespace Vidu2_13

{

class Program

{

static void Main(string[] args)

{

int thang = 8;

int songay = 0;

switch ( thang )

{

case 1:songay = 31; break;

case 2: songay = 28; break;

case 3:songay = 31; break;

case 4:songay = 30; break;

case 5:songay = 31; break;

case 6:songay = 30; break;

case 7:songay = 31; break;

case 8:songay = 31; break;

Hiển thị ra màn hình số ngày của tháng đó.

32

case 9:songay = 30; break;

case 10:songay = 31; break;

case 11: songay = 30; break;

case 12: songay = 31; break;

default:

Console.WriteLine( "Nhap ngay khong thoa man");

break;

}

if(songay >0) Console.WriteLine( "Thang {0} co {1}", thang,

songay);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.11: Kết quả chương trình ví dụ 2.13.

Trong ví dụ trên, biến songay có giá trị bằng 31 nếu biến tháng có giá trị 1, 3, 5,

7, 8, 10, hoặc 12; biến songay có giá trị bằng 30 nếu biến tháng có giá trị 4, 6, 9 hoặc

11, để tránh lặp lại việc viết câu lệnh gán giá trị cho biến songay thì chƣơng trình trên

namespace Vidu2_12

{

class Program

{

static void Main(string[] args)

{

int thang = 7 ;

int songay = 0;

switch ( thang )

{

case 1:

case 3:

case 5:

case 7:

case 8:

case 10:

case 12: songay = 31; break;

case 4:

có thể sửa lại nhƣ sau:

33

case 6:

case 9:

case 11: songay = 30; break;

case 2: songay = 28; break;

default:

Console.WriteLine( "Nhap ngay khong thoa man");

break;

}

if(songay >0) Console.WriteLine( "Thang {0} co {1}", thang,

songay);

Console.ReadLine();

}

}

Tập bài giảng Lập trình cơ bản

} 2.6. Câu lệnh lặp

2.6.1. Câu lệnh while

Cú pháp: while ()

{;}

Hoạt động: Xác định giá trị của biểu thức logic:

Nếu biểu thức có giá trị falsethì kết thúc câu lệnh while.

Nếu biểu thức có giá trị truethì thực hiện lệnh hoặc khối lệnh trong thân của

while và quay lại xác định biểu thức logic.

Cụ thể hoạt động của vòng lặp while đƣợc mô tả bằng hình sau:

Hình 2.12: Hoạt động của vòng lặp while

34

Tập bài giảng Lập trình cơ bản

Nhƣ vậy các câu lệnh ở trong thân vòng while có thể đƣợc thực hiện 0, 1, hoặc

nhiều lần.

Ví dụ 2.14: Lập trình tính và hiển thị ƣớc chung lớn nhất của hai số nguyên

namespace Vidu2_14

{

class Program

{

static void Main(string[] args)

{ int m,n;

Console.Write("Nhap m = ");

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

Console.Write("Nhap n = ");

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

while (m != n)

{

if (m > n) m = m - n;

else n = n - m;

}

Console.WriteLine("UCLN = {0}", m);

Console.ReadLine();

}

}

}

dƣơng m, n. Với m, n là hai số nguyên dƣơng nhập từ bàn phím.

Kết quả chƣơng trình:

Hình 2.13: Kết quả chương trình ví dụ 2.14.

{;}

2.6.2. Câu lệnh do...while Cú pháp: do while ();

Hoạt động: Bƣớc 1: Thực hiện lệnh hoặc khối lệnh trong thân vòng lặp.

Bƣớc 2: Thực hiện tính giá trị biểu thức logic:

Nếu biểu thức có giá trị true thì quay lại bƣớc 1. Nếu biểu thức có giá trị false thì kết thúc vòng lặp do…while.

35

Tập bài giảng Lập trình cơ bản

Cụ thể hoạt động của vòng lặp do…while đƣợc mô tả qua hình sau.

Hình 2.14: Hoạt động của vòng lặp do … while.

namespace Vidu2_15

{

class Program

{

static void Main(string[] args)

{ int m, n;

char tl ='\0';

do

{

Console.Write("Nhap m = ");

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

Console.Write("Nhap n = ");

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

while (m != n)

{

if (m > n) m = m - n;

else n = n - m;

}

Console.WriteLine("UCLN = {0}", m);

Console.Write("Ban co muon chay chuong trinh nua khong? C/K");

tl = char.Parse(Console.ReadLine());

} while (tl != 'k' && tl != 'K');

}

}

}

Ví dụ 2.15: Lập chƣơng trình chạy chƣơng trình tìm UCLN nhiều lần.

36

Tập bài giảng Lập trình cơ bản

Hình 2.15: Kết quả chương trình ví dụ 2.15.

2.6.3. Câu lệnh for

Cú pháp: for (; ; )

{;}

Hoạt động:

- Bƣớc 1: Thực hiện biểu thức gán - Bƣớc 2: Thực hiện biểu thức logic

 Nếu biểu thức logiccó giá trị false thì kết thúc câu lệnh for.  Nếu biểu thức logic có giá trị true thìthực hiện các câu lệnh trong

thân for.

- Bƣớc 3: Thực hiệnbƣớc nhảy và quay lại bƣớc 2. Cụ thể hoạt động của câu lệnh for đƣợc mô tả trong hình sau:

Hình 2.16: Hoạt động của vòng lặp for.

Ví dụ 2.16: Lập chƣơng trình tính tổng S = 1 + 1/2 + ... + 1/n. Với n là số

namespace Vidu2_16

{

class Program

nguyên dƣơng nhập từ bàn phím.

37

{

static void Main(string[] args)

{

int n;

Console.Write("Nhap n = ");

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

float t = 0;

for (int i = 1; i <= n; i++)

t = t + 1.0f / i;

Console.WriteLine("Gia tri cua tong = "+t.ToString());

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.17: Kết quả chương trình ví dụ 2.16

Lƣu ý là biến i đƣợc khai báo bên trong vòng lặp for chỉ có phạm vi hoạt động

bên trong vòng lặp. Ví dụ 2.17 sau sẽ xuất hiện một lỗi khi thực hiện in ra giá trị của

biến i.

namespace Vidu2_17

{

class Program

{

static void Main(string[] args)

{

for (int i = 0; i < 30; i++)

{

if (i %10 ==0)

{

Console.WriteLine("{0} ",i);

}

else

{

Console.Write("{0} ",i);

}

}

Console.WriteLine(" Ket qua cuoi cung cua i:{0}",i);

Ví dụ 2.17: Phạm vi của biến khai báo trong vòng lặp.

38

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

2.7. Câu lệnh nhảy

2.7.1. Câu lệnh break và continue Câu lệnh break và continue thƣờng đƣợc dùng trong thân các câu lệnh lặp for,

while, do ... while. Câu lệnh break dùng để thoát khỏi vòng lặp trong cùng chứa câu

lệnh này. Câu lệnh continue dùng để quay ngƣợc lại về đầu vòng lặp để thực hiện lần

lặp tiếp theo.

Ví dụ 2.18:Lập trình nhập vào một dãy số dƣơng, quá trình nhập kết thúc khi

namespace Vidu2_18

{

class Program

{

static void Main(string[] args)

{

float x, s;

s = 0;

while (true)

{

Console.Write("Nhap x =");

x = float.Parse(Console.ReadLine());

if (x < 0) continue;

if (x > 0) s += x;

else break;

}

Console.WriteLine("Tong cac so vua nhap = "+s.ToString());

Console.ReadLine();

}

}

}

nhập vào số 0. Đƣa ra màn hình tổng các số dƣơng đã nhập vào.

Kết quả chƣơng trình:

Hình 2.18: Kết quả chương trình ví dụ 2.18.

39

Tập bài giảng Lập trình cơ bản

2.7.2. Câu lệnh goto Câu lệnh goto đƣợc sử dụng để chuyển điều khiển tới một nhãn trong chƣơng

trình và có thể đƣợc dùng để thoát khỏi một vòng lặp lồng nhau. Mỗi nhãn đƣợc đặt

tên nhƣ tên biến và kết thúc bằng dấu hai chấm ―:‖. Nhãn có thể đƣợc gán cho bất kỳ câu lệnh nào trong chƣơng trình. Tuy nhiên, câu lệnh goto làm phá vỡ tính cấu trúc

của chƣơng trình, khuyến cáo là nên tránh sử dụng.

Ví dụ: ts: s=s++;

thì ở đây ts là nhãn của câu lệnh gán s=s++.

Câu lệnh goto có dạng:

goto nhãn;

Khi gặp câu lệnh này, chuyển điều khiển tới câu lệnh có nhãn viết sau từ khoá

goto.

namespace Vidu2_19

{

class Program

{

static void Main(string[] args)

{

int i = 0;

for (int a = 0; a < 10; a++) // Vòng lặp thứ nhất

{

for (int y = 0; y < 10; y++) // Vòng lặp thứ 2

{

for (int x = 0; x < 10; x++) // Vòng lặp thứ 3

{

if (x == 5 &&y == 5)

{

goto Nhan;

}

}

i++;

}

Nhan:continue;

}

Console.WriteLine("Gia tri i = {0}", i);

Console.ReadLine();

}

}

}

Ví dụ 2.19: Sử dụng câu lệnh goto để thoát khỏi vòng lặp lồng nhau.

Kết quả chƣơng trình

40

Tập bài giảng Lập trình cơ bản

Hình 2.19: Kết quả chương trình 2.19

2.7.3. Câu lệnh return Lệnh return đƣợc sử dụng để thoát khỏi phƣơng thức của một lớp, chuyển điều

khiển về ngay sau nơi gọi phƣơng thức. Tùy theo kiểu dữ liệu trả về của phƣơng thức

là void hoặc có một kiểu dữ liệu cụ thể, lệnh return phải tƣơng ứng không trả về kiểu

dữ liệu gì, hoặc là trả về một giá trị có kiểu dữ liệu thích hợp.

2.8. Xử lý ngoại lệ Ngôn ngữ C# cũng giống nhƣ các ngôn ngữ hƣớng đối tƣợng khác, cho phép xử

lý những lỗi và những ngoại lệ. Ngoại lệ là một đối tƣợng đóng gói những thông tin về

sự cố của một chƣơng trình không bình thƣờng.Một điều quan trọng là cần phân biệt

giữa bug, lỗi và ngoại lệ. Một bug là một lỗi lập trìnhcó thể đƣợc sửa chữa trƣớc khi mã nguồn đƣợc thực thi. Một lỗi có nguyên nhân do hành động của ngƣời sử dụng. Ví

dụ, chƣơng trình yêu cầu nhập vào một số nhƣng lại nhập vào ký tự chữ cái. Trong

trƣờng hợp nhƣ vậy, lỗi có thể làm xuất hiện ngoại lệ, nhƣng có thể ngăn ngừa điều

này bằng cách bắt giữ lỗi nhờ kiểm tra điều kiện. Thậm chí nếu xóa tất cả những bug

và dự đoán tất cả các lỗi của ngƣời dùng, cũng có thể gặp phải những vấn đề không

mong đợi, nhƣ là xuất hiện trạng thái thiếu bộ nhớ (out of memory), thiếu tài nguyên

hệ thống, ... những nguyên nhân này có thể do các chƣơng trành khác cùng hoạt động

ảnh hƣởng đến. Tuy không thể ngăn ngừa các ngoại lệ này, nhƣng có thể xử lý chúng

để chúng không thể làm ảnh hƣởng đến chƣơng trình.

Khi một chƣơng trình gặp một tình huống ngoại lệ, nhƣ là thiếu bộ nhớ thì nó

sẽ tạo một ngoại lệ. Khi một ngoại lệ đƣợc tạo ra, việc thực thi của các chức năng hiện

hành sẽ bị treo cho đến khi nào việc xử lý ngoại lệ tƣơng ứng đƣợc tìm thấy. Nếu không thực hiện việc xử lý ngoại lệ, ngoại lệ sẽ đƣợc xử lý sớm bởi CLR, điều này dẫn đến chƣơng trình sẽ kết thúc. Xử lý ngoại lệ trong C# đƣợc xây dựng dựa trên 4 từ khóa là: try, catch, finally và throw.

-

try: Một khối try nhận diện một khối code mà ở đó các exception cụ thể đƣợc kích hoạt. Nó đƣợc theo sau bởi một hoặc nhiều khối catch.

- catch: Một chƣơng trình bắt một Exception với một Exception Handler tại vị trí trong một chƣơng trình nơi muốn xử lý vấn đề đó. Từ khóa catch trong C# chỉ

dẫn việc bắt một exception.

41

Tập bài giảng Lập trình cơ bản

- finally: Một khối finally đƣợc sử dụng để thực thi một tập hợp lệnh đã cho, có

hay không một exception đƣơc ném hoặc không đƣợc ném. Ví dụ, nếu mở một

file, nó phải đƣợc đóng, nếu không sẽ có một exception đƣợc tạo ra.

-

throw: Một chƣơng trình ném một exception khi có một vấn đề xuất hiện. Điều này đƣợc thực hiện bởi sử dụng từ khóa throw trong C#.

Cú pháp để sử dụng try/catch trong C# nhƣ sau:

try

{

// Câu lệnh có thể phát sinh ra ngoại lệ

}

catch( ExceptionName e1 )

{

// Xử lý ngoại lệ 1

}

catch( ExceptionName e2 )

{

// Xử lý ngoại lệ 2

}

catch( ExceptionName eN )

{

// Xử lý ngoại lệ N

}

finally

{ // Các câu lệnh sẽ được thực thi

}

Có thể liệt kê nhiều lệnh catch để bắt các kiểu exception khác nhau trong

trƣờng hợp khối try xuất hiện nhiều hơn một exception trong các tình huống khác nhau.

namespace Vidu2_20

{

class Program

{

static void Main(string[] args)

{

Ví dụ 2.20: Lập chƣơng trìnhxuất hiện một exception khi chia một số cho số 0.

42

int so1, so2;

so1 = 10;

so2 = 0;

int ketqua;

ketqua = 0;

try

{

ketqua = so1 / so2;

}

catch (DivideByZeroException e)

{

Console.WriteLine("Exception caught: {0}", e);

}

finally

{

Console.WriteLine("Ketqua: {0}", ketqua);

}

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.20: Kết quả chương trình ví dụ 2.20

Ở trong ví dụ 2.20, chƣơng trình thực hiện một phép chia một số cho 0, do vậy

sẽ phát sinh ngoại lệ, ở đây là ngoại lệ của lớp DivideByZeroException và sẽ xuất hiện

thông báo lỗi nhƣ trong hình 2.20. Trong chƣơng trình có sử dùng câu lệnh finally, nên

sau khi xuất hiện lỗi sẽ thực hiện in ra giá trị của biến ketqua với giá trị ban đầu bằng

4. Nếu thay giá trị biến so2 bằng 2 thì ngoại lệ sẽ không xuất hiện và sẽ in ra giá trị

của biến ketqua bằng 5 (do ketqua = so1/so2).

Lớp Exception trong C# Các Exception trong C# đƣợc biểu diễn bởi các lớp. Các lớp Exception trong C# chủ yếu đƣợc kế thừa một cách trực tiếp hoặc không trực tiếp từ lớp System.Exception. Một số lớp Exception kế thừa từ lớp System.Exception là các lớp System.ApplicationException và System.SystemException.

Lớp System.ApplicationException hỗ trợ các exception đƣợc tạo bởi các

chƣơng trình ứng dụng. Vì thế, các exception đƣợc định nghĩa bởi lập trình viên nên

kế thừa từ lớp này.

43

Tập bài giảng Lập trình cơ bản

Lớp System.SystemException là lớp cơ sở cho tất cả system exception đã đƣợc

định nghĩa. Bảng sau cung cấp một số lớp Exception đƣợc kế thừa từ lớp

Sytem.SystemException trong C#:

Lớp Exception Miêu tả

System.IO.IOException Xử lý các ngoại lệ I/O

System.IndexOutOfRangeException Xử lý các ngoại lệ đƣợc tạo ra khi tham

chiếu tới phân từ có một chỉ mục bên ngoài

mảng

System.ArrayTypeMismatchException Xử lý ngoại lệ đƣợc tạo khi kiểu là không

phù hợp với kiểu mảng

System.NullReferenceException Xử lý các ngoại lệ đƣợc tạo từ việc tham

chiếu một đối tƣợng null

System.DivideByZeroException Xử lý ngoại lệ đƣợc tạo khi chia cho số 0

System.InvalidCastException Xử lý ngoại lệ đƣợc tạo trong khi ép kiểu

System.OutOfMemoryException Xử lý ngoại lệ đƣợc tạo từ việc thiếu bộ nhớ

System.StackOverflowException

Xử lý ngoại lệ đƣợc tạo từ việc tràn ngăn xếp (stack)

Bảng 2.10: Một số lớp ngoại lệ

Tạo User-Defined Exception trong C# Có thể tự định nghĩa một exception để xử lý cho một ngoại lệ nào đó. Các lớp

User-Defined Exception đƣợc kế thừa từ lớp ApplicationException trong C#. Ví dụ

2.21 sau minh họa điều này:

namespace Vidu2_21

{

class Program

{

static void Main(string[] args)

{

Nhietdo nhietdo = new Nhietdo();

try

{

nhietdo.hienthinhietdo();

}

catch (Ngoailekhongdo e)

{

Console.WriteLine("Ngoailekhongdo: {0}", e.Message);

}

Console.ReadKey();

Ví dụ 2.21: Tự định nghĩa exception.

44

}

}

public class Ngoailekhongdo : ApplicationException

{

public Ngoailekhongdo(string message)

: base(message)

{

}

}

public class Nhietdo

{

int nhietdo = 0;

public void hienthinhietdo()

{

if (nhietdo == 0)

{

throw (new Ngoailekhongdo("Nhiet do la khong do"));

}

else

{

Console.WriteLine("Nhietdo: {0}", nhietdo);

}

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.21: Kết quả chương trình ví dụ 2.21

Bài tập

Bài 2.1 Lập chƣơng trình thực hiện các công việc sau: 1. Nhập số thực x từ bàn phím. Nếu dữ liệu nhập vào không đúng, chƣơng trình

yêu cầu nhập lại.

2. Tính giá trị hàm số sau rồi in kết quả ra màn hình:

𝑓 𝑥 = 𝑥 + 1 𝑛ế𝑢 𝑥 ≥ −1 𝑥 + 𝑠𝑖𝑛𝑥 𝑛ế𝑢 𝑥 < −1

Hƣớng dẫn thực hiện:

45

Tập bài giảng Lập trình cơ bản

- Bƣớc 1: Tạo ứng dụng Console đặt tên là Bai2_1. - Bƣớc 2: Trong phƣơng thức Main() thêm đoạn mã lệnh thực hiện việc kiểm tra

Boolean kt;

float x;

do

{

Console.Write("Nhap x = ");

kt = float.TryParse(Console.ReadLine(), out x);

if (!kt) Console.WriteLine("Hay nhap so!");

} while (!kt); - Bƣớc 3: Viết mã lệnh tính giá trị hàm số và in kết quả

if (x <= -1) f = x + (float)Math.Sin(x);//Sử dụng lớp Math

else f = (float)Math.Sqrt(x+1);

Console.WriteLine(" f({0}) = {1}", x, f);

Console.ReadLine(); Kết quả chƣơng trình:

nhập x đúng theo yêu cầu.

Hình 2.22: Kết quả chương trình bài 2.1.

Bài 2.2 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập số thực x từ bàn phím. Nếu dữ liệu nhập vào không đúng, chƣơng trình

yêu cầu nhập lại.

2. Tính giá trị hàm số sau rồi in kết quả ra màn hình:

𝐹 𝑥 =

2𝑥2 + 3 𝑛ế𝑢 𝑥 ≤ 1 2𝑐𝑜𝑠𝑥 − 𝑒𝑥 𝑛ế𝑢 1 < 𝑥 < 2 5𝑥 + 1 𝑛ế𝑢 𝑥 ≥ 2

if (x <= 1) f = 2*x*x + 3;

else if (x < 2) f = 2*(float)Math.Cos(x) - (float)Math.Exp(x);

else f = 5*x+1;

Console.WriteLine(" f({0}) = {1}", x, f);

Console.ReadLine();

Gợi ý: Viết mã lệnh tính giá trị hàm số và in kết quả

Bài 2.3

46

Tập bài giảng Lập trình cơ bản

Lập chƣơng trình thực hiện các công việc sau:

1. Nhập số thực x từ bàn phím. Nếu dữ liệu nhập vào không đúng, chƣơng trình

yêu cầu nhập lại.

2. Tính giá trị hàm số sau rồi in kết quả ra màn hình:

𝑓 𝑥 =

2𝑥2 + 1 𝑛ế𝑢 𝑥 < 1 5 − 𝑒𝑥 𝑛ế𝑢 𝑥 > 1 4 𝑛ế𝑢 𝑥 = 1

Bài 2.4 Lập chƣơng trình thực hiện các công việc sau: 1. Nhập số thực x từ bàn phím. Nếu dữ liệu nhập vào không đúng, chƣơng trình

yêu cầu nhập lại.

2. Tính giá trị hàm số sau rồi in kết quả ra màn hình:

𝑓 𝑥 = 𝑥 − 2 𝑛ế𝑢 𝑥 ≥ 2 2 + 𝑒𝑥 𝑛ế𝑢 𝑥 < 2

Bài 2.5 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập số nguyên dƣơng n từ bàn phím. Nếu dữ liệu nhập vào không đúng,

chƣơng trình yêu cầu nhập lại.

2. Tính giá trị biểu thức sau rồi in kết quả ra màn hình:

𝑆 = 1 + + + ⋯ + 1 2 1 3 1 𝑛

Hƣớng dẫn thực hiện: - Bƣớc 1: Tạo ứng dụng Console đặt tên là Bai2_5. - Bƣớc 2: Trong phƣơng thức Main() thêm đoạn mã lệnh thực hiện việc kiểm tra

Boolean kt;

float S; int n;

do

{

Console.Write("Nhap n = ");

kt = int.TryParse(Console.ReadLine(), out n);

if (!kt||n<=0) Console.WriteLine("Hay nhap so nguyen duong!");

} while (!kt||n<=0); - Bƣớc 3: Viết mã lệnh tính tổng và in kết quả:

S = 0;//Khởi tạo tổng ban đầu = 0

for (int i = 1; i <= n; i++)

S += (float)1 / i;

Console.WriteLine("Tong S = {0}", S);

nhập n đúng theo yêu cầu.

47

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 2.23: Kết quả chương trình bài 2.5

Bài 2.6 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập số nguyên dƣơng n từ bàn phím. Nếu dữ liệu nhập vào không đúng,

chƣơng trình yêu cầu nhập lại.

2. Tính giá trị biểu thức sau rồi in kết quả ra màn hình:

𝑆 = 1 + + + ⋯ + 1 2! 1 3! 1 𝑛 !

float S = 0, M=1;

for (int i = 1; i <= n; i++)

{

M *= i;

S += (float)1 / M;

}

Console.WriteLine("Tong S = {0}", S);

Console.ReadLine();

Gợi ý: Mã lệnh tính tổng:

Bài 2.7 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập số nguyên dƣơng n và số thực x từ bàn phím. Nếu dữ liệu nhập vào

không đúng, chƣơng trình yêu cầu nhập lại.

2. Tính giá trị biểu thức sau rồi in kết quả ra màn hình:

S = 1- x + x2 + …+ (-1)n xn

Bài 2.8 Lập chƣơng trình thực hiện các công việc sau: 1. Nhập số nguyên dƣơng n từ bàn phím. Nếu dữ liệu nhập vào không đúng,

chƣơng trình yêu cầu nhập lại.

2. Tính giá trị biểu thức sau rồi in kết quả ra màn hình:

S= 1- 2 + 4 – 6 +…+(-1)n 2n

Bài 2.9

48

Tập bài giảng Lập trình cơ bản

Lập chƣơng trình thực hiện các công việc sau:

1. Nhập hai số nguyên dƣơng m, n từ bàn phím. Nếu dữ liệu nhập vào không

đúng, chƣơng trình yêu cầu nhập lại.

2. Hiển thị ƣớc chung lớn nhất và bội số chung lớn nhất của hai số m và n. 3. Tính tổng các chữ số của n.

Gợi ý

int du;

do

{

du = n % m;

n = m;

m = du;

} while (du != 0);

Console.WriteLine(‚UCLN {0}‛,n); - Mã lệnh tính tổng các chữ số của n

int tong = 0;

while(n!=0)

{

du = n % 10;

n = n/10;

tong+=du;

}

Console.WriteLine(‚Tong cac chu so {0}‛,n);

- Mã lệnh tìm ƣớc chung lớn nhất của hai số m, n

Bài 2.10 Lập chƣơng trình thực hiện in các số từ 0 đến 99 ra màn hình theo cách sau:

0 1 2 3 4 5 6 7 8 9

10 11 12 13 14 15 16 17 18 19

20 21 22 23 24 25 26 27 28 29

.................

90 91 92 93 94 95 96 97 98 99

Bài 2.11 Lập chƣơng trình thực hiện nhập số nguyên dƣơng n và in ra màn hình giá trị

biểu thức:

Bài 2.12 Lập chƣơng trình thực hiện nhập số nguyên dƣơng n và thực hiện các công

việc sau:

49

Tập bài giảng Lập trình cơ bản

- -

In ra màn hình những số nguyên tố nhỏ hơn n. In ra màn hình những số hoàn hảo nhỏ hơn n.( số hoàn hảo là số bằng tổng các ƣớc số của nó mà không kể chính nó)

CHƢƠNG 3: MỘT SỐ CẤU TRÚC DỮ LIỆU

3.1. Mảng Mảng là một tập hợp có thứ tự của những đối tƣợng, tất cả các đối tƣợng này có

cùng một kiểu dữ liệu. 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, do đó

mảng sẽ có các phƣơng thức và thuộc tính.

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 lớp System.Array.

Một số các thuộc tính và phƣơng thức của lớp System.Array

Phƣơng thức

Mô tả

BinarySearch

Phƣơng thức tĩnh tìm kiếm một mảng một chiều đã sắp thứ tự.

Clear

Phƣơng thức tĩnh thiết lập các thành phần của mảng về 0 hay null.

Copy

Phƣơng thức tĩnh đã nạp chồng thực hiện sao chép một vùng của mảng vào mảng khác.

CreateInstance Phƣơng thức tĩnh đã nạp chồng tạo một thể hiện

mới cho mảng

50

Tập bài giảng Lập trình cơ bản

IndexOf Phƣơng thức tĩnh thực hiện tìm kiếm phần tử nào đó

có trong mảng hay không và trả về chỉ mục của

phần tử đầu tiên bằng với phần tử đó nếu tìm thấy

LastIndexOf

Phƣơng thức tĩnh thực hiện tìm kiếm phần tử nào đó có trong mảng hay không và trả về chỉ mục của

phần tử cuối cùng bằng với phần tử đó nếu tìm thấy

Reverse Phƣơng thức tĩnh đảo thứ tự của các phần tử trong

mảng một chiều

Sort Phƣơng thức tĩnh sắp xếp các phần tử trong mảng

một chiều

IsFixedSize Thuộc tính thể hiện mảng có kích thƣớc cố định hay

không.

IsReadOnly Thuộc tính thể hiện mảng chỉ đọc hay không

Length Thuộc tính xác định chiều dài của mảng

Rank Thuộc tính xác định số chiều của mảng

GetLength Phƣơng thức trả về kích thƣớc của một chiều cố

định trong mảng

GetLowerBound Phƣơng thức trả về cận dƣới của chiều xác định

trong mảng

GetUpperBound Phƣơng thức trả về cận trên của chiều xác định

trong mảng

Bảng 3.1: Các phương thức và thuộc tính của System.Array.

3.1.1. Mảng một chiều Mảng một chiều là dãy hữu hạn các phần tử có cùng kiểu dữ liệu. Các phần tử

trong mảng có cùng chung một tên và phân biệt nhau bởi một chỉ số.

Khai báo mảng Khai báo mảng một chiều trong C# với cú pháp sau:

[]

Ví dụ có khai báo nhƣ sau: int[] mang_a;

Kiểu dữ liệu là kiểu của các thành phần bên trong mảng. Trong ví dụ bên

trênmang_ađƣợc khai báo là mảng số nguyên.

Ngoài ra có thể tạo thể hiện của mảng bằng cách sử dụng từ khóa new nhƣ sau:

51

Tập bài giảng Lập trình cơ bản

mang_a = new int[6];

Khai báo này sẽ thiết lập bên trong bộ nhớ một mảng chứa sáu số nguyên. Đối

tƣợng mang_alà một mảng, thành phần của mảng là sáu số nguyên. Mảng trong ngôn

ngữ C# là kiểu dữ liệu tham chiếu, đƣợc tạo ra trên heap.

Giá trị mặc định Khi tạo một mảng có kiểu dữ liệu giá trị, mỗi thành phần sẽ chứa giá trị mặc

định của kiểu dữ liệu. Với khai báo: mang_a = new int[5];

sẽ tạo ra một mảng năm số nguyên và mỗi thành phần đƣợc thiết lập giá trị mặc định là

0, đây cũng là giá trị mặc định của số nguyên.

Không giống với mảng kiểu dữ liệu giá trị, những kiểu tham chiếu trong một mảng không đƣợc khởi tạo giá trị mặc định. Thay vào đó, chúng sẽ đƣợc khởi tạo giá

trị null. Nếu cố truy cập đến một thành phần trong mảng kiểu dữ liệu tham chiếu trƣớc

khi chúng đƣợc khởi tạo giá trị xác định, sẽ sinh ra một ngoại lệ.

Giả sử khai báo một mảng các đối tƣợng Button với cú pháp sau:

Button[] mangNut;

và tạo thể hiện của mảng nhƣ sau:

mangNut = new Button[3];

Không giống với ví dụ mảng số nguyên trƣớc, câu lệnh này không tạo ra một

mảng với những tham chiếu đến ba đối tƣợng Button. Thay vào đó việc này sẽ tạo ra

một mảng mangNut với ba tham chiếu null. Để sử dụng mảng này, đầu tiên phải tạo và

gán đối tƣợng Button cho từng thành phần tham chiếu trong mảng.

Truy cập các thành phần trong mảng Để truy cập vào thành phần trong mảng có thể sử dụng toán tử chỉ mục ([]).

Trong mảng, chỉ mục của thành phần đầu tiên luôn luôn là 0. Nhƣ ví dụ trƣớc thành phần đầu tiên là mang_a[0].

Mảng là đối tƣợng và do đó nó có những thuộc tính. Một trong những thuộc

tính hay sử dụng là Length, thuộc tính này cho biết số phần tử có trong một mảng. Một

mảng đƣợc đánh chỉ mục từ 0 đến Length –1. Do đó nếu có năm thành phần trong mảng thì các chỉ mục là: 0, 1, 2, 3, 4.

Ví dụ 3.1: Lập chƣơng trình thực hiện các công việc sau: - Nhập một dãy số gồm n số nguyên từ bàn phím (n là một số nguyên dƣơng

nhập từ bàn phím);

- Hiển thị lại dãy số vừa nhập; - Tính và hiển thị tổng các số có trong dãy; - Tính và hiển thị số lớn nhất có trong dãy;

52

Tập bài giảng Lập trình cơ bản

namespace Vidu3_1{

class Program

{

static void Main(string[] args)

{

int[] a;

int n;

bool kt;

do

{

Console.Write("Nhap kich thuoc mang n = ");

kt = int.TryParse(Console.ReadLine(), out n);

if (!kt || n <= 0) Console.WriteLine("Nhap n nguyen duong!");

}

while (!kt || n <= 0);

a = new int[n];

// Nhập mảng

Console.WriteLine("Nhap gia tri cac phan tu trong mang:");

for (int i = 0; i < n; i++)

{

Console.Write("a[{0}] = ", i);

a[i] = int.Parse(Console.ReadLine());

}

//Hiển thị mảng

Console.Write("Day so: ");

for (int i = 0; i < a.Length; i++)

{

Console.Write("{0} ", a[i]);

}

Console.WriteLine();

//Tìm số nhỏ nhất

int min = a[0];

for (int i = 1; i < a.Length; i++)

if (a[i] < min) min = a[i];

Console.WriteLine("So nho nhat {0}", min);

/*

* Có thể tìm min bằng cách sử dụng phương thức Min

* min = a.Min();

*/

//Tinh tổng các số

int td = 0;

for (int i = 0; i < a.Length; i++)

if (a[i] > 0) td += a[i];

Console.WriteLine("Tong cac so trong day {0}", td);

//Sắp xếp dãy tăng dần

- Sắp xếp và hiển thị dãy số theo chiều tăng dần;

53

Array.Sort(a);//Sử dụng phương thức Sort của lớp Array

//Hiển thị mảng

Console.Write("Day so sau khi sap xep: ");

for (int i = 0; i < a.Length; i++)

{

Console.Write("{0} ", a[i]);

}

Console.WriteLine();

Console.ReadLine();

} }

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.1: Kết quả chương trình ví dụ 3.1.

Khởi tạo thành phần của mảng Khởi tạo một mảng ngay lúc tạo thể hiện của mảng bằng cách đặt những giá trị

bên trong dấu ngoặc ({}). C# cung cấp hai cú pháp để khởi tạo các thành phần của

mảng, một cú pháp dài và một cú pháp ngắn:

int[] mang_a= new int[5] { 2, 4, 6, 8, 10};

int[] mang_a= { 2, 4, 6, 8, 10};

Câu lệnh lặp foreach Câu lệnh lặp foreach khá mới với những ngƣời đã học ngôn ngữ C, từ khóa này

đƣợc sử dụng trong ngôn ngữ Visual Basic. Câu lệnh foreach cho phép duyệt qua tất

cả các phần tử 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:

foreach ( in ) {

// thực hiện thông qua tương ứng với // từng mục trong mảng hay tập hợp

}

Do vậy, có thể cải tiến ví dụ 3.1 trƣớc bằng cách thay việc sử dụng vòng lặp for

bằng vòng lặp foreach để truy cập đến từng thành phần trong mảng.

Ví dụ 3.2: Sử dụng foreach

54

namespace Vidu3_2

{

class Program

{

static void Main(string[] args)

{

int[] a;

int n;

bool kt;

do

{

Console.Write("Nhap kich thuoc mang n = ");

kt = int.TryParse(Console.ReadLine(), out n);

if (!kt || n <= 0) Console.WriteLine("Nhap n nguyen duong!");

}

while (!kt || n <= 0);

a = new int[n];

// Nhập mảng

Console.WriteLine("Nhap gia tri cac phan tu trong mang:");

for (int i = 0; i < n; i++)

{

Console.Write("a[{0}] = ", i);

a[i] = int.Parse(Console.ReadLine());

}

//Hiển thị mảng

Console.Write("Day so: ");

foreach(int pt in a)

{

Console.Write("{0} ", pt);

}

Console.WriteLine();

//Tìm số nhỏ nhất

int min = a[0];

foreach (int pt in a)

if (pt < min) min = pt;

Console.WriteLine("So nho nhat {0}", min);

//Tinh tổng các số

int td = 0;

foreach (int pt in a)

td += pt;

Console.WriteLine("Tong cac so trong day {0}", td);

//Sắp xếp dãy tăng dần

Array.Sort(a);

//Hiển thị mảng

Console.Write("Day so sau khi sap xep: ");

foreach (int pt in a)

Tập bài giảng Lập trình cơ bản

55

{

Console.Write("{0} ", pt);

}

Console.WriteLine();

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.2. Kết quả chương trình ví dụ 3.2.

Sử dụng foreach, khi đó vòng lặp sẽ tự động lấy ra từng phần tử tuần tự trong

foreach (int pt in a)

{

Console.Write("{0} ", pt);

}

mảng và gán tạm vào một biến pt khai báo ở đầu vòng lặp:

3.1.2. Mảng đa chiều Ngôn ngữ C# hỗ trợ hai kiểu mảng đa chiều là:

- Mảng đa chiều cùng kích thƣớc: trong mảng này mỗi dòng trong mảng có cùng

kích thƣớc với nhau. Mảng này có thể là hai hay nhiều hơn hai chiều.

- Mảng đa chiều không cùng kích thƣớc: trong mảng này các dòng có thể không

cùng kích thƣớc với nhau.

Mảng đa chiều cùng kích thƣớc Mảng đa chiều cùng kích thƣớc còn gọi là mảng hình chữ nhật (rectanguler array). Trong mảng hai chiều cổ điển, chiều đầu tiên đƣợc tính bằng số dòng của mảng và chiều thứ hai đƣợc tính bằng số cột của mảng. Để khai báo mảng hai chiều, có thể sử dụng cú pháp theo sau:

[,]

Ví dụ để khai báo một mảng hai chiều có tên là mang2chieuđể chứa hai dòng và

ba cột các số nguyên, có thể viết nhƣ sau:

int [ , ] mang2chieu;

Ví dụ 3.3: Lập chƣơng trình thực hiện các công việc sau:

56

Tập bài giảng Lập trình cơ bản

1. Nhập và hiển thị ma trận số nguyên gồm n hàng, m cột (n, m nguyên dƣơng

nhập từ bàn phím)

2. Tìm phần tử nhỏ nhất có trong của ma trận

3. Tính trung bình cộng các số lẻ có trong ma trận 4. Tính tổng các phần tử thuộc hàng k (k là một số nguyên dƣơng nhập từ bàn

namespace Vidu3_3

{

class Program

{

static void Main(string[] args)

{

int[,] a; int n, m;

//Nhập n, m

Console.WriteLine("Nhap kich thuoc mang");

Console.Write("n = "); n = int.Parse(Console.ReadLine());

Console.Write("m = "); m = int.Parse(Console.ReadLine());

//Khởi tạo mảng 2 chiều có n hàng m cột

a = new int[n, m];

int i, j;

//Nhập các phần tử trong ma trận

for (i = 0; i < n; i++)

for (j = 0; j < m; j++)

{

Console.Write("a[{0},{1}] = ", i, j);

a[i, j] = int.Parse(Console.ReadLine());

}

//Hiển thị ma trận vừa nhập

Console.WriteLine("Ma tran vua nhap:");

for (i = 0; i < n; i++)

{

Console.WriteLine("\n");

for (j = 0; j < m; j++)

Console.Write("{0} ", a[i, j]);

}

Console.WriteLine("\n");

//Tìm phần tử nhỏ nhất

int min = a[0,0];

for (i = 0; i < n; i++)

for (j = 0; j < m; j++)

if (a[i, j] < min) min = a[i, j];

Console.WriteLine("Phan tu nho nhat trong ma tran: {0} ",

min);

//Trung bình cộng các số lẻ có trong ma trận

phím)

57

float tbc = 0, tong = 0;

int d = 0;

for (i = 0; i < n; i++)

for (j = 0; j < m; j++)

if (a[i, j] % 2 == 0)

{

tong += a[i, j];

d++;

}

if (d == 0) tbc = tong / d;

Console.WriteLine("Trung binh cong: {0} ", tbc);

//Tổng các phần tử thuộc hàng k

int k;

Console.Write("Nhap k = ");

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

if (k < 0 || k >= n) Console.WriteLine("Nhap k khong thoa man");

else

{

int t = 0;

for (i = 0; i < m; i++)

t += a[k, i];

Console.WriteLine("Tong hang {0} = {1}", k, t);

}

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.3: Kết quả chương trình ví dụ 3.3

58

Tập bài giảng Lập trình cơ bản

Nhƣ đã biết, khởi tạo mảng một chiều bằng cách sử dụng danh sách các giá trị

bên trong dấu ngoặc ({}). Điều này tƣơng tự với mảng hai chiều. Trong đoạn mã dƣới

đây khai báo mảng hai chiều có tênmang2chieu và khởi tạo các thành phần của nó

thông qua các danh sách các giá trị trong ngoặc, sau đó in ra mảng.

// khai báo và định nghĩa mảng 4x3

int[,] mang2chieu = {

{0,1,2}, {3,4,5}, {6,7,8},{9,10,11}

};

Nếu viết nhƣ sau:

int[,] mang2chieu =

{ {0,1,2,3}, {4,5,6,7}, {8,9,10,11}

};

thì sẽ tạo ra một mảng 3x4.

Mảng đa chiều có kích khác nhau Để khai báo mảng đa chiều có kích thƣớc khác nhau sử dụng cú pháp sau, khi

đó số ngoặc chỉ ra số chiều của mảng:

[] [] ...

Ví dụ, có thể khai báo mảng số nguyên hai chiều khác kích thƣớc có tên

mang_da_chieu nhƣ sau:

int [] [] mang_da_chieu;

và để truy cập thành phần thứ năm của mảng thứ ba bằng cú pháp:

mang_da_chieu [2][4].

Ví dụ 3.4: Lập chƣơng trình tạo ra mảng khác kích thƣớc tên mang_da_chieu,

namespace Vidu3_4

{

class Program

{

static void Main(string[] args)

{

const int hang = 4;

// khai báo mảng tối đa bốn dòng

int[][] mang_da_chieu = new int[hang][];

// dòng đầu tiên có 5 phần tử

mang_da_chieu[0] = new int[5];

// dòng thứ hai có 2 phần tử

mang_da_chieu[1] = new int[2];

// dòng thứ ba có 3 phần tử

khởi tạo các thành phần, rồi sau đó in ra màn hình.

59

mang_da_chieu[2] = new int[3];

// dòng cuối cùng có 5 phần tử

mang_da_chieu[3] = new int[5];

// khởi tạo một vài giá trị cho các thành phần của mảng

mang_da_chieu[0][3] = 15;

mang_da_chieu[1][1] = 12;

mang_da_chieu[2][1] = 9;

mang_da_chieu[2][2] = 99;

mang_da_chieu[3][0] = 10;

mang_da_chieu[3][1] = 11;

mang_da_chieu[3][2] = 12;

mang_da_chieu[3][3] = 13;

mang_da_chieu[3][4] = 14;

for(int i = 0; i < 5; i++)

{

Console.WriteLine("Phantu[0][{0}]

=

{1}",i,

mang_da_chieu[0][i]);

}

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

{

Console.WriteLine("Phantu[1][{0}]

=

{1}",

i,

mang_da_chieu[1][i]);

}

for(int i = 0; i < 3; i++)

{

Console.WriteLine("Phantu[2][{0}]

=

{1}",

i,

mang_da_chieu[2][i]);

}

for(int i = 0; i < 5; i++)

{

Console.WriteLine("Phantu[3][{0}]

=

{1}",

i,

mang_da_chieu[3][i]);

}

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

60

Tập bài giảng Lập trình cơ bản

Hình 3.4: Kết quả chương trình ví dụ 3.4.

3.2. Xâu ký tự. Ngôn ngữ C# hỗ trợ khá đầy đủ các chức năng của kiểu chuỗi mà có thể thấy

đƣợc ở các ngôn ngữ lập trình cấp cao khác. Điều quan trọng hơn là ngôn ngữ C# xem những chuỗi nhƣ là những đối tƣợng và đƣợc đóng gói tất cả các thao tác, sắp xếp và

các phƣơng thức tìm kiếm thƣờng đƣợc áp dụng cho chuỗi ký tự.

Trong phần này sẽ giới thiệu kiểu dữ liệu string của ngôn ngữ C#, kiểu string

này chính là một định danh của lớp System.String của .NET Framework.

Lớp đối tƣợng String C# xem những chuỗi nhƣ là những kiểu dữ liệu cơ bản tức là các lớp này rất

linh hoạt mạnh mẽ và nhất là dễ sử dụng. Mỗi đối tƣợng chuỗi là một dãy cố định các

ký tự Unicode. Nói cách khác, các phƣơng thức đƣợc dùng để làm thay đổi một chuỗi

thực sự trả về một bản sao đã thay đổi, chuỗi nguyên thủy không thay đổi. Khi khai

báo một chuỗi trong C# bằng cách dùng từ khóa string, tức là đã khai báo một đối

tƣợng của lớp System.String, đây là một trong những kiểu dữ liệu đƣợc xây dựng sẵn

đƣợc cung cấp bởi thƣ viện lớp .NET (.NET Framework Class Library). Do đó kiểu dữ

liệu chuỗi C# là kiểu dữ liệu System.String và trong phần này dùng hai tên hoán đổi lẫn nhau.

Tạo một chuỗi Cách đơn giản để tạo một biến kiểu chuỗi là khai báo và gán một hằng chuỗi

cho nó:

string chuoi = “Day la chuoi hang”;

Một số ký tự đặc biệt có quy tắc riêng nhƣ ―\n‖, ‖\‖, ―\t‖ đại diện cho ký tự xuống dòng, dấu ―\‖ hay tab muốn thêm vào chuỗi thì phải thêm dấu ―\‖ vào trƣớc các ký tự đó. Ví dụ khai báo sau:

string duongdan = “C:\\WinNT\\Temp”;

Chuỗi cũng có thể đƣợc tạo bằng cách sử dụng chuỗi cố định hay nguyên văn,

tức là các ký tự trong chuỗi đƣợc giữ nguyên không thay đổi. Chuỗi này đƣợc bắt đầu

61

Tập bài giảng Lập trình cơ bản

với biểu tƣợng @. Trong chuỗi nguyên văn, ký tự ―\‖ và những ký tự sau nó đơn giản

là những ký tự đƣợc thêm vào chuỗi. Ví dụ hai khai báo sau là tƣơng đƣơng:

string chuoicodinh = “\\\\MyDocs\\CSharp\\ProgrammingC#.cs”;

string chuoinguyenvan = @”\\MyDocs\CSharp\ProgrammingC#.cs”;

Tạo chuỗi dùng phƣơng thức ToString của đối tƣợng Một cách rất phổ biến khác để tạo một chuỗi là gọi phƣơng thức ToString() của

một đối tƣợng và gán kết quả đến một biến chuỗi. Trong ví dụ sau, phƣơng thức ToString() của kiểu dữ liệu int đƣợc gọi để lƣu trữ giá trị của nó trong một chuỗi:

int songuyen = “9”;

string xausonguyen = songuyen.ToString();

Phƣơng thức songuyen.ToString() trả về một đối tƣợng String và đối tƣợng này

đƣợc gán cho xausonguyen.

Thao tác trên chuỗi Lớp string cung cấp rất nhiều các phƣơng thức để so sánh, tìm kiếm và thao tác

trên chuỗi, các phƣơng thức này đƣợc trình bày trong bảng 3.2:

Phƣơng thức/ Trƣờng

Ý nghĩa

Trƣờng thể hiện một chuỗi rỗng. Empty

Phƣơng thức để so sánh hai chuỗi. Compare

CompareOrdinal Phƣơng thức để so sánh hai chuỗi khôngquan tâm đến

thứ tự.

Phƣơng thức để tạo chuỗi mới từ một hay nhiều chuỗi. Concat

Phƣơng thức tạo ra một chuỗi mới bằngsao chép từ chuỗi Copy

khác

Phƣơng thức kiểm tra xem hai chuỗi có giống nhau hay Equal

không

Format

Phƣơng thức định dạng một chuỗi dùng ký tự lệnh định dạng xác định.

Indexer của chuỗi. Chars

Chiều dài của chuỗi. Length

CompareTo So sánh hai chuỗi.

62

Tập bài giảng Lập trình cơ bản

CopyTo Sao chép một số các ký tự xác định đến một mảng ký

tự Unicode.

EndsWidth Xác định xem phần cuối của một chuỗi có khớp với một

chuỗi đầu vào không

Insert Trả về chuỗi mới đã đƣợc chèn thêmmột chuỗi mới.

LastIndexOf Chỉ ra vị trí xuất hiện cuối cùng của một chuỗiđầu vào

trong chuỗi.

Xóa đi một số ký tự xác định. Remove

Trả về chuỗi đƣợc phân tách bởi những ký tự xác định Split

trong chuỗi.

StartWidth Xem chuỗi có bắt đầu bằng một chuỗi nào đó haykhông.

SubString Trả về một chuỗi con.

ToCharArray Sao chép những ký tự từ một chuỗi đến mảng ký tự.

Trả về bản sao của chuỗi ở kiểu chữ thƣờng. ToLower

Trả về bản sao của chuỗi ở kiểu chữ hoa. ToUpper

Loại bỏ khoảng trắng hoặc tập từ ký nào đó ở đầu và cuối Trim

xâu

Loại bỏ khoảng trắng hoặc tập từ ký nào đó ở đầu xâu TrimEnd

Loại bỏ khoảng trắng hoặc tập từ ký nào đó ở cuối xâu TrimStart

Bảng 3.2: Phương thức và thuộc tính của lớp String

Trong ví dụ 3.5 sau đây minh họa việc sử dụng một số các phƣơng thức của chuỗi nhƣ Compare(), Concat() (và dùng toán tử +), Copy() (và dùng toán tử =),

Insert(), EndsWith() và IndexOf.

namespace Vidu3_5

{

class Program

{

static void Main(string[] args)

{

// khởi tạo một số chuỗi để thao tác

Ví dụ 3.5: Thao tác với chuỗi.

63

string s1 = "abcd";

string s2 = "ABCD";

string s3 = @"Khoa CNTT

Truong Dai hoc Su pham Ky thuat Nam Dinh";

int ketqua;

// So sánh hai chuỗi với nhau có phân biệt chữ thường và chữ hoa

ketqua = string.Compare( s1 ,s2);

Console.WriteLine("So sanh hai chuoi S1: {0} và S2: {1} ket qua:

{2} \n",s1 ,s2 ,ketqua);

// Sử dụng tiếp phương thức Compare() nhưng trường hợp này không

biệt

// chữ thường hay chữ hoa

// Tham số thứ ba là true sẽ bỏ qua kiểm tra ký tự thường – hoa

ketqua = string. Compare(s1, s2, true);

Console.WriteLine("Khong phan biet chu thuong va hoa\n");

Console.WriteLine("S1: {0} , S2: {1}, ket qua : {2}\n", s1, s2,

ketqua);

// phương thức nối các chuỗi

string s4 = string.Concat(s1, s2);

Console.WriteLine("Chuoi S4 noi tu chuoi S1 va S2: {0}", s4);

// sử dụng nạp chồng toán tử +

string s5 = s1 + s2;

Console.WriteLine("Chuoi S5 duoc noi tu chuoi S1 va S2: {0}", s5);

// Sử dụng phương thức copy chuỗi

string s6 = string.Copy(s5);

Console.WriteLine("S6 duoc sao chep tu S5: {0}", s6);

// Sử dụng nạp chồng toán tử =

string s7 = s6;

Console.WriteLine("S7 = S6: {0}", s7);

// Sử dụng ba cách so sánh hai chuỗi

// Cách 1 sử dụng một chuỗi để so sánh với chuỗi còn lại

Console.WriteLine("S6.Equals(S7) ?: {0}", s6.Equals(s7));

// Cách 2 dùng hàm của lớp string so sánh hai chuỗi

Console.WriteLine("Equals(S6, s7) ?: {0}", string.Equals(s6, s7));

// Cách 3 dùng toán tử so sánh

Console.WriteLine("S6 == S7 ?: {0}", s6 == s7);

// Sử dụng hai thuộc tính hay dùng là chỉ mục và chiều dài của

chuỗi

Console.WriteLine("\nChuoi S7 co chieu dai la : {0}", s7.Length);

Console.WriteLine("Ky tu thu 3 cua chuoi S7 la : {0}", s7[2] );

// Kiểm tra xem một chuỗi có kết thúc với một nhóm ký

// tự xác định hay không

Console.WriteLine("S3: {0}\n ket thuc voi chu CNTT ? : {1}\n",

s3, s3.EndsWith("CNTT"));

Console.WriteLine("S3: {0}\n ket thuc voi chu Dinh ? : {1}\n",

s3, s3.EndsWith("Dinh"));

Tập bài giảng Lập trình cơ bản

64

// Trả về chỉ mục của một chuỗi con

Console.WriteLine("\nTim vi tri xuat hien dau tien cua chu CNTT ");

Console.WriteLine("trong chuoi S3 là {0}\n", s3.IndexOf("CNTT"));

// Chèn từ nhân lực vào trước CNTT trong chuỗi S3

string s8 = s3.Insert(18, "nhan luc ");

Console.WriteLine(" S8 : {0}\n", s8);

// Ngoài ra có thể kết hợp như sau

string s9 = s3.Insert( s3.IndexOf( "CNTT" ) , "nhan luc ");

Console.WriteLine(" S9 : {0}\n", s9);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.5: Kết quả chương trình ví dụ 5

Chƣơng trình bắt đầu với ba khai báo chuỗi:

string s1 = “abcd”; string s2 = “ABCD”; string s3 = @“Khoa CNTT

Truong Dai hoc Su pham Ky thuat Nam Dinh”;

65

Tập bài giảng Lập trình cơ bản

Hai chuỗi đầu s1 và s2 đƣợc khai báo chuỗi ký tự bình thƣờng, còn chuỗi thứ ba

đƣợc khai báo là chuỗi nguyên văn (verbatim string) bằng cách sử dụng ký hiệu @

trƣớc chuỗi. Chƣơng trình bắt đầu bằng việc so sánh hai chuỗi s1và s2. Phƣơng thức

Compare() là phƣơng thức tĩnh của lớp string và phƣơng thức này đã đƣợc nạp chồng. Phiên bản đầu tiên của phƣơng thức nạp chồng này là lấy hai chuỗi và so sánh chúng

với nhau:

// So sánh hai chuỗi với nhau có phân biệt chữ thường và chữ hoa ketqua = string.Compare( s1 ,s2);

Console.WriteLine(“So sanh hai chuoi s1: {0} và s2: {1} ket qua: {2} \n”,

s1 ,s2 ,ketqua);

Ở đây việc so sánh có phân biệt chữ thƣờng và chữ hoa, phƣơng thức trả về các

giá trị khác nhau phụ thuộc vào kết quả so sánh:

- Một số âm nếu chuỗi đầu tiên nhỏ hơn chuỗi thứ hai - Giá trị 0 nếu hai chuỗi bằng nhau - Một số dƣơng nếu chuỗi thứ nhất lớn hơn chuỗi thứ hai. Trong trƣờng hợp so sánh trên thì đƣa ra kết quả là chuỗi s1 nhỏ hơn chuỗi s2.

Trong

Unicode cũng nhƣ ASCII thì thứ tự của ký tự thƣờng nhỏ hơn thứ tự của ký tự hoa:

So sanh hai chuoi S1: abcd và S2: ABCD ket qua: -1

Cách so sánh thứ hai dùng phiên bản nạp chồng Compare() lấy ba tham số.

Tham số Boolean quyết định bỏ qua hay không bỏ qua việc so sánh phân biệt chữ

thƣờng và chữ hoa. Tham số này có thể bỏ qua. Nếu giá trị của tham số là true thì việc

so sánh sẽ bỏ qua sự phân biệt chữ thƣờng và chữ hoa. Việc so sánh sau sẽ không quan

tâm đến kiểu loại chữ:

// Tham số thứ ba là true sẽ bỏ qua kiểm tra ký tự thường – hoa ketqua = string. Compare(s1, s2, true);

Console.WriteLine(“Khong phan biet chu thuong va hoa\n”);

Console.WriteLine(“S1: {0} , S2: {1}, ket qua : {2}\n”, s1, s2, ketqua);

Lúc này thì việc so sánh hoàn toàn giống nhau và kết quả trả về là giá trị 0: Khong phan biet chu thuong va hoa S1: abcd , S2: ABCD, ket qua : 0 Ví dụ 3.5 tiếp tục với việc nối các chuỗi lại với nhau. Ở đây sử dụng hai cách

để nối hai chuỗi. Thứ nhất có thể sử dụng phƣơng thức Concat()là phƣơng thức public static của string:

string s4 = string.Concat(s1, s2);

Hay cách khác đơn giản hơn là việc sử dụng toán tử nối hai chuỗi (+):

66

Tập bài giảng Lập trình cơ bản

string s5 = s1 + s2;

Trong cả hai trƣờng hợp thì kết quả nối hai chuỗi hoàn toàn thành công và nhƣ

sau:

Chuoi S4 noi tu chuoi S1 va S2: abcdABCD Chuoi S5 duoc noi tu chuoi S1 + S2: abcdABCD

Tƣơng tự nhƣ vậy, việc tạo một chuỗi mới có thể đƣợc thiết lập bằng hai cách.

Đầu tiên là có thể sử dụng phƣơng thức static Copy() nhƣ sau:

string s6 = string.Copy(s5);

Hoặc thuận tiện hơn có thể sử dụng phƣơng thức nạp chồng toán tử (=) thông

qua việc sao chép ngầm định:

string s7 = s6; Kết quả của hai cách tạo trên đều hoàn toàn nhƣ nhau:

S6 duoc sao chep tu S5: abcdABCD

S7 = S6: abcdABCD

Lớp String của .NET cung cấp ba cách để kiểm tra bằng nhau giữa hai chuỗi.

Đầu tiên là có thể sử dụng phƣơng thức nạp chồng Equals() để kiểm tra trực tiếp rằng

S6 có bằng S7 hay không:

Console.WriteLine(“S6.Equals(S7) ?: {0}”, S6.Equals(S7));

Kỹ thuật so sánh thứ hai là truyền cả hai chuỗi vào phƣơng thức Equals() của

string:

Console.WriteLine(“Equals(S6, s7) ?: {0}”, string.Equals(S6, S7));

Và phƣơng pháp cuối cùng là sử dụng nạp chồng toán tử so sánh (==) của

String:

Console.WriteLine(“S6 == S7 ?: {0}”, s6 == s7);

Trong cả ba trƣờng hợp thì kết quả trả về là một giá trị Boolean, kết quả nhƣ

sau:

S6.Equals(S7) ?: True

Equals(S6, s7) ?: True

S6 == S7 ?: True Các đoạn chƣơng trình tiếp theo của ví dụ sử dụng toán tử chỉ mục ([]) để tìm ra ký tự xác định trong một chuỗi. Và dùng thuộc tính Length để lấy về chiều dài của toàn bộ một chuỗi:

Console.WriteLine(“\nChuoi S7 co chieu dai la : {0}”, s7.Length); Console.WriteLine(“Ky tu thu 3 cua chuoi S7 la : {0}”, s7[2] ); Kết quả là:

Chuoi S7 co chieu dai la: 8

67

Tập bài giảng Lập trình cơ bản

Ky tu thu 3 cua chuoi S7 la: c

Phƣơng thức EndsWith() kiểm tra xem một chuỗi có chứa một chuỗi con ở vị

trí chuỗi hay không. Do vậy, để kiểm tra chuỗi S3 có kết thúc bằng chuỗi ―CNTT‖ hay

chuỗi ―Dinh‖:

// Kiểm tra xem một chuỗi có kết thúc với một nhóm ký tự xác định hay không

Console.WriteLine(“S3: {0}\n ket thuc voi chu CNTT ? : {1}\n”,

s3, s3.EndsWith(“CNTT”)); Console.WriteLine(“S3: {0}\n ket thuc voi chu Dinh ? : {1}\n”,

s3, s3.EndsWith(“Dinh”));

Kết quả trả về là lần kiểm tra đầu tiên là sai do chuỗi S3 không kết thúc chữ

―CNTT‖ và lần kiểm tra thứ hai là đúng:

S3: Khoa CNTT

Truong Dai hoc Su pham Ky thuat Nam Dinh

ket thuc voi chu CNTT ? : False

S3: Khoa CNTT

Truong Dai hoc Su pham Ky thuat Nam Dinh

ket thuc voi chu Dinh? : True

Phƣơng thức IndexOf() chỉ ra vị trí của một chuỗi con bên trong một chuỗi (nếu

có). Và phƣơng thức Insert() chèn một chuỗi con vào một bản sao chép của chuỗi ban

đầu. Đoạn lệnh tiếp theo của ví dụ minh họa thực hiện việc xác định vị trí xuất hiện

đầu tiên của chuỗi ―CNTT‖ trong chuỗi S3:

Console.WriteLine(“\nTim vi tri xuat hien dau tien cua chu CNTT ”);

Console.WriteLine(“trong chuoi S3 là {0}\n”, s3.IndexOf(“CNTT”));

Và kết quả tìm đƣợc là 5:

Tim vi tri xuat hien dau tien cua chu CNTT trong chuoi S3 là 5

Để chèn vào chuỗi s3 từ ―nhan luc‖ và theo sau chuỗi này là một khoảng trắng

vàotrong chuỗi ban đầu. Khi thực hiện thì phƣơng thức trả về bản sao của chuỗi đã

Truong Dai hoc Su pham Ky thuat Nam Dinh

đƣợc chènvào chuỗi con và đƣợc gán lại vào chuỗi S8: string s8 = s3.Insert(18, “nhan luc ”); Console.WriteLine(“ S8 : {0}\n”, s8); Kết quả đƣa ra là: S8: Khoa CNTT nhan luc Cuối cùng, kết hợp một số các phép toán để thực hiện việc chèn nhƣ sau:

string s9 = s3.Insert( s3.IndexOf( “CNTT” ) , “nhan luc ”);

68

Tập bài giảng Lập trình cơ bản

Console.WriteLine(“ S9 : {0}\n”, s9);

Kết quả cuối cùng cũng tƣơng tự nhƣ cách chèn bên trên:

S9: Khoa nhan luc CNTT

Truong Dai hoc Su pham Ky thuat Nam Dinh

Tìm một chuỗi con Trong kiểu dữ liệu String cung cấp phƣơng thức Substring() để trích một chuỗi

con từ chuỗi ban đầu. Có hai hàm tải bội của phƣơng thức Substring(). Trong ví dụ 3.6 minh họa việc sử dụng phƣơng thức Substring() của chuỗi.

namespace Vidu3_6

{

class Program

{

static void Main(string[] args)

{

// Khai báo các chuỗi để sử dụng

string s1 = "Mot hai ba bon";

int ix;

// lấy chỉ số của khoảng trắng cuối cùng

ix = s1.LastIndexOf(" ");

// lấy từ cuối cùng

string s2 = s1.Substring( ix+1);

// thiết lập lại chuỗi s1 từ vị trí 0 đến vị trí ix

// do đó s1 có giá trị mới là mot hai ba

s1 = s1.Substring(0, ix);

// tìm chỉ số của khoảng trắng cuối cùng (sau hai)

ix = s1.LastIndexOf(" ");

// thiết lập s3 là chuỗi con bắt đầu từ vị trí ix

// do đó s3 = "ba"

string s3 = s1.Substring(ix+1);

// thiết lập lại s1 bắt đầu từ vị trí 0 đến cuối vị trí ix

// s1 = "mot hai"

s1 = s1.Substring(0, ix);

// ix chỉ đến khoảng trắng giữa "mot" va "hai"

ix = s1.LastIndexOf(" ");

// tạo ra s4 là chuỗi con bắt đầu từ sau vị trí ix, do

// vậy có giá trị là "hai"

string s4 = s1.Substring( ix+1);

// thiết lập lại giá trị của s1

s1 = s1.Substring(0, ix);

// lấy chỉ số của khoảng trắng cuối cùng, lúc này ix là –1

ix = s1.LastIndexOf(" ");

// tạo ra chuỗi s5 bắt đầu từ chỉ số khoảng trắng, nhưng không có

khoảng

Ví dụ 3.6: Sử dụng phƣơng thức Substring().

69

// trắng và ix là –1 nên chuỗi bắt đầu từ 0

string s5 = s1.Substring(ix +1);

Console.WriteLine("s2 : {0}\n s3 : {1}", s2, s3);

Console.WriteLine("s4 : {0}\n s5 : {1}\n", s4, s5);

Console.WriteLine("s1: {0}\n", s1);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.6: Kết quả chương trình ví dụ 3.6.

Chia chuỗi Để sử dụng Split(), phải truyền vào một mảng các ký tự phân cách, các ký tự

này đƣợc dùng để chia các từ trong chuỗi. Và phƣơng thức sẽ trả về một mảng những

chuỗi con.

namespace Vidu3_7

{

class Program

{

static void Main(string[] args)

{

// tạo các chuỗi để làm việc

string s1 = "Mot, hai, ba Trung Tam Dao Tao CNTT";

// tạo ra hằng ký tự khoảng trắng và dấu phẩy

const char khoangcach = ' ';

const char dauphay = ',';

// tạo ra mảng phân cách

char[] mangphancach = new char[]

{

khoangcach,

dauphay

};

string chuoiketqua = "";

int ctr = 1;

// thực hiện việc chia một chuỗi dùng vòng lặp

// đưa kết quả vào mảng các chuỗi

Ví dụ 3.7: Sử dụng phƣơng thức Split().

70

foreach ( string chuoicon in s1.Split(mangphancach) )

{

chuoiketqua += ctr++;

chuoiketqua += ": ";

chuoiketqua += chuoicon;

chuoiketqua += "\n";

}// end foreach

Console.WriteLine(chuoiketqua);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.7: Kết quả chương trình ví dụ 3.7

Đoạn chƣơng trình bắt đầu bằng việc tạo một chuỗi để minh họa việc phân tích:

string s1 = “Mot, hai, ba Trung Tam Dao Tao CNTT”;

Hai ký tự khoảng trắng và dấu phẩy đƣợc dùng làm các ký tự phân cách. Sau đó

phƣơng thức Split() đƣợc gọi trong chuỗi này và truyền kết quả vào mỗi vòng lặp:

foreach ( string chuoicon in s1.Split(delimiters) )

Chuỗi chuoiketqua chứa các chuỗi kết quả đƣợc khởi tạo là chuỗi rỗng. Ở đây

chuỗi chuoiketquađƣợc tạo ra qua bốn bƣớc. Đầu tiên là nối giá trị của biến đếm ctr,

tiếp theo là thêm dấu hai chấm, rồi đƣa chuỗi đƣợc chia ra từ chuỗi ban đầu và cuối

cùng là thêm ký tự qua dòng mới. Và bốn bƣớc trên cứ đƣợc lặp đến khi nào chuỗi

không còn chia ra đƣợc.

3.3. Xử lý tập tin Khả năng để lƣu thông tin vào trong một tập tin hay đọc thông tin từ trong một tập tin có thể làm cho chƣơng trình có nhiều hiệu quả hơn. Phần tiếp sau sẽ tìm hiểu những đặc tính cơ bản của việc thao tác trên tập tin.

Làm việc với tập tin dữ liệu Việc thực hiện trên tập tin là đọc và viết những thông tin từ tập tin. Trong phần

này sẽ tìm hiểu về luồng nhập xuất và cách tạo mới một tập tin để ghi hay mở một tập tin đã tồn tại để đọc thông tin.

Luồng nhập xuất

71

Tập bài giảng Lập trình cơ bản

Thuật ngữ tập tin thì nói chung là liên quan đến những thông tin lƣu trữ bên

trong ỗ đĩa hoặc trong bộ nhớ. Khi làm việc với tập tin gắn liền với việc sử dụng một

luồng. Nhiều ngƣời nhầm lẫn về sự khác nhau giữa tập tin và luồng. Một luồng đơn

giản là luồng của thông tin, chứa thông tin sẽ đƣợc chuyển qua, còn tập tin thì để lƣu trữ thông tin. Một luồng đƣợc sử dụng để gởi và nhận thông tin từ bộ nhớ, từ mạng,

web, từ một chuỗi,... Một luồng còn đƣợc sử dụng để đọc và ghi ra một tập tin dữ liệu.

Thứ tự của việc đọc một tập tin Khi đọc hay ghi dữ liệu lên một tập tin, cần thiết phải theo một trình tự xác

định. Đầu tiên là phải thực hiện công việc mở tập tin. Nếu tạo mới tập tin thì việc mở tập tin cùng lúc với việc tạo ra tập tin đó. Khi một tập tin đã mở, cần thiết phải tạo cho

nó một luồng để ghi thông tin vào trong một tập tin hay là lấy thông tin ra từ tập tin.

Khi tạo một luồng, cần thiết phải chỉ ra thông tin trực tiếp sẽ đƣợc đi qua luồng. Sau

khi tạo một luồng gắn với một tập tin thì lúc này có thể thực hiện việc đọc ghi các dữ

liệu trên tập tin. Khi thực hiện việc đọc thông tin từ một tập tin, cần thiết phải kiểm tra

xem con trỏ tập tin đã chỉ tới cuối tập tin chƣa, tức là đã đọc đến cuối tập tin hay chƣa.

Khi hoàn thành việc đọc ghi thông tin trên tập tin thì tập tin cần phải đƣợc đóng lại.

Tóm lại các bƣớc cơ bản để làm việc với một tập tin là:

- Bƣớc 1: Mở hay tạo mới tập tin - Bƣớc 2: Thiết lập một luồng ghi hay đọc từ tập tin - Bƣớc 3: Đọc hay ghi dữ liệu lên tập tin - Bƣớc 4: Đóng lập tin lại

Các phƣơng thức cho việc tạo và mở tập tin Có nhiều kiểu luồng khác nhau. Việc sử dụng các luồng và các phƣơng thức khác nhau phụ thuộc vào kiểu dữ liệu bên trong của tập tin. Trong phần này sẽ giới thiệu

việc đọc/ghi dữ liệu trên tập tin văn bản và phần kế tiếp là trên tập tin nhị phân.

Để mở một tập tin trên đĩa cho việc đọc và viết tập tin văn bản, cần phải sử dụng

một trong hai lớp File và FileInfo. Một vài phƣơng thức có thể sử dụng trong những lớp này. Các phƣơng thức này bao gồm:

Phƣơng thức Mô tả

AppendText

Tạo luồng StreamWriter sử dụng để ghi dữ liệu vào tập tin văn bản đã có, hoặc một tập tin mới tạo nếu tập tin đó không tồn tại.

Create Tạo mới một tập tin

CreateText Tạo hoặc mở một tập tin văn bản.

72

Tập bài giảng Lập trình cơ bản

Open Mở một tập tin để đọc/ghi.

OpenRead Mở một tập tin để đọc

OpenText Mở một tập tin văn bản để đọc.

OpenWrite Mở một tập tin văn bản đã có hoặc tạo mới một tập tin văn bản

để ghi dữ liệu lên tập tin đó

Bảng 3.3: Một số phương thức mở tập tin

Lớp File chứa tất cả các phƣơng thức tĩnh, thêm vào đó lớp File tự động kiểm tra quyền trên một tập tin. Trong khi đó nếu muốn dùng lớp FileInfo thì phải tạo thể

hiện của lớp này. Nếu muốn mở một tập tin chỉ một lần thì tốt nhất là sử dụng lớp File,

còn nếu tổ chức việc sử dụng tập tin nhiều lần bên trong chƣơng trình, tốt nhất là dùng

lớp FileInfo.

Viết vào một tập tin văn bản Cách tốt nhất để nắm vững cách thức làm việc với tập tin là tìm hiểu một ví dụ

minh họa việc tạo ra một tập tin văn bản rồi sau đó viết lại thông tin vào nó.

namespace Vidu3_8{

class Program

{

static void Main(string[] args)

{

StreamWriter teptin = File.CreateText( @"E:\taptin.txt");

teptin.WriteLine("Khong co viec gi kho");

teptin.WriteLine("Chi so long khong ben");

teptin.WriteLine("Dao nui va lap bien");

teptin.WriteLine("Quyet chi at lam nen");

for(int i=0; i < 10; i++)

{

teptin.Write("{0} ",i);

}

teptin.Close();

Console.ReadLine();

}

}

}

Ví dụ 3.8: Viết dữ liệu vào tập tin văn bản

Kết quả chƣơng trình:

73

Tập bài giảng Lập trình cơ bản

Hình 3.8: Kết quả chương trình ví dụ 3.8

Chƣơng trình thực hiện việc tạo tập tin mới theo đƣờng dẫn ―E:\taptin.txt‖ và

tập tin văn bản mới đƣợc tạo ra có nội dung nhƣ sau:

Khong co viec gi kho

Chi so long khong ben Dao nui va lap bien

Quyet chi at lam nen 0 1 2 3 4 5 6 7 8 9

Phƣơng thức CreateText của lớp File đƣợc gọi để tạo ra một đối tƣợng

StreamWriter mới gọi là teptin. Tham số đƣợc truyền cho hàm là tên của tập tin sẽ

đƣợc tạo. Kết quả là tạo ra một tập tin văn bản mới. Dữ liệu sẽ đƣợc đƣa vào tập tin

thông qua StreamWriter với thể hiện của nó là teptin. Khi một luồng đƣợc thiết lập và

chỉ đến một tập tin thì dữ liệu có thể đƣợc ghi vào trong luồng và nó sẽ đƣợc ghi vào

tập tin:

teptin.WriteLine(“Khong co viec gi kho”);

Dòng lệnh trên ghi một chuỗi vào trong tập tin, việc ghi này giống nhƣ là hiển

thị ra màn hình console. Sau khi thực hiện toàn bộ công việc, cần thiết phải đóng

luồng lại bằng cách gọi phƣơng thức Close.

Đọc tập tin văn bản Đọc dữ liệu từ tập tin văn bản cũng tƣơng tự nhƣ việc ghi thông tin vào tập tin.

Ví dụ minh họa tiếp sau đây thực hiện việc đọc tập tin đƣợc tạo ra từ chƣơng trình

minh họa 3.8 trƣớc.

namespace Vidu3_9

{

class Program

{

static void Main(string[] args)

{

string chuoi;

StreamReader teptin = File.OpenText(@"E:\taptin.txt");

while ((chuoi = teptin.ReadLine()) != null)

Ví dụ 3.9: Đọc một tập tin văn bản.

74

{

Console.WriteLine(chuoi);

}

teptin.Close();

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.9: Kết quả chương trình ví dụ 3.9.

Đầu tiên là khai báo một chuỗi dùng để lƣu thông tin đọc từ tập tin. Để mở tập

tin văn bản sử dụng phƣơng thức OpenText. Phƣơng thức này đƣợc truyền vào tên của

tập tin văn bản cần mở ―E:\taptin.txt‖. Một lần nữa một luồng tên teptin đƣợc tạo ra

gắn với tập tin đã cho, luồng này có kiểu là StreamReader. Phƣơng thức ReadLine()

của teptin thực hiện việc đọctừng dòng trong tập tin và sau đó đƣợc xuất ra màn hình

console. Việc đọc này kết hợp vớiviệc kiểm tra là đã đọc đến cuối tập tin chƣa, nếu

đọc đến cuối tập tin, tức là hàm ReadLine()trả về chuỗi rỗng, lúc này chƣơng trình sẽ kết thúc việc đọc. Cuối cùng hàm Close đƣợc gọiđể đóng tập tin lại và chƣơng trình

chấm dứt.

Viết thông tin nhị phân vào tập tin Nếu sử dụng một tập tin văn bản thì khi lƣu dữ liệu kiểu số thì phải thực hiện

việc chuyển đổi sang dạng chuỗi ký tự để lƣu vào trong tập tin văn bản và khi lấy ra

cũng lấy đƣợc giá trị chuỗi ký tự do đólại phải chuyển sang dạng số. Đôi khi muốn có

cách thức nào đó tốt hơn để lƣu trực tiếp giá trị vào trong tập tin và sau đó đọc trựctiếp giá trị ra từ tập tin. Ví dụ khi viết một số lƣợng lớn các số integer vào trong tập tin nhƣ lànhững số nguyên thì khi đó có thể đọc các giá trị này ra nhƣ là số integer. Để làm điều đó, có thể gắn một kiểu luồng nhị phân BinaryStream vào trong một tập tin,rồi sau đó đọc và ghi thông tin nhị phân từ luồng này.Hãy xem ví dụ 3.10 minh họa việc đọc viết dữ liệu nhị phân vào một tập tin.

Ví dụ 3.10: Lập chƣơng trình lƣucác số nguyên từ 0 đến 99 vào một tập tin nhị

phân.

75

namespace Vidu3_10

{

class Program

{

static void Main(string[] args)

{

FileStream

teptin

=

new

FileStream(@"E:\tapnhiphan.data",

FileMode.CreateNew);

BinaryWriter bwTep = new BinaryWriter(teptin);

for (int i = 0; i < 100; i++)

{

bwTep.Write(i);

}

bwTep.Close();

teptin.Close();

}

}

}

Tập bài giảng Lập trình cơ bản

Hình 3.10: Nội dung tập tin tapnhiphan.data được mở bằng WordPad.

Nếu mở tập tin và xem thì chỉ thấy các ký tự mở rộng đựơc hiện thị, sẽ không

thấy những số đọc đƣợc nhƣ hình 3.9. Trong chƣơng trình này thực hiện việc tạo và mở tập tin khác với việc mở tập tin văn bản. Lệnh trên tạo một đối tƣợng FileStream gọi là teptin. Luồng này đƣợc gắn với tập tin thông qua bộ khởi dựng. Tham số đầu tiên của bộ khởi dựng là tên của tập tin đƣợc tạo ra ―E:\tapnhiphan.data‖, tham số thứ hai là thể hiện chế độ mở tập tin. Tham số này là giá trị kiểu liệt kêFileMode, trong chƣơng trình thì do thực hiện việc tạo mới để ghi nên sử dụng giátrị

FileMode.CreateNew. Bảng 3.4 sau liệt kê những giá trị khác trong kiểu liệt

kêFileMode.

76

Tập bài giảng Lập trình cơ bản

Giá trị

Giải thích

Append Mở một tập tin hiện hữu hoặc tạo một tập tin mới

Create Tạo một tập tin mới. Nếu một tập tin đã hiện hữu,

nó sẽ bị xóa và một tập tin mới sẽ đƣợc tạo ra với cùng tên.

CreateNew Tạo một tập tin mới. Nếu một tập tin đã tồn tại thì

một ngoại lệ sẽ đƣợc phát sinh.

Open Mở tập tin hiện hữu.

OpenOrCreate Mở tập tin hay tạo tập tin mới nếu tập tin chƣa tồn

tại

Truncate Mở một tập tin hiện hữu và xóa nội dung của nó.

Bảng 3.4: Giá trị của FileMode

Sau khi tạo ra FileStream, cần thiết phải thiết lập để nó làm việc với dữ liệu nhị

phân. Dòng lệnh tiếp theo:

BinaryWriter bwTep = new BinaryWriter(teptin);

Dòng này thiết lập một kiểu viết dữ liệu nhị phân vào trong luồng bằng cách

khai báo kiểuBinaryWrite. Đối tƣợng thể hiện của BinaryWrite là bwTepđƣợc tạo

ra.Đối tƣợng teptin đƣợc truyềnvào bộ khởi dựng BinaryWrite, nó sẽ gắn bwTepvới

teptin.

for (int i=0; i < 100; i++)

{

bwTep.Write(i);

}

Vòng lặp này thực hiện việc ghi trực tiếp giá trị của biến i vào trong BinaryWrite bwTep bằng cách sử dụng phƣơng thức Write. Dữ liệu đƣợc ghi có thể là

các kiểu dữ liệu khác. Trong chƣơng trình này là giá trị kiểu integer. Khi thực hiện

xong các công việc ghi dữ liệu vào tập tin, cần thiết phải đóng luồng đã mở.

Đọc thông tin nhị phân từ tập tin Trong phần trƣớc đã thực hiện việc ghi thông tin nhị phân vào trong tập tin và bây giờ sẽ thực hiện đọc các thông tin đã ghi vào trong tập tin. Việc đọc thông tin cũng khá đơn giản nhƣ là việc ghi dữ liêu. Chƣơng trình 3.11sau minh họa cho công việc này.

Ví dụ 3.11: Lập chƣơng trình đọc thông tin từ tập nhị phân đƣợc tạo ra từ ví dụ

namespace Vidu3_11

3.10.

77

{

class Program

{

static void Main(string[] args)

{

FileStream teptin = new FileStream( @"E:\tapnhiphan.data",

FileMode.Open);

BinaryReader brTep = new BinaryReader(teptin);

// đọc dữ liệu

Console.WriteLine("Dang doc tap tin....");

while (brTep.PeekChar() != -1)

{

Console.Write("<{0}>", brTep.ReadInt32());

}

Console.WriteLine("....Doc xong");

brTep.Close();

teptin.Close();

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.11: Kết quả chương trình ví dụ 3.11

Với ứng dụng này, thực hiện đọc dữ liệu mà đã đƣợc ghi trong ví dụ 3.10.

Trong ví dụ này tạo ra luồng FileStream. Lúc này, mode thao tác của tập tin đƣợc sử

dụng là mode FileMode.Open. Sau đó thực hiện việc gắn luồng này với luồng BinaryReader trong dòng tiếp sau, luồng này sẽ giúp cho việc đọc thông tin nhị phân:

FileStream teptin = new FileStream( args[0], FileMode.Open); BinaryReader brTep = new BinaryReader(teptin);

Sau khi tạo ra luồng giúp cho việc đọc thông tin nhị phân từ tập tin, chƣơng

trình bắt đầu đọc thông qua vòng lặp:

while (brTep.PeekChar() != -1) {

Console.Write(“<{0}>”, brTep.ReadInt32());

78

Tập bài giảng Lập trình cơ bản

}

Ở đây phƣơng thức PeekChar của lớp BinaryReader đƣợc sử dụng. Phƣơng

thức này sẽ lấy ký tự kế tiếp trong luồng. Nếu ký tự kế tiếp là cuối tập tin thì giá trị -1

đƣợc trả về. Ngƣợc lại thì ký tự kế tiếp đƣợc trả về. Khi ký tự kế tiếp không phải ký tự cuốitập tin thì lệnh bên trong vòng lặp sẽ đọc một số integer từ đối tƣợng

BinaryStream brTep.

Phƣơng thức đƣợc sử dụng để đọc một số nguyên là ReadInt32, nên sử dụng

kiểu tên của Framework tốt hơn là kiểu do C# đƣa ra.

Ngoài ra, lớp BinaryReader còn có các phƣơng thức khác để thực hiện việc đọc

các kiểu dữ liệu khác nhau. Những phƣơng thức đọc này đƣợc sử dụng cùng với cách

mà ReadInt32 đƣợc sử dụng trong chƣơng trình. Bảng 3.5 sau liệt kê một số phƣơng thức dùng để đọc các kiểu dữ liệu.

Phƣơng thức

Ý nghĩa

Read

Đọc những ký tự và chuyển vị trí đọc sang vị trí tiếp theo. Phƣơng thức này đƣợc nạp chồng gồm 3 phƣơng thức.

ReadBoolean Đọc một giá trị boolean từ luồng hiện thời và chuyển vị trí

đọc sang một byte.

ReadByte Đọc byte kế tiếp từ luồng hiện thời và chuyển vị trí đọc

sang 1 byte.

ReadBytes Đọc n byte từ luồng hiện thời sang một mảng byte và

chuyển vị trí đọc sang n byte.

ReadChar Đọc vị trí kế tiếp trong luồng hiện hành và chuyển vị trí

đọc của luồng theo sau sử dụng mã hóa và ký tự xác định

đƣợc đọc từ luồng.

ReadChars Đọc n ký tự từ luồng hiện hành vào một mảng n ký tự. Và

chuyển vị trí đọc của luồng theo sau sử dụng mã hóa và ký tự xác định đƣợc đọc từ luồng.

ReadDecimal Đọc giá trị decimal và chuyển vị trí đọc sang 16 byte.

ReadDouble Đọc giá trị thực 8 byte và chuyển vị trí đọc sang 8 byte.

ReadInt16

Đọc giá trị 2 byte integer có dấu và chuyển vị trí đọc sang 2 byte.

ReadInt32

Đọc giá trị 4 byte integer có dấu và chuyển vị trí đọc sang 4 byte.

ReadSByte Đọc một signed byte từ luồng và chuyển vị trí đọc sang 1

79

Tập bài giảng Lập trình cơ bản

byte.

ReadSingle

Đọc giá trị thực 4 byte từ luồng và chuyển vị trí đọc sang 4 byte.

ReadString Đọc một chuỗi từ luồng. Chuỗi đƣợc cố định chiều dài

trƣớc.Và đƣợc mã hóa mỗi lần nhƣ là số nguyên 7 bit.

ReadUInt16 Đọc giá trị 2-byte unsigned integer từ luồng. Sử dụng mã

hóa thứ tự nhỏ ở cuối (little endian encoding). Và chuyển

vị trí hiện hành sang 2 byte.

Bảng 3.5: Các phương thức đọc của BinaryReader.

3.4. Lớp Điểm mạnh của C# là khả năng tạo ra những kiểu dữ liệu mới, phức tạp. Ngƣời

lập trình tạo ra các kiểu dữ liệu mới bằng cách xây dựng các lớp đối tƣợng và đó cũng

chính là các vấn đề cần thảo luận trong phần này. Đây là khả năng để tạo ra những kiểu dữ liệu mới, một đặc tính quan trọng của ngôn ngữ lập trình hƣớng đối tƣợng. Có

thể xây dựng những kiểu dữ liệu mới trong ngôn ngữ C# bằng cách khai báo và định

nghĩa lớp. Thể hiện của một lớp đƣợc gọi là những đối tƣợng (object). Những đối

tƣợng này đƣợc tạo trong bộ nhớ khi chƣơng trình đƣợc thực hiện.

Lợi ích to lớn của những lớp trong ngôn ngữ lập trình là khả năng đóng gói các

thuộc tính và tính chất của một thực thể trong một khối đơn, tự có nghĩa, tự khả năng

duy trì. Ví dụ khi muốn sắp nội dung những thể hiện hay đối tƣợng của lớp điều khiển

ListBox trên Windows, chỉ cần gọi phƣơng thức sắp xếp các đối tƣợng này thì chúng

sẽ tự sắp xếp, còn việc chúng làm ra sao thì không quan tâm và cũng chỉ cần biết bấy

nhiêu đó thôi.

Đóng gói cùng với đa hình (polymorphism) và kế thừa (inheritance) là các

thuộc tínhchính yếu của bất kỳ một ngôn ngữ lập trình hƣớng đối tƣợng nào.

Trong phần này sẽ trình bày cách để xây dựng các lớp đối tƣợng. Thành phần

của một lớp, các hành vi và các thuộc tính, đƣợc xem nhƣ là thành viên của lớp (class member). Tiếp theo là khái niệm về phƣơng thức (method) đƣợc dùng để định nghĩa hành vi của một lớp và trạng thái của các biến thành viên hoạt động trong một lớp. Một đặc tính mới mà ngôn ngữ C# đƣa ra để xây dựng lớp là khái niệm thuộc tính (property).

Định nghĩa lớp Cú pháp đầy đủ của khai báo một lớp nhƣ sau:

[Bổ sung truy cập] class <Định danh lớp>

{

80

Tập bài giảng Lập trình cơ bản

phương thức hành động >

}

Thành phần bổ sung truy cập sẽ đƣợc trình bày tiếp ngay mục dƣới. Định danh lớp chính là tên của lớp do ngƣời xây dựng chƣơng trình tạo ra. 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, phần thân này sẽ đƣợc bao bọc bởi hai

dấu ({}).

Bây giờ sẽ tìm hiểu cách tạo một lớp và tạo các thể hiện thông qua ví dụ minh họa

3.12. Ví dụ này tạo một lớp có chức năng hiểu thị thời gian trong một ngày. Lớp này

có hành vi thể hiện ngày, tháng, năm, giờ, phút, giây hiện hành. Để làm đƣợc điều trên

thì lớp này có 6 thuộc tính hay còn gọi là biến thành viên, cùng với một phƣơng thức nhƣ sau:

namespace Vidu3_12

{

public class ThoiGian

{

public void ThoiGianHienTai()

{

Console.WriteLine("Hien thi thoi gian hien hanh");

}

// Các biến thành viên

int Nam;

int Thang;

int Ngay;

int Gio;

int Phut;

int Giay;

}

class Program

{

static void Main(string[] args)

{

ThoiGian t = new ThoiGian();

t.ThoiGianHienTai();

Console.ReadLine();

}

}

}

Ví dụ 3.12: Tạo một lớp Thoigian đơn giản:

Kết quả chƣơng trình:

81

Tập bài giảng Lập trình cơ bản

Hình 3.12: Kết quả chương trình ví dụ 3.12.

Lớp ThoiGian chỉ có một phƣơng thức chính là hàm ThoiGianHienTai(), phần

thân của phƣơng thức này đƣợc định nghĩa bên trong của lớp ThoiGian. Phần cuối của

định nghĩa lớp là phần khai báo các biến thành viên: Nam, Thang, Ngay, Gio, Phut và Giay.

Sau khi định nghĩa xong lớp ThoiGian thì tiếp theo là phần định nghĩa lớp

Program, lớp này có chứa một hàm Main(). Bên trong hàm Main có một thể hiện của

lớp ThoiGian đƣợc tạo ra và gán giá trị cho đối tƣợng t. Bởi vì t là thể hiện của đối

tƣợng ThoiGian, nên trong hàm Main() có thể sử dụng phƣơng thức của t:

t.ThoiGianHienTai();

Phạm vi truy cập Phạm vi truy cập quyết định khả năng các phƣơng thức của lớp và các phƣơng

thức của lớp khác có thể nhìn thấy và sử dụng các biến thành viên hay những phƣơng

thức của một lớp. Bảng 3.6 đƣa ra các từ khóa mô tả phạm vi truy cập trong C#.

Từ khóa Giới hạn truy cập

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 Thành viên trong một lớp A đƣợc đánh dấu là private thì chỉ đƣợc

truy cập bởi các phƣơng thức của lớp A.

protected Thành viên trong lớp A đƣợc đánh dấu là protected thì chỉ đƣợc

các phƣơng thức bên trong lớp A và những phƣơng thức dẫn xuất từ lớp A truy cập.

internal

Thành viên trong lớp A đƣợc đánh dấu là internal thì đƣợc truy cập bởi những phƣơng thức của bất cứ lớp nào trong cùng khối hợp ngữ với A.

protected Thành viên trong lớp A đƣợc đánh dấu là protected internal đƣợc

internal truy cập bởi các phƣơng thức của lớp A, các phƣơng thức của lớp

dẫn xuất của A và bất cứ lớp nào trong cùng khối hợp ngữ của A.

82

Tập bài giảng Lập trình cơ bản

Bảng 3.6: Thuộc tính truy cập.

Mong muốn chung là thiết kế các biến thành viên của lớp ở thuộc tính private.

Khi đó chỉ có phƣơng thức thành viên của lớp truy cập đƣợc giá trị của biến. C# xem

các biến thành viên private là mặc định nên trong ví dụ 3.12 không khai báo phạm vi truy cập cho 6 biến nên mặc định chúng là private:

Do lớp Program và phƣơng thức thành viên ThoiGianHienTai của lớp ThoiGian

đƣợc khai báo là public nên bất kỳ lớp nào cũng có thể truy cập đƣợc.

Tham số của phƣơng thức Trong các ngôn ngữ lập trình thì tham số và đối số đƣợc xem là nhƣ nhau, cũng

tƣơng tự khi đang nói về ngôn ngữ hƣớng đối tƣợng thì gọi một hàm là một phƣơng

thức hay hành vi. Tất cả các tên này điều tƣơng đồng với nhau.

Một phƣơng thức có thể lấy bất kỳ số lƣợng tham số nào, các tham số này theo

sau bởi tên của phƣơng thức và đƣợc bao bọc bên trong dấu ngoặc tròn (). Mỗi tham

số phải khai báo kèm với kiểu dữ liệu. Ví dụ có một khai báo định nghĩa một phƣơng

thức có tên là Method, phƣơng thức không trả về giá trị nào cả (khai báo giá trị trả về

là void) và có hai tham số là một kiểu int và button:

void Method( int param1, button param2)

{

//...

}

Bên trong thân của phƣơng thức, các tham số này đƣợc xem nhƣ những biến

cục bộ, giống nhƣ là khai báo biến bên trong phƣơng thức và khởi tạo giá trị bằng giá

trị của tham số truyền vào. Ví dụ 3.13 minh họa việc truyền tham số vào một phƣơng

thức, trong trƣờng hợp này thì hai tham số của kiểu là int và float.

namespace Vidu3_13{

public class Lop1

{

public void PT(int p1, float p2)

{

Console.WriteLine("Ham nhan duoc hai tham so: {0} va {1}", p1,p2);

}

}

class Program

{

static void Main(string[] args)

{

int bien1 = 5;float bien3 = 10.5f;

Lop1 c = new Lop1();

Ví dụ 3.13: Truyền tham số cho phƣơng thức:

83

c.PT( bien1, bien3 );

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.13: Kết quả chương trình ví dụ 3.13

Phƣơng thức PTsẽ lấy hai tham số int và float rồi hiển thị chúng ra màn hình

bằng việc dùng hàm Console.WriteLine(). Những tham số này có tên là p1 và p2 đƣợc

xem nhƣ là biến cục bộ bên trong của phƣơng thức. Trong phƣơng thức Main, có hai biến cục bộ đƣợc tạo ra là bien1 và bien3. Khi hai biến này đƣợc truyền cho phƣơng

thức PT thì chúng đƣợc ánh xạ thành hai tham số p1 và p2 theo thứ tự danh sách biến

đƣa vào.

Tạo đối tƣợng Trong Chƣơng 2 có đề cập đến sự khác nhau giữa kiểu dữ liệu giá trị và kiểu dữ

liệu tham chiếu. Những kiểu dữ liệu chuẩn của C# nhƣ int, char, float,… là những kiểu

dữ liệu giá trị và các biến đƣợc tạo ra từ các kiểu dữ liệu này đƣợc lƣu trên stack. Tuy

nhiên, với các đối tƣợng kiểu dữ liệu tham chiếu thì đƣợc tạo ra trên heap, sử dụng từ

khóa new để tạo một đối tƣợng:

ThoiGian t = new ThoiGian();

t thật sự không chứa giá trị của đối tƣợng ThoiGian, nó chỉ chứa địa chỉ của đối tƣợng

đƣợc tạo ra trên heap, do vậy t chỉ chứa tham chiếu đến một đối tƣợng mà thôi.

Bộ khởi dựng Thử xem lại ví dụ minh họa 3.11, câu lệnh tạo một đối tƣợng cho lớp ThoiGian

tƣơng tự nhƣ việc gọi thực hiện một phƣơng thức:

ThoiGian t = new ThoiGian();

Đúng nhƣ vậy, một phƣơng thức sẽ đƣợc gọi thực hiện khi tạo mới một đối tƣợng. Phƣơng thức này đƣợc gọi là bộ khởi dựng (constructor). Các phƣơng thức này đƣợc định nghĩa khi xây dựng lớp, nếu không đƣợc định nghĩa thì CLR sẽ tạo ra phƣơng thức khởi dựng một cách mặc định. Chức năng của bộ khởi dựng là tạo ra đối tƣợng đƣợc xác định bởi một lớp. Trƣớc khi bộ khởi dựng đƣợc thực hiện thì đối

tƣợng chƣa đƣợc cấp phát trong bộ nhớ. Sau khi bộ khởi dựng thực hiện hoàn thành thì

bộ nhớ sẽ lƣu giữ một thể hiện hợp lệ của lớp vừa khai báo. Lớp ThoiGian trong ví dụ 84

Tập bài giảng Lập trình cơ bản

3.12 không định nghĩa bộ khởi dựng. Do không định nghĩa nên trình biên dịch sẽ cung

cấp một bộ khởi dựng cho lớp này. Phƣơng thức khởi dựng mặc định đƣợc tạo ra cho

một đối tƣợng sẽ không thực hiện bất cứ hành động nào, tức là bên trong thân của

phƣơng thức rỗng. Các biến thành viên sẽ đƣợc khởi tạo bằng các giá trị mặc định nhƣ biến nguyên có giá trị là 0 và chuỗi thì khởi tạo rỗng. Bảng 3.7 sau tóm tắt các giá trị

mặc định đƣợc gán cho các kiểu dữ liệu cơ bản.

Kiểu dữ liệu Giá trị mặc định

int, long, byte,… 0

bool false

char ‗\0‘ (null)

enum 0

reference null

Bảng 3.7: Giá trị mặc định của kiểu dữ liệu cơ bản.

Để định nghĩa một bộ khởi dựng riêng cần phải khai báo một phƣơng thức có

tên giống nhƣ tên lớp đã khai báo. Phƣơng thức khởi dựng không có giá trị trả về và

đƣợc khai báo là public. Nếu phƣơng thức khởi dựng này đƣợc truyền tham số thì phải

khai báo danh sách tham số giống nhƣ khai báo với bất kỳ phƣơng thức nào trong một

lớp. Ví dụ 3.14 đƣợc viết lại từ ví dụ 3.12 và thêm một bộ khởi dựng riêng, phƣơng

phức khởi dựng này sẽ nhận một tham số là một đối tƣợng kiểu DateTime do C# cung

cấp.

namespace Vidu3_14

{

public class ThoiGian

{

public void ThoiGianHienHanh()

{

Console.WriteLine(" Thoi gian hien hanh la : {0}/{1}/{2} {3}:{4}:{5}",

Ngay, Thang, Nam, Gio, Phut, Giay);

}

// Hàm khởi dựng

public ThoiGian( System.DateTime dt )

{

Nam = dt.Year;

Thang = dt.Month;

Ngay = dt.Day;

Gio = dt.Hour;

Phut = dt.Minute;

Giay = dt.Second;

}

Ví dụ 3.14: Định nghĩa một bộ khởi dựng:

85

// Biến thành viên private

int Nam;

int Thang;

int Ngay;

int Gio;

int Phut;

int Giay;

}

public class Program

{

static void Main()

{

System.DateTime thoigianhientai = System.DateTime.Now;

ThoiGian t = new ThoiGian(thoigianhientai);

t.ThoiGianHienHanh();

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.14: Kết quả chương trình ví dụ 3.14

Trong ví dụ trên, phƣơng thức khởi dựng lấy một đối tƣợng DateTime và khởi

tạo tất cả các biến thành viên dựa trên giá trị của đối tƣợng này. Khi phƣơng thức này

thực hiện xong, một đối tƣợng ThoiGian đƣợc tạo ra và các biến của đối tƣợng cũng

đã đƣợc khởi tạo.

Ngoài ra trong chƣơng trình 3.14 trên có sử dụng đối tƣợng của lớp DateTime,

lớp DateTime này đƣợc cung cấp bởi thƣ viện System, lớp này cũng cung cấp các biến thành viên public nhƣ: Year, Month, Day, Hour, Minute và Second tƣơng tự nhƣ lớp ThoiGian. Thêm vào đó là lớp này có đƣa ra một phƣơng thức thành viên tĩnh tên là Now, phƣơng thức Now sẽ trả về một tham chiếu đến một thể hiện của một đối tƣợng

DateTime đƣợc khởi tạo với thời gian hiện hành. Theo nhƣ trên khi lệnh:

System.DataTime thoigianhientai = System.DateTime.Now(); đƣợc thực hiện thì phƣơng thức tĩnh Now() sẽ tạo ra một đối tƣợng DateTime và gán cho biến đối tƣợng thoigianhientai. Sau khi đối tƣợng thoigianhientai đƣợc tạo thì câu lệnh tiếp theo sẽ thực hiện việc truyền đối tƣợng thoigianhientai cho phƣơng thức khởi

dựng để tạo một đối tƣợng ThoiGian:

86

Tập bài giảng Lập trình cơ bản

ThoiGian t = new ThoiGian( thoigianhientai );

Bên trong phƣơng thức khởi dựng này tham số dt sẽ tham chiếu đến đối tƣợng

DateTime là đối tƣợng vừa tạo mà thoigianhientai cũng tham chiếu tới. Nói cách khác

lúc này tham số dt và thoigianhientai cùng tham chiếu đến một đối tƣợng DateTime trong bộ nhớ. Nhờ vậy phƣơng thức khởi dựng ThoiGian có thể truy cập đƣợc các biến

thành viên public của đối tƣợng DateTime đƣợc tạo trong hàm Main().

Khởi tạo biến thành viên Các biến thành viên có thể đƣợc khởi tạo trực tiếp khi khai báo trong quá trình

khởi tạo, thay vì phải thực hiện việc khởi tạo các biến trong bộ khởi dựng. Để thực

hiện việc khởi tạo này rất đơn giản là việc sử dụng phép gán giá trị cho một biến:

private int Giay = 30; // Khởi tạo

Việc khởi tạo biến thành viên sẽ rất có ý nghĩa, vì khi xác định giá trị khởi tạo

nhƣ vậy thì biến sẽ không nhận giá trị mặc định mà trình biên dịch cung cấp.

Từ khóa this Từ khóa this đƣợc dùng để tham chiếu đến thể hiện hiện hành của một đối

tƣợng. Tham chiếu this này đƣợc xem là con trỏ ẩn đối với tất cả các phƣơng thức

không có thuộc tính tĩnh trong một lớp. Mỗi phƣơng thức có thể tham chiếu đến những

phƣơng thức khác và các biến thành viên thông qua tham chiếu this này.

Tham chiếu this này đƣợc sử dụng thƣờng xuyên theo hai cách:

- Sử dụng khi các biến thành viên bị che lấp bởi tham số đƣa vào, nhƣ trƣờng

hợp sau:

public void ThietlapNam( int Nam)

{

this.Nam = Nam;

}

Nhƣ trong đoạn mã trên phƣơng thức ThietlapNam sẽ thiết lập giá trị của biến

thành viên Nam, tuy nhiên do tham số đƣa vào có tên là Nam, trùng với biến thành

viên, nên phải dùng tham chiếu this để xác định rõ các biến thành viên và tham số

đƣợc truyền vào. Khi đó this.Nam chỉ đến biến thành viên của đối tƣợng, trong khi Nam chỉ đến tham số.

- Sử dụng tham chiếu this để truyền đối tƣợng hiện hành nhƣ một tham số của

một phƣơng thức của đối tƣợng khác: public void Phuongthuc( Lop1dt1 ) {

// Sử dụng tham chiếu this để truyền tham số là bản

// thân đối tượng đang thực hiện.

87

Tập bài giảng Lập trình cơ bản

dt1.SetObject( this );

}

Nhƣ trong phƣơng thức trên, khi cần truyền một tham số là chính bản thân của

đối tƣợng đang thực hiện thì bắt buộc phải dùng tham chiếu this để truyền.

Sử dụng các thành viên tĩnh (static member) Những thuộc tính và phƣơng thức trong một lớp có thể là những thành viên thể

hiện (instance members) hay những thành viên tĩnh (static members). Thành viên tĩnh đƣợc xem nhƣ một phần của lớp. Thành viên tĩnh của một lớp đƣợc truy cập thông qua

tên lớp đã đƣợc khai báo. Ví dụ có một lớp tên là Button với hai thể hiện của lớp tên là

btnUpdate và btnDelete. Giả sử lớp Button này có một phƣơng thức tĩnh là Show(). Để

truy cập phƣơng thức tĩnh này ta viết:

Button.Show();

Không đƣợc viết là:

btnUpdate.Show();

Ghi chú: Trong ngôn ngữ C# không cho phép truy cập đến các phương thức tĩnh và các biến thành viên tĩnh thông qua một thể hiện, nếu cố làm điều đó thì trình

biên dịch C# sẽ báo lỗi, điều này khác với ngôn ngữ C++.

Trong một số ngôn ngữ thì có sự phân chia giữa phƣơng thức của lớp và các

phƣơng thức khác (toàn cục) tồn tại bên ngoài không phụ thuộc bất cứ một lớp nào.

Tuy nhiên, điều này không cho phép trong C#, ngôn ngữ C# không cho phép tạo các

phƣơng thức bên ngoài của lớp, nhƣng có thể tạo đƣợc các phƣơng thức giống nhƣ vậy

bằng cách tạo các phƣơng thức tĩnh bên trong một lớp. Phƣơng thức tĩnh hoạt động ít

nhiều giống nhƣ phƣơng thức toàn cục, truy cập phƣơng thức này mà không cần phải

tạo bất cứ thể hiện hay đối tƣợng của lớp chứa phƣơng thức toàn cục. Tuy nhiên, lợi

ích của phƣơng thức tĩnh vƣợt xa phƣơng thức toàn cục vì phƣơng thức tĩnh đƣợc bao bọc trong phạm vi của một lớp nơi nó đƣợc định nghĩa, do vậy sẽ không gặp tình trạng

lộn xộn giữa các phƣơng thức trùng tên do chúng đƣợc đặt trong namespace. Nhƣ đã

biết phƣơng thức Main() là một phƣơng thức tĩnh. Phƣơng thức tĩnh đƣợc xem nhƣ là

phần hoạt động của lớp hơn là của thể hiện một lớp. Chúng cũng không cần có một tham chiếu this hay bất cứ thể hiện nào tham chiếu tới. Phƣơng thức tĩnh không thể truy cập trực tiếp đến các thành viên không có tính chất tĩnh (nonstatic). Ví dụ 3.15 minh họa việc sử dụng biến tĩnh để đếm số thể hiện đã đƣợc tạo ra của một lớp và hiển thị giá trị của biến tĩnh đó.

namespace Vidu3_15

{

public class Dem

Ví dụ 3.15: Sử dụng thuộc tính tĩnh để đếm số thể hiện.

88

{

public Dem()

{

sodoituong++;

}

public static void HienthiDemDoiTuong()

{

Console.WriteLine("{0} doi tuong", sodoituong);

}

private static int sodoituong = 0;

}

class Program

{

static void Main(string[] args)

{

Dem.HienthiDemDoiTuong();

Dem doituong1 = new Dem();

Dem.HienthiDemDoiTuong();

Dem doituong2 = new Dem();

Dem doituong3 = new Dem();

Dem.HienthiDemDoiTuong();

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.15: Kết quả chương trình ví dụ 3.15.

Bên trong lớp Demkhai báo một biến thành viên tĩnh tên là sodoituong biến này dùng để đếm số thể hiện của lớp Dem, biến này đƣợc khởi tạo giá trị 0. Lƣu ý rằng biến thành viên tĩnh đƣợc xem là thành phần của lớp, không phải là thành viên của thể hiện, do vậy nó sẽ không đƣợc khởi tạo bởi trình biên dịch khi tạo các thể hiện. Khởi tạo tƣờng minh là yêu cầu bắt buộc với các biến thành viên tĩnh. Khi một thể hiện

đƣợc tạo ra thì bộ dựng của lớp Demsẽ thực hiện tăng biến sodoituong lên một đơn vị. Và có phƣơng thức tĩnh HienthiDemDoiTuong() để hiện thị ra giá trị của biến

sodoituong.

89

Tập bài giảng Lập trình cơ bản

Truyền tham chiếu Những phƣơng thức chỉ có thể trả về duy nhất một giá trị, mặc dù giá trị này có

thể là một tập hợp các giá trị. Nếu muốn phƣơng thức trả về nhiều hơn một giá trị thì

cách thực hiện là tạo các tham số dƣới hình thức tham chiếu. Khi đó trong phƣơng thức sẽ xử lý và gán các giá trị mới cho các tham số tham chiếu này, kết quả là sau khi

phƣơng thức thực hiện xong sẽ dùng các tham số truyền vào nhƣ là các kết quả trả về.

Ví dụ 3.16 sau minh họa việc truyền tham số tham chiếu cho phƣơng thức.

namespace Vidu3_16

{

public class ThoiGian

{

public void Hienthithoigian()

{

Console.WriteLine("{0}/{1}/{2}/ {3}:{4}:{5}", Ngay,

Thang, Nam, Gio, Phut, Giay);

}

public int TraveGio()

{

return Gio;

}

public void TraveGioPhutGiay(int h, int m, int s)

{

h = Gio;

m = Phut;

s = Giay;

}

public ThoiGian(System.DateTime dt)

{

Nam = dt.Year;

Thang = dt.Month;

Ngay = dt.Day;

Gio = dt.Hour;

Phut = dt.Minute;

Giay = dt.Second;

}

private int Nam;

private int Thang;

private int Ngay;

private int Gio;

private int Phut;

private int Giay;

}

class Program

Ví dụ 3.16: Trả giá trị trả về thông qua tham số.

90

{

static void Main(string[] args)

{

System.DateTime thoigianhientai = System.DateTime.Now;

ThoiGian t = new ThoiGian( thoigianhientai);

t.Hienthithoigian();

int gio = 0;

int phut = 0;

int giay = 0;

t.TraveGioPhutGiay( gio, phut, giay);

System.Console.WriteLine("Thoi gian hien tai: {0}:{1}:{2}", gio,

phut, giay);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.16: Kết quả chương trình ví dụ 3.16

Kết quả xuất ra ở dòng cuối cùng là ba giá trị 0:0:0, rõ ràng phƣơng thức

TraveGioPhutGiay() không thực hiện nhƣ mong muốn là gán giá trị Gio, Phut, Giay

cho các tham số truyền vào. Tức là ba tham số này đƣợc truyền vào dƣới dạng giá trị.

Do đó để thực hiện nhƣ mục đích là lấy các giá trị của Gio, Phut, Giay thì phƣơng thức

TraveGioPhutGiay() có ba tham số đƣợc truyền dƣới dạng tham chiếu. Việc này đƣợc

thực hiện nhƣ sau, đầu tiên, thêm khai báo ref vào trƣớc các tham số trong phƣơng

thức TraveGioPhutGiay():

public void TraveGioPhutGiay(ref int h, ref int m, ref int s) { h = Gio; m = Phut;

s = Giay; } Điều thay đổi thứ hai là bổ sung cách gọi hàm TraveGioPhutGiayđể truyền các

tham số dƣới dạng tham chiếu nhƣ sau:

91

Tập bài giảng Lập trình cơ bản

t.TraveGioPhutGiay(ref gio, ref phut, ref giay);

Nếu không thực hiện bƣớc thứ hai, tức là không đƣa từ khóa ref khi gọi hàm thì

trình biên dịch C# sẽ báo một lỗi rằng không thể chuyển tham số từ kiểu int sang kiểu

ref int.

Cuối cùng khi biên dịch lại chƣơng trình sẽ đƣợc kết quả đúng nhƣ yêu cầu.

Bằng việc khai báo tham số tham chiếu, trình biên dịch sẽ truyền các tham số dƣới

dạng các tham chiếu, thay cho việc tạo ra một bản sao chép các tham số này. Khi đó các tham số bên trong TraveGioPhutGiay() sẽ tham chiếu đến cùng biến đã đƣợc khai

báo trong hàm Main(). Nhƣ vậy mọi sự thay đổi với các biến này đều có hiệu lực

tƣơng tự nhƣ là thay đổi trong hàm Main(). Tóm lại cơ chế truyền tham số dạng tham

chiếu sẽ thực hiện trên chính đối tƣợng đƣợc đƣa vào. Còn cơ chế truyền tham số giá trị thì sẽ tạo ra các bản sao các đối tƣợng đƣợc truyền vào, do đó mọi thay đổi bên

trong phƣơng thức không làm ảnh hƣởng đến các đối tƣợng đƣợc truyền vào dƣới

dạng giá trị.

Truyền tham chiếu với biến chƣa khởi tạo Ngôn ngữ C# bắt buộc phải thực hiện một phép gán cho biến trƣớc khi sử dụng,

do đó khi khai báo một biến nhƣ kiểu cơ bản thì trƣớc khi có lệnh nào sử dụng các

biến này thì phải có lệnh thực hiện việc gán giá trị xác định cho biến. Nhƣ trong ví dụ

3.16 trên, nếu không khởi tạo biến gio, phut vàgiay trƣớc khi truyền vào phƣơng thức

TraveGioPhutGiay() thì trình biên dịch sẽ báo lỗi nhƣ đoạn mã sau:

int gio;

int phu;

int giay;

t.TraveGioPhutGiay( ref int gio, ref int phut, ref int giay);

Việc sử dụng các đoạn lệnh trên không phải hoàn toàn vô lý vì mục đích là nhận các giá trị của đối tƣợng ThoiGian, việc khởi tạo giá trị của các biến đƣa vào là

không cần thiết.

Tuy nhiên khi biên dịch với đoạn mã lệnh nhƣ trên sẽ đƣợc báo các lỗi sau:

Use of unassigned local variable ‗gio‘ Use of unassigned local variable ‗phut‘ Use of unassigned local variable ‗giay‘

Để mở rộng cho yêu cầu trong trƣờng hợp này ngôn ngữ C# cung cấp thêm một bổ sung tham chiếu là out. Khi sử dụng tham chiếu out thì yêu cầu bắt buộc phải khởi tạo các tham số tham chiếu đƣợc bỏ qua. Nhƣ các tham số trong phƣơng thức TraveGioPhutGiay(), các tham số này không cung cấp bất cứ thông tin nào cho

phƣơng thức mà chỉ đơn giản là cơ chế nhận thông tin và đƣa ra bên ngoài. Do vậy có

92

Tập bài giảng Lập trình cơ bản

thể đánh dấu tất cả các tham số tham chiếu này là out, khi đó sẽ giảm đƣợc công việc

phải khởi tạo các biến này trƣớc khi đƣa vào phƣơng thức.

Lƣu ý là bên trong phƣơng thức có các tham số tham chiếu out thì các tham số

này phải đƣợc gán giá trị trƣớc khi trả về. Ta có một số thay đổi cho phƣơng thức TraveGioPhutGiay() nhƣ sau:

public void TraveGioPhutGiay( out int h, out int m, out int s)

{

h = Gio;

m = Phut;

s = Giay;

}

và cách gọi mới phƣơng thức TraveGioPhutGiay() trong Main():

t. TraveGioPhutGiay( out gio, out phut, out giay);

Tóm lại có các cách khai báo các tham số trong một phƣơng thức nhƣ sau:

truyền theo giá trị, truyền tham chiếu sử dụng từ khóa ref và cuối cùng là truyền tham

chiếu sử dụng từ khóa out. Ví dụ 3.17minh họa việc sử dụng ba kiểu tham số trên.

namespace Vidu3_17

{

public class ThoiGian

{

public void Hienthithoigian()

{

Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Ngay, Thang, Nam,

Gio, Phut, Giay);

}

public int TraveGio()

{

return Gio;

}

public void TraveGioPhutGiay(int h, out int m, ref int s)

{

// Nếu số giây truyền vào >30 thì tăng số Minute và Second = 0

if ( s >=30 )

{

Phut++;

Giay = 0;

}

Gio = h; // thiết lập giá trị hr được truyền vào

// Trả về giá trị mới cho min và sec

m = Phut;

Ví dụ 3.17: Sử dụng tham số.

93

s = Giay;

}

public ThoiGian( System.DateTime dt)

{

Nam = dt.Year;

Thang = dt.Month;

Ngay = dt.Day;

Gio = dt.Hour;

Phut = dt.Minute;

Giay = dt.Second;

}

// biến thành viên private

private int Nam;

private int Thang;

private int Ngay;

private int Gio;

private int Phut;

private int Giay;

}

class Program

{

static void Main(string[] args)

{

System.DateTime thoigianhientai = System.DateTime.Now;

ThoiGian t = new ThoiGian(thoigianhientai );

t.Hienthithoigian();

int gio = 3;

int phut;

int giay = 20;

t.TraveGioPhutGiay( gio, out phut, ref giay);

Console.WriteLine("Bay gio la: {0} phut va {1} giay", phut, giay);

giay = 45;

t.TraveGioPhutGiay( gio, out phut, ref giay);

Console.WriteLine("Bay gio la: {0} phut va {1} giay", phut, giay);

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.17: Kết quả chương trình ví dụ 3.17

94

Tập bài giảng Lập trình cơ bản

Phƣơng thức TraveGioPhutGiaytrên đã minh họa việc sử dụng ba kiểu truyền

tham số vào một phƣơng thức. Tham số thứ nhất gio đƣợc truyền vào dạng giá trị, mục

đích của tham số này là để thiết lập giá trị cho biến thành viên Gio. Tham số thứ hai là

phut đƣợc truyền vào phƣơng thức chỉ để nhận giá trị trả về của biến thành viên Phut, do đó tham số này đƣợc khai báo với từ khóa out. Cuối cùng tham số giay đƣợc truyền

vào với khai báo ref, biến tham số này dùng để thiết lập giá trị và nhận giá trị của biến

thành viên Giay trong phƣơng thức. Nếu giay lớn hơn 30 thì giá trị của biến thành viên Phut tăng thêm một đơn vị và biến thành viên Giay đƣợc thiết lập về 0. Sau cùng thì

giay đƣợc gán giá trị của biến thành viên Giay và đƣợc trả về. Hai biến gio và giay

đƣợc sử dụng trong phƣơng thức TraveGioPhutGiaynên phải đƣợc khởi tạo trƣớc khi

truyền vào phƣơng thức. Còn với biến phut thì không cần thiết vì nó không đƣợc sử dụng trong phƣơng thức mà chỉ nhận giá trị trả về.

Nạp chồng phƣơng thức Thông thƣờng khi xây dựng các lớp, mong muốn là tạo ra nhiều hàm có cùng

tên. Cũng nhƣ hầu hết trong các ví dụ trƣớc thì các lớp đều có nhiều hơn một phƣơng

thức khởi dựng. Lớp ThoiGian có các phƣơng thức khởi dựng nhận các tham số khác

nhau, nhƣ tham số là đối tƣợng DateTime, hay tham số có thể đƣợc tùy chọn để thiết

lập các giá trị của các biến thành viên thông qua các tham số nguyên. Tóm lại có thể

xây dựng nhiều các phƣơng thức cùng tên nhƣng nhận các tham số khác nhau. Chức

năng này đƣợc gọi là nạp chồng phƣơng thức.

Một ký hiệu (signature) của một phƣơng thức đƣợc định nghĩa nhƣ tên của

phƣơng thức cùng với danh sách tham số của phƣơng thức. Hai phƣơng thức khác

nhau khi ký hiệu của chúng khác nhau tức là khác về tên phƣơng thức hoặc danh sách

tham số. Danh sách tham số đƣợc xem là khác nhau bởi số lƣợng các tham số hoặc là

kiểu dữ liệu của tham số. Ví dụ đoạn mã sau, phƣơng thức thứ nhất khác phƣơng thức thứ hai do số lƣợng tham số khác nhau. Phƣơng thức thứ hai khác phƣơng thức thứ ba

do kiểu dữ liệu tham số khác nhau:

void PT( int p1 );

void PT ( int p1, int p2 ); void PT ( int p1, string p2 );

Một lớp có thể có nhiều phƣơng thức, nhƣng mỗi phƣơng thức trong lớp phải

có ký hiệu khác với tất cả các phƣơng thức thành viên còn lại của lớp.

Ví dụ 3.18 minh họa lớp ThoiGian có hai phƣơng thức khởi dựng, một phƣơng thức nhận tham số là một đối tƣợng DateTime còn phƣơng thức thứ hai thì nhận sáu tham số nguyên.

Ví dụ 3.18: Minh họa nạp chồng phƣơng thức khởi dựng.

95

namespace Vidu3_18

{

public class ThoiGian

{

public void Hienthithoigian()

{

Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}",

Ngay, Thang, Nam, Gio, Phut, Giay);

}

public ThoiGian( System.DateTime dt)

{

Nam = dt.Year;

Thang = dt.Month;

Ngay = dt.Day;

Gio = dt.Hour;

Phut = dt.Minute;

Giay = dt.Second;

}

public ThoiGian(int Year, int Month, int Date, int Hour, int

Minute, int Second)

{

this.Nam = Year;

this.Thang = Month;

this.Ngay = Date;

this.Gio = Hour;

this.Phut = Minute;

this.Giay = Second;

}

// Biến thành viên private

private int Nam;

private int Thang;

private int Ngay;

private int Gio;

private int Phut;

private int Giay;

}

class Program

{

static void Main(string[] args)

{

System.DateTime thoigianhientai = System.DateTime.Now;

ThoiGian t1 = new ThoiGian( thoigianhientai);

t1.Hienthithoigian();

ThoiGian t2 = new ThoiGian(2002,6,8,18,15,20);

t2.Hienthithoigian();

Console.ReadLine();

Tập bài giảng Lập trình cơ bản

96

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.18: Kết quả chương trình ví dụ 3.18.

LớpThoiGian trong ví dụ minh họa 3.18 có hai phƣơng thức khởi dựng. Nếu hai

phƣơng thức có cùng ký hiệu thì trình biên dịch sẽ không thể biết đƣợc gọi phƣơng

thức nào khi khởi tạo hai đối tƣợng là t1 và t2. Tuy nhiên, ký hiệu của hai phƣơng thức này khác nhau vì tham số truyền vào khác nhau, do đó trình biên dịch sẽ xác định đƣợc

phƣơng thức nào đƣợc gọi dựa vào các tham số.

Khi thực hiện nạp chồng một phƣơng thức, bắt buộc phải thay đổi ký hiệu của phƣơng thức, số tham số, hay kiểu dữ liệu của tham số và cũng có thể thay đổi giá trị

trả về, nhƣng đây là tùy chọn. Nếu tạo ra hai phƣơng thức cùng ký hiệu nhƣng khác

nhau kiểu giá trị trả về sẽ tạo ra một lỗi biên dịch.

Đóng gói dữ liệu với thành phần thuộc tính Thuộc tính là khái niệm cho phép truy cập trạng thái của lớp thay vì thông qua

truy cập trực tiếp các biến thành viên, nó sẽ đựơc thay thế bằng việc thực thi truy cập

thông qua phƣơng thức của lớp. Thuộc tính là một đặc tính mới đƣợc giới thiệu trong

ngôn ngữ C#. Đặc tính này cung cấp khả năng bảo vệ các trƣờng dữ liệu bên trong một

lớp bằng việc đọc và viết chúng thông qua thuộc tính. Trong ngôn ngữ khác, điều này

có thể đƣợc thực hiện thông qua việc tạo các phƣơng thức lấy dữ liệu (getter method)

và phƣơng thức thiết lập dữ liệu (setter method).

Thuộc tính đƣợc thiết kế nhằm mục đích cung cấp một giao diện đơn giản cho

phép truy cập các biến thành viên và cách thức thực thi truy cập giống nhƣ phƣơng thức trong đó các dữ liệu đƣợc che dấu, đảm bảo cho yêu cầu thiết kế hƣớng đối tƣợng. Để hiểu rõ đặc tính này ta sẽ xem ví dụ 3.19 bên dƣới:

namespace Vidu3_19

{

public class ThoiGian

{

public void Hienthithoigian()

{

Ví dụ 3.19: Sử dụng thuộc tính.

97

Console.WriteLine("Time\t: {0}/{1}/{2} {3}:{4}:{5}", ngay, thang,

nam, gio, phut, giay);

}

public ThoiGian( System.DateTime dt)

{

nam = dt.Year;

thang = dt.Month;

ngay = dt.Day;

gio = dt.Hour;

phut = dt.Minute;

giay = dt.Second;

}

public int Gio

{

get

{

return gio;

}

set

{

gio = value;

}

}

// Biến thành viên private

private int nam;

private int thang;

private int ngay;

private int gio;

private int phut;

private int giay;

}

class Program

{

static void Main(string[] args)

{

System.DateTime thoigtianhientai = System.DateTime.Now;

ThoiGian t = new ThoiGian(thoigtianhientai);

t.Hienthithoigian();

// Lấy dữ liệu từ thuộc tính Hour

int gio = t.Gio;

Console.WriteLine("Gio ban dau: {0}", gio);

gio++;

t.Gio = gio;

Console.WriteLine("Gio duoc cap nhat: {0}", gio);

Console.ReadLine();

}

Tập bài giảng Lập trình cơ bản

98

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.19: Kết quả chương trình ví du 3.19.

Để khai báo thuộc tính, đầu tiên là khai báo tên thuộc tính để truy cập, tiếp theo là phần thân định nghĩa thuộc tính nằm trong cập dấu ({}). Bên trong thân của thuộc

tính là khai báo hai bộ truy cập lấy và thiết lập dữ liệu:

public int Gio

{

get

{

return gio;

}

set

{

gio = value;

}

}

Mỗi bộ truy cập đƣợc khai báo riêng biệt để làm hai công việc khác nhau là lấy

hay thiết lập giá trị cho thuộc tính. Giá trị thuộc tính có thể đƣợc lƣu trong cơ sở dữ

liệu, khi đó trong phần thân của bộ truy cập sẽ thực hiện các công việc tƣơng tác với

cơ sở dữ lịêu. Hoặc là giá trị thuộc tính đƣợc lƣu trữ trong các biến thành viên của lớp nhƣ trong ví dụ:

private int gio;

Truy cập lấy dữ liệu (get accessor) Phần khai báo tƣơng tự nhƣ một phƣơng thức của lớp dùng để trả về một đối tƣợng có kiểu dữ liệu nhƣ thuộc tính. Trong ví dụ trên, bộ truy cập lấy dữ liệu get của thuộc tính Gio cũng tƣơng tự nhƣ một phƣơng thức trả về một giá trị int. Nó trả về giá trị của biến thành viên gio nơi mà giá trị của thuộc tính Gio lƣu trữ:

get {

99

Tập bài giảng Lập trình cơ bản

return gio;

}

Bất cứ khi nào tham chiếu đến một thuộc tính hay là gán giá trị thuộc tính cho

một biến thì bộ truy cập lấy dữ liệu get sẽ đƣợc thực hiện để đọc giá trị của thuộc tính:

Time t = new Time( thoigianhientai );

int gio = t.Hour;

Khi lệnh thứ hai đƣợc thực hiện thì giá trị của thuộc tính sẽ đƣợc trả về, tức là bộ truy cập lấy dữ lịêu get sẽ đƣợc thực hiện và kết quả là giá trị của thuộc tính đƣợc

gán cho biến cục bộ gio.

Bộ truy cập thiết lập dữ liệu (set accessor) Bộ truy cập này sẽ thiết lập một giá trị mới cho thuộc tính và tƣơng tự nhƣ một phƣơng thức trả về một giá trị void. Khi định nghĩa bộ truy cập thiết lập dữ lịêu phải

sử dụng từ khóa value để đại diện cho tham số đƣợc truyền vào và đƣợc lƣu trữ bởi

thuộc tính:

set

{

gio = value;

}

Khi gán một giá trị cho thuộc tính thì bộ truy cập thiết lập dữ liệu set sẽ đƣợc tự

động thực hiện và một tham số ngầm định sẽ đƣợc tạo ra để lƣu giá trị muốn gán:

gio++;

t.Gio = gio;

Lợi ích của hƣớng tiếp cận này cho phép các thành phần bên ngoài có thể tƣơng

tác với thuộc tính một cách trực tiếp, mà không phải hy sinh việc che dấu dữ lịêu cũng

nhƣ đặc tính đóng gói dữ lịêu trong thiết kế hƣớng đối tƣợng.

3.5. Cấu trúc Cấu trúc là kiểu dữ liệu đơn giản do ngƣời dùng định nghĩa, kích thƣớc nhỏ

dùng để thay thế cho lớp. Cấu trúc thì tƣơng tự nhƣ lớp cũng chứa các phƣơng thức,

những thuộc tính, các trƣờng. Có một số sự khác nhau quan trọng giữa những lớp và cấu trúc. Ví dụ, cấu trúc thì không hỗ trợ kế thừa và bộ hủy giống nhƣ kiểu lớp. Một điều quan trọng nhất là trong khi lớp là kiểu dữ liệu tham chiếu thì cấu trúc là kiểu dữ lịêu giá trị. Do đó cấu trúc thƣờng dùng để thể hiển các đối tƣợng không đòi hỏi tham chiếu, hay một lớp nhỏ mà khi đặt vào trong stack thì có lợi hơn là đặt trong bộ nhớ heap.

Trong phần này sẽ tìm hiểu cách định nghĩa và làm việc với kiểu cấu trúc và

cách sử dụng bộ khởi dựng để khởi tạo những thể hiện của cấu trúc.

100

Tập bài giảng Lập trình cơ bản

Định nghĩa một cấu trúc Cú pháp để khai báo một cấu trúc cũng tƣơng tự nhƣ cách khai báo một lớp:

[thuộc tính] [bổ sung truy cập] struct [: danh sách giao diện]

{

[thành viên của cấu trúc]

}

Cách thức thức khai báo biến cấu trúc và truy nhập các thành phẩn của biến cấu

trúc cũng tƣơng tự nhƣ với biến kiểu lớp. Để hiểu rõ hơn hãy xét ví dụ sau đây.

Ví dụ 3.20: Lập chƣơng trình thực hiện các công việc sau: - Xây dựng cấu trúc Điểm để mô tả các điểm trong không gian hai chiều với các thuộc tính hoành độ, tung độ; với phƣơng thức nhập, hiển thị một điểm, các hàm tạo không đối, có hai đối để khởi gán giá trị cho các thuộc tính. - Xây dựng hàm tính khoảng cách giữa hai điểm trong không gian hai chiều. - Nhập một dãy điểm gồm n phần tử (với n là số nguyên dƣơng nhập từ bàn

namespace Vidu3_20

{

public struct Diem

{

public Diem( int xC, int yC)

{

_x = xC;

_y = yC;

}

public int x

{

get

{

return _x;

}

set

{

_x = value;

}

}

public int y

{

get

{

phím). Hiển thị dãy điểm vừa nhập ra màn hình. - Đƣa ra những điểm gần điểm có tọa độ (1, 2) nhất. Ví dụ 3.20: Cấu trúc Diem.

101

return _y;

}

set

{

_y = value;

}

}

public string ToString()

{

return (String.Format("{0}, {1}", _x, _y));

}

// thuộc tính private lưu toạ độ x, y

private int _x;

private int _y;

}

class Program

{

//Hàm tính khoảng cách giữa hai điểm bất kỳ

public static double Khoangcach ( Diem d1, Diem d2)

{

return

Math.Sqrt(Math.Pow(d1.x-d2.x,2)

+

Math.Pow(d1.y-

d2.y,2));

}

static void Main(string[] args)

{

Diem[] a;

int n;

Console.Write("Nhap n = "); ;

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

a = new Diem[n];

int i;

for (i = 0; i < n; i++)

{

Console.WriteLine("Nhap thong tin diem thu {0}",i);

Console.Write("Nhap

x

=

");

a[i].x

=

int.Parse(Console.ReadLine());

Console.Write("Nhap y = "); a[i].y = int.Parse(Console.ReadLine());

}

Console.WriteLine("Day diem: ");

for (i = 0; i < n; i++)

Console.WriteLine(a[i].ToString());

Diem diem = new Diem( 1, 2);

double min = Khoangcach(a[0],diem);

for (i = 1; i < n; i++)

if(min>Khoangcach(a[i],diem))min = Khoangcach(a[i],diem);

Console.Write("Cac diem gan diem (1,2) la: ");

Tập bài giảng Lập trình cơ bản

102

for(i = 0; i < n; i++)

if(min==Khoangcach(a[i],diem))Console.Write(a[i].ToString());

Console.ReadLine();

}

}

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.20: Kết quả chương trình ví dụ 3.20.

Tạo một thể hiện của cấu trúc bằng cách sử dụng từ khóa new trong câu lệnh

gán, nhƣ khi tạo một đối tƣợng của lớp. Nhƣ trong ví dụ 3.20, lớp Program tạo một thể

hiện của Diem nhƣ sau:

Diemdiem = new Diem(1, 2);

Ở đây một thể hiện mới tên là diem và nó đƣợc truyền hai giá trị là 1 và 2. Các

thức truy nhập vào thuộc tính hay phƣơng thức cũng tƣơng tự nhƣ với lớp.

Bài tập

Bài 3.1 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập và hiển thị mảng số thực gồm n phần tử (n nguyên dƣơng nhập từ bàn

phím)

2. Hiển thị mảng theo thứ tự đã sắp xếp tăng dần.

3. Nhập số nguyên x từ bàn phím. Kiểm tra xem trong mảng có phần tử nào

bằng x không?

4. Tìm phần tử có giá trị nhỏ nhất trong mảng. 5. Tính trung bình cộng các phần tử dƣơng trong mảng.

static void Nhapmang(ref float[] a, ref int n)

{

bool kt;

Hƣớng dẫn thực hiện Bƣớc 1: Tạo ứng dung Console và đặt tên là Bai3_1 Bƣớc 2: Viết hàm nhập và hiển thị mảng

103

do

{

Console.Write("Nhap kich thuoc mang n = ");

kt = int.TryParse(Console.ReadLine(), out n);

if (!kt || n <= 0) Console.WriteLine("Nhap n nguyen duong!");

}

while (!kt || n <= 0);

a = new float[n];

// Nhập mảng

Console.WriteLine("Nhap gia tri cac phan tu trong mang:");

for (int i = 0; i < n; i++)

{

Console.Write("a[{0}] = ", i);

a[i] = float.Parse(Console.ReadLine());

}

}

static void Hienthi(float[] a, int n)

{

for (int i = 0; i < a.Length; i++)

{

Console.Write("{0} ", a[i]);

}

}

Tập bài giảng Lập trình cơ bản

static float Timmin(float[] a, int n)

{

float min = a[0];

for (int i = 1; i < a.Length; i++)

if (a[i] < min) min = a[i];

return min;

}

static float Trungbinhcongduong(float[] a, int n)

{

float td =0; int d = 0;

for (int i = 0; i < a.Length; i++)

if (a[i] > 0) { td += a[i]; d++;}

if (d == 0) return 0;

else return td / d;

}

Bƣớc 3: Viết hàm tìm min và tính trung bình cộng

static void Main(string[] args)

{

float[] a = null;

int n = 0;

Bƣớc 4: Mã lệnh trong hàm Main()

104

Nhapmang(ref a, ref n);

Console.Write("Day sau khi sap xep: ");

Hienthi(a, n);

Console.WriteLine();

Array.Sort(a);

Console.Write("Day sau khi sap xep: ");

Hienthi(a, n);

Console.WriteLine();

Console.Write("x = ");

float x = float.Parse(Console.ReadLine());

if (a.Contains(x)) Console.WriteLine("co x trong day");

else Console.WriteLine("khong co x trong day");

Console.WriteLine("Phan tư nho nhat trong day: {0} ",

Timmin(a,n));

//Console.WriteLine("Phan tư nho nhat trong day: {0} ",

a.Min());

Console.Write("Trung binh cong cac phan tu duong trong day: {0}

", Trungbinhcongduong(a, n));

Console.ReadLine();

} Kết quả chƣơng trình:

Tập bài giảng Lập trình cơ bản

Hình 3.21: Kết quả chương trình bài 3.1

Bài 3.2

Lập chƣơng trình thực hiện các công việc sau:

1. Nhập, hiển thị dãy A gồm n số nguyên (n nguyên dƣơng bất kỳ nhập vào từ

bàn phím);

2. Tính trung bình cộng các số lẻ trong dãy; 3. Đƣa ra chỉ số của các phần tử có giá trị nhỏ nhất của dãy A. 4. Tính tổng các số dƣơng có trong dãy. 5. Cho biết dãy A có bao nhiêu số nguyên tố. 6. Xóa phần tử có giá trị dƣơng cuối cùng trong dãy nếu có, nếu không có thì

thông báo.

7. Nhập số nguyên dƣơng k và số thực x, thực hiện bổ sung phần tử mới có giá

trị là x vào vị trí thứ k trong dãy nếu có, nếu không có thì thông báo.

105

Tập bài giảng Lập trình cơ bản

8. Bổ sung số nguyên x vào vị trí thứ k trong mảng (với x, k là các số nguyên

nhập từ bàn phím)

9. Cho biết dãy A có tạo thành một cấp số cộng hay không?

Bài 3.3 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập và hiển thị ma trận số nguyên gồm n hàng, m cột (n, m nguyên dƣơng

nhập từ bàn phím)

2. Tìm phần tử lớn nhất trên mỗi hàng của ma trận

3. Đếm số phần tử lẻ trong ma trận

static void Nhapmatran(ref int[,] a, ref int n, ref int m)

{

Console.WriteLine("Nhap kich thuoc mang");

Console.Write("n = "); n = int.Parse(Console.ReadLine());

Console.Write("m = ");

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

a = new int[n, m];

int i, j;

for (i = 0; i < n; i++)

for (j = 0; j < m; j++)

{

Console.Write("a[{0}{1}] = ", i, j);

a[i, j] = int.Parse(Console.ReadLine());

}

}

static void Hienthimatran(int[,] a, int n, int m)

{

int i, j;

for (i = 0; i < n; i++)

{

Console.WriteLine("\n");

for (j = 0; j < m; j++) Console.Write("{0} ", a[i, j]);

}

Console.WriteLine("\n");

}

Hƣớng dẫn thực hiện: Bƣớc 1: Tạo ứng dụng Console và đặt tên là Bai3_3 Bƣớc 2: Viết các hàm nhập và hiển thị ma trận

static void Phantulonnhattrenhang(int[,] a, int n, int m)

{

for (int i = 0; i < n; i++)

Bƣớc 3: Viết các hàm tìm số lớn nhất trên hàng và đếm số phần tử lẻ trong ma trận.

106

{

int min = a[i, 0];

for (int j = 1; j < m; j++)

if (a[i, j] < min) min = a[i, j];

Console.WriteLine("Phan tu nho nhat tren hang {0} la: {1}

", i, min);

}

}

static int Demle(int[,] a, int n, int m)

{

int d = 0;

for (int i = 0; i < n; i++)

for (int j = 0; j < m; j++)

if (a[i, j] % 2 != 0) { d++; }

return d;

}

Tập bài giảng Lập trình cơ bản

static void Main(string[] args)

{

int n = 0, m = 0;

int[,] a = null;

Nhapmatran(ref a, ref n, ref m);

Console.WriteLine("Ma tran: ");

Hienthimatran(a, n, m);

Phantulonnhattrenhang(a, n, m);

Console.WriteLine("So phan tu le trong ma tran la: {0} ",

Demle(a,n,m));

Console.ReadLine();

}

Bƣớc 4: Viết mã lệnh trong hàm Main().

Kết quả chƣơng trình

Hình 3.22: Kết quả chương trình bài 3.3

Bài 3.4

107

Tập bài giảng Lập trình cơ bản

Lập chƣơng trình thực hiện các công việc sau:

1. Nhập và hiển thị ma trận vuông cấp n các phần tử là số nguyên (n nguyên

dƣơng nhập từ bàn phím)

2. Hiển thị các phần tử chẵn trên đƣờng chéo chính của ma trận. 3. Tính tổng các phần tử dƣơng trong ma trận.

static void Nhapmatran(ref int[,] a, ref int n)

{

Console.WriteLine("Nhap kich thuoc mang");

Console.Write("n = "); n = int.Parse(Console.ReadLine());

a = new int[n, n];

int i, j;

for (i = 0; i < n; i++)

for (j = 0; j < n; j++)

{

Console.Write("a[{0}{1}] = ", i, j);

a[i, j] = int.Parse(Console.ReadLine());

}

}

static void Hienthimatran(int[,] a, int n)

{

int i, j;

for (i = 0; i < n; i++)

{

Console.WriteLine("\n");

for (j = 0; j < n; j++) Console.Write("{0} ", a[i, j]);

}

Console.WriteLine("\n");

}

Hƣớng dẫn thực hiện: Bƣớc 1: Tạo ứng dụng Console và đặt tên là Bai3_4 Bƣớc 2: Viết các hàm nhập và hiển thị ma trận

Bƣớc 3: Viết các hàm hiển thị phần tử trên đƣờng chéo chính và tính tổng các

static void Phantuchantrencheochinh(int[,] a, int n)

{

Console.Write("Phan tu chan tren cheo chinh: ");

int d = 0;

for (int i = 0; i < n; i++)

{

if (a[i, i] % 2 == 0) { d++; Console.Write("{0} ", a[i,

i]); }

}

phần tử dƣơng trong ma trận

108

if (d == 0) Console.WriteLine("khong co phan tu nao");

}

static int Tongduong(int[,] a, int n)

{

int t = 0;

for (int i = 0; i < n; i++)

for (int j = 0; j < n; j++)

if (a[i, j] > 0) { t += a[i, j]; }

return t;

}

Tập bài giảng Lập trình cơ bản

static void Main(string[] args)

{

int n = 0, m = 0;

int[,] a = null;

Nhapmatran(ref a, ref n);

Console.WriteLine("Ma tran: ");

Hienthimatran(a, n);

Phantuchantrencheochinh(a, n);

Console.WriteLine("\nTong cac phan tu duong trong ma tran la: {0}

", Tongduong(a, n));

Console.ReadLine();

}

Bƣớc 4: Viết hàm Main()

Kết quả chƣơng trình:

Hình 3.23: Kết quả chương trình bài 3.4

Bài 3.5 Lập chƣơng trình thực hiện các công việc sau: 1. Nhập một ma trận số thực gồm n hàng, m cột (với n và m là hai số nguyên

dƣơng).

2. Hiển thị ma trận. 3. Tìm số âm lớn nhất của ma trận.

109

Tập bài giảng Lập trình cơ bản

4. Sắp xếp từng hàng của ma trận theo thứ tự tăng dần.

5. Nhập số nguyên dƣơng k, xóa hàng thứ k của ma trận nếu có.

6. Tính trung bình cộng các phần tử có giá trị âm trong ma trận

Bài 3.6 Tạo một ứng dụng Windows Form thực hiện các công việc sau:

1. Nhập một ma trận số thực vuông cấp n (với n là số nguyên dƣơng).

2. Hiển thị ma trận. 3. Tính tổng các phần tử nằm trên đƣờng chéo phụ của ma trận.

4. Tìm số dƣơng nhỏ nhất trên đƣờng chéo chính của ma trận

5. Đếm các phần tử của ma trận có giá trị chia hết cho 3 và 7.

Bài 3.7 Lập chƣơng trình thực hiện các công việc sau:

1. Khai báo kiểu cấu trúc Diem có hai thuộc tính là hoành độ và tung độ của

một điểm trong không gian hai chiều, các hàm getter, setter và hàm tạo.

2. Nhập một mảng cấu trúc Diem gồm n phần tử (với n là số nguyên dƣơng

nhập từ bàn phím).

3. Sắp xếp danh sách các điểm theo thứ tự hoành độ tăng dần.

Hƣớng dẫn thực hiện: Bƣớc 1: Tạo ứng dụng Console và đặt tên là Bai3_7

struct diem

{

private int _x;

private int _y;

public int X

{

get { return _x; }

set { _x = value; }

}

public int Y

{

get { return _y; }

set { _y = value; }

}

public diem(int hd, int td)

{

_x = hd;

_y = td;

}

}

Bƣớc 2: Tạo cấu trúc diem

110

Tập bài giảng Lập trình cơ bản

Bƣớc 3: Viết các hàm nhập mảng điểm, hiển thị mảng điểm và sắp xếp mảng

static void Nhapmang(ref diem[] a, ref int n)

{

bool kt;

do

{

Console.Write("Nhap kich thuoc mang n = ");

kt = int.TryParse(Console.ReadLine(), out n);

if (!kt || n <= 0) Console.WriteLine("Nhap n nguyen duong!");

}

while (!kt || n <= 0);

a = new diem[n];

// Nhập mảng

Console.WriteLine("Nhap gia tri cac phan tu trong mang:");

for (int i = 0; i < n; i++)

{

Console.WriteLine("Nhap điêm thu {0} ", i);

Console.Write("Nhap hoanh do: ");

a[i].X = int.Parse(Console.ReadLine());

Console.Write("Nhap tung do: ");

a[i].Y = int.Parse(Console.ReadLine());

}

}

static void Hienthi(diem[] a, int n)

{

for (int i = 0; i < a.Length; i++)

{

Console.WriteLine("({0}, {1})", a[i].X,a[i].Y);

}

}

static void Sapxeptheohoanhdo(ref diem[] a, int n)

{

diem tg;

for(int i =0;i

for (int j = i + 1; j < a.Length; j++)

if(a[i].X>a[j].X)

{

tg = a[i];

a[i] = a[j];

a[j] = tg;

}

}

điểm tăng dần theo hoành độ các điểm

static void Main(string[] args)

Bƣớc 4: Viết hàm Main()

111

{

diem[] a = null;

int n = 0;

Nhapmang(ref a, ref n);

Console.Write("Day diem: \n");

Hienthi(a, n);

Console.WriteLine();

Sapxeptheohoanhdo(ref a, n);

Console.Write("Day sau khi sap xep: \n");

Hienthi(a, n);

Console.ReadLine();

}

Tập bài giảng Lập trình cơ bản

Kết quả chƣơng trình:

Hình 3.24: Kết quả chương trình bài 3.7

Bài 3.8 Giả sử với mỗi thí sinh cần lƣu trữ các thông tin: Số báo danh, họ và tên, hộ khẩu thƣờng trú, điểm toán, điểm lý, điểm hóa. Lập chƣơng trình cho phép thực hiện các công việc sau:

1. Tạo danh sách thí sinh 2. Hiển thị danh sách thí sinh ra màn hình 3. Sửa thông tin của một thí sinh.

4. Xóa thông tin về một thí sinh khỏi danh sách. 5. Hiển thị thông tin về thí sinh khi biết số báo danh của thí sinh đó.

112

Tập bài giảng Lập trình cơ bản

6. Sắp xếp danh thí sinh theo tổng 3 môn tăng dần. Hiển thị lên màn hình danh

sách vừa sắp xếp

7. Nhập vào điểm chuẩn, đƣa ra những thí sinh trƣợt (những thí sinh có tổng 3

môn nhỏ hơn điểm chuẩn).

Bài 3.9 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập một xâu ký tự dƣới dạng họ tên của một ngƣời 2. Chuẩn hóa xâu vừa nhập.

3. Hiển thị ra màn hình tên, họ, đệm vừa nhập.

4. Hiển thị lại họ tên vừa nhập ra màn hình sao cho các ký tự đầu của mỗi từ

đều viết hoa (ví dụ: nhập vào nguyễn văn an thì in ra Nguyễn Văn An)

5. Đếm số từ trong xâu.

6. Đếm trong xâu có bao nhiêu ký tự ‗n‘.

Hƣớng dẫn thực hiện:

Bƣớc 1: Tạo ứng dụng Console và đặt tên là Bai3_9

static void Chuanhoaxau(ref string st)

{

st = st.Trim();//loại bỏ khoảng cách ở đầu và cuối xâu

int i = 1, j;

while (i < st.Length)

{

if (st[i] == ' ')//Hai ký tự gần nhau đều là khoảng trắng thì

sẽ xóa đi 1

{

j = i + 1;

while (j < st.Length && st[j] == ' ') st = st.Remove(j, 1);

i = j + 1;

}

else i++;

}

}

static void Hienthitenhodem(string hoten)

{

// trích tên

string ten = hoten.Remove(0, hoten.LastIndexOf(' ') + 1);

Console.WriteLine("\n Chao ban: " + ten);

// trích họ đệm

string ho = hoten.Substring(0, hoten.LastIndexOf(' '));

Console.WriteLine("\n Ho cua ban la: " + ho);

}

Bƣớc 2: Viết các hàm chuẩn hóa, hiển thị tên, họ đệm

113

Tập bài giảng Lập trình cơ bản

static void Chuyenchuhoadautu(ref string hoten)

{

char[] s = hoten.ToCharArray();

s[0] = char.ToUpper(s[0]);

hoten = s[0].ToString();

for (int i = 1; i < s.Length; i++)

{

if (s[i] == ' ') s[i + 1] = char.ToUpper(s[i + 1]);

hoten+=s[i];

}

}

static int demtu(string hoten)

{

int d = 0;

for (int i = 0; i < hoten.Length; i++)

if (hoten[i] == ' ') d++;

return d + 1;

}

static int demkytu(string hoten)

{

int d = 0;

for (int i = 0; i < hoten.Length; i++)

if (hoten[i] == 'n') d++;

return d;

}

Bƣớc 3: Viết các hàm đếm từ, đếm ký tự ‗n‘, chuyển hoa các ký tự đầu từ.

static void Main(string[] args)

{

string hoten;

Console.Write("Nhap ho ten: ");

hoten = Console.ReadLine();

Chuanhoaxau(ref hoten);

Console.WriteLine("Xau sau khi chuan hoa {0}", hoten);

Hienthitenhodem(hoten);

Chuyenchuhoadautu(ref hoten);

Console.WriteLine("Xau sau khi chuyen thanh hoa {0}", hoten);

Console.WriteLine("So tu trong xau {0}", demtu(hoten));

Console.WriteLine("So ky tu n trong xau {0}", demkytu(hoten));

Console.ReadLine();

}

Bƣớc 4: Viết hàm Main()

Kết quả chƣơng trình:

114

Tập bài giảng Lập trình cơ bản

Hình 3.25: Kết quả chương trình bài 3.9

Bài 3.10 Lập chƣơng trình thực hiện các công việc sau:

1. Nhập một xâu ký tự 2. Đếm xem trong xâu có bao nhiêu ký tự là chữ số

3. Kiểm tra xâu vừa nhập có phải là xâu đối xứng hay không (xâu ―abcdcba‖ là

xâu đối xứng)

4. Thay các ký tự ‗a‘ có trong xâu bằng ký tự ‗b‘.

5. Đƣa ra từ có độ dài lớn nhất trong xâu.

115

Tập bài giảng Lập trình cơ bản

CHƢƠNG 4: LẬP TRÌNH TRÊN FORM

Trong chƣơng này, giới thiệu cách xây dựng một ứng dụng Windows Forms cơ

bản bằng cách sử dụng các điều khiển thông dụngtrong các ứng dụng GUI. Đồng thời

hƣớng dẫn cách thiết lập các thuộc tính của Windows Forms và các điều khiển bằng

cách sử dụng thiết kế trực quan hoặc cửa sổ Properties và thay đổi hoặc kiểm tra giá trị

của các thuộc tính tự động bằng cách sử dụng mã lệnh trong C#.

4.1. Giới thiệu về lập trình trên Form Trƣớc .NET, các nhà phát triển có vài chọn lựa trong việc xây dựng một ứng

dụng Windows. Họ có thể xây dựng một ứng dụng bằng C hay C++ sử dụng Win32

API. Việc này là công việc rất khó và chi phối thời gian. Tiếp đến là sử dụng

Microsoft Foundation Classes (MFC) là một thƣ viện lớp sử dụng C++ đƣợc gói gọn

trong Win32 API để xây dựng úng dụng Windows và Visual Basic là một công cụ phát

triển mạnh cho phép tạo các ứng ụng Windows tƣơng đối nhanh chóng. Tuy nhiên, các giải pháp này đều không sử dụng .NET Framework hay CLR.

.NET Framework chứa một tầng lớp tiện ích mới dựa trên Win32 API và giống

nhƣ MFC và Visual Basic, nó cho phép phát triển các ứng dụng Windows hiệu suất

cao hơn và dễ dàng hơn. Môi trƣờng này đƣợc gọi là Windows Forms, cho phép các lập trình viên tạo racác ứng dụng Windows tƣơng tác tốt hơn và lớn hơn sử dụng bất kỳ ngôn ngữ .NET nào.

4.2. Làm việc với Form

4.2.1. Một số khái niệm Windows Forms là một tập hợp các thƣ viện lớpđƣợc quản lý trong .NET Framework để phát triển các ứng dụng desktop trên máy tính. Trong Windows Forms,

Form là một cửa sổ giao diện cho phép hiển thị thông tin và tƣơng tác với ngƣời dùng.

116

Tập bài giảng Lập trình cơ bản

Các ứng dụng Windows Forms thƣờng đƣợc xây dựng bằng cách thêm các điều khiển

vào Form và xây dựng sự kiện tƣơng ứng với các hành động của ngƣời dùng, chẳng

hạn nhƣ kích chuột hay bấm phím nào đó. Một điều khiển (control) là một thành phần

có giao diện riêng (User Interface) và có thể hiển thị dữ liệu hoặc nhận dữ liệu vào.

Để xây dựng một ứng dụng Windows Forms, có thể sử dụng rất nhiều đối

tƣợng của lớp thuộc các không gian tên khác nhau (namespace), tuy nhiên có một

không tên quan trọng không thể thiếu trong ứng dụng Windows Forms đó là System.Windows.Forms.

System.Windows.Forms chứa các lớp dùng để tạo ứng dụng Windows với giao

diện ngƣời sử dụng mang các đặc điểm ƣu việt có trên hệ điều hành Windows.

Ví dụ 4.1 sau đây sẽ tạo ứng dụng Windows Form nhƣ mẫu sau:

Hình 4.1: Giao diện ví dụ 4.1

Yêu cầu:

- Đặt dòng tiêu đề Form là Ví dụ 4_1

- Hiển thị dòng chữ Xin chào trên Form

-Khi kích chuột vào nút ―Thoát‖: Thực hiện đóng Form trên.

Hướng dẫn thực hiện:

Bƣớc 1: Tạo ứng dụng Windows Forms Application: Mở Visual Studio 2010 vào File|New|Project và thực hiện thiết lập theo hình

4.2.

117

Tập bài giảng Lập trình cơ bản

Hình 4.2: Các bước tạo ứng dụng Windows Forms Application

Sau khi click ―Ok‖, Visual Stuidio 2010 sẽ có giao diện nhƣ hình 4.3:

Hình 4.3: Giao diện ứng dụng Windows Forms Application sau khi tạo.

Khi làm việc với ứng dụng Windows Form, một số cửa sổ thƣờng xuyên sử

dụng, nhƣ hình 4.3, ở giữa sẽ là giao diện của Form1 vừa tạo ra (Form1.cs[Design]),

nơi đƣợc dùng để thiết kế giao diện ứng dụng, sẽ chứa những điều khiển đƣợc thêm

vào, bên trái sẽ là cửa số Toolbox nơi chứa các điều khiển cho phép kéo thả vào Form.

118

Tập bài giảng Lập trình cơ bản

Hình 4.4: Cửa sổ Toolbox.

Bên phải là cửa sổ Cửa sổSolutionExplorer:Hiển thị các Project trong Solution, hiển

thị tất cả các tệp trong Project và Project với tên đƣợc tô đậmsẽ đƣợc chạy đầu tiên

Hình 4.5: Cửa sổ Solution Explorer.

Chú ý: Nếu các cửa sổ này không xuất hiện thì vào View để mở lại các cửa sổ

đó. Bƣớc 2: Thay đổi tiêu đề cho Form. Để thay đổi tiêu đề Form, chọn Form1 trong cửa sổ Form1.cs[Design] và mở

cửa sổ Properties để thay đổi thuộc tính Text trên Form1.

119

Tập bài giảng Lập trình cơ bản

Hình 4.6: Cửa sổ Properties của Form1. Nếu cửa sổ Properties không xuất hiện thì chọn Form1 và nhấn phím F4.

Bƣớc 3: Hiển thị dòng chữ ―Xin chào‖ trên Form1.

, giữ chuột và kéo vào Form1

- Mở cửa sổ Toolbox, tìm tới điều khiển Label nhƣ hình 4.7:

Hình 4.7: Thêm điều khiển Label vào Form1.

- Chọn điều khiển label1 trên Form1, mở cửa sổ Properties của điều khiển label1 và sửa thuộc tính tính Text ban đầu là ―label1‖ thành ―Xin chào!‖

120

Tập bài giảng Lập trình cơ bản

Hình 4.8: Thay đổi thuộc tính Text của điều khiển label1.

Kết quả:

Hình 4.9: Kết quả sau khi thay đổi thuộc tính Text của điều khiển label1

- Tiếp theo thay đổi Font chữ cho điều khiển label1. Mở cửa sổ Properties của

sẽ xuất

điều khiển label1, chọn thuộc tính Font, kích chuột vào biểu tƣợng hiện của sổ Font nhƣ hình 4.10.

Hình 4.10: Cửa sổ Font.

- Thực hiện các thay đổi sau:

Font: Time New Roman

121

Tập bài giảng Lập trình cơ bản

Size: 16

Font style: True

- Sau đó thay đổi màu chữ bằng cách thiết lập thuộc tính ForeColor: Blue

Kết quả:

Hình 4.11: Thay đổi Font và màu chữ của điều khiển label1.

Bƣớc 4: Thêm nút ―Thoát‖ và viết mã lệnh cho sự kiệnKích chuộtcủa nút

―Thoát‖

- Thêm điều khiển Button từ Toolbox vào Form1, thực hiện các thiết lập

thuộc tính chon button1 nhƣ sau:

Name:btThoat

Text: Thoát

- Trên cửa sổ Properties của nút ―Thoát‖, chọn biểu tƣợng để mở danh sách

các sự kiện (event) của đối tƣợng lớp Button nhƣ hình 4.12, chọn sự kiện Click

và double click vào sự kiện này, sẽ xuất hiện trong file Forms.cs một phƣơng

thức đƣợc sinh ra tƣơng ứng với sự kiện Click của nút thoát (btThoat_Click)

nhƣ hình 4.13.

122

Tập bài giảng Lập trình cơ bản

Hình 4.12: Chọn sự kiện Click

Hình 4.13: Phương thức btThoat_Click

private void btThoat_Click(object sender, EventArgs e)

{

this.Close();//Phương thức dùng để đóng Form

}

- Viết mã lệnh cho sự kiện Kích chuộtcủa nút ―Thoát‖

Bƣớc 5: Ấn phím F5 để chạy thử chƣơng trình và đƣợc kết quả nhƣ hình 4.1.

4.2.2. Các loại Form Form có ba loại chính là Form dạnh Multiple Document Interface (MDI) còn

đƣợc gọi là MDI Form (Form cha) cho phép trình bày các Form (Child Form hay

Form con)khác bên trong. Những Form mở ra không nằm trong MDI Form gọi là

Normal Form

MDI Form Một Form đƣợc gọi là MDI Form khi thuộc tính IsMdiContainer có giá trị True.

Khi chuyển thuộc tính IsMdiContainer của Form từ False sang True, lập tức màu nền

của Form đổi thành màu xám nhƣ hình 4.14.

Hình 4.14: Màu nền của MDI Form.

Ví dụ 4.2: Thiết lập thuộc tính IsMdiContainer

//Tạo Form frm và cho frm là MDI Form

123

Tập bài giảng Lập trình cơ bản

Form frm = newForm1();

frm.IsMdiContainer = true;

frm.Show();//Hiển thị Form

Child Form Child Form là Form khi nạp lên sẽ nằm trong một MDI Form. Để Form trở

thành Child Form thì khai báo thuộc tính MdiParent tƣơng ứng với MDI Form.

Ví dụ 4.3: Khai báo để mở Child Form có tên frm lớp Form3. Form frm = new Form3();

frm.MdiParent = this;//this thể hiện Form gọi đến Form Frm là MDI Form

frm.Show();//Hiển thị Form

Normal Form Normal Form là Form không phải MDI Form hoặc Child Form

4.2.3. Thuộc tính của Form Những thuộc tính chung của Windows Form đƣợc liệt kê trong bảng sau:

Thuộc tính Mô tả

Name Là thuộc tính để xác định tên của Form, mặc định, thuộc

tính Name của Form đầu tiên trong ứng dụng là Form1

Backcolor Thuộc tính xác định màu nền của Form

BackgroundImage Thuộc tính xác định hình nền cho Form

Font Thuộc tính xác định kiểu, kích thƣớc và loại font đƣợc hiển

thị trên Form và trong những điều khiển trong Form

Size Kích thƣớc của Form bao gồm: Width và Height

Start Position Thuộc tính xác định vị trị mặc định xuất hiện của Form trên

màn hình máy tính ngƣời sử dụng, có các thuộc tính sau:

- Manual - vị trí và kích thƣớc của Form phụ thuộc vào vị

trí xuất hiện của nó

- CenterScreen - xuất hiện ở chính giữa màn hình

- WindowsDefaultLocation - Form xuất hiện tại vị trí mặc định của Windows theo kích thƣớc của Form. - Windows DefaultBounds - Form đƣợc hiển thị tại vị trí mặc định của Windows và các chiều của chúng phụ thuộc vào hệ điều hành Windows. - Center Parent - Form đƣợc mở nhƣ một cửa sổ con của một Form khác và xuất hiện tại vị trí chính giữa so với Form cha.

Text Xác định tiêu đề của Form

124

Tập bài giảng Lập trình cơ bản

WindowState Xác định trạng thái xuất hiện của Form: Normal, Maximized,

hay Minimized.

Bảng 4.1: Một số thuộc tính của Form

Ví dụ 4.4: Tạo Form và thực hiện thay đổi một số thuộc tính trên Form nhƣ sau:

Name: frm4_4

Text: Ví dụ 4_4

Size: 500, 500

BackColor:Red WindowState: Maximized

Kết quả Form hiển thị nhƣ hình 4.15.

Hình 4.15: Form sau khi thay đổi một số thuộc tính theo ví dụ 4.4.

4.2.4. Sự kiện trên Form Những sự kiện trong Windows Form đƣợc liệt kê nhƣ bảng sau:

Mô tả Sự kiện

Click Sự kiện này xảy ra khi click vào bất kỳ nơi nào trên Form

Closed Sự kiện này xảy ra khi một Form đƣợc đóng lại

Deactivate Sự kiện xảy ra khi một Formbị mất trạng thái sử dụng

Load Sự kiện xảy ra khi một Formđƣợc tải trong bộ nhớ cho lần đầu tiên.

MouseMove Sự kiện này xuất hiện khi chuột đƣợc rê trên một Form

MouseDown Sự kiện xảy ra khi chuột đƣợc nhấn trên Form

MouseUp Sự kiện xảy ra khi chuột đƣợc thả trên Form

Resize Sự kiện xảy ra khi thay đổi kích thƣớc Form

Closing Sự kiện xảy ra khi đang đóng Form

Bảng 4.2: Một số sự kiện của Form

4.2.5. Phƣơng thức của Form

Phƣơng thức Mô tả

125

Tập bài giảng Lập trình cơ bản

Show Đƣợc sử dụng để xuất hiện một Form bằng cách thiết lập thuộc

tính Visible của Form ấy là true

ShowDialog Hiển thị Form dạng modal (không cho phép dùng Form khác khi

trừ khi nó đƣợc đóng lại)

Close Dùng để đóng một Form

Hide Dùng để ẩn một Form

Bảng 4.3: Một số phương thức của Form

Ví dụ 4.5: Các sự kiện và phƣơng thức của Form

Yêu cầu:

- Tạo Form nhƣ mẫu sau:

Hình 4.16: Giao diện Form ví dụ 4.5

- Viết các thông báo cho các sự kiện Load(), Closing(), Resize(), Closed()

- Khi kích chuột vào nút ―Hiện Form‖: Hiển thị 1 Form mới

- Khi kích chuột vào nút ―Ẩn Form‖: Ẩn Form vừa mở

- Khi kích chuột vào nút ―Hiện Form dạng modal‖: Mở Form dƣới dạng modal

- Khi kích chuột vào nút ―Đóng Form‖: Đóng Form.

Bƣớc 1: Tạo Form đặt tên là frmVidu4_5

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_5 1 Form Text Ví dụ 4_5

Text 2 Label Một số phƣơng thức của Form

Name btHien 3 Button Text Hiện Form

126

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

Name btAn 4 Button Text Ẩn Form

Name btHienModal 5 Button Text Hiện Form dạng modal

Name btDong 6 Button Text Đóng Form

private void frmVidu4_5_Load(object sender, EventArgs e)

{

MessageBox.Show("Form được load");

}

private void frmVidu4_5_MouseClick(object sender, MouseEventArgs e)

{

MessageBox.Show("Form vừa được kích chuột");

}

private void frmVidu4_5_FormClosed(object sender, FormClosedEventArgs e)

{

MessageBox.Show("Form đã đóng");

}

private void frmVidu4_5_FormClosing(object sender,FormClosingEventArgs e)

{

MessageBox.Show("Form đang đóng");

} Bƣớc 3: Viết mã lệnh cho sự kiện Click của các nút trên Form:

Form frm = new Form();//Khai báo đối tượng Form frm sử dụng trong các sự

kiện click của các nút

private void btHien_Click(object sender, EventArgs e)

{

frm.Show();

}

private void btAn_Click(object sender, EventArgs e)

{

frm.Hide();

}

private void btDong_Click(object sender, EventArgs e)

{

frm.Close();

}

private void btHienModal_Click(object sender, EventArgs e)

{

Bƣớc 2: Viết mã lệnh cho các sự kiện của Form

127

frm.ShowDialog();

}

Tập bài giảng Lập trình cơ bản

Trong ví dụ trên có sử dụng lớp MessageBox và phƣơng thức tĩnh Show() của lớp này để hiển thị một hộp thoại thông báo, chi tiết về lớp MessageBox sẽ đƣợc giới thiệu trong phần 4.4.3. Điều khiển Dialog.

4.3. Một số điều khiển thông dụng

4.3.1. Các thuộc tính và sự kiện chung Hầu hết các điều khiển trên Form đều có một số thuộc tính chung nhƣ trong

bảng 4.4:

Mô tả

Thuộc tính BackColor

Màu nền của điều khiển.

Enabled Điều khiển đƣợc phép tƣơng tác (true) hay không đƣợc phép tƣơng

tác (false) với ngƣời dùng.

ForeColor Màu chữ của điều khiển.

Name Tên của điều khiển.

Text Nội dung chuỗi hiển thị trên điều khiển.

Visible Cho phép điều khiển hiện (True) / không hiện (False) khi chạy ứng

dụng.

Width

Là chiều rộng của điều khiển tính từ cạnh trái của điều khiển đến cạnh phải của điều khiển.

Height Là chiều cao của điều khiển tính từ cạnh trên của điều khiển đến

cạnh dƣới của điều khiển.

Bảng 4.4: Một số thuộc tính chung của các điều khiển

Các sự kiện chung thƣờng sử dụng của các điều khiển đƣợc trình bày trong

bảng 4.5.

Sự kiện Mô tả

Click Xảy ra khi điều khiển bị kích chuột. Trong một vài điều khiển,

event này cũng xảy ra khi nhấn phím Enter.

MouseDown Xảy ra khi kích chuột trái nhƣng chƣa thả ra.

MouseMove Xảy ra đến khi con trỏ chuột đi qua 1 điều khiển.

MouseUp Xảy ra khi kích chuột trái và thả ra.

KeyDown

Xảy ra khi vừa bấm một phím bất kỳ từ 1 điều khiển đang đƣợc chọn.Sự kiện này luôn đƣợc gọi trƣớc sự kiện KeyUp.

KeyPress

Xảy ra khi vừa bấm một phím bất kỳ từ 1 điều khiển đang đƣợc chọn. Sự kiện này đƣợc gọi sau sự kiện KeyUp.

KeyUp Xảy ra khi vừa bấm một phím bất kỳ rồi thả ra từ 1 điều khiển

128

Tập bài giảng Lập trình cơ bản

đang đƣợc chọn. Sự kiện này luôn đƣợc gọi sau sự kiện KeyDown.

Bảng 4.5: Một số sự kiện chung của các điều khiển

4.3.2. Nhóm điều khiển Label

1. Label

- Công dụng: Hiển thị chuỗi ký tự. - Thuộc tính:

Thuộc tính Mô tả

AutoSize

Điều chỉnh kích thƣớc đối tƣợng cho vừa với chiều dài chuỗi ký tự

Font Kiểu và kích thƣớc của chữ trình bày trên điều khiển

TextAlign Canh lề (Left / Center / Right)

Bảng 4.6: Một số thuộc tính của Label

Chẳng hạn, thiết kế Form dạng đăng nhập, bên cạnh các điều khiển yêu cầu

nhập họ tên sinh viên, mã sinh viên, lớp, Form chứa các điều khiển Label:―Họ tên

SV‖, ―Mã SV‖, ―ĐĂNG NHẬP‖, ―Lớp‖ nhƣ hình 4.17.

Hình 4.17: Sử dụng điều khiển Label.

2. LinkLabel - Công dụng: ngoài chức năng hiển thị chuỗi thì điều khiển LinkLabel cho

phép liên kết đến địa chỉ Internet hoặc Email.

- Thuộc tính:

Thuộc tính Mô tả

LinkArea Vùng liên kết theo chiều dài và ký tự bắt đầu

LinkBehavior

Trạng thái của liên kết, mặc định là SystemDefault, có thể hay chọn: AllwasUnderline, HoverUnderline

NeverUnderline.

129

Tập bài giảng Lập trình cơ bản

LinkColor Màu của liên kết

VisitedLinkColor Màu của liên kết sau khi đã chọn

Bảng 4.7: Các thuộc tính của LinkLabel

- Sự kiện:

Sự kiện Mô tả

LinkClicked Xảy ra khi kích chuộttrên điều khiển LinkLabel

DoubleClick Xảy ra khi kích chuột hai lần trên điều khiển LinkLabel

Bảng 4.8: Các sự kiện của LinkLabel

Ví dụ 4.6: Điều khiển LinkLabel

Yêu cầu: - Tạo Form theo mẫu:

Hình 4.18: Ví dụ về điều khiển LinkLabel.

- Khi kích chuột vào điều khiển LinkLabel sẽ chuyển tới địa chỉ trang

https://www.google.com.vn/ trên trình duyệt nhƣ hình sau:

Hình 4.19: Hiển thị trang https://www.google.com.vn/ trên trình duyệt web

Hướng dẫn thực hiện

130

Tập bài giảng Lập trình cơ bản

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_6, them điều khiển LinkLabel

vào trong Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_6 1 Form Text Điều khiển LinkLabel

Text https://www.google.com.vn 2 LinkLabel Name linkLabel1

Bƣớc 2: Viêt khai báo liên kết cho điều khiển LinkLabel trong sự kiện

private void frmVidu4_6_Load(object sender, EventArgs e)

{

this.linkLabel1.Links.Add(0,100,‛https://www.google.com.vn");

} //Thêm một liên kết mới vào đối tương linkLabel1.

frmVidu4_6_Load.

Bƣớc 3: Kích chuột hai lần vào điều khiển linkLabel1 để sinh sự kiện

private void linkLabel1_LinkClicked(object sender,

LinkLabelLinkClickedEventArgs e)

{

string strURL = Convert.ToString(e.Link.LinkData);

if (strURL.StartsWith(@"https://www"))

Process.Start(strURL);//thực thi một ứng dụng ngoài, cho phép xem một tài liệu

hay một trang web

}

// Sử dụng thêm không gian tên System.Diagnostics;

LinkClicked và thực hiện thêm đoạn mã lệnh sau vào sự kiện này.

Bƣớc 4: Nhấn F5 để chạy chƣơng trình.

4.3.3. Nhóm điều khiển TextBox

1. Textbox

- Công dụng: Dùng để nhập và hiển thị văn bản. - Thuộc tính:

Thuộc tính Mô tả

Text Xác định chuỗi hiển thị của TextBox

Multiline Cho phéphiển thị văn bản trên nhiều dòng.

PasswordChar

Thuộc tính này cho phép lấy một ký tự làm đại diện cho tất cả các ký tự khác đƣợc nhập vào

Bảng 4.9: Một số thuộc tính của TextBox

- Sự kiện:

Sự kiện Mô tả

TextChanged Xảy ra khi chuỗi trên điều khiển thay đổi

131

Tập bài giảng Lập trình cơ bản

MouseClick Xảy ra khi kích chuột trên điều khiển TextBox

MultilineChanged Xảy ra khi thuộc tính Multiline thay đổi giá trị từ True

sang False hay ngƣợc lại.

Bảng 4.10: Một số sự kiện của TextBox

Ví dụ 4.7: Điều khiển TextBox

Yêu cầu:

- Tạo Form theo mẫu sau:

Hình 4.20: Ví dụ về điều khiển TextBox - Các nhãn: ―Tên đăng nhập‖, ―Mật khẩu‖, ―Mô tả‖ - Các điều khiển để nhập tên đăng nhập, mật khẩu và mô tả là các Textbox Lập trình cho các sự kiện: - Kích chuộtvào nút ―Đăng nhập‖: Kiểm tra xem tên đăng nhập có phải là ―abcde‖ và mật khẩu là ―12345‖ hay không và sẽ đƣa ra thông báo là

đăng nhập thành công hay thất bại

- Kích chuột vào nút ―Xóa‖: Thực hiện xóa nội dung của các điều khiển

TextBox

- Kích chuột vào nút ―Thoát‖: Thực hiện đóng Form. - Nếu TextBox tên đăng nhập là rỗng thì nút ―Đăng nhập‖ bị vô hiệu hóa,

ngƣợc lại cho phépkiểm tra khi kích chuột vào nút ―Đăng nhập‖.

Hướng dẫn thực hiện

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_7, thêm các điều khiển TextBox

và Button vào trong Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_7 1 Form Text Điều khiển TextBox

Multiline True TextBox 2 Name txtMota

TextBox PasswordChar * 3

132

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

Name txtMatkhau

TextBox 4 Name txtTendangnhap

Text Đăng nhập Button 5 Name btDangnhap

Text Xóa 6 Button Name btXoa

Text Thoát 7 Button Name btThoat

8 Label Text Tên đăng nhập

9 Label Text Mật khẩu

10 Label Text Mô tả

private void Vidu4_7_Load(object sender, EventArgs e)

{

btDangnhap.Enabled = false;

}

Bƣớc 2: Viết mã lệnh cho sự kiện Vidu4_7_Load

Bƣớc 3: Viết mã lệnh cho các sự kiện Click của các nút Đăng nhập, nút Thoát

private void btThoat_Click(object sender, EventArgs e)

{

this.Close();

}

private void btXoa_Click(object sender, EventArgs e)

{

txtMatkhau.Clear();//Xóa nội dung của TextBox

txtTendangnhap.ResetText();//Gán giá trị thuộc tính Text bằng giá

trị mặc định

}

private void btDangnhap_Click(object sender, EventArgs e)

{

if (txtTendangnhap.Text == "abcde" && txtMatkhau.Text == "12345")

MessageBox.Show("Đăng nhập thành công");

else MessageBox.Show("Đăng nhập thất bại");

}

và nút Xóa

private void txtTendangnhap_TextChanged(object sender, EventArgs e)

{

if (txtTendangnhap.Text != "") btDangnhap.Enabled = true;

Bƣớc 4: Viết mã lệnh cho sự kiện TextChanged của txtTendangnhap, nếu có ký tự đƣợc nhập vào thì nút ―Đăng nhập‖ có thuộc tính Enabled là True, ngƣợc lại sẽ là False

133

else btDangnhap.Enabled = false;

}

Tập bài giảng Lập trình cơ bản

Ví dụ 4.8: Chƣơng trình tìm ƣớc chung lớn nhất, bội chung nhỏ nhất:

Yêu cầu: - Tạo Form theo mẫu sau:

Hình 4.21: Giao diện ví dụ 4.8. - Các điều khiển để nhập số thứ nhất, số thứ 2, UCLN và BCNN là các TextBox - Các nhãn: ―UCLN, BCNN‖, ―Nhập số 1‖, ―Nhập số 2‖. - Khi kích chuột vào nút ―UCLN‖: Thực hiện tính và hiển thị ƣớc chung lớn nhất

của 2 số nguyên dƣơng đƣợc nhập vào.

- Khi kích chuột vào nút ―BCNN‖: Thực hiện tính bội chung nhỏ nhất của 2 số

nguyên dƣơng đƣợc nhập vào.

- Trong sự kiệnkích chuột của hai nút có kiểm tra dữ liệu của 2 số nhập vào có phải là 2 số nguyên dƣơng không, nếu không phải đƣa ra thông báo dữ liệu

không hợp lệ.

Hướng dẫn thực hiện:

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_8, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_8 1 Form Text Tìm ƢCLN, BCNN

2 TextBox Name txtSo1

3 TextBox Name txtSo2

4 TextBox Name txtUCLN

5 TextBox Name txtBCNN

Text UCLN 6 Button Name btUCLN

7 Button Text BCNN

134

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

Name btBCNN

8 Label Text Nhập số 1

9 Label Text Nhập số 2

Text UCLN, BCNN

Font Times New Roman 10 Label Font style Bold

Size 22

private bool Kiemtra()

{

int so1, so2;

bool kt1, kt2;

kt1 = int.TryParse(txtSo1.Text, out so1);

kt2 = int.TryParse(txtSo2.Text, out so2);

return kt1 && kt2 && so1 >0 && so2 >0;

}

private int UCLN(int n, int m)

{

int du;

do

{

du = n % m;

n = m;

m = du;

} while (du != 0);

return n;

}

Bƣớc 2: Xây dựng các hàm kiểm tra dữ liệu và hàm tìm ƢCLN.

Bƣớc 3: Viết mã lệnh cho sự kiện kích chuột của các nút ―UCLN‖ và nút

private void btUCLN_Click(object sender, EventArgs e)

{

if (Kiemtra())

{

int so1, so2;

so1 = int.Parse(txtSo1.Text);

so2 = int.Parse(txtSo2.Text);

txtUCLN.Text = UCLN(so1, so2).ToString();

}

else

MessageBox.Show("Dữ

liệu

không

hợp

lệ","Thông

báo",

MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

}

―BCNN‖

135

private void btBCNN_Click(object sender, EventArgs e)

{

if (Kiemtra())

{

int so1, so2;

so1 = int.Parse(txtSo1.Text);

so2 = int.Parse(txtSo2.Text);

txtBCNN.Text = ((so1*so2)/UCLN(so1, so2)).ToString();

}

else

MessageBox.Show("Dữ

liệu

không

hợp

lệ","Thông

báo",

MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

}

Tập bài giảng Lập trình cơ bản

2. MaskedTextBox

- Công dụng: Đƣợc sử dụng để quy định dạng thức cho dữ liệu nhập vào - Thuộc tính:

Thuộc tính Mô tả

Mask Thiết lập mặt nạ cho điều khiển MaskedTextBox, một số

mặt nạ có sẵn đƣợc mô tả trong hình 4.21.

PromptChar Ký tự nhắc nhở khi nhập dữ liệu

BeepOnError Xuất hiện tiếng Beep khi dữ liệu nhập không hợp lệ

PasswordChar Thuộc tính này cho phép lấy một ký tự làm đại diện cho

tất cả các ký tự đƣợc nhập vào.

Bảng 4.11: Một số thuộc tính của MaskedTextBox

Hình 4.22: Một số định dạng cho thuộc tính Mask

- Sự kiện:

Sự kiện Mô tả

TextChanged Xảy ra khi chuỗi trên điều khiển thay đổi

MouseClick Xảy ra khi kích chuột trên điều khiển

MaskedTextBox

136

Tập bài giảng Lập trình cơ bản

MaskChanged Xảy ra khi định dạng nhập liệu trong thuộc tính

Mask thay đổi

MaskInputRejected Xảy ra khi dữ liệu nhập vào điều khiển bị từ chối

TypeValidationCompleted Xảy ra khi MaskedTextBox hoàn tất việc kiểm tra

cú pháp (parsing) cho giá trị hiện hành

thông qua property ValidatingType

Bảng 4.12: Một số sự kiện của MaskedTextBox

Ví dụ 4.9: Điều khiển MaskedTextBox

Yêu cầu:

- Tạo Form theo mẫu sau:

Hình 4.23: Ví dụ về điều khiển MaskedTextBox

- Điểu khiển MaskedTextBox cho phép nhập ngày tháng năm, sẽ xuất hiện thông báo lỗi nếu nhập sai và hiển thị kết quả ngày tháng năm nếu nhập

đúng

- Khi kích chuột vào nút ―Hiển thị‖: Hiển thị ngày tháng năm nếu nhập

đúng trong điều khiển MaskedTextBox

Hướng dẫn thực hiện

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_9, thêm các điều khiển

MaskedTextBox và Button vào trong Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_9

1 Form Text

Điều khiển MaskedTextBox

Mask 00/00/0000, Datetime 2 MaskedTextBox Name mtbNgaythangnam

Text Hiển thị 3 Button Name btHienthi

137

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

4 Label Text Nhập ngày tháng năm

private

void

mtbNgaythangnam_MaskInputRejected(object

sender,

MaskInputRejectedEventArgs e)

{

MessageBox.Show("Lỗi: " + e.RejectionHint.ToString() +

"; vị trí: " + e.Position.ToString());

}//Xuất hiện lỗi nếu nhập dữ liệu không đúng

Bƣớc 2: Viết mã lệnh cho sự kiện MaskInputRejected, bằng cách click 2 lần chuột vào điều khiển mtbNgaythangnam

private void btHienthi_Click(object sender, EventArgs e)

{

DateTime value;

bool kt = DateTime.TryParse(mtbNgaythangnam.Text, out value);

if(kt) MessageBox.Show("Ngày: " + value.ToLongDateString());

else MessageBox.Show("Ngày không hợp lệ ");

}

Bƣớc 3: Viết mã lệnh cho các sự kiện Click của các nút ―Hiển thị‖

3. RichTextBox

- Công dụng: cho phép hiển thị văn bản trên nhiều dòng - Thuộc tính và sự kiên: tƣơng tự nhƣ điều khiển TextBox

4.3.4. Nhóm điều khiển ComboBox, ListBox

1. ComboBox

- Công dụng: Dùng để hiển thị một danh sách các mục cho phép lựa chọn /

hoặc nhập vào một chuỗi để lựa chọn.

- Thuộc tính:

Thuộc tính Mô tả

Items Lƣu trữ các mục (item) trong ComboBox, thuộc tính

Itemscó rất nhiều phƣơng thức đƣợc sử dụng nhƣ để

thêm1 phần tử(Add), xóamột phần tử (Remove), xóa toàn

bộ (Clear) hay trả về số phần tử thông quá thuộc tính Count của Items…

SelectedItem Trả về hoặc gán Item (object) đƣợc chọn

SelectedText

Trả về hoặc gán nội dung thể hiện ứng với phần tử đƣợc chọn

SelectedIndex Trả về hoặc gán giá trị chỉ mục ứng với phần tửđang chọn

Text Trả về hoặc gán giá trị chuỗi ứng với phần tử đƣợc chọn

DropDownStyle Kiểu trình bày danh sách các phần tử, mặc định là

138

Tập bài giảng Lập trình cơ bản

DropDown (cho phép nhập chuỗi), DropDownList chỉ

cho phép chọn trong danh sách, Simple (dạng danh sách)

Bảng 4.13: Một số thuộc tính của ComboBox

- Sự kiện:

Sự kiện Mô tả

TextChanged Xảy ra khi chuỗi trên điều khiển thay đổi

MouseClick ra khi kích chuột trên điều khiển

Xảy ComboBox

SelectedIndexChanged Xảy ra khi chỉ mục chọn thay đổi

Bảng 4.14: Một số sự kiện của ComboBox

Ví dụ 4.10: Điều khiển ComboBox Yêu cầu:

- Tạo Form theo mẫu sau:

Hình 4.24: Ví dụ về điều khiển ComboBox

- Điểu khiển ComboBox lƣu trữ các phép toán (+ - * / %) - Các nhãn:‖Số hạng 1‖, ―Số hạng 2‖, ―Phép tính‖, ―=‖ và một nhãn dùng

để hiển thị kết quả của phép tính.

- Các điều khiển nhập số hạng 1 và số hạng 2 là các điều khiển TextBox. - Khi kích chuột vào nút ―Tính‖: Dựa trên việc lựa chọn phép tính sẽ tính kết quả của phép tính đó với hai số hạng đƣợc nhập vào và hiển thị ra nhãn kết quả

- Khi kích chuột vào ―Thoát‖: Đóng Form - Nếu chọn phép toán ―/‖ trong điều khiển ComboBox sẽ xuất hiện một

thông báo yêu cầu nhập số hạng thứ 2 là một số khác 0.

Hướng dẫn thực hiện:

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_10, thêm các điều khiển vào trong

Form.

139

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_10 1 Form Text Phép tính

DropDownStyle DropDownList 2 ComboBox Name cbbPheptoan

Text Tính 3 Button Name btTinh

Text Số hạng 1 4 Label

Text Phép tính 5 Label

Text Số hạng 2 6 Label

Text Kết quả 7 Label

Text = 8 Label

Text 9 Label Name lblKetqua

Text Thoát 10 Button Name btThoat

Bƣớc 2: Thêm các ký hiệu phép toán vào điều khiển ComboBox. Chọn

ComboBox, tại cửa sổ Properties Window, chọn thuộc tính Items, nhấn vào nút và cửa sổ String Collection Editor xuất hiện nhƣ hình 4.25 và thực hiện thêm các ký hiệu

phép toán vào.

Hình 4.25: Cửa sở String Collection Editor

Bƣớc 3: Cách thứ 2 để thêm phần tử vào điều khiển ComboBox là sử dụng

private void frmVidu4_10_Load(object sender, EventArgs e)

{

cbbPheptoan.SelectedIndex = 0; //thiết lập mục chọn đầu tiên ở

trong combobox

cbbPheptoan.Items.Add("%");//Thêm phép toán % vào trong thuộc tính

Items của combobox

phƣơng thức Add của thuộc tính Items nhƣ trong đoạn mã lệnh sau:

140

}

Tập bài giảng Lập trình cơ bản

Bƣớc 4: Viết mã lệnh cho sự kiện SelectedIndexChanged của đối tƣợng

ComboBox cbbPheptoan (kích chuột 2 lần vào điểu khiển ComboBox để sinh sự kiện

SelectedIndexChanged). Kiểm tra phép toán đƣợc chọn có phải là ―/‖, nếu đúng thì

private void cbbPheptoan_SelectedIndexChanged(object sender, EventArgs e)

{

if(cbbPheptoan.Text=="/")

MessageBox.Show("Số hạng thứ 2 phải là số khác 0");

}

đƣa ra thông báo phải nhập số hạng thứ 2 là số khác 0

private void btTinh_Click(object sender, EventArgs e)

{

if (kiemtra())

{

float sh1, sh2;

sh1 = float.Parse(txtSohang1.Text);

sh2 = float.Parse(txtSohang2.Text);

float kq = 0;

string tb = "";

switch (cbbPheptoan.SelectedItem.ToString())//trả về dòng được

chọn trong combobox

{

case "+": kq = sh1 + sh2; break;

case "-": kq = sh1 - sh2; break;

case "*": kq = sh1 * sh2; break;

case "/": if (sh2 != 0) kq = sh1 / sh2; else tb = "Số hạng

thứ 2 là một 0"; break;

case "%": kq = sh1 % sh2; break;

default: tb = "Không phải là phép toán cho phép"; break;

}

if (tb == "") lbKetqua.Text = kq.ToString();

else lbKetqua.Text = tb;

}

}

Bƣớc 5: Viết mã lệnh cho sự kiện kích chuột vào nút ―Tính‖

private void btThoat_Click(object sender, EventArgs e)

{

this.Close();

}

Bƣớc 6: Viết mã lệnh cho sự kiện kích chuột vào nút ―Thoát‖

2. ListBox

- Công dụng: Hiển thị và cho phép lựa chọn một danh sách cácphần tử - Thuộc tính:

141

Tập bài giảng Lập trình cơ bản

Thuộc tính Mô tả

Items Lƣu trữ các phần tử trong ListBox, thuộc tính Items có rất

nhiều phƣơng thức đƣợc sử dụng nhƣ để thêm một phần

tử (Add), xóa một phần tử (Remove), xóa toàn bộ (Clear) hay trả về số phần tử thông qua thuộc tính Count của

Items…

SelectedItem Trả về hoặc gán phần tử (object) đƣợc chọn

SelectedText Trả về hoặc gán chuỗi thể hiện ứng với phần tử đƣợc

chọn

SelectedIndex Trả về hoặc gán giá trị chỉ mục ứng với phần tử đang

chọn

Text Trả về hoặc gán giá trị chuỗi ứng với phần tử đƣợc chọn

SelectionMode Xác định cách lựa chọn các phần tử trong ListBox. Có 4

giá trị

- None: không cho phép chọn bất cứ phần tử nào trong

ListBox

- One: chỉ chọn một phần tử từ ListBox

- MultiSimple: cho phép chọn nhiều phần tử từ ListBox.

- MultiExtended: có thể chọn nhiều phần tử và sử dụng

phím SHIFT, CTRL và phím mũi tên để chọn những phần

tử từ ListBox.

Bảng 4.15: Một số thuộc tính của ListBox

- Sự kiện:

Sự kiện Mô tả

TextChanged Xảy ra khi chuỗi trên điều khiển thay đổi

MouseClick Xảy ra khi ngƣời sử dụng kích chuột trên điều

khiển ListBox

SelectedIndexChanged Xảy ra khi chỉ mục chọn thay đổi

Bảng 4.16: Một số sự kiện của ListBox

Ví dụ 4.11: Điều khiển ListBox Yêu cầu:

- Tạo Form theo mẫu sau:

142

Tập bài giảng Lập trình cơ bản

Hình 4.26: Ví dụ về điều khiển ListBox

- Điểu khiển ListBox lƣu trữ các số nguyên - Điều khiển để nhập một số nguyên là điều khiển TextBox: Lập trình sự kiện khi kích chuột vào các nút nhƣ sau: - Với nút ―Thêm‖: Thêm số nguyên vào ListBox - Với nút ―Thoát‖: Đóng Form - Với nút ―Tổng các phần tử‖: Tính tổng các số nguyên có trong ListBox - Với nút ―Xóa phần tử đầu‖: Xóa phần tử đầu tiên trong ListBox - Với nút ―Xóa phần tử cuối‖: Xóa phần tử cuối cùng trong ListBox - Với nút ―Xóa phần tử hiện tại‖: Xóa phần tử đƣợc chọn trong ListBox

Hướng dẫn thực hiện

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_11, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_11 1 Form Text Làm việc với Listbox

SelectionMode One 2 ListBox Name lbDayso

Text Thêm 3 Button Name btThem

Text Làm việc với Listbox

Font Times New Roman 4 Label Font style Bold

Size 22

143

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

Text ListBox 5 Groupbox Name groupBox1

Text Xử lý ListBox 6 Groupbox Name groupBox2

7 Label Text Nhập số nguyên

Text Kết quả 8 Label Name lblKetqua

Text Tổng các phần tử 9 Button Name btTong

Text Xóa phần tử đầu 10 Button Name btXoadau

Button Text Xóa phần tử cuối 11 Name btXoacuoi

Button Text Xóa phần tử hiện tại 12 Name btXoahientai

Button Text Thoát 13 Name btThoat

TextBox Text 14 Name txtSonguyen

private bool Kiemtra()

{

int so;

bool ktso = int.TryParse(txtSonguyen.Text, out so);

return ktso;

}

Bƣớc 2: Xây dựng hàm kiểm tra dữ liệu nhập vào TextBox txtSonguyen

private void btThem_Click(object sender, EventArgs e)

{

if (Kiemtra())

{

int so = int.Parse(txtSonguyen.Text);

lbDayso.Items.Add(so);//thêm một phần tử vào listbox

}

else MessageBox.Show("Dữ liệu không hợp lệ");

}

private void btThoat_Click(object sender, EventArgs e)

{

Bƣớc 3: Viết mã lệnh cho sự kiện kích chuột vào các nút có trong Form

144

this.Close();

}

private void btTong_Click(object sender, EventArgs e)

{

if (lbDayso.Items.Count > 0)//count trả về số phần tử có trong

listbox

{

int tong = 0;

int n = lbDayso.Items.Count;

for (int i = 0; i < n; i++)

{

int so = int.Parse(lbDayso.Items[i].ToString());//truy nhập

phần tử có chỉ số i trong items

tong = tong + so;

}

lbKetqua.Text = "Kết quả: tổng = " + tong.ToString();

}

else lbKetqua.Text = "Kết quả: không có phần tử trong listbox";

}

private void btXoadau_Click(object sender, EventArgs e)

{

if (lbDayso.Items.Count > 0)

{

lbDayso.Items.RemoveAt(0);//phần tử đầu có chỉ số bằng 0

MessageBox.Show("Loại bỏ phần tử đầu thành công");

}

}

private void btXoacuoi_Click(object sender, EventArgs e)

{

if (lbDayso.Items.Count > 0)

{

lbDayso.Items.RemoveAt(lbDayso.Items.Count - 1);//chỉ số phần

tử cuối cùng

MessageBox.Show("Loại bỏ phần tử cuối thành công");

}

}

private void btXoahientai_Click(object sender, EventArgs e)

{

if (lbDayso.Items.Count > 0)

{

if (lbDayso.SelectedIndex >= 0)

{

MessageBox.Show("Loại bỏ phần tử hiện tại với chỉ số = " +

lbDayso.SelectedIndex.ToString());

lbDayso.Items.RemoveAt(lbDayso.SelectedIndex);//chỉ số phần

tử hiện tại

Tập bài giảng Lập trình cơ bản

145

}

}

}

Tập bài giảng Lập trình cơ bản

4.3.5. Nhóm điều khiển CheckBox, RadioButtom

1. CheckBox

- Công dụng: Cho phép chọn một trong hai giá trị Yes/No hoặc True/False. Điều khiển CheckBox cho phép hiển thị hình ảnh, chuỗi hoặc cả hai trên điều khiển.

- Thuộc tính:

Thuộc tính Mô tả

Text Thuộc tính này sử dụng để nhận hoặc gán chuỗi ký tự

hiển thị của Checkbox

Checked Đƣợc sử dụng để xác định CheckBox đƣợc chọn hay

không

CheckState Trạng thái của điều khiển CheckBox đang chọn, có ba

trạng thái: Checked, Unchecked, Indeterminate.

ThreeState Cho phép hay không 3 trạng thái Checked, Unchecked,

Indeterminate của điều khiển CheckBox

Bảng 4.17: Một số thuộc tính của CheckBox

- Sự kiện:

Sự kiện Mô tả

MouseClick Xảy ra khi kích chuộtvào điều khiển ListBox

CheckedChanged Xảy ra khi kích chuột vào điều khiển CheckBox

Click Xảy ra khi kích chuột vào điều khiển CheckBox

CheckStateChanged Xảy ra khi thuộc tính CheckState bị thay đổi

Bảng 4.18: Một số sự kiện của CheckBox

Ví dụ 4.12: Điều khiển CheckBox Yêu cầu:

- Tạo Form theo mẫu sau:

146

Tập bài giảng Lập trình cơ bản

Hình 4.27: Ví dụ về điều khiển CheckBox

- Các điều khiển nhập 6 số a, b, c, d, e, f là các TextBox - Điều khiển để hiển thị kết quả là RichTextBox - Khi chọn CheckBox ―Tìm max‖: Hiển thị số lớn nhất trong 6 số đƣợc

nhập trong các điều khiển TextBox

- Khi chọn CheckBox ―Giải hệ phƣơng trình‖: Hiển thị nghiệm của hệ

phƣơng trình:

𝑎𝑥 + 𝑏𝑦 = 𝑒 𝑐𝑥 + 𝑑𝑦 = 𝑓

Hướng dẫn thực hiện

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_12, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_12 1 Form Text Làm việc với CheckBox

CheckState Unchecked

2 Name cbbTimmax CheckBox

Text Tìm max

Text Giải hệ phƣơng trình

3 CheckBox CheckState Unchecked

Name cbbGiaihephuongtrinh

Text Lựa chọn 4 Groupbox Name groupBox1

Text Kết quả 5 Groupbox Name groupBox2

Text Nhập a: 6 Label

Text Nhập b: 7 Label

Text Nhập c: 8 Label

Text Nhập d: 9 Label

147

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

10 Label Text Nhập e:

11 Label Text Nhập f:

12 RichTextBox Name txtKetqua

13 TextBox Name txtA

14 TextBox Name txtB

15 TextBox Name txtC

16 TextBox Name txtD

17 TextBox Name txtE

18 TextBox Name txtF

float a, b, c, d, e, f;//Khai báo các biến

bool Kiemtra(out float a,TextBox txtA)

{

bool kta;

kta = float.TryParse(txtA.Text,out a);

return kta;

}

Bƣớc 2: Xây dựng hàm kiểm tra dữ liệu nhập vào TextBox txtSonguyen

float max3so(float a, float b, float c)

{

float max = a;

if (max < b) max = b;

if (max < c) max = c;

return max;

}

Bƣớc 3: Xây dựng hàm tìm số lớn nhất của 3 số:

Bƣớc 4: Xây dựng hàm Tinhtoan dựa vào việc lựa chọn của các CheckBox để

void Tinhtoan()

{

if (Kiemtra(out a,txtA) && Kiemtra(out b,txtB) && Kiemtra(out

c,txtC) && Kiemtra(out d,txtD) && Kiemtra(out e,txtE) && Kiemtra(out f,txtF))

{

txtKetqua.Text = "";

if (cbbTimmax.Checked)

{

float max1, max2,max;

max1 = max3so(a, b, c);

max2 = max3so(d, e, f);

max = max1;

if (max < max2) max = max2;

txtKetqua.Text += "Số lớn nhất = " + max.ToString();

đƣa ra kết quả.

148

}

if (cbbGiaihephuongtrinh.Checked)

{

float D, Dx, Dy;

D = a * d - b * c;

Dx = e * d - b * f;

Dy = a * f - e * c;

if (D != 0) txtKetqua.Text += "\r\nHệ phương trình có

nghiệm duy nhất:\r\nx = " + (Dx / D).ToString() + "\r\ny = " + (Dy /

D).ToString();

else

{

if (Dx == 0 && Dy == 0) txtKetqua.Text += "\r\nHệ

phương trình vô số nghiệm";

else txtKetqua.Text += "\r\nHệ phương trình vô nghiệm";

}

}

}

else MessageBox.Show("Nhập hệ số không thỏa mãn");

}

Tập bài giảng Lập trình cơ bản

Bƣớc 5: Gọi hàm Tinhtoan() trong các sự kiện CheckedChanged của các điều

khiển CheckBox (Sự kiện CheckedChanged đƣợc sinh ra khi kích chuột 2 lần

private void cbbGiaihephuongtrinh_CheckedChanged(object sender, EventArgs e)

{

Tinhtoan();

}

private void cbbTimmax_CheckedChanged(object sender, EventArgs e)

{

Tinhtoan();

}

vào các điều khiển CheckBox)

2. CheckedListBox

- Công dụng: Hiển thị một danh sách phần tử mà bên cạnh đó có biểu

tƣợng CheckBox ứng với mỗi phần tử

- Thuộc tính:

Thuộc tính Mô tả

Items

Liệt kê các mục giá trị trong CheckedListBox, thuộc tính Items có rất nhiều phƣơng thức đƣợc sử dụng nhƣ để

thêm phần tử (Add), xóa một phần tử (Remove), xóa toàn

bộ (Clear) hay trả về số phần tử thông quá thuộc tính

Count của Items…

149

Tập bài giảng Lập trình cơ bản

SelectedItem Trả về hoặc gán Item (object) đƣợc chọn

SelectedValue Trả về hoặc gán giá trị ứng với phần tử kiểu object đƣợc

chọn

SelectedIndex Trả về hoặc gán giá trị chỉ mục ứng với phần tử đang

chọn

SelectionMode Xác định cách thức mà lựa chọn những phần tử trong

CheckedListBox.

CheckedItems Trả về tập phần tử đƣợc Check

Bảng 4.19: Một số thuộc tính của CheckedListBox

- Sự kiện:

Sự kiện Mô tả

SelectedIndexChanged Xảy ra khi chỉ mục chọn thay đổi

SelectedValueChanged Xảy ra khi giá trị của phần tử thay đổi

ItemChecked Xảy ra khi kích chuộtvào biểu tƣợng CheckBox

của từng phần tử

Bảng 4.20: Một số sự kiện của CheckedListBox

Ví dụ 4.13: Điều khiển CheckedListBox

Yêu cầu:

- Tạo Form theo mẫu sau:

Hình 4.28: Ví dụ về điều khiển CheckedListBox - Các điều khiển nhập m, n là các điều khiển TextBox - Khi chọn CheckBox ―ƢCLN‖: Hiển thị ƣớc số chung lớn nhất của 2 số

đƣợc nhập trong các điều khiển TextBox

- Khi chọn CheckBox ―BCNN‖: Hiển thị bội số chung nhỏ nhất của 2 số

đƣợc nhập trong các điều khiển TextBox

- Khi chọn CheckBox ―Số lớn nhất‖: Hiển thị số lớn nhất của 2 số đƣợc

nhập trong các điều khiển TextBox

Hướng dẫn thực hiện

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_13, thêm các điều khiển vào

trong Form.

150

Tập bài giảng Lập trình cơ bản

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_13

1 Form Text

Làm việc với CheckedListbox

CheckedListBox SelectionMode One 2 Name clbLuachon

Label 3 Text Nhập n

Label 4 Text Nhập m

Label 5 Text Lựa chọn

Label 6 Text Kết quả

Multiline True 7 TextBox Name txtKetqua

8 TextBox Name txtN

9 TextBox Name txtM

Bƣớc 2: Thêm các item vào trong điều khiển CheckedListBox, cách thực hiện

giống với điều khiển ListBox.

Bƣớc 3: Xây dựng hàm kiểm tra dữ liệu nhập vào TextBox và hàm tìm ƣớc

int n,m;//Khai báo hai biến để nhận giá trị từ các TextBox

bool Kiemtra()

{

bool ktn,ktm;

ktn = int.TryParse(txtN.Text, out n);

ktm = int.TryParse(txtM.Text, out m);

return ktn && (n > 0)&&(m>0);

}

int ucln(int n, int m)

{

if (n % m == 0) return m;

else return ucln(m, n % m);

}

chung lớn nhất

private void clbLuachon_SelectedIndexChanged(object sender, EventArgs e)

{

txtKetqua.Text = "";

if (clbLuachon.CheckedItems.Count > 0)

{

if (Kiemtra())

for (int i = 0; i < clbLuachon.CheckedItems.Count; i++)

Bƣớc 3: Viết mã lệnh cho sự kiện SelectedIndexChanged của điều khiển CheckedListBox.

151

{

int uc = ucln(n, m);

if (clbLuachon.CheckedItems[i].ToString() == "UCLN")

{

txtKetqua.Text += "UCLN = " + uc.ToString() + "\r\n";

}

else if (clbLuachon.CheckedItems[i].ToString() == "BCNN")

{

txtKetqua.Text += "BCNN = " + (n * m / uc).ToString()+"\r\n";

}

else

{

int max = (n > m) ? n : m;

txtKetqua.Text += "Số lớn nhất = " + max.ToString()

+ "\r\n";

}

}

else MessageBox.Show("Nhập n hoặc m không thỏa mãn");

}

}

Tập bài giảng Lập trình cơ bản

3. RadioButton

- Công dụng: Khác với điều khiển CheckBox cho phép chọn nhiều tùy chọn trong danh sách tùy chọn thì điều khiển RadioButton chỉ cho phép

chọn một trong danh sách các tùy chọn.

- Thuộc tính:

Thuộc tính Mô tả

Text Thuộc tính này sử dụng để nhận hoặc gán chuỗi ký tự là

tiêu đề của RadioButton

Checked Là thuộc tính đƣợc sử dụng để xác định RadioButton

đƣợc chọn

Bảng 4.21: Một số thuộc tính của RadioButton

- Sự kiện:

Sự kiện Mô tả

MouseClick ra khi kích chuột trên điều khiển

Xảy RadioButton

CheckedChanged ra khi kích chuột vào điều khiển

Xảy RadioButton

Click Xảy ra khi kích chuột vào điều khiển CheckBox

Bảng 4.22: Một số sự kiện của RadioButton

Ví dụ 4.14: Điều khiển RadioButton

152

Tập bài giảng Lập trình cơ bản

Yêu cầu:

- Tạo Form theo mẫu sau:

Hình 4.29: Ví dụ về điều khiển RadioButton

- Khi chọn RadioButton ―Tính tổng chữ số của n‖: Hiển thị tổng các chữ

số của n, giá trị đƣợc nhập trong điều khiển TextBox

- Khi chọn RadioButton ―Tính 1 + 1/2 + 1/3+ ... + 1/n‖: Hiển thị tổng. - Nhãn: ―Nhập n‖ và nhãn đƣợc dùng để hiển thị kết quả.

Hướng dẫn thực hiện

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_14, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_14 1 Form Text Điều khiển RadioButton

Text Tính tổng chữ số của n 2 RadioButton Name rbTinhtongchuson

Text Tính 1 + 1/2 + 1/3+ ... +

1/n 3 RadioButton

Name rbTong

Text Lựa chọn 4 Groupbox Name groupBox1

5 Label Text Nhập n:

Text Kết quả 6 Label Name lblKetqua

7 TextBox Name txtN

int n;

bool Kiemtra()

{

bool ktn;

Bƣớc 2: Xây dựng hàm kiểm tra dữ liệu nhập vào TextBox

153

ktn = int.TryParse(txtN.Text, out n);

return ktn&&(n>0);

}

Tập bài giảng Lập trình cơ bản

Bƣớc 3: Viết mã lệnh cho sự kiện CheckedChanged cho các điều khiển

private void rbTinhtongchuson_CheckedChanged(object sender, EventArgs e)

{

if(rbTinhtongchuson.Checked)

if (Kiemtra())

{

int tong = 0, du;

int tg = n;

while (tg != 0)

{

du = tg % 10;

tong += du;

tg /= 10;

}

lbKetqua.Text = "Tổng các chữ số của "+ n.ToString() + " = " +

tong.ToString();

}

else MessageBox.Show("Nhập n không thỏa mãn");

}

private void rbTong_CheckedChanged(object sender, EventArgs e)

{

if (rbTong.Checked)

if (Kiemtra())

{

float tong = 0; int i;

for (i = 1; i <= n; i++) tong = tong + 1.0f / i;

lbKetqua.Text = " Tổng = " + tong.ToString();

}

else MessageBox.Show("Nhập n không thỏa mãn");

}

RadioButton

4.3.6. Điều khiển Button

- Công dụng: để thực hiện một tác vụ nào đó khi kích chuột vào điều

khiển

- Thuộc tính:

Thuộc tính Mô tả

Text

Thuộc tính này sử dụng để nhận hoặc gán chuỗi ký tự là tiêu đề của Button

Image

Chọn Image trong phần Resource để trình bày hình trên điều khiển Button.

154

Tập bài giảng Lập trình cơ bản

Bảng 4.23: Một số thuộc tính của Button

- Sự kiện:

Sự kiện Mô tả

MouseClick Xảy ra khi kích chuột trên điều khiển Button

Click Xảy ra khi kích chuộtvào điều khiển Button

Bảng 4.24: Một số sự kiện của Button

4.4. Một số điều khiển đặc biệt

4.4.1 Nhóm điều khiển Menu

1. Điều khiển MenuStrip

- Công dụng: tổ chức các phần tử (ToolStripMenuItem) theo cấu trúc cây và trình bày trên màn hình thành thanh menu để có thể lựa chọn, ngoài ra

còn có các điều khiển con ToolStripComboBox (ComboBox),

ToolStripSeparator (Gạch phân cách) và ToolStripTextBox (TextBox).

- Thuộc tính:

Thuộc tính Mô tả

AllowItemReorder Thuộc tính này cho phép tùy chọn các phần tử bằng bàn

phím khi bấm phím Alt

TextDirection Thuộc tính này cho phép thay đổi hình thức trình bày trên

menu là ngang (Horizontal) hoặc dọc (Vertical90 hoặc

Vertical270)

Items Thuộc tính này trả về danh sách các phần tử của

MenuStrip

Bảng 4.25: Một số thuộc tính của MenuStrip

Hình 4.30: Ví dụ về điều khiển MenuStrip

155

Tập bài giảng Lập trình cơ bản

2. Điều khiển ToolStripMenuItem

- Công dụng: là một phần tử của MenuStrip, phần tử này có chức năng tƣơng tự nhƣ Button, nghĩa là cho phép kích chuột hoặc dùng phím để lựa chọn, từ đó

thực hiện tác vụ tƣơng ứng.

- Thuộc tính

Thuộc tính Mô tả

Image Hình ảnh xuất hiện bên cạnh chuỗi văn bản của

đối tƣợng.

Text Chuỗi hiển thị của đối tƣợng

ShortcutKeyDisplayString Hiển thị dòng ký tự ứng với phím tắt

ShortcutKeys Thuộc tính này quy định phím tắt để kích hoạt

ToolStripMenuItem

ShowShortcutKeys Cho phép hiển thị tổ hợp phím tắt hay không

TooltipText Quy định dòng văn bản sẽ xuất hiện khi đƣa

chuột qua điều khiển ToolStripMenuItem

Bảng 4.26: Một số thuộc tính của ToolStripMenuItem

- Sự kiện

Thuộc tính Mô tả

Click Sự kiện này xảy ra khi kích chuột vào đối tƣợng

DoubleClick Sự kiện này xảy ra khi kích đúp chuột vào đối

tƣợng

Bảng 4.27: Một số sự kiện của ToolStripMenuItem

Ví dụ 4.15: Ứng dung MDI Form và MenuStrip

Yêu cầu:

- Tạo Form theo mẫu sau:

Hình 4.31: Giao diện ví dụ 4.15

- Thực hiện tạo Menu nhƣ hình 4.31 trong đó:

o Khi click chọn ToolStripMenuItem―Đăng nhập‖ sẽ xuất hiện

Form ―Đăng nhập‖

156

Tập bài giảng Lập trình cơ bản

o Khi click chọnToolStripMenuItem ―Đăng ký‖ sẽ xuất hiện Form

―Đăng ký‖

o Khi click chọnToolStripMenuItem ―Thoát‖ sẽ đóng From Bƣớc 1: Tạo Form và đặt tên là frmVidu4_15, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_15

1 Form Text Điều khiển MenuStrip

IsMdiContainer True

Name menuStrip1 2 MenuStrip

Text Tài khoản 3 ToolStripMenuItem Name tàiKhoảnToolStripMenuItem

tàiKhoảnToolStripMenuItem có ba ToolStripMenuItem con:

Text Đăng nhập

4 ToolStripMenuItem Name đăngNhậpToolStripMenuItem

ShortcutKeys Ctrl+L

Text Đăng ký

5 ToolStripMenuItem Name đăngKýToolStripMenuItem

ShortcutKeys Ctrl+R

Text Thoát

6 ToolStripMenuItem Name thoátToolStripMenuItem

ShortcutKeys Ctrl+Shift+E

Bƣớc 2: Tạo Form ―Đăng nhập‖ đặt tên là frmDangnhap và tạo Form ―Đăng ký‖ đặt tên là frmDangky nhƣ hình 4.31. (Hai Form này đƣợc thiết kế với mục đích

minh họa cho việc viết mã lệnh sự kiện Click của các ToolStripMenuItem, không quan

tâm tới mã lệnh của các Form này)

Bƣớc 3: Viết mã lệnh cho sự kiện Click của các ToolStripMenuItem bằng cách

private void đăngNhậpToolStripMenuItem_Click(object sender, EventArgs e)

{

foreach (Form frm in this.MdiChildren)

frm.Close();

Form frmDangnhap = new frmDangnhap();

frmDangnhap.MdiParent = this;

frmDangnhap.Show();

}

kích chuột hai lần vào các điều khiển ToolStripMenuItem.

157

private void đăngKýToolStripMenuItem_Click(object sender, EventArgs e)

{

foreach (Form frm in this.MdiChildren)

frm.Close();

Form frmDangky = new frmDangky();

frmDangky.MdiParent = this;

frmDangky.Show();

}

private void thoátToolStripMenuItem_Click(object sender, EventArgs e)

{

this.Close();

}

Tập bài giảng Lập trình cơ bản

4.4.2. Điều khiển Container

1. Điều khiển GroupBox

- Công dụng: là khung có hay không có tựa đề dùng để nhóm các điều khiển khác, hữu ích cho việc nhóm các điều khiển RadioButton thành

một nhóm Thuộc tính:

Thuộc tính Mô tả

Dock Vị trí xuất hiện của điều khiển GroupBox trên

Form

Text Chuỗi xuất hiện nhƣ tiêu đề của GroupBox

Enabled Nếu thuộc tính này là False thì tất cả các điều

khiển trong điều khiển GroupBox sẽ bị vô hiệu

hóa

Visible Nếu thuộc tính này là False thì tất cả các điều

khiển trong điều khiển GroupBox và GroupBox

sẽ bị ẩn đi

Bảng 4.28: Một số thuộc tính của GroupBox

158

Tập bài giảng Lập trình cơ bản

Hình 4.32: Ví dụ về điểu khiển GroupBox

2. Điều khiển TabControl

- Công dụng: Chứa danh sách các đối tƣợng TabPage, cho phép thêm các

điều khiển khác trong từng TabPage.

- Thuộc tính

Thuộc tính Mô tả

Alignment Vị trí xuất hiện của Tab trên điều khiển

TabControl ứng với Top, Bottom, Left, Right

Appearance Hình thức xuất hiện của Tab trên điều khiển

TabControl nhƣ Normal, Buttons, hay

FlatButtons.

Multiline Nếu giá trị là True thì cho phép sắp xếp danh

sách Tab trên nhiều hàng

TabPages trong điều khiển

Danh sách các TabPage TabControl

Bảng 4.29: Một số thuộc tính của TabControl

159

Tập bài giảng Lập trình cơ bản

Hình 4.33: Ví dụ về điều khiển TabControl

4.4.3. Điều khiển Dialog 1. Lớp MessageBox - Công dụng: hiển thị hộp thoại thông báo, tiêu đề cùng với các nút và biểu tƣợng khác nhau. Đối tƣợng lớp MessageBox không cần tạo, thay vào đó sử dụng phƣơng thức tĩnh Show để hiển thị hôp thoại nhƣ hình 4.28.

Hình 4.34: Hộp thoại MessageBox

- Một số dạng hiển thị hộp thoại MessageBox

o Hiển thị mỗi nội dung thông báo:

MessageBox.Show("Xin chào”);

Hình 4.35: Hộp thoại MessageBox chỉ có nội dung

o Hiển thị nội dung và tiêu đề thông báo:

160

Tập bài giảng Lập trình cơ bản

MessageBox.Show("Xin chào","Thông báo");

Hình 4.36: Hộp thoại MessageBox có thêm tiều đề o Hiển thị nội dung, tiêu đề và thêm các nút bấm khác

MessageBox.Show("Xin chào","Thông báo",MessageBoxButtons.OKCancel);

Hình 4.37: Hộp thoại MessageBox có thêm tùy chỉnh nút bấm o Hiển thị nội dung, tiêu đề, nút bấm và biểu tƣợng trong hộp thoại

MessageBox.Show("Xin chào","Thông

báo",MessageBoxButtons.OKCancel,MessageBoxIcon.InFormation);

Hình 4.38: Hộp thoại MessageBox có thêm tùy chỉnh biểu tượng

Để lựa chọn nút bấm, cần thêm 1 tham số kiểu enum là: Các MessageBoxButtons. loại nút có sẵn bao gồm: AbortRetryIgnore, OK, OKCancel,

RetryCancel,YesNo, YesNoCancel.

Để thêm vào icon thì cần thêm tham số kiểu enum là:

MessageBoxIcon.

161

Tập bài giảng Lập trình cơ bản

Có nhiều loại nhƣng phổ biến là Warning (tam giác vàng có dấu chấm than),

Error (hình tròn đỏ có chữ X), InFormation (hình tròn xanh lam có chữ i), Question

(hình tròn lam có dấu chấm hỏi).

- Sự kiện: để xử lý sự kiện trên MessageBox cần dùng một biến để lƣu giá trị trả về của phƣơng thức MessageBox.Show(). Biến đó có kiểu là

"Thông

DialogResult dlr = MessageBox.Show("Bạn có thích lập trình không?", báo", MessageBoxButtons.YesNoCancel,MessageBoxIcon.Question);

DialogResult. Ví dụ:

Hình 4.39: Hộp thoạiMessageBox

Đến lúc này chỉ cần xét giá trị của biến dlr với giá trị của MessageBox là các

trong DialogResult Enumeration nhƣ (DialogResult.Yes, trị

if (dlr == DialogResult.Yes)

{

MessageBox.Show("Bạn vừa click chọn nút Yes");

}

else

MessageBox.Show("Bạn không click chọn nút Yes");

giá nằm DialogResult.Abort,…). Ví dụ:

Hình 4.40: Xuất hiện hộp thoại MessageBox khi click chọn nút Yes.

2. Điều khiển ColorDialog

- Công dụng: trình bày hộp thoại với số màu nhất định cùng với điều khiển cho phép có thể định nghĩa màu tùy ý và màu trả về chính là màu đƣợc chọn trên hộp thoại

162

Tập bài giảng Lập trình cơ bản

- Thuộc tính

Thuộc tính Mô tả

AllowFullOpen Giá tri True cho phép định nghĩa màu

AnyColor Giá trị True thì hộp thoại Color trình bày danh

sách tất cả các màu cơ bản

Color Màu mặc định chọn của điều khiển

SolidColorOnly Giá trị True nếu chỉ cho phép chọn màu cơ bản

Bảng 4.30: Một số thuộc tính của điều khiển ColorDialog

Ví dụ 4.16: Điều khiển ColorDialog

Yêu cầu:

- Tạo Form theo mẫu:

Hình 4.41: Giao diện ví dụ 4.16

- Khi kích chuột vào nút ―Chọn màu‖: thực hiện xuất hiện hộp thoại ColorDialog, cho phép chọn màu và thực hiện thay đổi màu chữ của nhãn

―Xin chào!‖

Hướng dẫn thực hiện Bƣớc 1: Tạo Form và đặt tên là frmVidu4_16, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_16 1 Form Text Điều khiển ColorDialog

Name lblXinchao 2 Label Text Xin chào

Name btChonmau 3 Button Text Chọn màu

Name cdlMau 4 ColorDialog

Bƣớc 2: Viết mã lệnh cho sự kiện nút ―Chọn màu‖ để mở hộp thoại

ColorDialog

163

private void btChonmau_Click(object sender, EventArgs e)

{

if

(cdlMau.ShowDialog()

==

DialogResult.OK)//Mở

hộp

thoại

ColorDialog

{

lblXinchao.ForeColor = cdlMau.Color;//Lấy màu từ hộp loại

ColorDialog

}

}

Tập bài giảng Lập trình cơ bản

2. Điều khiển SaveFileDialog - Công dụng: cho phép chọn thƣ mục để lƣu tập tin mới hoặc ghi đè lên tập tin

đã có.

- Thuộc tính

Thuộc tính Mô tả

AddExtension Giá tri True cho phép thêm vào tên mở rộng

CheckFileExists

Giá trị True sẽ xuất hiện hộp thoại với chuỗi cảnh báo nếu chọn tập tin không tồn tại

ChekcPathExists Giá trị True sẽ kiểm tra đƣờng dẫn có hợp lệ hay

không trƣớc khi trả về

CreatePrompt Cửa sổ cảnh báo xuất hiện nếu tập tin chuẩn bị

ghi ra chƣa tồn tại

Gán hay trả về tên tập tin chọn FileName

Filter Khai báo chuỗi lọc các loại tập tin. Chẳng hạn,

khai báo txt files (*.txt)|*.txt|All files (*.*)|*.*

InitialDirectory Thƣ mục sẽ chọn khi hộp thoại kích hoạt. Nếu

không cung cấp giá trị cho thuộc tính này thì ổ

đĩa mặc định sẽ chọn

Title Tiều đề của hộp thoại

Bảng 4.31: Một số thuộc tính của điều khiển SaveFileDialog

Ví dụ 4.17: Điều khiển SaveFileDialog Yêu cầu: - Tạo Form theo mẫu:

164

Tập bài giảng Lập trình cơ bản

Hình 4.42: Giao diện ví dụ 4.17 và tập tin songuyen.txt được tạo ra

- Khi kích chuột vào nút ―Lƣu tập tin‖: thực hiện mở hộp thoại SaveFileDialog và lƣu vào tập tin songuyen.txt các số nguyên từ 0 đến 19.

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_17, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_17 1 Form Text Điều khiển SaveFileDialog

Name btLuutaptin 2 Button Text Lƣu tập tin

Name sfdTaptin

3 Filter SaveFileDialog

txt files (*.txt)|*.txt|All files (*.*)|*.*

Bƣớc 2: Viết mã lệnh cho sự kiện nút ―Lƣu tập tin‖ để mở hộp thoại

private void btLuutaptin_Click(object sender, EventArgs e)

{

if (sfdTaptin.ShowDialog() == DialogResult.OK)

{

StreamWriter myFile = File.CreateText(sfdTaptin.FileName);

for (int i = 0; i < 20; i++)

{

myFile.WriteLine("{0} ", i);

}

myFile.Close();

}

SaveFileDialog

165

}

Tập bài giảng Lập trình cơ bản

3. Điều khiển OpenFileDialog - Công dụng: cho phép chọn các tập tin trong một thƣ mục nào đó - Thuộc tính

Thuộc tính Mô tả

AddExtension Giá tri True cho phép thêm vào tên mở rộng

CheckFileExists Giá trị True sẽ xuất hiện hộp thoại với chuỗi

cảnh báo nếu chọn tập tin không tồn tại

ChekcPathExists Giá trị True sẽ kiểm tra đƣờng dẫn có hợp lệ hay

không trƣớc khi trả về

CreatePrompt Cửa sổ cảnh báo xuất hiện nếu tập tin chuẩn bị

ghi ra chƣa tồn tại

Gán hay trả về tên tập tin chọn FileName

Filter

Khai báo chuỗi lọc các loại tập tin. Chẳng hạn, khai báo txt files (*.txt)|*.txt|All files (*.*)|*.*

InitialDirectory Thƣ mục sẽ chọn khi hộp thoại kích hoạt. Nếu

không cung cấp giá trị cho thuộc tính này thì ổ

đĩa mặc định sẽ chọn

MultiSelect Giá trị True cho phép chọn nhiều tập tin

Bảng 4.32: Một số thuộc tính của điều khiển OpenFileDialog

Ví dụ 4.18: Điều khiển OpenFileDialog

Yêu cầu:

- Tạo Form theo mẫu:

Hình 4.43: Giao diện ví dụ 4.18

- Khi kích chuột vào nút ―Mở tập tin‖: thực hiện mở hộp thoại OpenFileDialog và đọc tập tin songuyen.txt đƣợc tạo ra trong ví dụ 4.17 và hiển thị các số

nguyên đó sử dụng điều khiển ListBox.

Hướng dẫn thực hiện

166

Tập bài giảng Lập trình cơ bản

Bƣớc 1: Tạo Form và đặt tên là frmVidu4_18, thêm các điều khiển vào trong

Form.

STT Đối tƣợng Thuộc tính Giá trị

Name frmVidu4_18 1 Form Text Điều khiển OpenFileDialog

Name btMotaptin 2 Button Text Mở tập tin

Name ofdTaptin

Filter txt files (*.txt)|*.txt|All files 3 OpenFileDialog (*.*)|*.*

FileName

Bƣớc 2: Viết mã lệnh cho sự kiện nút ―Mở tập tin‖ để mở hộp thoại

private void btMotaptin_Click(object sender, EventArgs e)

{

if (ofdTaptin.ShowDialog() == DialogResult.OK)

{

string buffer;

StreamReader myFile = File.OpenText(ofdTaptin.FileName);

while ((buffer = myFile.ReadLine()) != null)

{

lbDayso.Items.Add(buffer);

}

myFile.Close();

}

}

OpenFileDialog

Bài tập

Bài 4.1 Lập chƣơng trình thực hiện giải bất phƣơng trình trên Form theo mẫu:

Hình 4.44: Giải bất phương trình

Yêu cầu:

167

Tập bài giảng Lập trình cơ bản

- Nhãn Bất phƣơng trình ax+b>0: Font Time New Roman, size 14, màu đen,

căn giữa Form

- Các nhãn: nhập a, nhập b, kết quả: Font Time New Roman, size 12, màu đen.

- Các TextBox dùng để nhập a, b. - Các Button dùng để thực hiện giải bất phƣơng trình

Lập trình cho các sự kiện:

- Khi Load Form: các textbox để trống,nhãn để hiển thị kết quả ẩn, nút giải

phƣơng trình vô hiệu hóa.

- Khi kích chuột vào nút ―Tiếp tục‖ cho phép xóa dữ liệu cũ,sẵn sàng giải bất

phƣơng trình mới.

- Khi kích chuột vào nút ―Giải bất phƣơng trình‖: thực hiện giải bất phƣơng

trình ax+b>0, kết quả hiện thị lên nhãn kết quả.

Hướng dẫn thực hiện:

Viết mã lệnh cho các sự kiện:

private void Form5_Load(object sender, EventArgs e)

{

txt_a.ResetText();

txt_b.ResetText();

lb_ketqua.Visible= false;

txt_a.Focus();

}

- Viết mã lệnh sự kiện Load Form

bool kiemtra(string s)

{

if (string.IsNullOrWhiteSpace(s)) return true;

return false;

}

- Viết mã lệnh cho hàm kiểm tra chuỗi rỗng

bool kiemtra_dulieu()

{ double so;

if (kiemtra(txt_a.Text)||kiemtra(txt_b.Text)) return return

false;

if (!double.TryParse(txt_a.Text, out so)) return false;

if (!double.TryParse(txt_b.Text, out so)) return false;

return true;

}

- Viết mã lệnh cho hàm kiểm tra dữ liệu nhập vào.

private void bt_Tieptuc_Click(object sender, EventArgs e)

{

txt_a.ResetText();

- Viết mã lệnh cho sự kiện kích chuột vào nút kiểm tra

168

txt_b.ResetText();

lb_ketqua.Visible= false;

txt_a.Focus();

}

Tập bài giảng Lập trình cơ bản

private void bt_giaipt_Click(object sender, EventArgs e)

{

If(kiemtra_dulieu()){

if (a == 0)

{

if (b < 0)

lb_ketqua.Text = "Bất phương trình vô số nghiệm";

else lb_ketqua.Text = "Bất phương trình vô nghiệm";

}

else if(a>0)

lb_ketqua.Text = "Bất phương trình có nghiệm x > " + (-

b/a).ToString();

else

lb_ketqua.Text = "Bất phương trình có nghiệm x < " + (-

b / a).ToString();

}

}

- Viết mã lệnh cho sự kiện kích chuột vào nút giải phƣơng trình

Bƣớc 6. Kết quả chạy chƣơng trình

Hình 4.45: Kết quả chạy chương trình giải bất phương trình

Lập chƣơng trình giải phƣơng trình bậc 2: ax2 + bx+ c= 0 khi ngƣời sử dụng đã

Bài 4.2 nhập đủ các hệ số hợp lệ nhƣ hình sau:

169

Tập bài giảng Lập trình cơ bản

HInh 4.46: Giao diện ví dụ bài tập 2

Bài 4.3

Sử dụng các điều khiển: Combobox và Button lập chƣơng trình xây dựng từ

điển Anh – Việt đơn giản, trong đó cho phép:

- Thêm các từ tiếng Anh và nghĩa tiếng Việt của từ đó; - Xóa một từ tiếng Anh đƣợc chọn và nghĩa tiếng Việt tƣơng ứng; - Xóa toàn bộ danh sách từ; - Thực hiện tra cứu từ (khi chọn một từ tiếng Anh sẽ xuất hiện nghĩa tiếng Việt

tƣơng ứng của từ tiếng Anh đó) nhƣ hình sau:

Hình 4.47: Ứng dụng từ điển đơn giản

Bài 4.4 Lập chƣơng trình tạo menu File có 2 mục chọn con là New và Exit sao cho khi

chọn mục Exit thì kết thúc chƣơng trình và mỗi lần chọn mục New chƣơng trình sẽ in

ra một bộ hoán vị của các số từ 1 đến 16và đƣợc hiển thị nhƣ hình sau:

HÌnh 4.48: Giao diện bài tập Xếp Ô

170

Tập bài giảng Lập trình cơ bản

Bài 4.5

Lập chƣơng trình sử dụng các điều khiển: RichTextBox, TextBox, Button cho

phép nhập các ký từ vào RichTextBox. Nếu nhấn một ký tự là chữ cái thì ký tự đó

trong ―bảng chữ cái‖ chuyển sang màu đỏ, khi thả phím ra thì màu chữ trở lại màu đen. Nếu kích chuột vào nút ―Đếm số‖ sẽ đếm số chữ số khác nhau và hiển thị nhƣ

hình sau:

Hình 4.49: Giao diện bài tập Bàn phím ký tự

Lập chƣơng trình thực hiện các yêu cầu sau: Bài 4.6

Hình 4.50: Giao diện ví dụ Lucky Seven

1. Thiết kế Form nhƣ hình trên, khi chƣơng trình vừa bắt đầu thì 3 label sẽ hiển thị ba

số 7, máy tính có 100 đồng và ngƣời chơi có 100 đồng. 2. Khi kích vào nút ―Quay số‖:

Luật chơi: Mỗi lần quay số, ngƣời chơi trả trƣớc 30 đồng, tƣơng ứng là máy sẽ đƣợc cộng thêm 30 đồng. Và nếu ngƣời chơi có số tiền ít hơn 30 đồng thì sẽ không đƣợc phép chơi tiếp. Nếu mỗi lần quay đƣợc số 7, ngƣời chơi sẽ đƣợc thƣởng nhƣ sau: - Nếu ô đầu tiên là số 7 (random từ 0 đến 8), đƣợc thƣởng 100 đồng + 50% số

- Nếu ô số 2 là số 7(random từ 0 đến 9), ngƣời chơi đƣợc thƣởng 30 đồng + 50%

tiền của máy. tiền của máy.

171

Tập bài giảng Lập trình cơ bản

- Nếu ô số 3 là số 7(random từ 0 đến 10), ngƣời chơi đƣợc thƣởng 10 đồng;(số

tiền ngƣời chơi sẽ đƣợc cộng dồn nếu cả 3 ô cùng là số 7, tiền máy sẽ giảm đi phần

trăm tƣơng ứng).

3. Khi kích vào nút ―Game mới‖: Reset lại các label và các textbox tƣơng ứng. 4. Khi kích vào nút ―Kết thúc‖: thực hiện đóng chƣơng trình.

Bài 7

Viết một chƣơng trình thực hiện các yêu cầu sau: 1. Thiết kế Formtheo mẫu

Hình 4.51: Bài tập mảng một chiều

Yêu cầu:

- Nhãn một số thao tác trên mảng một chiều: Font Time New Roman, chữ hoa,

in đậm, cỡ chữ 14, căn giữa Form.

- Nhãn nhập kích thƣớc mảng, dãy vừa nhập là, kết quả, điều kiện 1, điều kiện

2: Font Time New Roman, chữ thƣờng, cỡ chữ 11

- Đối tƣợng ô để nhập kích thƣớc mảng, nhập giá trị, điều kiện 1, điều kiện 2, hiển thị dãy vừa nhập, hiển thị kết quả là các Textbox Font Time New Roman, chữ thƣờng, cỡ chữ 14.

- Các điều khiển ―Thanh lọc‖, ―Bổ sung‖, ―Loại bỏ‖, ―Tìm kiếm‖, ―Thoát‖ là

- Đối tƣợng điều kiện là một GroupBox.

các button. 2. Lập trình cho các nút chức năng: - Khi Load Form: + Các textbox để nhập giá trị, hiển thị dãy, kết quả vô hiệu hóa

+Group điều kiện ẩn

172

Tập bài giảng Lập trình cơ bản

+ Các nút ―Thanh lọc‖, ―Bổ sung‖, ―Loại bỏ‖, ―Tìm kiếm‖ vô hiệu hóa.

+ Textbox để nhập kích thƣớc mảng để trống, con trỏ đặt tại ô đó.

- Khi nhập một giá trị vào textbox tƣơng ứng với nhãn nhập kích thƣớc mảng

rồi nhấn phím Enter thì thực hiện kiểm tra xem dữ liệu nhập vào có hợp lệ không? (giá trị nhập vào là số nguyên dƣơng). Nếu dữ liệu nhập vào không đúng thì hiện lên hộp

thoại thông báo và cho phép nhập lại. Ngƣợc lại thì textbox tƣơng ứng với nhãn nhập

giá trị sáng lên cho phép hoạt động và con trỏ đặt tại ô đó. - Khi nhập giá trị vào textbox tƣơng ứng với nhãn nhập giá trị rồi nhấn phím

Enter thì hiển thị giá trị đó ra textbox tƣơng ứng với nhãn dãy vừa nhập, sau đó

textbox này rỗng và con trỏ lại đặt tại ô đó để nhập giá trị tiếp theo. Lặp lại quá trình

này cho tới khi nhập xong giá trị cho các phần tử của mảng. Sau khi đã nhập xong dãy thì các nút ―Thanh lọc‖, ―Bổ sung‖, ―Loại bỏ‖, ―Tìm kiếm‖ sáng lên cho phép hoạt

động, các textbox tƣơng ứng với nhãn nhập kích thƣớc mảng, nhập giá trị vô hiệu hóa.

- Khi kích vào nút ―Thanh lọc‖: thực hiện loại khỏi dãy những phần tử giống

nhau (chỉ giữ lại một) và hiển thị dãy sau khi thanh lọc lên textbox tƣơng ứng với dãy

kết quả.

- Khi kích vào nút ―Bổ sung‖ thì:

+ Groupbox điều kiện sáng lên

+ Label điều kiện 2 và textbox tƣơng ứng với nhãn này ẩn

+ Thuộc tính Text của Label điều kiện 1 là ―Nhập vị trí cần bổ sung‖

+ Textbox tƣơng ứng với nhãn điều kiện 1 để trống và con trỏ đặt tại đó

- Khi nhập một giá trị vào textbox tƣơng ứng với nhãn điều kiện một thì thực

hiện kiểm tra xem dữ liệu có hợp lệ không? (giá trị nhập vào phải là số nguyên

dƣơng). Nếu không hợp lệ thì hiện lên hộp thoại thông báo và yêu cầu nhập lại, ngƣợc

lại thì Label điều kiện 2 hiện lên, thuộc tính Text của nhãn đó là ―Nhập giá trị cần bổ sung‖, textbox tƣơng ứng với nhãn điều kiện 2 cũng hiện lên và để trống, con trỏ đặt

tại textbox đó.

- Khi nhập một giá trị vào textbox tƣơng ứng với nhãn điều kiện 2 rồi nhấn

phím Enter thì thực hiện kiểm tra xem dữ liệu nhập vào có hợp lệ không? (giá trị nhập vào là số nguyên). Nếu dữ liệu không hợp lệ thì hiện lên hộp thoại thông báo và cho phép nhập lại, ngƣợc lại thì thực hiện bổ sung giá trị x ( x là giá trị nhập ở textbox tƣơng ứng với nhãn điều kiện 2) vào vị trí thứ k (với k là giá trị nhập ở texthox tƣơng ứng với nhãn điều kiện 1), sau đó hiển thị dãy kết quả ra textbox tƣơng ứng với nhãn kết quả. - Khi kích vào nút loại bỏ thì Label điều kiện 1 và textbox tƣơng ứng với nó

hiện lên, Label điều kiện 2 và textbox tƣơng ứng với nó ẩn. Thuộc tính text của nhãn

173

Tập bài giảng Lập trình cơ bản

điều kiện 1 là ―Nhập vị trí cần loại bỏ‖, textbox tƣơng ứng với nhãn này để trống và

con trỏ đặt tại ô đó cho phép nhập vào một giá trị.

- Khi nhập một giá trị vào textbox tƣơng ứng với nhãn điều kiện rồi nhấn phím

Enter thì thực hiện kiểm tra xem giá trị nhập vào có hợp lệ không? (giá trị nhập vào là số nguyên dƣơng). Nếu dữ liệu không hợp lệ thì hiện lên hộp thoại thông báo và cho

phép nhập lại, ngƣợc lại thực hiện xóa giá trị phần tử thứ k ra khỏi dãy (với k là giá trị

của texbox tƣơng ứng với nhãn điều kiện 1) và hiển thị lại dãy ra textbox tƣơng ứng với nhãn kết quả.

- Khi kích chuột vào nút ―Tìm kiếm‖: Label điều kiện 2 và textbox tƣơng ứng

với nó ẩn, Label điều kiện 1 và nhãn tƣơng ứng với nó hiện lên, thuộc tính text của

nhãn điều kiện 2 là ― Nhập giá trị cần tìm kiếm‖ và textbox tƣơng ứng với nhãn này để trống; con trỏ đặt ở đó chờ nhập vào một giá trị.

- Khi nhập một giá trị vào textbox tƣơng ứng với nhãn điều kiện 2 rồi nhấn

phím Enter thì thực hiện kiểm tra xem giá trị nhập vào có hợp lệ không? (giá trị nhập

vào phải là số nguyên). Nếu không hợp lệ thì hiện lên hộp thoại thông báo và cho phép

nhập lại, ngƣợc lại thì hiện tìm xem x có trong dãy không (với x là giá trị của textbox

tƣơng ứng với nhãn điều kiện 1), kết quả hiện thị lên textbox tƣơng ứng với nhãn kết

quả.

- Khi kích vào nút ―Thoát‖ thì thực hiện thoát khỏi chƣơng trình.

Hướng dẫn thực hiện 1. Thiết kế Form như yêu cầu đề bài

2. Phân tích yêu cầu

Theo yêu cầu của bài toán thì phải có một Form chứa:

- Các đối tƣợng có nội dung ―MỘT SỐ THAO TÁC TRÊN MẢNG MỘT

CHIỀU‖,‖Nhập kích thƣớc mảng‖, ―Nhập giá trị‖, ―Dãy vừa nhập‖, ―Kết quả‖, ―Điều kiện 1‖, ―Điều kiện 2‖ là các Label.

- Các đối tƣợng ô để nhập kích thƣớc mảng, giá trị, điều kiện 1, điều kiện 2 và

để hiển thị dãy vừa nhập, kết quả là các Textbox.

- Các nút ―Thanh lọc‖, ―Bổ sung‖, ―Loại bỏ‖, ―Tìm kiếm‖, ―Thoát‖ là các

- Đối tƣợng điều kiện là GroupBox.

Nhƣ vậy, để thực hiện công việc thiết kế Form nhƣ yêu cầu bài toán, ngƣời lập

Button. 3. Các bước thực hiện trình thực hiện các bƣớc sau: Bƣớc 1. Mở C#

Bƣớc 2. Tạo Form mới

174

Tập bài giảng Lập trình cơ bản

Bƣớc 3. Thiết kế Form theo mẫu và gắn các điều khiển

- Để tạo điểu khiển MỘT SỐ THAO TÁC TRÊN MẢNG MỘT CHIỀU theo yêu

cầu cần thực hiện:

+ Kéo điều khiển Label từ cửa sổ Toolbox + Kích phải chuột vào Label chọn Properties và thiết lập các thuộc tính cho

Label nhƣ sau:

Text: MỘT SỐ THAO TÁC TRÊN MẢNG MỘT CHIỀU Font: Time New Roman

Size: 14

Font style: True

Trên menu chọn Format/Center in Form/Horizontally để căn giữa. Thực hiện thao tác tƣơng tự với Label nhập kích thƣớc mảng, nhập giá trị, dãy

vừa nhập, kết quả, điều kiện 1, điều kiện 2.

- Để tạo điều khiển textbox tƣơng ứng với nhãn nhập kích thƣớc mảng theo yêu

cầu cần thực hiện:

+ Kéo điểu khiển Textbox từ cửa sổ Toolbox vào Form.

+ Kích phải chuột vào Textbox chọn Properties và thiết lập các thuộc tính cho

Textbox nhƣ sau:

Name: txt_n

Font: Time New Roman

Size: 11

Thực hiện tƣơng tự với các textbox tƣơng ứng với nhãn nhập giá trị, hiển thị,

điều kiện 1, điều kiện 2.

- Để tạo GroupBox điều kiện theo yêu cầu cần thực hiện nhƣ sau:

+ Kéo điều khiển GroupBox từ cửa sổ Toolbox vào Form. + Kích phải chuột vào GroupBox chọn Properties và thiết lập các thuộc tính cho

GroupBox nhƣ sau:

Text: Điều kiện

Font: Time New Roman Size: 11

- Để tạo điều khiển Button thanh lọc theo yêu cầu cần thực hiện nhƣ sau: + Kéo điều khiển Button từ cửa sổ Toolbox vào Form. + Kích phải chuột vào Button và thiết lập các thuộc tính cho Button này: Name: bt_thanhloc Text: Thanh lọc

Font: Time New Roman

175

Tập bài giảng Lập trình cơ bản

Size: 11

Thực hiện tƣơng tự với các Button: Bổ sung, loại bỏ, tìm kiếm và thoát.

Bƣớc 4. Kết quả thiết kế

Hình 4.52: Kết quả thiết kế Form bài tập mảng một chiều

Bƣớc 5. Viết mã lệnh cho các sự kiện - Viết mã lệnh khai báo mảng số nguyên, biến nguyên n, biến spt để đếm số

phần tử nhập vào; các biến kt_loaibo, kt_bosung,kt_timkiem để đánh dấu sự

int[] A = new int [100]; int n, spt = 0; bool kt_loaibo = false, kt_bs

= false, kt_timkiem = false;

kiện kích chuột vào các nút tƣơng ứng.

private void Form1_Load(object sender, EventArgs e)

{

group_dieukien.Visible = false;

txt_giatri.Enabled = false;

txt_hienthi.Enabled = false;

txt_ketqua.Enabled = false; txt_ketqua.ResetText();

vohieuhoa(false);

txt_n.ResetText();

txt_n.Focus();

}

- Viết mã lệnh cho sự kiện Load Form

private void txt_n_KeyUp(object sender, KeyEventArgs e)

{

if (e.KeyCode == Keys.Enter)

if (kiemtra_dulieu())

{

txt_giatri.Enabled = true; txt_giatri.Focus();

}

else

{

MessageBox.Show("Nhập

sai

giá

trị

n");

txt_n.Focus(); }

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn nhập kích thƣớc mảng

176

}

Tập bài giảng Lập trình cơ bản

private void txt_giatri_KeyUp(object sender, KeyEventArgs e)

{

bool kt;

if (e.KeyCode == Keys.Enter)

do

{

kt= int.TryParse(txt_giatri.Text, out A[spt]);

if (kt) { txt_hienthi.Text += A[spt].ToString() + "

"; spt++; txt_giatri.ResetText(); txt_giatri.Focus(); }

if (spt == n) { MessageBox.Show("Nhập xong dãy",

"Thông

báo");

vohieuhoa(true);

txt_giatri.Enabled

=

false;

txt_n.Enabled = false; }

}while (!kt);

}

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn giá trị

private void bt_thanhloc_Click(object sender, EventArgs e)

{

int i, j; txt_ketqua.ResetText();

i = 0;

while (i < n)

{

j = i + 1;

while (j

if (A[i] == A[j])

{

for (int k = j; k < n - 1; k++) A[k] = A[k + 1];

n--;

}

else j++;

i++;

}

for (i = 0; i < n; i++) txt_ketqua.Text += A[i].ToString()

+ " ";

}

- Viết mã lệnh cho sự kiện kích chuột vào nút thanh lọc

private void bt_bosung_Click(object sender, EventArgs e)

{

kt_bs = true; txt_ketqua.ResetText();

group_dieukien.Visible = true;

lb_dieukien2.Visible = false;

txt_dieukien2.Visible = false;

lb_dieukien1.Text = "Nhập vị trí cần bổ sung";

txt_dieukien1.TabIndex = 1;

- Viết mã lệnh cho sự kiện kích chuột vào nút bổ sung

177

txt_dieukien1.Focus();

txt_dieukien1.ResetText();

}

Tập bài giảng Lập trình cơ bản

private void txt_dieukien1_KeyUp(object sender, KeyEventArgs e)

{

bool kt; int k;

if (kt_bosung == true)

{

if (e.KeyCode == Keys.Enter)

{

if

(kiemtra(txt_dieukien1.Text))

{

MessageBox.Show("Bạn chưa nhập vị trí k"); txt_dieukien1.Focus(); }

else

{

kt = int.TryParse(txt_dieukien1.Text, out k);

if

(!kt

||

k

<=

0

||

k

>

n)

MessageBox.Show("Không có vị trí thứ k");

else

{

group_dieukien.Visible = true;

lb_dieukien2.Visible = true;

lb_dieukien2.Text = "Nhâp giá trị cần bổ

sung";

txt_dieukien2.Visible = true;

txt_dieukien2.TabIndex

=

1;

txt_dieukien2.Focus(); kt_bosung = false;

}

}

}

}

else if (kt_timkiem == true)

{

int x;

if (e.KeyCode == Keys.Enter)

{

if

(kiemtra(txt_dieukien1.Text))

{

MessageBox.Show("Bạn

chưa

nhập

giá

trị

càn

tìm

kiếm");

txt_dieukien1.Focus(); }

else

{

kt = int.TryParse(txt_dieukien1.Text, out x);

if (!kt) MessageBox.Show("Giá trị cần tìm kiếm

không hợp lệ");

else

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn điều kiện 1

178

{

int i = 0;

while (i < n && A[i] != x) i++;

if (i < n) txt_ketqua.Text = x.ToString()

+ " có trong dãy";

else txt_ketqua.Text = x.ToString() + "

không có trong dãy"; kt_timkiem = false;

}

}

}

}

else if (kt_loaibo == true) // thực hiện loai bo

{

if (e.KeyCode == Keys.Enter)

{

if

(kiemtra(txt_dieukien1.Text))

{

MessageBox.Show("Bạn

chưa

nhập

vị

trí

cần

loại

bỏ");

txt_dieukien1.Focus(); }

else

{

kt = int.TryParse(txt_dieukien1.Text, out k);

if (!kt||k<=0||k>n) MessageBox.Show("Vị trí

thứ k không hợp lệ");

else

{

for (int i = k-1; i < n; i++) A[i] = A[i +

1];

n--;

for (int i = 0; i < n; i++)

txt_ketqua.Text+=

A[i].ToString();

kt_loaibo = false;

}

}

}

}

}

Tập bài giảng Lập trình cơ bản

private void txt_dieukien2_KeyUp(object sender, KeyEventArgs e)

{

bool kt; int x;

if (e.KeyCode == Keys.Enter)

{

if

(kiemtra(txt_dieukien2.Text))

{

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn điều kiện 2

179

MessageBox.Show("Bạn

chưa

nhập

giá

trị

cần

bổ

sung");

txt_dieukien2.Focus(); }

else

{

kt = int.TryParse(txt_dieukien2.Text, out x);

if (!kt) MessageBox.Show("Giá trị nhập vào không

hợp lệ");

else

{

int k = int.Parse(txt_dieukien1.Text);

for (int i = n; i >=k; i--) A[i] = A[i - 1];

A[k-1] = x;

n++;

txt_ketqua.ResetText();

for (int i = 0; i < n; i++) txt_ketqua.Text +=

A[i].ToString() + " ";

}

}

}

}

Tập bài giảng Lập trình cơ bản

private void bt_loaibo_Click(object sender, EventArgs e)

{

kt_loaibo = true;

group_dieukien.Visible = true;

lb_dieukien2.Visible = false;

txt_dieukien2.Visible = false;

lb_dieukien1.Visible = true;

txt_dieukien1.Visible = true;

lb_dieukien1.Text = "Nhập vị trí cần loại bỏ";

txt_dieukien1.ResetText();

txt_dieukien1.TabIndex = 1;

txt_dieukien1.Focus();

}

- Viết mã lệnh cho sự kiện kích chuột vào nút loại bỏ

private void bt_timkiem_Click(object sender, EventArgs e)

{

kt_timkiem = true;

group_dieukien.Visible = true;

lb_dieukien1.Visible = true;

lb_dieukien1.Text = "Nhập giá trị cần tìm kiếm";

txt_ketqua.ResetText();

txt_dieukien2.Visible = false;

lb_dieukien2.Visible = false;

- Viết mã lệnh cho sự kiện kích chuột vào nút tìm kiếm

180

txt_dieukien1.Visible = true; txt_dieukien1.TabIndex = 1;

txt_dieukien1.Focus();

}

Tập bài giảng Lập trình cơ bản

bool kiemtra(string s)

{

if (string.IsNullOrWhiteSpace(s)) return true;

else return false;

}

- Viết mã lệnh cho hàm kiểm tra chuỗi rỗng

bool kiemtra_dulieu()

{

bool kt;

if (kiemtra(txt_n.Text)) return false;

kt = int.TryParse(txt_n.Text, out n);

return kt && n > 0;

}

- Viết mã lệnh cho hàm kiểm tra dữ liệu nhập vào

private void vohieuhoa(bool gt)

{

bt_thanhloc.Enabled = gt;

bt_loaibo.Enabled = gt;

bt_bosung.Enabled = gt;

bt_timkiem.Enabled = gt;

}

- Viết mã lệnh cho hàm vô hiệu hóa các nút

private void bt_thoat_Click(object sender, EventArgs e)

{

this.Close();

}

- Viết mã lệnh cho sự kiện kích chuột vào nút thoát

Bƣớc 6. Một số kết quả khi chạy chƣơng trình

181

Tập bài giảng Lập trình cơ bản

Hình4.53:Kết quả chạy chương trình khi kích vào nút bổ sung

Hình 4.54: Kết quả chạy chương trình khi kích vào nút loại bỏ

182

Tập bài giảng Lập trình cơ bản

Hình 4.55: Kết quả chạy chương trình khi kích vào nút tìm kiếm

Tạo một ứng dụng Windows Form thực hiện các công việc sau: Bài 4.8

1. Nhập dãy A gồm n số nguyên (n nguyên dƣơng).

2. Hiển thị dãy A.

3. Kiểm tra xem dãy có lập thành cấp số nhân hay không?

4. Liệt kê các số nguyên tố có trong dãy.

5. Đƣa ra phần tử xuất hiện nhiều nhất trong dãy A.

6. Kiểm tra xem dãy có đan dấu không?

Tạo một ứng dụng Windows Forms thực hiện các công việc sau: Bài 4.9

1. Nhập dãy A gồm n số thực (n nguyên dƣơng).

2. Hiển thị dãy A.

3. Xóa phần tử cuối cùng trong dãy có giá trị bằng x (x là số thực). 4. Sắp xếp dãy tăng dần.

Bài 4.10 Viết một chƣơng trình thực hiện các yêu cầu sau: 1. Thiết kế Form theo mẫu

183

Tập bài giảng Lập trình cơ bản

Hình 4.56: Bài tập về mảng hai chiều

Yêu cầu:

- Nhãn bài tập về mảng hai chiều: Font Time New Roman, chữ hoa, in đậm, cỡ

chữ 14, căn giữa Form.

- Nhãn nhập số hàng, nhập số cột, nhập giá trị: Font Time New Roman, chữ

thƣờng, cỡ chữ 11.

- Điều khiển để nhập số nguyên dƣơng n, m và nhập giá trị từng phần tử của ma

trận là các Textbox.

- Điều khiển để hiển thị ma trận và kết quả là các RichTextBox.

- Các điều khiển ―Tìm giá trị lớn nhất‖, ―Tính tổng các số lẻ‖, ―Đếm các số chia

hết cho 3 và 7‖, ― Tính tổng từng hàng‖, ― Liệt kê các số nguyên tố‖, ―Thoát‖là các

Button.

- Đối tƣợng ―Ma trận vừa nhập‖, ―Kết quả‖ là cá GroupBox.

2. Lập trình thực hiện các công việc:

- Khi Load Form:

+ Textbox tƣơng ứng với nhãn nhập số hàng để trống, sáng lên và con trỏ đặt

tại ô đó.

+ Textbox tƣơng ứng vỡi nhãn nhập số cột, nhập giá trị, các nút ―Tìm giá trị lớn nhất‖, ―Tính tổng các số lẻ‖, ―Đếm các số chia hết cho 3 và 7‖, ― Tính tổng từng hàng‖, ― Liệt kê các số nguyên tố‖, đối tƣơng GroupBox Ma trận vừa nhập và kết quả vô hiệu hóa. - Khi nhập một giá trị vào textbox tƣơng ứng với nhãn nhập số hàng rồi nhấn phím Enter thì thực hiện kiểm tra xem dữ liệu nhập vào có hợp lệ hay không? (giá trị nhập vào phải là số nguyên dƣơng). Nếu không hợp lệ thì hiện lên hộp thoại thông báo

và yêu cầu nhập lại. Ngƣợc lại thì textbox tƣơng ứng với nhãn nhập số cột sáng lên, để

trống và con trỏ đặt tại đó.

184

Tập bài giảng Lập trình cơ bản

- Khi nhập một giá trị vào textbox tƣơng ứng với nhãn nhập số cột rồi nhấn

phím Enter thì thực hiện kiểm tra xem dữ liệu nhập vào có hợp lệ hay không? (giá trị

nhập vào phải là số nguyên dƣơng). Nếu không hợp lệ thì hiện lên hộp thoại thông báo

và yêu cầu nhập lại. Ngƣợc lại thì textbox tƣơng ứng với nhãn nhập giá trị sáng lên, để trống và con trỏ đặt tại đó.

- Khi nhập giá trị vào textbox tƣơng ứng với nhãn nhập giá trị rồi nhấn phím

Enter thì hiển thị giá trị đó ra richtextbox trong Group Ma trận vừa nhập, sau đó textbox này để trống và con trỏ lại đặt tại ô đó để nhập giá trị tiếp theo. Lặp lại quá

trình này cho tới khi nhập xong giá trị cho các phần tử của ma trận thì đƣa ra thông

báo đã nhập xong ma trận và đồng thời các nút ―Tìm giá trị lớn nhất‖, ―Tính tổng các

số lẻ‖, ―Đếm các số chia hết cho 3 và 7‖, ― Tính tổng từng hàng‖, ― Liệt kê các số nguyên tố‖ sáng lên cho phép hoạt động, các textbox tƣơng ứng với nhập số hàng,

nhập số cột, nhập giá trị vô hiệu hóa.

- Khi kích vào nút ― Tìm giá trị lớn nhất‖: thực hiện tìm giá trị lớn nhất của ma

trận và hiển thị kết quả ra richtextbox ở trong Groupbox kết quả.

- Khi kích vào nút ― Tổng các số lẻ‖: thực hiện tính tổng các phần tử có giá trị

lẻ của ma trận và hiển thị kết quả ra richtextbox ở trong Groupbox kết quả.

- Khi kích vào nút ― Đếm các số chia hết cho 3 và 7‖: thực hiện đếm các phần

tử có giá trị chia hết cho 3 và của ma trận và hiển thị kết quả ra richtextbox ở trong

Groupbox kết quả.

- Khi kích vào nút ― Tính tổng từng hàng‖: thực hiện tính tổng các phần tử trên

từng hàng của ma trận và hiển thị kết quả ra richtextbox ở trong Groupbox kết quả.

- Khi kích vào nút ― Liệt kê các số nguyên tố‖: Hiển thị ra richtextbox ở trong

Groupbox các số nguyên tố có trong ma trận.

- Khi kích vào nút ― Thoát‖: thực hiện dừng chƣơng trình.

Hướng dẫn thực hiện 1. Thiết kế Form như yêu cầu đề bài

2. Phân tích yêu cầu

Theo yêu cầu của bài toán thì phải có một Form chứa: - Các đối tƣợng có nội dung ―BÀI TẬP VỀ MẢNG HAI CHIỀU‖,‖Nhập số

hàng‖, ―Nhập số cột‖, ‖Nhập giá trị‖ là các Label.

- Đối tƣợng ô để nhập số hàng, nhập số cột và nhập giá trị là các Textbox. - Đối tƣợng ma trận vừa nhập, kết quả là các GroupBox. - Điều khiển để hiển thị ma trận vừa nhập và kết quả là các Richtextbox.

185

Tập bài giảng Lập trình cơ bản

- Các nút ―Tìm giá trị lớn nhất‖, ―Tính tổng các số lẻ‖, ―Đếm các số chia hết

cho 3 và 7‖, ― Tính tổng từng hàng‖, ― Liệt kê các số nguyên tố‖, ―Thoát‖là các

Button.

Nhƣ vậy, để thực hiện công việc thiết kế Form nhƣ yêu cầu bài toán, ngƣời lập 3. Hướng dẫn thực hiện

trình thực hiện các bƣớc sau:

Bƣớc 1. Mở C# Bƣớc 2. Tạo Form mới

Trên thanh menu, chọn File/New/Project.Trên màn hình xuất hiện cửa sổ New

Project, chọn ứng dụng Windows Form Appication, sau đó nhập tên của Project vào ô

Name, kích vào Browse để chọn thƣ mục lƣu trữ Project, sau đó chọn OK. Bƣớc 3. Thiết kế Form theo mẫu và gắn các điều khiển

Bƣớc 4. Kết quả thiết kế Form

Hình 4.57: Kết quả thiết kế Form bài tập mẫu về mảng hai chiều

Bƣớc 5. Viết mã lệnh cho các sự kiện

int[,] A= new int [100,100]; int n, m, spt=0, i=0,j=0;

- Viết mã lệnh khai báo ma trận và biến

private void Form1_Load(object sender, EventArgs e)

{

vohieuhoa(false);

txt_n.ResetText();

txt_n.TabIndex = 1;

txt_n.Focus();

}

- Viết mã lệnh cho sự kiện Load Form

private void vohieuhoa(bool gt)

{

txt_m.Enabled = gt;

txt_giatri.Enabled = gt;

- Viết mã lệnh cho hàm vô hiệu hóa các điều khiển khi Load Form

186

bt_demchia21.Enabled = gt;

bt_lietkeSNT.Enabled = gt;

bt_timMax.Enabled = gt;

bt_tongle.Enabled = gt;

bt_tongtunghang.Enabled = gt;

group_Hienthi.Enabled = gt;

group_ketqua.Enabled = gt;

}

Tập bài giảng Lập trình cơ bản

bool kiemtra(string s)

{

if (string.IsNullOrWhiteSpace(s)) return true;

else return false;

}

- Viết mã lệnh cho hàm kiểm tra xâu rỗng

bool kiemtra_dulieu(string s)

{

bool kt;

if (kiemtra(s)) return false;

kt = int.TryParse(s, out n);

return kt &&n>0;

}

- Viết mã lệnh cho hàm kiểm tra dữ liệu nhập vào

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn nhập số

private void txt_n_KeyUp(object sender, KeyEventArgs e)

{

if (e.KeyCode == Keys.Enter)

{

if (kiemtra_dulieu(txt_n.Text))

{

txt_m.Enabled = true; txt_m.TabIndex = 1;

txt_m.Focus();

}

else { MessageBox.Show("Bạn chưa nhập đúng n");

txt_n.Focus(); vohieuhoa(false); }

}

}

hàng

private void txt_m_KeyUp(object sender, KeyEventArgs e)

{

if (e.KeyCode == Keys.Enter)

{

if (kiemtra_dulieu(txt_m.Text))

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn nhập số cột

187

{

txt_giatri.Enabled = true; txt_giatri.TabIndex =

1; txt_giatri.Focus();

}

else { MessageBox.Show("Bạn chưa nhập đúng m");

txt_giatri.TabIndex

=

1;

txt_m.Focus();

vohieuhoa(false);

txt_m.Enabled = true; }

}

}

Tập bài giảng Lập trình cơ bản

private void txt_giatri_KeyUp(object sender, KeyEventArgs e)

{

bool

kt;

n

=

int.Parse(txt_n.Text);

m

=

int.Parse(txt_m.Text);

if (e.KeyCode == Keys.Enter)

{

kt = int.TryParse(txt_giatri.Text, out A[i, j]);

if (kt) { rtbox_hienthi.Text += A[i, j].ToString()

+ " "; spt++; txt_giatri.ResetText(); txt_giatri.Focus(); j++; }

if (j == m) { rtbox_hienthi.Text += "\n"; i++; j =

0; }

if (spt == n * m) { MessageBox.Show("Nhập xong

dãy", "Thông báo"); vohieuhoa(false); vohieuhoa2(); txt_m.Enabled =

false; txt_n.Enabled = false; }

}

}

- Viết mã lệnh cho hàm vô hiệu hóa các nút sau khi nhập xong ma trận

private void vohieuhoa2()

{

bt_demchia21.Enabled = true; bt_lietkeSNT.Enabled = true;

bt_timMax.Enabled = true; bt_tongle.Enabled = true;

bt_tongtunghang.Enabled = true;

}

- Viết mã lệnh cho sự kiện KeyUp của textbox tƣơng ứng với nhãn nhập giá trị

private void bt_timMax_Click(object sender, EventArgs e)

{

rtbox_ketqua.ResetText();

int max = A[0, 0];

for (int i = 0; i < n; i++)

for (int j = 0; j < m; j++)

if (A[i, j] > max) max = A[i, j];

rtbox_ketqua.Text = "Giá trị lớn nhất của ma trận là:" +

max.ToString();

}

- Viết mã lệnh cho sự kiện kích chuột vào nút tìm giá trị lớn nhất

188

Tập bài giảng Lập trình cơ bản

private void bt_tongle_Click(object sender, EventArgs e)

{

rtbox_ketqua.ResetText();

int s = 0;

for (int i = 0; i < n; i++)

for (int j = 0; j < m; j++)

if (A[i, j] % 2 != 0) s += A[i, j];

rtbox_ketqua.Text = "Tổng các số lẻ của ma trận là: " +

s.ToString();

}

- Viết mã lệnh cho sự kiện kích chuột vào nút tính tổng các số lẻ

private void bt_demchia21_Click(object sender, EventArgs e)

{

rtbox_ketqua.ResetText();

int d = 0;

for (int i = 0; i < n; i++)

for (int j = 0; j < m; j++)

if (A[i, j] % 21 == 0) d++;

rtbox_ketqua.Text = "Ma trận có " + d.ToString() + " số

chia hết cho cả 3 và 7";

}

- Viết mã lệnh cho sự kiện kích chuột vào nút đếm các số chia hết cho 3 và 7

private void bt_tongtunghang_Click(object sender, EventArgs e)

{

int s; rtbox_ketqua.ResetText();

for (int i = 0; i < n; i++)

{

s=0;

for (int j = 0; j < m; j++) s += A[i, j];

rtbox_ketqua.Text+= "Tổng hàng " + (i+1).ToString() +

"là: " + s.ToString();

rtbox_ketqua.Text += "\n";

}

}

- Viết mã lệnh cho sự kiện kích chuột vào nút tính tổng từng hàng

private void bt_lietkeSNT_Click(object sender, EventArgs e)

{

rtbox_ketqua.Text=" Các số nguyên tố của ma trận là: ";

int d = 0;

for (int i = 0; i < n; i++)

for (int j = 0; j < m; j++)

if (kt_SNT(A[i, j])) { rtbox_ketqua.Text += A[i,

j].ToString() + " "; d++; }

if (d == 0) rtbox_ketqua.Text = "Ma trận không có số

- Viết mã lệnh cho sự kiện kích chuột vào nút tính liệt kê các số nguyên tố

189

nguyên tố";

}

Tập bài giảng Lập trình cơ bản

bool kt_SNT(int n)

{

bool kt;

if (n < 2) kt = false;

else

{

kt = true;

for(int i=2;i<=n/2;i++)

if (n % i == 0)

{

kt = false; break;

}

}

return kt;

}

- Viết mã lệnh cho hàm kiểm tra số nguyên tố

Bƣớc 6. Kết quả chạy chƣơng trình

Hình 4.58: Kết quả chạy chương trình bài tập mẫu về mảng hai chiều

Bài 4.11

Tạo một ứng dụng Windows Form thực hiện các công việc sau: 1. Nhập một ma trận số thực gồm n hàng, m cột (với n và m là hai số nguyên

dƣơng).

2. Hiển thị ma trận. 3. Tìm số âm nhỏ nhất của ma trận. 4. Sắp xếp từng cột của ma trận theo thứ tự tăng dần.

5. Nhập số nguyên dƣơng k, xóa cột thứ k của ma trận nếu có.

190

Tập bài giảng Lập trình cơ bản

6. Tính trung bình cộng các phần tử có giá trị chẵn trong ma trận

Bài 4.12

Tạo một ứng dụng Windows Form thực hiện các công việc sau:

1. Nhập một ma trận số thực vuông cấp n (với n là số nguyên dƣơng). 2. Hiển thị ma trận.

3. Tính tổng các phần tử nằm trên đƣờng chéo phụ của ma trận.

4. Tìm số âm lớn nhất trên đƣờng chéo chính của ma trận 5. Đếm các phần tử của ma trận có giá trị chia hết cho 3 và 5.

Bài 4.13

Viết một chƣơng trình thực hiện các công việc sau:

1. Thiết kế Form theo mẫu

Hình 4.59: Chương trình xử lý chuỗi

Yêu cầu:

- Nhãn chƣơng trình xử lý chuỗi: Font Time New Roman, chữ hoa, in đậm, cỡ

chữ 16, căn giữa Form.

- GroupBox nhập và kết quả: Font Time New Roman, cỡ chữ 14.

- Điều khiển để nhập chuỗi A, chuỗi B và hiển thị kết quả là các RichTextBox.

- Các điều khiển ―So sánh‖, ―Nối chuỗi‖, ―Chèn‖, ―Thêm chuỗi‖, ―Thay thế‖,

- Khi Load Form: + RichTextBox nhập A và B sáng cho phép nhập xâu ký tự. + Các điều khiển khác vô hiệu hóa (nút ―Thoát‖ luôn sáng, richTextBox kết quả

―Chuỗi hoa‖, ―Chuỗi thƣờng‖, ‖Thoát‖là các Button. 2. Lập trình cho các sự kiện: luôn ẩn). - Khi nhập xâu vào richTextBox nhập A hoặc B thì các button sẽ sáng lên. - Khi kích vào nút ―So sánh‖:

191

Tập bài giảng Lập trình cơ bản

+ Kiểm tra xem đã nhập xâu hay chƣa? Nếu chƣa thì đƣa ra hộp thoại thông

báo.

+ Thực hiện so sánh hai xâu theo thứ tự từ điển trong bảng mã ASCII.

+ Hiển thị kết quả ra richTextBox kết quả. - Khi kích vào nút ―Chèn‖:

+ Kiểm tra xem đã nhập xâu A và xâu B hay chƣa? Nếu chƣa nhập đủ thì đƣa ra

hộp thoại thông báo. + Hiện lên cửa sổ cho phép nhập vào số nguyên dƣơng n.

+ Thực hiện nối xâu B vào vị trí thứ n của xâu A.

+ Hiển thị xâu kết quả ra richTextBox kết quả.

- Khi kích vào nút ―Nối chuỗi‖: + Kiểm tra xem đã nhập xâu A và xâu B hay chƣa? Nếu chƣa nhập đủ thì đƣa ra

hộp thoại thông báo.

+ Thực hiện nối xâu B vào cuối xâu A.

+ Hiển thị xâu kết quả ra richTextBox kết quả.

- Khi kích vào nút ―Thay thế‖:

+ Kiểm tra xem đã nhập xâu A và xâu B hay chƣa? Nếu chƣa nhập đủ thì đƣa ra

hộp thoại thông báo.

+ Thực hiện thay thế xâu A bằng xâu B.

+ Hiển thị xâu kết quả ra richTextBox xâu A.

- Khi kích vào nút ―Xâu hoa‖:

+ Kiểm tra xem đã nhập xâu A và xâu B hay chƣa? Nếu chƣa nhập đủ thì đƣa ra

hộp thoại thông báo.

+ Thực hiện chuyển xâu A và xâu B về xâu chứa toàn ký tự hoa.

+ Hiển thị xâu kết quả ra richTextBox xâu A và richTextBox xâu B. - Khi kích vào nút ―Thoát‖: thực hiện kết thúc chƣơng trình.

Hướng dẫn thực hiện 1. Thiết kế Form như yêu cầu đề bài

2. Phân tích yêu cầu Theo yêu cầu của bài toán thì phải có một Form chứa: - Các đối tƣợng có nội dung ―CHƢƠNG TRÌNH XỬ LÝ CHUỖI‖, ―Nhập

chuỗi A‖, ―Nhập chuỗi B‖ là các Label.

- Đối tƣợng ô nhập xâu A, xâu B và kết quả là các RichTextBox. - Đối tƣợng nhập và kết quả là các GroupBox. - Các nút ―So sánh‖, ―Nối chuỗi‖, ― Chèn‖, ―Thay thế‖, ― Chuỗi hoa‖, ―Thoát‖

là các Button.

192

Tập bài giảng Lập trình cơ bản

3. Hướng dẫn thực hiện

Nhƣ vậy, để thực hiện công việc thiết kế Form nhƣ yêu cầu bài toán, ngƣời lập

trình thực hiện các bƣớc sau:

Bƣớc 1. Mở C# Bƣớc 2. Tạo Form mới

Trên thanh menu, chọn File/New/Project.Trên màn hình xuất hiện cửa sổ New

Project, chọn ứng dụng Windows Form Appication, sau đó nhập tên của Project vào ô Name, kích vào Browse để chọn thƣ mục lƣu trữ Project, sau đó chọn OK.

Bƣớc 3. Thiết kế Form theo mẫu và gắn các điều khiển

Bƣớc 4. Kết quả thiết kế Form

Hình 4.60: Kết quả thiết kế Form chương trình xử lý xâu

Bƣớc 5. Viết mã lệnh cho các nút chức năng

private void Form1_Load(object sender, EventArgs e)

{

vohieuhoa(false);

rtbox_A.ResetText();

rtbox_B.ResetText();

rtbox_A.Focus();

}

- Viết mã lệnh cho sự kiện Form Load

void vohieuhoa(bool gt)

{

bt_chen.Enabled = gt;

bt_chuoihoa.Enabled = gt;

bt_noichuoi.Enabled = gt;

bt_sosanh.Enabled = gt;

bt_thaythe.Enabled = gt;

}

- Viết mã lệnh cho hàm vô hiệu hóa các button

- Viết mã lệnh cho sự kiện TextChanged của richTextBox nhập xâu A

193

private void rtbox_A_TextChanged(object sender, EventArgs e)

{

vohieuhoa(true);

}

Tập bài giảng Lập trình cơ bản

private void rtbox_B_TextChanged(object sender, EventArgs e)

{

vohieuhoa(true);

}

- Viết mã lệnh cho sự kiện TextChanged của richTextBox nhập xâu B

private void bt_sosanh_Click(object sender, EventArgs e)

{

rtbox_ketqua.ResetText();

if

(kiemtra(rtbox_A.Text)

||

kiemtra(rtbox_B.Text))

MessageBox.Show("Chưa nhập xâu", "Thông báo");

else if (string.Compare(rtbox_A.Text, rtbox_B.Text) == 0)

rtbox_ketqua.Text = "Hai chuỗi giống nhau";

else if (string.Compare(rtbox_A.Text, rtbox_B.Text) <0)

rtbox_ketqua.Text = "Chuỗi A nhỏ hơn chuỗi B";

else rtbox_ketqua.Text = "Chuỗi A lớn hơn chuỗi B";

}

- Viết mã lệnh cho sự kiện kích chuột vào nút so sánh

bool kiemtra(string st)

{

if (string.IsNullOrWhiteSpace(st)) return true;

else return false;

}

- Viết mã lệnh cho hàm kiểm tra chuỗi rỗng

private void bt_noichuoi_Click(object sender, EventArgs e)

{

rtbox_ketqua.ResetText();

if

(kiemtra(rtbox_A.Text)

||

kiemtra(rtbox_B.Text))

MessageBox.Show("Chưa nhập xâu", "Thông báo");

else

{

string st, st1, st2;

st1 = rtbox_A.Text;

st2 = rtbox_B.Text;

st = string.Concat(st1, st2);

rtbox_ketqua.Text = st;

}

}

- Viết mã lệnh cho sự kiện kích chuột vào nút nối chuỗi

private void bt_chen_Click(object sender, EventArgs e)

- Viết mã lệnh cho sự kiện kích chuột vào nút chèn

194

{

bool kt; int n;

rtbox_ketqua.ResetText();

if

(kiemtra(rtbox_A.Text)

||

kiemtra(rtbox_B.Text))

MessageBox.Show("Chưa nhập xâu", "Thông báo");

else

{

string st, st1, st2;

st1 = rtbox_A.Text;

st2 = rtbox_B.Text;

do

{

kt

=

int.TryParse(Microsoft.VisualBasic.Interaction.InputBox("Nhập vị trí

cần bổ sung n = "), out n);

} while (!kt || n < 1 || n > st1.Length);

st = st1.Insert(n, st2);

rtbox_ketqua.Text = st;

}

}

Tập bài giảng Lập trình cơ bản

private void bt_thaythe_Click(object sender, EventArgs e)

{

if (kiemtra(rtbox_A.Text))MessageBox.Show("Chưa nhập xâu",

"Thông báo");

else

{

string xau_can_thay = Microsoft.VisualBasic.Interaction.InputBox("Nhập xâu cần

thay thế", "Nhập xâu", "", 100, 100);

string xau_thay_the =

Microsoft.VisualBasic.Interaction.InputBox("Nhập xâu thay thế", "Nhập xâu", "",

100, 100); st1 = st1.Replace(xau_can_thay, xau_thay_the);

rtbox_A.Text = st1;

}

} - Viết mã lệnh cho sự kiện kích chuột vào nút chuỗi hoa

private void bt_chuoihoa_Click(object sender, EventArgs e)

{

rtbox_ketqua.ResetText();

if

(kiemtra(rtbox_A.Text)

||

kiemtra(rtbox_B.Text))

MessageBox.Show("Chưa nhập xâu", "Thông báo");

else

{

- Viết mã lệnh cho sự kiện kích chuột vào nút thay thế

195

string st1, st2;

st1 = rtbox_A.Text;

st2 = rtbox_B.Text;

st1 = st1.ToUpper();

st2 = st2.ToUpper();

rtbox_A.Text = st1;

rtbox_B.Text = st2;

}

}

Tập bài giảng Lập trình cơ bản

private void bt_Thoat_Click(object sender, EventArgs e)

{

this.Close();

}

- Viết mã lệnh cho sự kiện kích chuột vào nút thoát

Bƣớc 6. Kết quả chạy chƣơng trình

Hình 4.61: Kết quả chạy chương trình xử lý xâu

Bài 4.14 Lập chƣơng trình thực hiện các yêu cầu sau:

1. Thiết kế Form nhƣ hình sau

Hình 4.62: Chuẩn hóa và đếm từ trong xâu

196

Tập bài giảng Lập trình cơ bản

Yêu cầu:

- Nhãn chuẩn hóa và đếm từ trong xâu: Font Time New Roman, chữ hoa, in

đậm, cỡ chữ 16, căn giữa Form.

- GroupBox nhập xâu và kết quả: Font Time New Roman, cỡ chữ 14 - Điều khiển để nhập xâu và hiển thị kết quả là các RichTextBox và đƣợc đặt

trong các GroupBox tƣơng ứng.

- Nhãn đếm từ: Font Time New Roman, cỡ chữ 14. - Các điều khiển ―Chuẩn hóa‖, ―Đếm từ‖, ―Thoát là các Button.

2. Lập trình cho các nút sự kiện:

- Khi Load Form:

+ richTextBox nhập xâu sáng lên cho phép nhập xâu. + Các điều khiển khác vô hiệu hóa (nút ―Thoát‖ luôn sáng).

- Nút ―Chuẩn hóa‖ sáng lên khi nhập ở richTextBox nhập xâu.

- Khi kích vào nút ―Chuẩn hóa‖ thì:

+ RichTextBox nhập xâu vô hiệu hóa.

+ Thực hiện chuẩn hóa xâu và đƣa kết quả ra richTextBox kết quả

+ Nút ―Đếm từ‖ sáng lên đồng thời lúc này nút ―Chuẩn hóa‖ vô hiệu hóa.

- Khi kích vào nút ―Đếm từ‖ thì:

+ Thực hiện đếm từ của xâu đã chuẩn hóa.

+ Hiển thị kết quả ra nhãn đếm từ.

TAI LIỆU THAM KHẢO [1] Phạm Hữu Khang, Đoàn Thiện Ngân. C# 2005 - Lập trình cơ bản. Nhà xuất bản

Lao động xã hội. 2006.

[2] Phạm Hữu Khang, Đoàn Thiện Ngân. C# 2005 - Lập trình Windows Forms. Nhà

xuất bản Lao động xã hội. 2006.

[3] Microsoft .net (C#), Trung tâm đào tạo CNTT chất lƣợng cao, cổng cntt Việt Nam.

www.itgatevn.com.vn

[4] Programming C#, Jesse Liberty, O‘Reilly. [5] Hƣớng dẫn thực hành lâp trình cơ bản, Đại học Công nghệ Đồng Nai

[6] Windows Forms Programming with C#, Erik Brown, Manning.

197

Tập bài giảng Lập trình cơ bản

[7] http://msdn.microsoft.com

198