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

pdf 125 trang Gia Huy 17/05/2022 3371
Bạn đang xem 20 trang mẫu của tài liệu "Tập bài giảng Lập trình cơ bản", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdftap_bai_giang_lap_trinh_co_ban.pdf

Nội dung text: Tập bài giảng Lập trình cơ bản

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. Tập bài giảng Lập trình cơ bản Hình 4.19: Hiển thị trang 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
  9. 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
  10. 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êñ Thi ̣Thu Thủy x
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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 để xây dựng bất cứ ứng dụng nào. 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#. 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
  16. 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
  17. 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++. - 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: // 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(); 7
  18. 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 đƣ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. 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 8
  19. Tập bài giảng Lập trình cơ bản Console.Write("Nhap b = "); b = float.Parse(Console.ReadLine()); 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 màn hình. float max; max = a; if (max < b) max = b; Console.WriteLine("So lon nhat = {0}", max); 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ự ―*/‖. Ví dụ 1.2: Minh họa dùng chú thích trên nhiều dòng. 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(); }}} Kết quả thực thi chƣơng trình: 9
  20. 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: là từ khóa khai báo một NameSpace - NamespaceName: là tên của một Namespace Ví dụ: namespace CSharpProgram { class Basic { } class Advanced { } } 10
  21. 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#. Các tên đúng: a_1 delta x1 _step GAMA 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
  22. 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
  23. 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ị byte 1 Byte Số nguyên từ 0 đến 255 char 2 Char Ký tự Unicode bool 1 Boolean {true, false} sbyte 1 Sbyte Số nguyên từ -128 đến 127 short 2 Int16 Số nguyên từ -32768 đến32767. ushort 2 Uịnt16 Số nguyên không dấu từ 0 – 65535 int 4 Int32 Số nguyên từ –2.147.483.647 đến 2.147.483.647 uint 4 Uint32 Số nguyên từ 0 đến 4.294.967.295 float 4 Single 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
  24. 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. Ví du 2.3: Khởi tạo và gán giá trị đến một biến. namespace Vidu2_3{ class Program 14
  25. Tập bài giảng Lập trình cơ bản { 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(); } } } 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: Ví dụ 2.4: Sử dụng một biến không khởi tạo. 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(); } } } 15
  26. 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 đó. Ví dụ 2.5: Biến không đƣợc khi tạo nhƣng sau đó đƣợc gán giá trị. 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(); } } } 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ị; Ví dụ 2.6: Sử dụng hằng. namespace Vidu2_6 { class Program { 16
  27. Tập bài giảng Lập trình cơ bản 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(); } } } 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). 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: v=e 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 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; 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 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
  28. 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). Ví dụ 2.7: Minh họa sử dụng các phép toán các số nguyên, thực 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); 18
  29. Tập bài giảng Lập trình cơ bản 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: 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 true value1 == 50 false != Không bằng value2 != 100 false value2 != 90 true > Lớn hơn value1 > value2 true value2 > value1 false >= Lớn hơn hay bằng value2 >= 50 true < Nhỏ hơn value1 < value2 false value2 < value1 true 19
  30. 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
  31. 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 Ví dụ 2.8: Minh hoạ sử dụng toán tử tăng trƣớc và tăng sau khi gán. 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(); } } } Kết quả chƣơng trình: 21
  32. 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. is Xác định xem một đối tƣợng có phải có kiểu nào đó hay không as Chuyển đổi không phát sinh 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 (x) x.y f(x) a[x] x++ x—new Trái 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
  33. Tập bài giảng Lập trình cơ bản 5 Dịch bit > Trái 6 Quan hệ = is as Trái 7 So sánh bằng == != Phả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 || Trái 13 Điều kiện ?: Phải 14 Phép gán = *= /= %= += -= >= &= Phải ^= |= Bảng 2.8: Thứ tự ưu tiên các phép toán. Các phép toán đƣợc liệt kê cùng loại sẽ có thứ tự theo mục thứ tự của bảng: thứ tự trái tức là độ ƣu tiên của các phép toán từ bên trái sang, thứ tự phải thì các phép toán có độ ƣu tiên từ bên phải qua trái. Các toán tử khác loại thì có độ ƣu tiên từ trên xuống dƣới, do vậy các toán tử loại cơ bản sẽ có độ ƣu tiên cao nhất và phép toán gán sẽ có độ ƣu tiên thấp nhất trong các toán tử. Biểu thức điều kiện Hầu hết các toán tử đòi hỏi có một toán hạng nhƣ toán tử (++, ) hay hai toán hạng nhƣ (+,-,*,/, ). Tuy nhiên, C# còn cung cấp thêm một toán tử có ba toán hạng (?:). Toán tử này có cú pháp sử dụng nhƣ sau: ? : Toán tử này sẽ xác định giá trị của biểu thức điều kiện và biểu thức điều kiện này phải trả về một giá trị kiểu bool. Khi điều kiện đúng thì sẽ đƣợc thực hiện, còn ngƣợc lại điều kiện sai thì sẽ đƣợc thực hiện. Có thể diễn giải theo ngôn ngữ tự nhiên thì toán tử này có ý nghĩa: ―Nếu điều kiện đúng thì làm công việc thứ nhất, còn ngƣợc lại điều kiện sai thì làm công việc thứ hai‖. Cách sử dụng toán tử ba ngôi này đƣợc minh họa trong ví dụ 2.9 sau. Ví dụ 2.9: Lập chƣơng trình tìm số lớn nhất của hai số 23
  34. Tập bài giảng Lập trình cơ bản 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(); } } } 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
  35. 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
  36. 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 thực ) = 124 Exp 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 Trả về số lớn nhất trong hai số Max(3,7) = 7 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
  37. 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 ra, lớp Math có hai thuộc tính PI, E, trong đó PI = 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: Bắt đầu Biểu thức logic True Lệnh hoặc khối lệnh False Kết thúc 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 từ bàn phím. namespace Vidu_2_10 { class Program { static void Main(string[] args) { float a, b; 27
  38. Tập bài giảng Lập trình cơ bản Console.Write("Nhap a = "); a = float.Parse(Console.ReadLine()); Console.Write("Nhap b = "); b = float.Parse(Console.ReadLine()); float max = a; if(max ) { ;} 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
  39. Tập bài giảng Lập trình cơ bản Bắt đầu Biểu thức logic False True Lệnh hoặc khối Lệnh hoặc khối lệnh 1 lệnh 2 Kết thúc 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à các số thực nhập từ bàn phím. 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(); } } } Kết quả chƣơng trình: Hình 2.9: Kết quả chương trình ví dụ 2.11 29
  40. Tập bài giảng Lập trình cơ bản 3. Câu lệnh if lồng nhau Các câu lệnh if trên chỉ cho phép rẽ 1 hoặc 2 nhánh, trong trƣờng hợp rẽ nhiều hơn 2 nhánh thì có thể sử dụng câu lệnh if lồng nhau. Cú pháp: if ( ) { ;} else if ( ) { ;} else if ( ) { ;} else { ;} Hoạt động: Bƣớc 1: Thực hiện tính biểu thức logic 1, nếu biếu thức logic 1 là đúng thì thực hiện lệnh hoặc khối lệnh 1 và kết thúc câu lệnh if lồng nhau. Ngƣợc lại lệnh hoặc khối lệnh 1 bị bỏ qua. Bƣớc 2: Thực hiện tính biểu thức logic 2, nếu biếu thức logic 2 là đúng thì thực hiện lệnh hoặc khối lệnh 2 và kết thúc câu lệnh if lồng nhau. Ngƣợc lại lệnh hoặc khối lệnh 2 bị bỏ qua. Bƣớc n-1: Thực hiện tính biểu thức logic n-1, nếu biếu thức logic n-1 là đúng thì thực hiện lệnh hoặc khối lệnh n-1 và kết thúc câu lệnh if lồng nhau. Ngƣợc lại lệnh hoặc khối lệnh n - 1 bị bỏ qua. Bƣớc n: Thực hiện lệnh hoặc khối lệnh n và kết thúc câu lệnh if lồng nhau. Ví dụ 2.12: Lập chƣơng trình giải phƣơng trình bậc hai ax2 + bx + c = 0 với a, b, c là các số thực nhập từ bàn phím. 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 = "); 30
  41. Tập bài giảng Lập trình cơ bản 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 ) { case : ; break; 31
  42. Tập bài giảng Lập trình cơ bản case : ; break; case : ; break; [default: ; break;] } Hoạt động: Bƣớc 0: Tính giá trị biểu thức nguyên. Bƣớc 1: Nếu giá trị biểu thứcnguyên bằng giá trị 1 thì thực hiện lệnh hoặc khối lệnh 1 và kết thúc switch. Ngƣợc lại lệnh hoặc khối lệnh 1 và câu lệnh break bị bỏ qua. Bƣớc 2: Nếu giá trị biểu thứcnguyên bằng giá trị2 thì thực hiện lệnh hoặc khối lệnh 2 và kết thúc switch. Ngƣợc lại lệnh hoặc khối lệnh 2 và câu lệnh break bị bỏ qua. Bƣớc n: Nếu giá trị biểu thứcnguyên bằng giá trịn thì thực hiện lệnh hoặc khối lệnh nvà kết thúc switch. Ngƣợc lại lệnh hoặc khối lệnh n và câu lệnh break bị bỏ qua và kết thúc switch nếu không có tùy chọn default: ; break;. Nếu có tùy chọn default: ; 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. Hiển thị ra màn hình số ngày của tháng đó. 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; 32
  43. Tập bài giảng Lập trình cơ bản 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(); } } } 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 có thể sửa lại nhƣ sau: 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: 33
  44. Tập bài giảng Lập trình cơ bản 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(); } } } 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: Bắt đầu Biểu thức logic true Lệnh hoặc khối false lệnh Kết thúc Hình 2.12: Hoạt động của vòng lặp while 34
  45. 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 dƣơng m, n. Với m, n là hai số nguyên dƣơng nhập từ bàn phím. 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(); } } } 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
  46. 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. Bắt đầu Lệnh hoặc khối lệnh true Biểu thức logic false Kết thúc Hình 2.14: Hoạt động của vòng lặp do while. Ví dụ 2.15: Lập chƣơng trình chạy chƣơng trình tìm UCLN nhiều lần. 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'); } } } 36
  47. 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: Bắt đầu Biểu thức gán Biểu thức logic Bƣớc nhảy true false Lệnh hoặc khối lệnh Kết thúc 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ố nguyên dƣơng nhập từ bàn phím. namespace Vidu2_16 { class Program 37
  48. Tập bài giảng Lập trình cơ bản { 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(); } } } 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. Ví dụ 2.17: Phạm vi của biến khai báo trong vòng lặp. 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); 38
  49. Tập bài giảng Lập trình cơ bản Console.ReadLine(); } } } 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 nhập vào số 0. Đƣa ra màn hình tổng các số dƣơng đã nhập vào. 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) s += x; else break; } Console.WriteLine("Tong cac so vua nhap = "+s.ToString()); Console.ReadLine(); } } } Kết quả chƣơng trình: Hình 2.18: Kết quả chương trình ví dụ 2.18. 39
  50. 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. Ví dụ 2.19: Sử dụng câu lệnh goto để thoát khỏi vòng lặp lồng nhau. 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(); } } } Kết quả chƣơng trình 40
  51. 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
  52. 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. Ví dụ 2.20: Lập chƣơng trìnhxuất hiện một exception khi chia một số cho số 0. namespace Vidu2_20 { class Program { static void Main(string[] args) { 42
  53. Tập bài giảng Lập trình cơ bản 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(); } } } 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
  54. 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: Ví dụ 2.21: Tự định nghĩa exception. 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(); 44
  55. Tập bài giảng Lập trình cơ bản } } 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); } } } } 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
  56. 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 nhập x đúng theo yêu cầu. 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: 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 Gợi ý: Viết mã lệnh tính giá trị hàm số và in kết quả 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(); Bài 2.3 46
  57. 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 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 1 푆 = 1 + + + ⋯ + 2 3 푛 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 nhập n đúng theo yêu cầu. 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); 47
  58. 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 1 푆 = 1 + + + ⋯ + 2! 3! 푛 ! Gợi ý: Mã lệnh tính tổng: 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(); 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
  59. 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 ý - Mã lệnh tìm ƣớc chung lớn nhất của hai số m, n 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); 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: 1 1 1 1 S ( 1)n 1 1! 2! 3!n ! 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
  60. 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
  61. 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
  62. 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
  63. Tập bài giảng Lập trình cơ bản - Sắp xếp và hiển thị dãy số theo chiều tăng dầ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) td += a[i]; Console.WriteLine("Tong cac so trong day {0}", td); //Sắp xếp dãy tăng dần 53
  64. Tập bài giảng Lập trình cơ bản 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 in ) { // thực hiện thông qua tương ứng với // từng mục trong mảng hay tập hợp } Do vậy, có thể cải tiến ví dụ 3.1 trƣớc bằng cách thay việc sử dụng vòng lặp for bằng vòng lặp foreach để truy cập đến từng thành phần trong mảng. Ví dụ 3.2: Sử dụng foreach 54
  65. Tập bài giảng Lập trình cơ bản 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) 55
  66. Tập bài giảng Lập trình cơ bản { Console.Write("{0} ", pt); } Console.WriteLine(); Console.ReadLine(); } } } 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 mảng và gán tạm vào một biến pt khai báo ở đầu vòng lặp: foreach (int pt in a) { Console.Write("{0} ", pt); } 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
  67. 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 phím) 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 57
  68. Tập bài giảng Lập trình cơ bản float tbc = 0, tong = 0; int d = 0; for (i = 0; i = 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(); } } } Kết quả chƣơng trình: Hình 3.3: Kết quả chương trình ví dụ 3.3 58
  69. 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, khởi tạo các thành phần, rồi sau đó in ra màn hình. 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ử 59
  70. Tập bài giảng Lập trình cơ bản 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(); } } } Kết quả chƣơng trình: 60
  71. 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
  72. 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 Empty Trƣờng thể hiện một chuỗi rỗng. Compare Phƣơng thức để so sánh hai chuỗi. CompareOrdinal Phƣơng thức để so sánh hai chuỗi khôngquan tâm đến thứ tự. Concat Phƣơng thức để tạo chuỗi mới từ một hay nhiều chuỗi. Copy Phƣơng thức tạo ra một chuỗi mới bằngsao chép từ chuỗi khác Equal Phƣơng thức kiểm tra xem hai chuỗi có giống nhau hay 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. Chars Indexer của chuỗi. Length Chiều dài của chuỗi. CompareTo So sánh hai chuỗi. 62
  73. 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. Remove Xóa đi một số ký tự xác định. Split Trả về chuỗi đƣợc phân tách bởi những ký tự xác định 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ự. ToLower Trả về bản sao của chuỗi ở kiểu chữ thƣờng. ToUpper Trả về bản sao của chuỗi ở kiểu chữ hoa. Trim Loại bỏ khoảng trắng hoặc tập từ ký nào đó ở đầu và cuối xâu TrimEnd Loại bỏ khoảng trắng hoặc tập từ ký nào đó ở đầu xâu TrimStart Loại bỏ khoảng trắng hoặc tập từ ký nào đó ở cuối xâu 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. Ví dụ 3.5: Thao tác với chuỗi. namespace Vidu3_5 { class Program { static void Main(string[] args) { // khởi tạo một số chuỗi để thao tác 63
  74. Tập bài giảng Lập trình cơ bản 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")); 64
  75. Tập bài giảng Lập trình cơ bản // 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(); } } } 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
  76. 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