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:
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 (
{
{
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
31
Tập bài giảng Lập trình cơ bản
case
...
case
[default:
}
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 (
// thực hiện thông qua
}
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 { [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à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. 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 198Mô tả
Thuộc tính
BackColor