Bài giảng Ngôn ngữ lập trình ứng dụng (Phần 1)

pdf 45 trang ngocly 1230
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Ngôn ngữ lập trình ứng dụng (Phần 1)", để 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:

  • pdfbai_giang_ngon_ngu_lap_trinh_ung_dung_phan_1.pdf

Nội dung text: Bài giảng Ngôn ngữ lập trình ứng dụng (Phần 1)

  1. TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG BỘ MÔN TRUYỀN THÔNG ĐA PHƯƠNG TIỆN BÀI GIẢNG Ngôn ngữ lập trình ứng dụng Thông tin môn học Số tín chỉ : 3 Số tiết lý thuyết : 30 Số tiết thực hành : 30 Số tiết thảo luận : 0 Hệ đào tạo : Đại học Ngành đào tạo : Truyền thông đa phương tiện Thái Nguyên, 2014
  2. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện MỤC LỤC Chương 1: Tổng quan 5 1.1 Tổng quan về Microsoft .Net 5 1.1.1 Nguồn gốc Microsft .Net 5 1.2 Ngôn ngữ C# 10 1.2.1 Tại sao chọn ngôn ngữ C# 10 1.2.2 Ngôn ngữ C# với ngôn ngữ khác 12 1.3 Làm quen với visual studio 2010 13 1.3.1 Giới thiệu Visual Studio.NET 2010 13 1.3.2 Khởi động Visual C# 2010 và giao diện 14 1.3.3 Viết chương trình đầu tiên 15 Chương 2: Ngôn ngữ lập trình C# 17 2.1 Biến hằng và các kiểu dữ liệu 17 2.1.1 Biến 17 2.1.2 Hằng 17 2.1.3 Các kiểu dữ liệu 18 2.1.4 Chuyển kiểu dữ liệu 19 2.2 Biểu thức, toán tử, khoảng trắng 19 2.3 Nhập / xuất dữ liệu 23 2.4 Các cấu trúc điều khiển 24 2.4.1 Câu lệnh lựa chọn if 24 2.4.2 Câu lệnh lựa chọn Case 25 2.4.3 Cấu trúc lặp for 26 2.4.4 Cấu trúc lặp while. 27 2.4.5 Cấu trúc lặp do while 27 2.5 Mảng 28 2.5.1 Mảng một chiều 28 2.5.2 Câu lệnh foreach 29 2.5.3 Mảng đa chiều 29 2.7 Hàm và cách truyền tham số 34 2.8 Xử lý ngoại lệ 38 2.7.1 Phát sinh và bắt giữ ngoại lệ 39 2.7.2 Những đối tượng ngoại lệ 44 Chương 3: Lập trình hướng đối tượng trong C# 46 3.1 Xây dựng lớp – Đối tượng 46 3.1.1 Định nghĩa lớp 46 3.1.2 Tạo đối tượng 49 2 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  3. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện 3.1.3 Sử dụng các thành viên static 53 3.1.4 Nạp chồng 54 3.2 Kế thừa - Đa hình 54 3.2.1 Sự kế thừa 54 3.2.2 Đa hình 58 3.2.3 Lớp trừu tượng, lớp cô lập, giao diện 62 3.3 Các lớp cơ sở trong .NET 67 3.3.1 System.Object 67 3.3.2 Xử lý mảng 71 3.3.3 Xử lý chuỗi 72 3.3.4 Biểu thức chính quy ( Regular Expression) 83 3.3.5 Nhóm các đối tượng 88 3.3.6 Dictionaries 94 Chương 4: Lập trình winform 104 4.1 Tìm hiểu các điều khiển cơ bản 104 4.1.1 Form 106 4.1.3 Nút – Button 109 4.1.4 Nhãn – Label 109 4.1.5 ToolTip 109 4.2 Một số điều khiển khác 110 4.2.1 Hộp đánh dấu – CheckBox 110 4.2.2 Nút tuỳ chọn – RadioButton 110 4.2.3 Nhóm – GroupBox 110 4.2.4 Hộp danh sách – ListBox 111 4.2.5 Hộp lựa chọn – ComboBox 112 4.2.6 Điều khiển Panel 112 4.2.7 Điều khiển PictureBox 112 4.2.8 Điều khiển Timer 113 4.2.9 ErrorProvider ( ) 113 4.3 Các hộp thoại thông dụng 113 4.3.1 Hộp hội thoại Open File 113 4.3.2 Hộp thoại SaveFile và luồng FileStream 115 4.3.3 Hộp thoại Color 116 4.3.4 Hộp thoại Font 117 4.4 Menu 118 4.4.1 Menu – MenuStrip 118 4.4.2 Popup menu – ContextMenuStrip 119 3 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  4. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Chương 5: Lập trình cơ sở dữ liệu 121 5.1 Hệ quản trị cơ sở dữ liệu MS SQL Server 2008 121 5.1.1 Tổng quan về SQL Server 2008 121 5.1.2 SQL Server Management Studio 122 5.1.3 Tạo cơ sở dữ liệu (database) 123 5.1.3 Truy vấn dữ liệu cơ bản 128 5.2 Kết nối CS L 131 5.2.1 Giới thiệu về A O.NET 131 5.2.2 Kết nối 133 5.3 Các đối tượng hiển thị và xử lý dữ liệu 134 5.3.1 DataSet 134 5.3.2 Xây dựng một lớp CS L dùng chung 137 5.4 Thiết kế báo cáo 142 4 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  5. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Chương 1: Tổng quan 1.1 Tổng quan về Microsoft .Net 1.1.1 Nguồn gốc Microsft .Net .NET Framework là một nền tảng lập trình tập hợp các thư viện lập trình có thể được cài thêm hoặc đã có sẵn trong các hệ điều hành Windows của hãng Microsoft. Nó cung cấp những giải pháp thiết yếu cho những yêu cầu thông thường của các chương trình điện toán như lập trình giao diện người dùng, truy cập dữ liệu, kết nối cơ sở dữ liệu, ứng dụng web, các giải thuật số học và giao tiếp mạng. Ngoài ra, .NET Framework quản lý việc thực thi các chương trình được viết dựa trên .NET Framework do đó người dùng cần phải cài .NET Framework để có thể chạy các chương trình được viết trên nền .NET. Các phiên bản của .net .NET framework 1.0 – 2002 Ngày 12/2/2002 đánh dấu bước quan trọng đầu tiên trong “cuộc đời” của .NET Framework, khi phiên bản 1.0 cùng với Visual Studio.NET 2002 được chính thức ra mắt. Chính .NET Framework 1.0 là điểm nhấn đáng chú ý nhất và làm cho Visual Studio. NET 2002 khác biệt hẳn với Visual Studio 6.0 đã phát hành năm 1998. Lần đầu tiên, Microsoft giới thiệu về “lập trình hợp nhất”, với việc lấy .NET Framework làm nền tảng. .NET framework 1.1 – 2003 Một năm sau ngày .NET Framework 1.0 ra đời, ngày 24/4/2003, Microsoft đã có ngay bản cập nhật 1.1 ra mắt cùng với Visual Studio.NET 2003. Không có nhiều nâng cấp đáng chú ý trong lần ra mắt này, đáng kể nhất là sự ra đời của .NET Compact Framework, phiên bản thu gọn của .NET Framework cho các thiết bị di động. Điều đáng tiếc là mặc dù có nền tảng rất tốt, cùng với sự hỗ trợ mạnh mẽ từ Microsoft, cho đến nay, .NET Compact Framework vẫn chưa phát triển như “lẽ ra nó phải thế”. Hiện nay số thiết bị di động chạy Windows Mobile/Windows Phone khá khiêm tốn so với các hệ điều hành (HĐH) còn lại. .NET Framework 1.1 cũng mở ra một “truyền thống” là kể từ đây, các HĐH Windows đều được cài đặt sẵn phiên bản .NET Framework mới nhất. Windows Server 2003 tiên phong với phiên bản 1.1, sau đó là Windows Vista với .NET 3.0, và gần đây nhất là Windows 7/Server 2008 với .NET 3.5 SP1. .NET framework 2.0 – 2005 Microsoft mất đến hơn 2 năm để phát triển .NET Framework 2.0 và Visual Studio 2005, và thời gian bỏ ra là thật sự đáng giá. Tháng 11/2005, hai sản phẩm này ra mắt với hàng loạt tính năng mới, trong đó đáng kể nhất là việc hỗ trợ hoàn toàn cho tính toán 64-bit, .NET Micro Framework, bổ sung và nâng cấp nhiều control của 5 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  6. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện ASP.NET và đặc biệt là hỗ trợ Generics. .NET 2.0 hoàn toàn khác biệt so với các phiên bản trước. Generic cho phép chúng ta định kiểu an toàn (type safety). Chúng cho phép ta tạo ra một cấu trúc dữ liệu mà không cần phải xác định đó là kiểu dữ liệu gì. Tuy nhiên khi cấu trúc dữ liệu này được sử dụng, trình biên dịch phải đảm bảo rằng kiểu dữ liệu được sử dụng với nó là kiểu an toàn. Generic cũng tương đương vơi Template trong C++ tuy nhiên việc sử dụng Generic trong .NET dễ dàng hơn nhiều so với Template. Phiên bản 1.0 và 1.1 của .NET Framework không hỗ trợ generics. Thay vào đó, lập trình viên sử dụng lớp Object với các tham số và thành viên sẽ phải chuyển đổi tới các lớp khác dựa trên lớp Object. Generics mang đến hai tính năng cải tiến đáng kể đối với việc sử dụng lớp Object: Giảm bớt lỗi vận hành (Reduced run-time errors), Hiệu suất được cải thiện (Improved performance). .NET framework 3.5 – 2008 Nếu như 3 phiên bản trước đó, .NET Framwork đều gắn liền với một phiên bản Visual Studio nào đó, thì.NET Framework 3.5 đã “phá” truyền thống này khi ra mắt cùng với hệ điều hành Windows Vista vào cuối năm 2006. Ba “điểm nhấn” trong lần nâng cấp này là thành phần được kỳ vọng thay thế Winform – Windows Presentation Foundation – WPF, Windows Communitcation Foundation – WCF, Windows Workflow Foundation – WF, và Windows Card Space. .NET Framework 3.5 không phải là một phiên bản mới hoàn toàn, thực tế là một bản nâng cấp của .NET 2.0, hay đúng hơn là một bản nâng cấp cho thư viện của .NET 2.0. Chính vì không có Visual Studio “đi kèm”, mà .NET 3.5 đành phải “ký gửi” vào Visual Studio 2005 với một bộ công cụ mở rộng. Người dùng phải đợi đến tháng 11 năm 2007 mới được sử dụng một phiên bản Visual Studio hỗ trợ đầy đủ và toàn diện cho .NET 3.5, và hơn thế nữa. LINQ [LINQ: Language Integrated Query - đây là thư viện mở rộng cho các ngôn ngữ lập trình C# và Visual Basic.NET (có thể mở rộng cho các ngôn ngữ khác) cung cấp khả năng truy vấn trực tiếp dữ liệu đối tượng, CSDL và XML] là phần nổi bật và đáng chú ý nhất trong .NET 3.5. .NET framework 4.0 – 2010 Ngày 12/4/2010 Microsoft lại nâng cấp .NET Framework và Visual Studio. Đây là phiên bản đầu tiên sau .NET 2.0 kể từ 2005, có một CLR hoàn toàn mới: CLR 4.0. Cũng cần nhắc lại là cả .NET 3.0 và 3.5 đều sử dụng CLR 2.0, và không có CLR 3.0. Việc Microsoft chuyển thẳng lên 4.0 không chỉ để “đồng bộ” phiên bản, mà còn nhằm khẳng định đây là một bước tiến lớn. Các tính năng mới và cải tiến trong .NET Framework 4 là: 6 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  7. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện • Application Compatibility and eployment (Khả năng tương thích ứng dụng và triển khai) • Core New Features and Improvements (Các tính năng mới và cải tiến của phần nhân) • Managed Extensibility Framework (Quản lý mở rộng Framework) • Parallel Computing (Điện toán song song) • Networking • Web • Client • ata • Windows Communication Foundation (WCF) • Windows Workflow Foundation (WF) 1.1.2 Microsoft .Net .NET Framework được thiết kế đầy đủ để đáp ứng theo quan điểm sau: - Để cung cấp một môi trường lập trình hướng đối tượng vững chắc, trong đó mã nguồn đối tượng được lưu trữ và thực thi một cách cục bộ. Thực thi cục bộ nhưng được phân tán trên Internet, hoặc thực thi từ xa. - Để cung cấp một môi trường thực thi mã nguồn mà tối thiểu được việc đóng gói phần mềm và sự tranh chấp về phiên bản. - Để cung cấp một môi trường thực thi mã nguồn mà đảm bảo việc thực thi an toàn mã nguồn, bao gồm cả việc mã nguồn được tạo bởi hãng thứ ba hay bất cứ - Để làm cho những người phát triển có kinh nghiệm vững chắc có thể nắm vững nhiều kiểu ứng dụng khác nhau, từ những ứng dụng trên nền Windows đến những ứng dụng dựa trên web. - Để xây dựng tất cả các thông tin dựa trên tiêu chuẩn công nghiệp để đảm bảo rằng mã nguồn trên .NET có thể tích hợp với bất cứ mã nguồn khác. 7 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  8. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Các thành phần trong .NET Framework. Common Language Runtime (CLR) CLR thực hiện quản lý bộ nhớ, quản lý thực thi tiểu trình, thực thi mã nguồn, xác nhận mã nguồn an toàn, biên bịch và các dịch vụ hệ thống khác. Những đặc tính trên là nền tảng cơ bản cho những mã nguồn được quản lý chạy trên CLR. Do chú trọng đến bảo mật, những thành phần được quản lý được cấp những mức độ quyền hạn khác nhau, phụ thuộc vào nhiều yếu tố nguyên thủy của chúng như: liên quan đến Internet, hệ thống mạng trong nhà máy, hay một máy tính cục bộ. Điều này có nghĩa rằng, một thành phần được quản lý có thể có hay không có quyền thực hiện một thao tác truy cập tập tin, thao tác truy cập registry, hay các chức năng nhạy cảm khác. CLR thúc đẩy mã nguồn thực hiện việc truy cập bảo mật. Ví dụ, người sử dụng giới hạn rằng việc thực thi nhúng vào trong một trang web có thể chạy được hoạt hình trên màn hình hay hát một bản nhạc, nhưng không thể truy cập được dữ liệu riêng tư, tập tin hệ thống, hay truy cập mạng. o đó, đặc tính bảo mật của CLR cho phép những phần mềm đóng gói trên Inernet có nhiều đặc tính mà không ảnh hưởng đến việc bảo mật hệ thống. CLR còn thúc đẩy cho mã nguồn được thực thi mạnh mẽ hơn bằng việc thực thi mã nguồn chính xác và sự xác nhận mã nguồn. Nền tảng của việc thực hiện này là Common Type System (CTS). CTS đảm bảo rằng những mã nguồn được quản lý thì được tự mô tả (self - describing). Sự khác nhau giữa Microsoft và các trình biên dịch ngôn ngữ của hãng thứ ba là việc tạo ra các mã nguồn được quản lý có thể thích hợp với CTS. Điều này thì mã nguồn được quản lý có thể sử dụng những kiểu được quản lý 8 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  9. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện khác và những thể hiện, trong khi thúc đẩy nghiêm ngặt việc sử dụng kiểu dữ liệu chính xác và an toàn. Thêm vào đó, môi trường được quản lý của runtime sẽ thực hiện việc tự động xử lý layout của đối tượng và quản lý những tham chiếu đến đối tượng, giải phóng chúng khi chúng không còn được sử dụng nữa. Việc quản lý bộ nhớ tự động này còn giải quyết hai lỗi chung của ứng dụng: thiếu bộ nhớ và tham chiếu bộ nhớ không hợp lệ. Trong khi runtime được thiết kế cho những phần mềm của tương lai, nó cũng hỗ trợ cho phân mềm ngày nay và trước đây. Khả năng hoạt động qua lại giữa mã nguồn được quản lý và mã nguồn không được quản lý cho phép người phát triển tiếp tục sử dụng những thành phần cần thiết của COM và DLL. Rutime được thiết kế để cải tiến hiệu suất thực hiện. Mặc dù CLR cung cấp nhiều các tiêu chuẩn dịch vụ runtime, nhưng mã nguồn được quản lý không bao giờ được dịch. Có một đặc tính gọi là Just-in-Time (JIT) biên dịch tất cả những mã nguồn được quản lý vào trong ngôn ngữ máy của hệ thống vào lúc mà nó được thực thi. Khi đó, trình quản lý bộ nhớ xóa bỏ những phân mảnh bộ nhớ nếu có thể được và gia tăng tham chiếu bộ nhớ cục bộ, và kết quả gia tăng hiệu quả thực thi. Thư viện lớp .NET Framework Thư viện lớp .NET Framework là một tập hợp những kiểu dữ liệu được dùng lại và được kết hợp chặt chẽ với Common Language Runtime. Thư viện lớp là hướng đối tượng cung cấp những kiểu dữ liệu mà mã nguồn được quản lý của chúng ta có thể dẫn xuất. Điều này không chỉ làm cho những kiểu dữ liệu của .NET Framework dễ sử dụng mà còn làm giảm thời gian liên quan đến việc học đặc tính mới của .NET Framework. Thêm vào đó, các thành phần của các hãng thứ ba có thể tích hợp với những lớp trong.NET Framework. Cũng như mong đợi của người phát triển với thư viện lớp hướng đối tượng, kiểu dữ liệu .NET Framework cho phép người phát triển thiết lập nhiều mức độ thông dụng của việc lập trình, bao gồm các nhiệm vụ như: quản lý chuỗi, thu thập hay chọn lọc dữ liệu, kết nối với cơ cở dữ liệu, và truy cập tập tin. Ngoài những nhiệm vụ thông dụng trên. Thư viện lớp còn đưa vào những kiểu dữ liệu để hỗ trợ cho những kịch bản phát triển chuyên biệt khác. Ví dụ người phát triển có thể sử dụng .NET Framework để phát triển những kiểu ứng dụng và dịch vụ như sau: - Ứng dụng Console - Ứng dụng giao diện GUI trên Windows (WindowsForms) - Ứng dụng ASP.NET - Dịch vụ XMLWeb - Dịch vụ Windows 9 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  10. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Trong đó những lớp Windows Forms cung cấp một tập hợp lớn các kiểu dữ liệu nhằm làm đơn giản việc phát triển các ứng dụng GUI chạy trên Windows. Còn nếu như viết các ứng dụng ASP.NET thì có thể sử dụng các lớp WebForms trong thư viện .NET Framework. 1.2 Ngôn ngữ C# C# là một trong rất nhiều ngôn ngữ lập trình được hỗ trợ bởi .NET Framework (như C++, Java,VB ). Ngôn ngữ này được xây dựng và kiến trúc bởi Anders Hejlsberg, người đã viết nên trình biên dịch Pascal và có nhiều đóng góp cho elphi cũng như Java. Chính vì vậy dù mang họ nhà C nhưng C# là một ngôn ngữ hướng đối tượng hiện đại và dễ học, chịu ảnh hưởng và học hỏi nhiều tính ưu việt từ Java, C++ và các ngôn ngữ khác. Nếu bạn đã làm quen với Java thì không thể không biết đến máy ảo Java (JVM) nổi tiếng, nhưng đừng nghĩ .Net Framework là một máy ảo bởi thực tế bộ khung này không cài đặt các kỹ thuật máy ảo (ứng dụng viết bằng java sẽ chạy trên JVM). Ứng dụng trên nền .NET thực sự được biên dich và chạy ở mức mã máy, tương tự những ứng dụng quen thuộc viết bằng C, hay VB. Ngôn ngữ C# khá đơn giản, chỉ khoảng 80 từ khóa và hơn mười mấy kiểu dữ liệu được xây dựng sẵn. Tuy nhiên, ngôn ngữ C# lại có ý nghĩa cao khi nó thực thi những khái niệm lập trình hiện đại. C# bao gồm tất cả những hỗ trợ cho cấu trúc, thành phần component, lập trình hướng đối tượng. Những tính chất đó hiện diện trong một ngôn ngữ lập trình hiện đại. Và ngôn ngữ C# hội đủ những điều kiện như vậy, hơn nữa nó được xây dựng trên nền tảng của hai ngôn ngữ mạnh nhất là C++ và Java. 1.2.1 Tại sao chọn ngôn ngữ C# 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. Microsoft bắt đầu với công việc trong C và C++ 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 tóm tắt như sau: - C# là ngôn ngữ đơn giản - C# là ngôn ngữ hiện đại - 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# sẽ trở nên phổ biến C# là ngôn ngữ đơn giản 10 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  11. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện C# loại bỏ một vài sự phức tạp và rối rắm 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++. Ngôn ngữ C# đơn giản vì nó dựa trên nền tảng C và C++. Nếu chúng ta thân thiện với C và C++ hoậc thậm chí là Java, chúng ta 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àyvà 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ể chúng ta 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 chúng ta sẽ dần dần được tìm hiểu những đặc tính đó. 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. Phần hướng đối tượng của C# sẽ được trình bày chi tiết trong một chương riêng ở phần sau. 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úng ta chỉ bị giới hạn ở chính bởi bản thân hay là trí tưởng tượng của chúng ta. 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 ứng dụng xử lý văn bản, ứng dụng đồ họa, bản 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. Phần lớn các từ khóa được sử dụng để mô tả thông tin. Chúng ta 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#, chúng ta có thể tìm thấy rằng ngôn ngữ này có thể được sử dụng để làm bất cứ nhiệm vụ nào. Bảng sau liệt kê các từ khóa của ngôn ngữ C#. 11 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  12. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Bảng 1.2: Từ khóa của ngôn ngữ C#. 1.2.2 Ngôn ngữ C# với ngôn ngữ khác Chúng ta đã từng nghe đến những ngôn ngữ khác như Visual Basic, C++ và Java. Có lẽ chúng ta cũng tự hỏi sự khác nhau giữa ngôn ngữ C# và nhưng ngôn ngữ đó. Và cũng tự hỏi tại sao lại chọn ngôn ngữ này để học mà không chọn một trong những ngôn ngữ kia. Có rất nhiều lý do và chúng ta hãy xem một số sự so sánh giữa ngôn ngữ C# với những ngôn ngữ khác giúp chúng ta phần nào trả lời được những thắc mắc. Microsoft nói rằng C# mang đến sức mạnh của ngôn ngữ C++ với sự dễ dàng của ngôn ngữ Visual Basic. Có thể nó không dễ như Visual Basic, nhưng với phiên bản Visual Basic.NET (Version 7) thì ngang nhau. Bởi vì chúng được viết lại từ một nền tảng. Chúng ta có thể viết nhiều chương trình với ít mã nguồn hơn nếu dùng C#. Mặc dù C# loại bỏ một vài các đặc tính của C++, nhưng bù lại nó tránh được những lỗi mà thường gặp trong ngôn ngữ C++. Điều này có thể tiết kiệm được hàng giờ hay thậm chí hàng ngày trong việc hoàn tất một chương trình. Một điều quan trọng khác với C++ là mã nguồn C# không đòi hỏi phải có tập tin header. Tất cả mã nguồn được viết trong khai báo một lớp. Như đã nói ở bên trên. .NET runtime trong C# thực hiện việc thu gom bộ nhớ tự động. Do điều này nên việc sử dụng con trỏ trong C# ít quan trọng hơn trong C++. 12 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  13. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Những con trỏ cũng có thể được sử dụng trong C#, khi đó những đoạn mã nguồn này sẽ được đánh dấu là không an toàn (unsafecode). Điểm giống nhau C# và Java là cả hai cùng biên dịch ra mã trung gian: C# biên dịch ra MSIL còn Java biên dịch ra bytecode. Sau đó chúng được thực hiện bằng cách thông dịch hoặc biên dịch just-in-time trong từng máy ảo tương ứng. Tuy nhiên, trong ngôn ngữ C# nhiều hỗ trợ được đưa ra để biên dịch mã ngôn ngữ trung gian sang mã máy. C# chứa nhiều kiểu dữ liệu cơ bản hơn Java và cũng cho phép nhiều sự mở rộng với kiểu dữ liệu giá trị. Ví dụ, ngôn ngữ C# hỗ trợ kiểu liệt kê (enumerator), kiểu này được giới hạn đến một tập hằng được định nghĩa trước, và kiểu dữ liệu cấu trúc đây là kiểu dữ liệu giá trị do người dùng định nghĩa. Chúng ta sẽ được tìm hiểu kỹ hơn về kiểu dữ liệu tham chiếu và kiểu dữ liệu giá trị sẽ được trình bày trong phần sau. Tương tự như Java, C# cũng từ bỏ tính đa kế thừa trong một lớp, tuy nhiên mô hình kế thừa đơn này được mở rộng bởi tính đa kế thừa nhiều giao diện. 1.3 Làm quen với visual studio 2010 1.3.1 Giới thiệu Visual Studio.NET 2010 Visual Studio .NET là môi trường tích hợp phát triển phần mềm (Integrated Development Environment (IDE)) của Microsoft, là công cụ cho phép bạn viết mã, gỡ rối và biên dịch chương trình trong nhiều ngôn ngữ lập trình .NET khác nhau như C#, Vb.Net, C++.Net 13 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  14. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện 1.3.2 Khởi động Visual C# 2010 và giao diện Để khởi động chương trình Visual Studio.Net 2010 click vào biểu tượng (shortcut) của VS 2010 trên màng hình desktop hoặc trong menu Start của window để khởi chạy chương trình. Khi chương trình chạy lên ta sẽ có giao diện như sau: 1 - Đây là chức năng cho phép ta làm việc theo nhóm khi giữa các nhóm người lập trình xây dựng cùng một project 2 - Thực hiện việc tạo một project mới (Bạn cũng có thể vào menu file –> new project cũng được) 3 - Mở một project mà bạn đã làm trước đó. 4 - Danh sách các project mà bạn đã mở gần đây nhất (mặc định của nó là 5 project mở gần nhất). 5 - Nơi cung cấp các đường link hướng dẫn, quảng cáo và giới thiệu sử dụng nó cho việc lập trình. 6 - Đây là các ockBar động của nó: - Server Explorer: dùng để kế nối với các cơ sở dữ liệu - ToolBox: Chứa các control cho bạn thiết kế - Document Outline: Thể hiện sơ đồ cấu trúc của các control được bạn thiết kế trên form 7 - Cũng là một DockBar - Solution Explorer: Hiển thị sơ đồ cấu trúc của project. Nó khác với Ouline Document ở chỗ nó là sơ đồ tổng thể của project, còn Ourline ocument là sơ đồ chi tiết thiết kế các control trên một form và nó sẽ tùy biến theo các form mà bạn chọn. 14 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  15. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện - Team Explorer: Sơ đồ của các nhóm làm việc chung trong một project - Class View: Thể hiện các class, namespace của các hàm mà bạn sẽ sử dụng cho viết code có trong Visual Studio (VS) 8 - Cũng là một DockBar - Output: Các giá trị sẽ thể hiện cho người lập trình thấy khi chạy chương trình - Error List: Danh sách các lỗi xảy ra khi thực hiện buil chương trình. 1.3.3 Viết chương trình đầu tiên - Bước 1. Mở VS2010 tạo project mới 15 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  16. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện - Bước 2. Viết code - Bước 3. Chạy chương trình (nhấn F5) 16 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  17. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Chương 2: Ngôn ngữ lập trình C# 2.1 Biến hằng và các kiểu dữ liệu 2.1.1 Biến Một biến là một vùng lưu trữ một kiểu dữ liệu. Biến có thể được gán giá trị và cũng có thể thay đổi giá trị khi thực hiện các lệnh trong chương trình. Để tạo một biến chúng ta phải khai báo kiểu của biến và gán cho biến một tên duy nhất. 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. Cú pháp: [= giá trị khởi tạo]; Ví dụ. Khai báo biến static void Main() { int bien1; //Khai báo biến kiểu nguyên tên là bien1, mặc định khi khởi tạo bien1=0 int bien2= 9;//Khai báo biến kiểu nguyên có tên là bien2 với giá trị khởi tạo là 9 } *Lưu ý: Quy tắc đặt tên biến - Tên biến chỉ có thể bao gồm chữ số, chữ cái và “_” - Tên biến không được bắt đầu bằng số - Tên trong C# là phân biệt chữ hoa chữ thường - Theo quy ước đặt tên của Microsoft thì đề nghị sử dụng cú pháp lạc đà (camel notation) như sau: tên biến bắt đầu bằng ký tự thường (cú pháp Pascal), tên hàm và các định danh có ký tự đầu tiên viết hoa. 2.1.2 Hằng Hằng cũng là một biến nhưng giá trị của hằng không thay đổi. Biến là công cụ rất mạnh, tuy nhiên khi làm việc với một giá trị được định nghĩa là không thay đổi, ta phải đảm bảo giá trị của nó không được thay đổi trong suốt chương trình. Ví dụ, khi lập một chương trình thí nghiệm hóa học liên quan đến nhiệt độ sôi, hay nhiệt độ đông của nước, chương trình cần khai báo hai biến là DoSoi và DoDong, nhưng không cho phép giá trị của hai biến này bị thay đổi hay bị gán.Để ngăn ngừa việc gán giá trị khác, ta phải sử dụng biến kiểu hằng. Cú pháp: = ; Ví dụ: const int DoSoi=100; //Hằng DoSoi này sẽ có giá trị là 100 trong suốt chương trình và không thể thay đổi được 17 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  18. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện 2.1.3 Các kiểu dữ liệu 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. Kiểu dữ liệ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 sự xác nhận 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. Việc chọn một kiểu dữ liệu để sử dụng dựa vào độ lớn, kiểu của giá trị muốn sử dụng. Một số kiểu dữ liệu xây dựng sẵn trong C# Kiểu C# Kích thước Kiểu .Net Mô tả (byte) byte 1 Byte Số nguyên dương không dấu từ 0-255 char 2 Char Ký tự Unicode int 4 Int32 Số nguyên có dấu –2.147.483.647 và 2.147.483.647 float 4 Float Kiểu dấu chấm động, giá trị xấp xỉ từ 3,4E-38 đến 3,4E+38, với 7 chữ số có nghĩa double 8 Double Kiểu dấu chấm động có độ chính xác gấp đôi, giá trị xấp xỉ từ 1,7E-308 đến 1,7E+308, với 15,16 chữsố có nghĩa. bool 1 Bool Giá trị logic true/ false 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 Kiểu chuỗi ký tự Kiểu dữ liệu chuỗi khá thân thiện với người lập trình trong bất cứ ngôn ngữ lập trình nào, kiểu dữ liệu chuỗi lưu giữ một mảng những ký tự. Để khai báo một chuỗi 18 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  19. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện chúng ta sử dụng từ khoá string tương tự như cách tạo một thể hiện của bất cứ đối tượng nào: string chuoi; Một hằng chuỗi được tạo bằng cách đặt các chuỗi trong dấu nháy đôi: “Xin chao” Đây là cách chung để khởi tạo một chuỗi ký tự với giá trị hằng: string chuoi = “Xinchao” 2.1.4 Chuyển kiểu dữ liệu 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 được thực hiện một cách tự động, trình biên dịch sẽ thực hiện công việc này. Còn chuyển đổi tường minh diễn ra khi chúng ta gán ép một giá trị cho kiểu dữ liệu khác. Việc chuyển đổi giá trị ngầm định được thực hiện một cách tự động và đảm bảo không mất thông tin. Ví dụ, chúng ta 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 chúng ta thực hiện chuyển đổi ngược lại, chắc chắn chúng ta sẽ bị mất thông tin. 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ên dị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 !!! Để không bị lỗi chúng ta phải dùng lệnh gán tường minh, đoạn mã trên được viết lại như sau: 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 2.2 Biểu thức, toán tử, khoảng trắng Biểu thức Những câu lệnh mà thực hiện việc đánh giá một giá trị gọi là biểu thức. Một phép gán một giá trị cho một biến cũng là một biểu thức: var1 = 24; 19 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  20. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Trong câu lệnh trên phép đánh giá hay định lượng chính là phép gán có giá trị là 24 cho biến var1. Lưu ý là toán tử gán (‘=’) không phải là toán tử so sánh. Do vậy khi sử dụng toán tử này thì biến bên trái sẽ nhận giá trị của phần bên phải. Các toán tử của ngôn ngữ C# như phép so sánh hay phép gán sẽ được trình bày chi tiết trong mục toán tử. Do var1 = 24 là một biểu thức được định giá trị là 24 nên biểu thức này có thể được xem như phần bên phải của một biểu thức gán khác: var2 = var1 = 24; Lệnh này sẽ được thực hiện từ bên phải sang khi đó biến var1 sẽ nhận được giá trị là 24 và tiếp sau đó thì var2 cũng được nhận giá trị là 24. Do vậy cả hai biến đều cùng nhận một giá trị là 24. Có thể dùng lệnh trên để khởi tạo nhiều biến có cùng một giá trị như: a = b =c = d = 24; Khoảng trắng C# sẽ bỏ qua tất cả các khoảng trắng vô nghĩa, do vậy chúng ta có thể viết như sau: var1 = 24; hay var1 = 24 ; và trình biên dịch C# sẽ xem hai câu lệnh trên là hoàn toàn giốngnhau. Tuy nhiên lưu ý là khoảng trắng trong một chuỗi sẽ không được bỏ qua. Nếu chúng ta viết: System.WriteLine(“Xin chao!”); mỗi khoảng trắng ở giữa hai chữ “Xin” và “chao” đều được đối xử bình thường như các ký tự khác trong chuỗi. Câu lệnh (statement) Trong C# một chỉ dẫn lập trình đầy đủ được gọi là câu lệnh. Chương trình bao gồm nhiều câu lệnh tuần tự với nhau. Mỗi câu lệnh phải kết thúc với một dấu chấm phẩy, ví dụ như: int x; // một câu lệnh x = 32; // câu lệnh khác int y =x; // đây cũng là một câu lệnh Chúng ta có thể viết lời chú thích bằng việc sử dụng // (chú thích trên một dòng) hoặc /* */ (chú thích trên nhiều dòng). Toán tử 20 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  21. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Toán tử được kí hiệu bằng một biểu tượng dùng để thực hiện một hành động. Các kiểu dữ liệu cơ bản của C# như kiểu nguyên hỗ trợ rất nhiều các toán tử như toán tử gán, toán tử toán học, logic - Toán tử gán Toán tử gán hay phép gán làm cho toán hạng bên trái thay đổi giá trị bằng với giá trị của toán hạng bên phải. Toán tử gán “=” là toán tử hai ngôi. Đây là toán tử đơn giản nhất thông dụng nhất và cũng dễ sử dụng nhất. - Toán tử toán học + Các phép toán số học cơ bản (+,-,*,/) : Các phép toán này không thể thiếu trong bất cứ ngôn ngữ lập trình nào, C# cũng không ngoại lệ, các phép toán số học đơn giản nhưng rất cần thiết bao gồm: phép cộng (+), phép trừ(-), phép nhân (*), phép chia (/) nguyên và không nguyên. Khi chia hai số nguyên, thì C# sẽ bỏ phần phân số, hay bỏ phần dư, tức là nếu ta chia 8/3 thì sẽ được kết quả là 2 và sẽ bỏ phần dư là 2, do vậy để lấy được phần dư này thì C# cung cấp thêm toán tử lấy dư. Tuy nhiên, khi chia cho số thực có kiểu như float, double, hay decimal thì kết quả chia được trả về là một số thực. + Phép toán chia lấy dư: Để tìm phần dư của phép chia nguyên, chúng ta sử dụng toán tử chia lấy dư (%). Ví dụ, câu lệnh sau 8%3 thì kết quả trả về là 2 (đây là phần dư còn lại của phép chia nguyên). - Toán tử tăng giảm Toán tử Ý nghĩa Ví dụ ++ Tăng biến lên 1 đơn vị x=3; x++; Kết quả x=4 Giảm biến đi 1 đơn vị x=5; x ;Kết quả x=4 += Cộng thêm giá trị toán hạng bên phải x =3; x+=5; vào giá trị toán hạng bên trái Kết quả x=x+5=8 -= Toán hạng bên trái được trừ bớt đi một x=10; x-=6; lượng bằng giá trị của toán hạng bên Kết quả x=x-6=4 phải *= Toán hạng bên trái được nhân với một x=2; x*=9; lượng bằng giá trị của toán hạng bên Kết quả: x=x*9=18 phải. /= Toán hạng bên trái được chia với một x= 10; x/=5; lượng bằng giá trị của toán hạng bên Kết quả: x=x/5=2 phải %= Toán hạng bên trái được chia lấy dư với x= 10; x%=3; một lượng bằng giá trị của toán hạng Kết quả: x=x%3=1 21 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  22. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện bên phải. - Toán tử quan hệ Những toán tử quan hệ được dùng để so sánh giữa hai giá trị, và sau đó trả về kết quả là một giá trị logic kiểu bool (true hay false). Ví dụ toán tử so sánh lớn hơn (>) trả về giá trị là true nếu giá trị bên trái của toán tử lớn hơn giá trị bên phải của toán tử. Do vậy 5 > 2 trả về một giá trị là true, trong khi 2 >5 trả về giá trị false. Giả sử ta có value1 = 100 và value2 = 50 Tến toán tử Kí hiệu 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 ? : Toán tử này sẽ xác định giá trị của một biểu thức điều kiện, và biểu thức điều kiện này phải trả về một giá trị kiểu bool. 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”. 22 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  23. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Ví dụ: int a, b,c; a=10; b=5; c=(a>b)?15:20;// Kết quả c sẽ có giá trị bằng 15 2.3 Nhập / xuất dữ liệu Nhập dữ liệu - Các nhập một chuỗi string chuoi = Console.ReadLine();//Nhập xong xuống dòng hoặc string chuoi = Console.Read(); Ví dụ: Console.WriteLine("Ban hay thu nhap mot chuoi trong C#:"); //Nhập vào một chuỗi trong C# //Ví dụ: chúng ta nhập chuỗi "xin chao cac ban" string chuoi = Console.ReadLine(); Console.Write("Chuoi ban vua nhap: "); //Xuất chuỗi vừa nhập ra màn hình Console.WriteLine(chuoi); - Cách nhập một số Kieudulieu bienso = kieudulieu.Parse(Console.ReadLine()); Trong đó: Kieudulieu: có thể là kiểu int, float, double Bienso: đặt tên biến có kiểu dữ liệu tương ứng Ví dụ: Console.WriteLine("Ban hay thu nhap mot so nguyen trong C#:"); //Nhập vào một so trong C# //Vi du chung ta nhâp số là kiểu số nguyên int so = int.Parse(Console.ReadLine()); Console.Write("So vua nhap la: "); //Xuất chuôi vừa nhập ra màn hình Console.WriteLine(so); Xuất dữ liệu Console.WriteLine("//thông tin cần xuất "); hoặc Console.WriteLine("//thông tin cần xuất{0} {1} ",bien1,bien2); 23 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  24. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện bien1 và bien 2 sẽ lần lượt xuất hiện tại vị trí {0} và {1} theo thứ tự, số lượng biến in ra là tùy ý. Nội dung cần xuất có thể được xử lý tính toán từ các biểu thức trước khi chính thức đưa ra màn hình. Thông thường chúng ta sẽ cần truyền tham số, thực hiện việc nối chuỗi, ép kiểu, . để đưa được kết quả mong muốn đến người dùng. 2.4 Các cấu trúc điều khiển 2.4.1 Câu lệnh lựa chọn if - Câu lệnh if else Cấu trúc if trong C# được mô tả như sau: if (biểu thức điều kiện) { // câu lệnh thực thi nếu biểu thức điều kiện đúng } [else { // câu lệnh thực thi nếu biểu thức điều kiện sai }] Ví dụ: if (20 % 4 > 0) { Console.WriteLine("Số 20 không chia hết cho 4"); } else { Console.WriteLine("Số 20 chia hết cho số 4"); } - Câu lệnh if lồng nhau Các lệnh điều kiện if có thể lồng nhau để phục vụ cho việc xử lý các câu điều kiện phức tạp. if(điều kiện 1) if(điều kiện 2) { }else { }else { } 24 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  25. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Ví dụ if(diemTrungBinh>=6.5) if(diemTrungBinh<8) { Console.WriteLine("Xếp loại khá"); }else { Console.WriteLine("Xếp loại giỏi"); }else { Console.WriteLine("Xếp loại trung bình"); } 2.4.2 Câu lệnh lựa chọn Case Khi có quá nhiều điều kiện để chọn thực hiện thì dùng câu lệnh if sẽ rất rối rắm và dài dòng, các ngôn ngữ lập trình cấp cao đều cung cấp một dạng câu lệnh switch liệt kê các giá trị và chỉ thực hiện các giá trị thích hợp. C# cũng cung cấp câu lệnh nhảy switch có cú pháp sau: // switch case switch (Biến điều kiện) { case giá trị 1: // Câu lệnh thực thi break; case giá trị 2: // Câu lệnh thực thi break; case giá trị 3: // Câu lệnh thực thi break; default: // Câu lệnh thực thi break; } Ví dụ: int x = 20 % 4; 25 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  26. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện switch (x) { case 1: Console.WriteLine("20 chia cho 4 được số dư là 1"); break; case 0: Console.WriteLine("20 chia hết cho 4"); break; case 2: Console.WriteLine("20 chia cho 4 được số dư là 2"); break; default: Console.WriteLine("Không thuộc tất cả các trường hợp trên"); break; } 2.4.3 Cấu trúc lặp for. Vòng lặp for là loại vòng lặp bước trước số lần lặp nó bao gồm ba phần chính: - Khởi tạo biến đếm vòng lặp - Kiểm tra điều kiện biến đếm, nếu đúng thì sẽ thực hiện các lệnh bên trong vòng for - Thay đổi bước lặp. Cú pháp sử dụng vòng lặp for như sau: for ([phần khởi tạo] ; [biểu thức điều kiện]; [bước lặp]) Ví dụ for (int i = 0; i < 30; i++) { if (i %10 ==0) { Console.WriteLine(“{0} ”,i); } else { Console.Write(“{0} ”,i); } } Kết quả: 26 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  27. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện 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 2.4.4 Cấu trúc lặp while. Cú pháp: while (biểu thức điều kiện) { // câu lệnh } Thực thi câu lệnh hoặc một loạt những câu lệnh đến khi điều kiện không được thỏa mãn. Ví dụ: public static void Main() { int n = 1; while (n < 10) { Console.WriteLine("Current value of n is {0}", n); n++; } } Kết quả: Current value of n is 1 Current value of n is 2 Current value of n is 3 Current value of n is 4 Current value of n is 5 Current value of n is 6 Current value of n is 7 Current value of n is 8 Current value of n is 9 2.4.5 Cấu trúc lặp do while Cấu trúc vòng lặp do while do { // câu lệnh 27 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  28. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện } while (biểu thức điều kiện) Thực thi câu lệnh ít nhất một lần đến khi điều kiện không được thỏa mãn. Ví dụ: public static void Main () { int x; int y = 0; do { x = y++; Console.WriteLine(x); } while (y [] ; Ví dụ khai báo một mảng số nguyên: int[] a;//Trong c# không cần chỉ kích thước mảng khi khai báo ban đầu 28 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  29. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Trước khi sử dụng mảng ta cần khởi tạo mảng, tức là tạo ra số phần tử trong mảng và gán giá trị cho các phần tử đó. Ta có cú pháp sau : [Tên mảng] = new [Kiểu dữ liệu] [Số phần tử mảng]; Ví dụ a = new int[100];//Khởi tạo mảng a có 100 phần tử Truy cập tới các phần tử trong mảng Các phần thử trong mảng được truy cập thông qua tên mảng kèm theo chỉ số tương ứng. Chỉ số mảng trong C# bắt đầu từ 0 Ví dụ a[0] = 10;// gán phần tử đầu tiên trong mảng a =10 2.5.2 Câu lệnh foreach Câu lệnh foreach sử dụng để lặp trong một nhóm mỗi phần tử trong mảng hoặc một dãy các tập hợp các phần tử của mảng. Câu lệnh foreach được sử dụng để lặp qua các phần tử thuộc mảng để lấy ra các thông tin mong muốn, nhưng ta cũng không nên lạm dụng để thay thế nội dung của mảng để tránh các trường hợp ta không kiểm soát được những thông tin mong muốn trong mảng. Bạn có thể thoát khỏi vòng lặp bất cứ lúc nào bằng cách sử dụng các câu lệnh Break, hoặc tiếp tục vòng lặp sử dụng continue. hoặc goto, return . Cú pháp foreach( in ) { câu lệnh; } Ví dụ: In tất cả giá trị trong mảng a sử dụng foreach int[] a = new int[10]; foreach(int bien in a) { Console.Writeln(bien); } 2.5.3 Mảng đa chiều Mảng nhiều chiều là mảng có số chiều từ 2 trở lên (Khai báo với số cặp [] nhiều hơn 1). Khai báo - Mảng 2 chiều [][] ; - Mảng 3 chiều [][][] ; 29 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  30. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện 2.6 Xử lý chuỗi Tạo một chuỗi Cách phổ biến nhất để tạo ra một chuỗi là gán cho một chuỗi trích dẫn tức là chuỗi nằm trong dấu ngoặc kép, kiểu chuỗi này cũng được biết như là một chuỗi hằng, khai báo như sau: string newString =“ ay la chuoi hang”; Những chuỗi trích dẫn có thể được thêm các ký tự escape, như là “\n” hay “\t”, ký tự này bắt đầu với dầu chéo ngược (“\”), các ký tự này được dùng để chỉ ra rằng tại vị trí đó xuống dòng hay tab được xuất hiện. Bởi vì dấu gạch chéo ngược này cũng được dùng trong vài cú pháp dòng lệnh, như là địa chỉ URLs hay đường dẫn thư mục, do đó trong chuỗi trích dẫn dấu chéo ngược này phải được đặt trước dấu chéo ngược khác, tức là dùng hai dấu chéo ngược trong trường hợp này. 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 (verbatim), 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 với biểu tượng @. Biểu tượng này bảo với hàm khởi dựng của lớp String rằng chuỗi theo sau là nguyên văn, thậm chí nó chứa nhiều dòng hoặc bao gồm những ký tự escape. Trong chuỗi nguyên văn, ký tự chéo ngược và những ký tự sau nó đơn giản là những ký tự được thêm vào chuỗi. Do vậy,ta có 2 định nghĩa chuỗi sau là tương đương với nhau: string literal1 = “\\\\MyDocs\\CSharp\\ProgrammingC#.cs”; string verbatim1= @”\\MyDocs\CSharp\ProgrammingC#.cs”; Trong chuỗi thứ nhất, là một chuỗi bình thường được sử dụng, do đó dấu ký tự chéo là ký tự escape, nên nó phải được đặt trước một ký tự chéo ngược thứ hai. Trong khai báo thứ hai chuỗi nguyên văn được sử dụng, nên không cần phải thêm ký tự chéo ngược. Một ví dụ thứ hai minh họa việc dùng chuỗi nguyên văn: string literal2 = “ ong mot \n dong hai”; string verbatim2= @” ong mot dong hai”; Nói chung ta ta có thể sử dụng qua lại giữa hai cách định nghĩa trên. Việc lựa chọn phụ thuộc vào sự thuận tiện trong từng trường hợp hay phong cách riêng của mỗi người. 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. Tất cả các kiểu dữ liệu cơ bản phủ quyết phương thức này rất đơn giản là chuyển đổi giá trị (thông thường là giá trị số) đến một chuỗi thể hiện của giá trị. 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 myInt = “9”; 30 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  31. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện string intString = myInt.ToString(); Phương thức myInt.ToString() trả về một đối tượng String và đối tượng này được gán cho intString. Lớp String của .NET cung cấp rất nhiều bộ khởi dựng hỗ trợ rất nhiều kỹ thuật khác nhau để gán những giá trị chuỗi đến kiểu dữ liệu chuỗi. Một vài bộ khởi dựng có thể cho phép chúng ta tạo một chuỗi bằng cách truyền vào một mảng ký tự hoặc một con trỏ ký tự. Truyền một mảng chuỗi như là tham số đến bộ khởi dựng của String là tạo ra một thể hiện CLR-compliant (một thể hiện đúng theo yêu cầu của CLR). Còn việc truyền một con trỏ chuỗi như một tham số của bộ khởi dựng String là việc tạo một thể hiện không an toàn (unsafe). Thao tác trên chuỗi Lớp string cung cấp rất nhiều số lượng 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 sau: Phương thức/ Thuộc Ý nghĩa tính Empty Trường public static thể hiện một chuỗi rỗng. Compare() Phương thức public static để so sánh hai chuỗi. CompareOrdinal() Phương thức public static để so sánh hai chuỗi không quan tâm đến thứ tự. Concat() Phương thức public static để tạo chuỗi mới từ một hay nhiều chuỗi. Copy() Phương thức public static tạo ra một chuỗi mới bằng sao từ chuỗi khác. Equal() Phương thức public static kiểm tra xem hai chuỗi có cùng giá trị hay không. Format() Phương thức public static định dạng một chuỗi dùng ký tự lệnh định dạng xác định. Intern() Phương thức public static trả về tham chiếu đến thể hiện của chuỗi. IsInterned() Phương thức public static trả về tham chiếu của chuỗi Join() Phương thức public static kết nối các chuỗi xác định giữa mỗi thành phần của mảng chuỗi. Chars() Indexer của chuỗi. Length() Chiều dài của chuỗi. Clone() Trả về chuỗi. CompareTo() So sánh haichuỗi. 31 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  32. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện CopyTo() Sao chép một số các ký tự xác định đến một mảng ký tự Unicode. EndsWidth() Chỉ ra vị trí của chuỗi xác định phù hợp với chuỗi đưa ra. Insert() Trả về chuỗi mới đã được chèn một chuỗi xác định. LastIndexOf() Chỉ ra vị trí xuất hiện cuối cùng của một chuỗi xác định trong chuỗi. PadLeft() Canh lề phải những ký tự trong chuỗi, chèn vào bên trái khoảng trắng hay các ký tự xác định. PadRight() Canh lề trái những ký tự trong chuỗi, chèn vào bên phải khoảng trắng hay các ký tự xác định. Remove() Xóa đi một số ký tự xác định. Split() Trả về chuỗi được phân định bởi những ký tự xác định trong chuỗi. StartWidth() Xem chuỗi có bắt đầu bằng một số ký tự xác định hay không. SubString() Lấy 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() Xóa bỏ tất cả sự xuất hiện của tập hợp ký tự xác định từ vị trí đầu tiên đến vị trí cuối cùng trong chuỗi. TrimEnd() Xóa như nhưng ở vị trí cuối. TrimStart() Xóa như Trim nhưng ở vị trí đầu. Ví dụ: // khởi tạo một số chuỗi để thao tác string s1 = “abcd”; string s2 = “ABCD”; string s3 = @“Dai hoc Cong nghe thong tin va Truyen thong”; int result; // So sánh hai chuỗi với nhau có phân biệt chữ thường và chữ hoa result = string.Compare( s1 ,s2); Console.WriteLine(“So sanh hai chuoi S1: {0} và S2: {1} ket qua: {2} \n”,s1 ,s2,result); // 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 result = string. Compare(s1, s2, true); 32 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  33. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Console.WriteLine(“Khong phan biet chu thuong va hoa\n”); Console.WriteLine(“S1: {0} , S2: {1}, ket qua : {2}\n”, s1, s2, result); // 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 Cong ? : {1}\n”, s3, s3.EndsWith(“Cong”)); Console.WriteLine(“S3: {0}\n ket thuc voi chu Thong ? : {1}\n”, s3, s3.EndsWith(“Thong”)); // 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 ta có thể kết hợp như sau 33 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  34. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện string s9 = s3.Insert( s3.IndexOf( “CNTT” ) , “nhan luc ”); Console.WriteLine(“ S9 : {0}\n”, s9); 2.7 Hàm và cách truyền tham số Tham số có kiểu dữ liệu là giá trị thì sẽ được truyền giá trị vào cho phương thức. Điều này có nghĩa rằng khi một đối tượng có kiểu là giá trị được truyền vào cho một phương thức, thì có một bản sao chép đối tượng đó được tạo ra bên trong phương thức. Một khi phương thức được thực hiện xong thì đối tượng sao chép này sẽ được hủy. Tuy nhiên, đây chỉ là trường hợp bình thường, ngôn ngữ C# còn cung cấp khả năng cho phép ta truyền các đối tượng có kiểu giá trị dưới hình thức là tham chiếu. Ngôn ngữ C# đưa ra một bổ sung tham số là ref cho phép truyền các đối tượng giá trị vào trong phương thức theo kiểu tham chiếu. Và tham số bổ sung out trong trường hợp muốn truyền dưới dạng tham chiếu mà không cần phải khởi tạo giá trị ban đầu cho tham số truyền. Ngoài ra ngôn ngữ C# còn hỗ trợ bổ sung params cho phép phương thức chấp nhận nhiều số lượng các tham số. Truyền tham chiếu Những phương thức chỉ có thể trả về duy nhất một giá trị, mặc dù giá trị này có thể là một tập hợp các giá trị. Nếu chúng ta muốn phương thức trả về nhiều hơn một giá trị thì cách thực hiện là tạo các tham số dưới hình thức tham chiếu. Khi đó trong phương thức ta sẽ xử lý và gán các giá trị mới cho các tham số tham chiếu này, kết quả là sau khi phương thức thực hiện xong ta dùng các tham số truyền vào như là các kết quả trả về. Ví dụ sau minh họa việc truyền tham số tham chiếu cho phương thức. using System; public class Time { public void DisplayCurrentTime() { Console.WriteLine(“{0}/{1}/{2}/ {3}:{4}:{5}”, Date, Month, Year, Hour, Minute, Second); } public int GetHour() { return Hour; } public void GetTime(int h, int m, int s) { h = Hour; m = Minute; s = Second; } public Time( System.DateTime dt) { Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; 34 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  35. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Second = dt.Second; } private int Year; private int Month; private int Date; private int Hour; private int Minute; private int Second; } public class Tester { static void Main() { System.DateTime currentTime = System.DateTime.Now; Time t = new Time( currentTime); t.DisplayCurrentTime(); int theHour = 0; int theMinute = 0; int theSecond = 0; t.GetTime( theHour, theMinute, theSecond); System.Console.WriteLine(“Current time: {0}:{1}:{2}”, theHour, theMinute, theSecond); } } Kết quả: 8/6/2002 14:15:20 Current time: 0:0:0 Như ta thấy, kết quả xuất ra ở dòng cuối cùng là ba giá trị 0:0:0, rõ ràng phương thức GetTime() không thực hiện như mong muốn là gán giá trị Hour, Minute, Second cho các tham số truyền vào. Tức là ba tham số này được truyền vào dưới dạng giá trị. Do đó để thực hiện như mục đích của chúng ta là lấy các giá trị của Hour, Minute, Second thì phương thức GetTime() có ba tham số được truyền dưới dạng tham chiếu. Ta thực hiện như sau, đầu tiên, thêm là thêm khai báo ref vào trước các tham số trong phương thức GetTime(): public void GetTime( ref int h, ref int m, ref int s) { h = Hour; m = Minute; s = Second; } Điều thay đổi thứ hai là bổ sung cách gọi hàm GetTime để truyền các tham số dưới dạng tham chiếu như sau: t.GetTime( ref theHour, ref theMinute, ref theSecond); Nếu chúng ta không thực hiện bước thứ hai, tức là không đưa từ khóa ref khi gọi hàm thì trình biên dịch C# sẽ báo một lỗi rằng không thể chuyển tham số từ kiểu int sang kiểu ref int. Cuối cùng khi biên dịch lại chương trình ta được kết quả đúng 35 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  36. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện như yêu cầu. Bằng việc khai báo tham số tham chiếu, trình biên dịch sẽ truyền các tham số dưới dạng các tham chiếu, thay cho việc tạo ra một bản sao chép các tham số này. Khi đó các tham số bên trong GetTime() sẽ tham chiếu đến cùng biến đa được khai báo trong hàm Main(). Như vậy mọi sự thay đổi với các biến này điều có hiệu lực tương tự như là thay đổi trong hàm Main(). Tóm lại cơ chế truyền tham số dạng tham chiếu sẽ thực hiện trên chính đối tượng được đưa vào. Còn cơ chế truyền tham số giá trị thì sẽ tạo ra các bản sao các đối tượng được truyền vào, do đó mọi thay đổi bên trong phương thức không làm ảnh hưởng đến các đối tượng được truyền vào dưới dạng giá trị. Truyền tham chiếu với biến chưa khởi tạo Ngôn ngữ C# bắt buộc phải thực hiện một phép gán cho biến trước khi sử dụng, do đó khi khai báo một biến như kiểu cơ bản thì trước khi có lệnh nào sử dụng các biến này thì phải có lệnh thực hiện việc gán giá trị xác định cho biến. Như trong ví dụ trên, nếu chúng ta không khởi tạo biến theHour, theMinute, và biến theSecond trước khi truyền như tham số vào phương thức GetTime() thì trình biên dịch sẽ báo lỗi. Nếu chúng ta sửa lại đoạn mã của ví dụ trên như sau: int theHour; int theMinute; int theSecond; t.GetTime( ref int theHour, ref int theMinute, ref int theSecond); Việc sử dụng các đoạn lệnh trên không phải hoàn toàn vô lý vì mục đích của chúng ta là nhận các giá trị của đối tượng Time, việc khởi tạo giá trị của các biến đưa vào là không cần thiết. Tuy nhiên khi biên dịch với đoạn mã lệnh như trên sẽ được báo các lỗi sau: Use of unassigned local variable ‘theHour’ Use of unassigned local variable ‘theMinute’ Use of unassigned local variable ‘theSecond’ Để mở rộng cho yêu cầu trong trường hợp này ngôn ngữ C# cung cấp thêm một bổ sung tham chiếu là out. Khi sử dụng tham chiếu out thì yêu cầu bắt buộc phải khởi tạo các tham số tham chiếu được bỏ qua. Như các tham số trong phương thức GetTime(), các tham số này không cung cấp bất cứ thông tin nào cho phương thức mà chỉ đơn giản là cơ chế nhận thông tin và đưa ra bên ngoài. o vậy ta có thể đánh dấu tất cả các tham số tham chiếu này là out, khi đó ta sẽ giảm được công việc phải khởi tạo các biến này trước khi đưa vào phương thức. Lưu ý là bên trong phương thức có các tham số tham chiếu out thì các tham số này phải được gán giá trị trước khi trả về. Ta có một số thay đổi cho phương thức GetTime() như sau: public void GetTime( out int h, out int m, out int s) { h = Hour; Xây Dựng Lớp - Đối Tượng 110 Ngôn Ngữ Lập Tr.nh C# m = Minute; s = Second; } và cách gọi mới phương thức GetTime() trong Main(): 36 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  37. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện t.GetTime( out theHour, out theMinute, out theSecond); Tóm lại ta có các cách khai báo các tham số trong một phương thức như sau: kiểu dữ liệu giá trị được truyền vào phương thức bằng giá trị. Sử dụng tham chiếu ref để truyền kiểu dữ liệu giá trị vào phương thức dưới dạng tham chiếu, cách này cho phép vừa sử dụng và có khả năng thay đổi các tham số bên trong phương thức được gọi. Tham chiếu out được sử dụng chỉ để trả về giá trị từ một phương thức. Ví dụ sau sử dụng ba kiểu tham số trên. Ví dụ: Sử dụng tham số. using System; public class Time { public void DisplayCurrentTime() { Console.WriteLine(“{0}/{1}/{2} {3}:{4}:{5}”, Date, Month, Year, Hour, Minute, Second); } public int GetHour() { return Hour; } public void SetTime(int hr, out int min, ref int sec) { // Nếu số giây truyền vào >30 thì tăng số Minute và Second = 0 if ( sec >=30 ) { Minute++; Second = 0; } Hour = hr; // thiết lập giá trị hr được truyền vào // Trả về giá trị mới cho min và sec min = Minute; sec = Second; } public Time( System.DateTime dt) { Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second; } // biến thành viên private private int Year; private int Month; private int Date; private int Hour; 37 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  38. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện private int Minute; private int Second; } public class Tester { static void Main() { System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime(); int theHour = 3; int theMinute; int theSecond = 20; t.SetTime( theHour, out theMinute, ref theSecond); Console.WriteLine(“The Minute is now: {0} and {1} seconds ”, theMinute, theSecond); theSecond = 45; t.SetTime( theHour, out theMinute, ref theSecond); Console.WriteLine(“The Minute is now: {0} and {1} seconds”, theMinute, theSecond); } } Kết quả: 8/6/2002 15:35:24 The Minute is now: 35 and 24 seconds The Minute is now: 36 and 0 seconds Phương thức SetTime trên đa minh họa việc sử dụng ba kiểu truyền tham số vào một phương thức. Tham số thứ nhất theHour được truyền vào dạng giá trị, mục đích của tham số này là để thiết lập giá trị cho biến thành viên Hour và tham số này không được sử dụng để về bất cứ giá trị nào. Tham số thứ hai là theMinute được truyền vào phương thức chỉ để nhận giá trị trả về của biến thành viên Minute, do đó tham số này được khai báo với từ khóa out. Cuối cùng tham số theSecond được truyền vào với khai báo ref, biến tham số này vừa dùng để thiết lập giá trị trong phương thức. Nếu theSecond lớn hơn 30 thì giá trị của biến thành viên Minute tăng thêm một đơn vị và biến thành viên Second được thiết lập về 0. Sau cùng thì theSecond được gán giá trị của biến thành viên Second và được trả về. Do hai biến theHour và theSecond được sử dụng trong phương thức SetTime nên phải được khởi tạo trước khi truyền vào phương thức. Còn với biến theMinute thì không cần thiết vì nó không được sử dụng trong phương thức mà chỉ nhận giá trị trả về. 2.8 Xử lý ngoại lệ Ngôn ngữ C# cũng giống như bất cứ ngôn ngữ hướng đối tượng khác, cho phép xử lý những lỗi và các điều kiện không bình thường với 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. 38 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  39. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Một điều quan trọng để phân chia giữa bug, lỗi, và ngoại lệ. Một bug là một lỗi lập trình có thể được sửa chữa trước khi mã nguồn được chuyển giao. Những ngoại lệ thì không được bảo vệ và tương phản với những bug. Mặc dù một bug có thể là nguyên nhân sinh ra ngoại lệ, chúng ta cũng không dựa vào những ngoại lệ để xử lý những bug trong chương trình, tốt hơn là chúng ta nên sửa chữa những bug này. Một lỗi có nguyên nhân là do phía hành động của người sử dụng. Ví dụ, người sử dụng nhập vào một số nhưng họ lại nhập vào ký tự chữ cái. Một lần nữa, lỗi có thể làm xuất hiện ngoại lệ, nhưng chúng ta có thể ngăn ngừa điều này bằng cách bắt giữ lỗi với mã hợp lệ. Những lỗi có thể được đoán trước và được ngăn ngừa. Thậm chí nếu chúng ta 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, chúng ta 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. Chúng ta không thể ngăn ngừa các ngoại lệ này, nhưng chúng ta có thể xử lý chúng để chúng không thể làm tổn hại đến chương trình. 2.7.1 Phát sinh và bắt giữ ngoại lệ Trong C#, một ngoại lệ là một đối tượng được tạo ra (hoặc được ném ) khi một trạng thái lỗi ngoại lệ cụ thể xuất hiện. Những đối tượng này chứa đựng những thông tin mà giúp ích cho việc truy ngược lại vấn đề. Mặc dù chúng ta có thể tự tạo ra những lớp ngoại lệ riêng (chúng ta sẽ làm sau này), .NET cũng cung cấp cho chúng ta nhiều lớp ngoại lệ được định nghĩa trước như ArgumentNullException, InValidCastException, và OverflowException, cũng như nhiều lớp khác nữa. Câu lệnh throw Để phát tín hiệu một sự không bình thường trong một lớp của ngôn ngữ C#, chúng ta phát sinh một ngoại lệ. Để làm được điều này, chúng ta sử dụng từ khóa throw. Dòng lệnh sau tạo ra một thể hiện mới của System.Exception và sau đó throw nó: throw new System.Exception(); Khi phát sinh ngoại lệ thì ngay tức khắc sẽ làm ngừng việc thực thi trong khi CLR sẽ tìm kiếm một trình xử lý ngoại lệ. Nếu một trình xử lý ngoại lệ không được tìm thấy trong phương thức hiện thời, thì CLR tiếp tục tìm trong phương thức gọi cho đến khi nào tìm thấy. Nếu CLR trả về lớp Main() mà không tìm thấy bất cứ trình xử lý ngoại lệ nào, thì nó sẽ kết thúc chương trình. Ví dụ: namespace Programming_CSharp { using System; 39 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  40. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện public class Test { public static void Main() { Console.WriteLine("Enter Main "); Test t = new Test(); t.Func1(); Console.WriteLine("Exit Main "); } public void Func1() { Console.WriteLine("Enter Func1 "); Func2(); Console.WriteLine("Exit Func1 "); } public void Func2() { Console.WriteLine("Enter Func2 "); throw new System.Exception(); Console.WriteLine("Exit Func2 "); } } } Kết quả: Enter Main Enter Func1 Enter Func2 Exception occurred: System.Exception: An exception of type System.Exception was throw. at Programming_CSharp.Test.Func2() in exception01.cs:line 26 at Programming_CSharp.Test.Func1() in exception01.cs:line 20 at Programming_CSharp.Test.Main() in exception01.cs:line 12 Ví dụ minh họa đơn giản này viết ra màn hình console thông tin khi nó nhập vào trong một hàm và chuẩn bị đi ra từ một hàm. Hàm Main() tạo thể hiện mới của kiểu Test và sau đó gọi hàm Func1(). Sau khi in thông điệp “Enter Func1”, hàm Func1() này gọi hàm Func2(). Hàm Func2() in ra thông điệp đầu tiên và phát sinh một ngoại lệ kiểu System.Exception. Việc thực thi sẽ ngưng ngay tức khắc, và CLR sẽ tìm 40 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  41. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện kiếm trình xử lý ngoại lệ trong hàm Func2(). Do không tìm thấy ở đây, CLR tiếp tục vào stack lấy hàm đã gọi trước tức là Func1 và tìm kiếm trình xử lý ngoại lệ. Một lần nữa trong Func1 cũng không có đoạn xử lý ngoại lệ. Và CLR trả về hàm Main. Tại hàm Main cũng không có, nên CLR sẽ gọi trình mặc định xử lý ngoại lệ, việc này đơn giản là xuất ra một thông điệp lỗi. Câu lệnh try catch Trong C#, một trình xử lý ngoại lệ hay một đoạn chương trình xử lý các ngoại lệ được gọi là một khối try catch và được tạo ra với từ khóa try catch. Ví dụ: using System; using System.Collections.Generic; using System.Text; namespace Programming_CSharp { public class Test { public static void Main() { Console.WriteLine("hàm Main "); Test t = new Test(); t.Func1(); Console.WriteLine("Kết thúc hàm Main "); Console.ReadLine(); } public void Func1() { Console.WriteLine("Bắt đầu hàm Func1 "); Func2(); Console.WriteLine("Kết thúc hàm Func1 "); } public void Func2() { Console.WriteLine("Bắt đầu hàm Func2 "); try { Console.WriteLine("Bắt đầu Khối try"); throw new System.Exception(); 41 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  42. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Console.WriteLine("Kết thúc khối try"); } catch { Console.WriteLine("Ngoại lệ đã được xử lý"); } Console.WriteLine("Kết thúc hàm Func2 "); } } } Cho đến khi chương trình thực hiện hàm Func2() khi lệnh throw phát sinh ra ngoại lệ, chương trình sẽ bị ngừng thực hiện và CLR sẽ tìm phần xử lý ngoại lệ trong stack, đầu tiên nó sẽ gọi đến hàm Func1() tại đây hàm Func2() được gọi và nó sẽ tìm thấy phần xử lý ngoại lệ trong khối catch , nó sẽ in ra dòng “Ngoại lệ đã được xử lý”. Đó cũng là lý do mà chương trình sẽ không bao giờ in ra dòng “Kết thúc khối try”. Câu lệnh finally Trong một số tình huống chúng ta cần phải thực hiện bất cứ khi nào một ngoại lệ được phát sinh ra, ví dụ như việc đóng một tập tin. Để làm việc này chúng ta có thể đặt câu lệnh trong cả hai khối try và catch. Tuy nhiên có một cách giải quyết tốt hơn, đó là sử dụng câu lệnh Finnally. Các hành động đặt trong khối finnally sẽ luôn được thực hiện mà không cần quan tâm tới việc có hay không một ngoại lệ phát sinh trong chương trình. Ví dụ: using System; namespace Programming_CSharp { public class Test { public static void Main() { Test t = new Test(); t.TestFunc(); Console.ReadLine(); } // chia hai số và xử lý ngoại lệ nếu có public void TestFunc() { 42 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  43. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện try { Console.WriteLine("mở file"); double a = 5; double b = 0; Console.WriteLine("{0} /{1} = {2}", a, b, DoDivide(a,b)); Console.WriteLine("dòng này có thể xuất hiện hoặc không"); } catch (System.DivideByZeroException) { Console.WriteLine("lỗi chia cho 0!"); } catch { Console.WriteLine("không có ngoại lệ"); } finally { Console.WriteLine("Đóng tệp."); } } // thực hiện chia nếu hợp lệ public double DoDivide(double a, double b) { if ( b == 0) { throw new System.DivideByZeroException(); } if ( a == 0) { throw new System.ArithmeticException(); } return a/b; } } } 43 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  44. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Đầu tiên hãy gán a= 5 và b=0 chạy chương trình Bạn sẽ thấy lệnh Console.WriteLine("dòng này có thể xuất hiện hoặc không"); Sẽ không được thực hiện do xuất hiện một ngoại lệ là lỗi chia cho 0 và chương trình sẽ tìm tới phần xử lý ngoại lệ này mà bỏ qua phần lệnh tiếp theo. Sau đó bạn thay đổi giá trị b=12 và chạy chương trình thì lệnh Console.WriteLine("dòng này có thể xuất hiện hoặc không"); được thực hiện. Tuy nhiên ở cả 2 trường hợp bạn đề thấy thực hiện lệnh Console.WriteLine("Đóng tệp."); Đó là vì lệnh này đã được đặt trong khối Finally. Nắm được cách xử lý ngoại lệ qua việc sử dụng các câu lệnh throw, catch và finally sẽ giúp bạn lập trình có hiệu quả hơn. 2.7.2 Những đối tượng ngoại lệ Trong phần này chúng ta sẽ tìm hiểu các đối tượng được xây dựng cho việc xử lý ngoại lệ. Đối tượng System.Exception cung cấp một số các phương thức và thuộc tính hữu dụng. Thuộc tính Message cung cấp thông tin về ngoại lệ, lý do tại sao ngoại lệ được phát sinh. Thuộc tính Message là thuộc tính chỉ đọc, đoạn chương trình phát sinh ngoại lệ có thể thiết lập thuộc tính Message như là một đối mục cho bộ khởi dựng của ngoại lệ. Thuộc tính HelpLink cung cấp một liên kết để trợ giúp cho các tập tin liên quan đến các ngoại lệ. Đây là thuộc tính chỉ đọc. Ví dụ: try { Console.WriteLine(“Open file here”); double a = 12; double b = 0; Console.WriteLine(“{0} /{1} = {2}”, a, b, DoDivide(a,b)); Console.WriteLine(“This line may or not print”); } catch (System.DivideByZeroException e) { Console.WriteLine(“\nDivideByZeroException! Msg: {0}”, e.Message); Console.WriteLine(“\nHelpLink: {0}”, e.HelpLink); Console.WriteLine(“\nHere’s a stack trace: {0}\n”, e.StackTrace); } catch { Console.WriteLine(“Unknown exception caught”); } 44 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông
  45. Bài giảng Ngôn ngữ lập trình ứng dụng – Ngành Truyền thông đa phương tiện Một số lớp ngoại lệ trong namespace System Tên ngoại lệ Mô tả MethodAccessException Lỗi truy cập, do truy cập đến thành viên hay phương thức không được truy cập ArgumentException Lỗi tham số đối mục ArgumentNullException Đối mục Null, phương thức được truyền đối mục null không được chấp nhận ArithmeticException Lỗi liên quan đến các phép toán ArrayTypeMismatchException Kiểu mảng không hợp, khi cố lưu trữ kiểu không thích hợp vào mảng DivideByZeroException Lỗi chia zero FormatException Định dạng không chính xác một định dạng nào đó IndexOutOfRangeException Chỉ số truy cập mảng không hợp lệ, dùng nhỏ hơn chỉ số nhỏ nhất hay lớn hơn chỉ số lớn nhất của mảng InvalidCastException Phép gán không hợp lệ MulticastNotSupportedException Multicast không được hỗ trợ, do việc kết hợp hai delegate không đúng NotFiniteNumberException Không phải số hữu hạn, số không hợp lệ NotSupportedException Phương thức không hỗ trợ, khi gọi một phương thức không tồn tại bên tronglớp. NullReferenceException Tham chiếu null không hợp lệ. OutOfMemoryException Out of memory OverflowException Lỗi tràn phép toán StackOverflowException Tràn stack TypeInitializationException Kiểu khởi tạo sai, khi bộ khởi dựng tĩnh có lỗi. 45 Bộ môn Truyền thông đa phương tiện – Trường Đại học Công nghệ thông tin và Truyền thông