bai 1 tiếng anh nguyễn địch long thư viện tư liệu giáo dục

147 6 0
bai 1 tiếng anh nguyễn địch long thư viện tư liệu giáo dục

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

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..[r]

(1)

Bài 1: Tổng quan lập trình

1.1.Giới thiệu môn học, phương pháp học

Đây module cung cấp cho người học nguyên lý lập trình, cấu trúc điều khiển, kiểu liệu, mơ hình hướng chức năng, cách thức xây dựng chương trình số toán khoa học kỹ thuật

Module sử dụng ngôn ngữ C# để minh họa, cài đặt Tuy nhiên người học dễ dàng cài đặt ngơn ngữ lập trình khác như: VB.NET, C/C++, Pascal

Sau hoàn thành module này, người học có khả năng: - Giải thích ngun lý lập trình máy

- Giải thích mô tả cú pháp, nguyên tắc hoạt động cách sử dụng cấu trúc điều khiển, chương trình Chỉ đặc điểm cách sử dụng kiểu liệu

- Mô tả thuật toán biểu diễn thuật toán dạng lưu đồ

- Phân tích, thiết kế cài đặt tốn theo mơ hình hướng chức

- Vận dụng kiến thức học để cài đặt toán đơn giản khoa học kỹ thuật - Hình thành thái độ học tập nghiêm túc, kỹ làm việc độc lập kỹ làm việc độc lập

và làm việc theo nhóm

Để học tốt mơn học người học phải tự xây dựng cho phương pháp học thích hợp Nhưng phương pháp chung để học mơn học người học phải hiểu thật kỹ phần lý thuyết sở vận dụng cách linh hoạt vào trường hợp cụ thể , phải làm nhiều tập…

1.2 Ngôn ngữ lập trình

Ngơn ngữ lập trình (Programming language) hệ thống kí hiệu quy tắc (về cú pháp ngữ nghĩa định nghĩa cách chặt chẽ) dùng để viết chương trình cho máy tính Có hàng trăm loại NNLT khác NNLT bậc thấp loại ngôn ngữ máy (Ngôn ngữ máy); gần với ngôn ngữ máy hợp ngữ (assembler language) bước đầu cho phép dùng cụm kí hiệu để biểu diễn mã máy, liệu, nhãn NNLT bậc cao loại gần với ngơn ngữ tự nhiên, phụ thuộc vào hạn chế máy, có khả hướng tới người sử dụng, hướng tới đối tượng, hướng tới loại vấn đề cần giải quyết, vd FORTRAN, BASIC, Pascal, C, vv

(2)

Theo định nghĩa ngơn ngữ lập trình phải thỏa mãn hai điều kiện là:

+ Nó phải dễ hiểu dễ sử dụng người lập trình, để người dùng giải tốn khác

+ Nó phải miêu tả cách đầy đủ rõ ràng tiến trình (process), để chạy máy tính khác

Một tập hợp thị biểu thị nhờ ngơn ngữ lập trình để thực thao tác máy tính thơng qua chương trình Các tên khác khái niệm không bị lầm lẫn chương trình máy tính hay chương trình điện toán

Lưu ý:

Khái niệm chương trình (program) viết cho máy vi tính nhằm giải vấn đế thường gọi phần mềm máy tính (Thí dụ chương trình MS Word cách gọi chung chung, xác phần mềm MS Word rõ chương trình ứng dụng.)

Chữ lập trình dùng để thao tác người nhằm kiến tạo nên chương trình máy tính thơng qua ngơn ngữ lập trình Người ta cịn gọi q trình lập trình q trình mã hố thơng tin tự nhiên thành ngơn ngữ máy Trong trường hợp xác định chữ lập trình cịn viết "viết mã" (cho chương trình máy tính)

Như vậy, theo định nghĩa, ngơn ngữ lập trình chương trình, dùng để tạo nên chương trình khác Một chương trình máy tính viết ngơn ngữ lập trình thị (của riêng ngơn ngữ ấy) góp phần tạo nên chương trình gọi mã nguồn chương trình

Thao tác chuyển dạng từ mã nguồn sang thành chuỗi thị máy tính đuợc thực hồn toàn tương tự việc chuyển dịch ngôn ngữ tự nhiên người Các thao tác gọi biên dịch (hay ngắn gọn dịch) Người ta phân việc biên dịch làm hai loại tùy theo trình dịch xảy trước trình thực thi tính tốn hay xảy lúc với q trình tính tốn:

Một phần mềm thơng dịch phần mềm có khả đọc, chuyển dịch mã nguồn ngôn ngữ lệnh cho máy tính tiến hành tính tốn dựa theo cú pháp ngôn ngữ

Một phần mềm biên dịch hay ngắn gọn trình dịch phần mềm có khả chuyển dịch mã nguồn ngôn ngữ ban đầu sang dạng mã thuộc ngôn ngữ cấp thấp

(3)

dịch tiếp sang tập tin thi hành Ngày nay, hầu hết trình dịch có khả viên dịch mã nguồn trực tiếp sang thành tập tin thi hành hay biên dịch sang dạng mã khác thấp tuỳ theo yêu cầu người lập trình

Một chương trình máy tính thực thi cách tổ hợp việc biên dịch thơng dịch Vì u cầu địi hỏi độ xác chi tiết cao nên việc viết mã thường gây khó khăn cho người đọc để theo dõi đơi gây khó cho lập trình viên tạo mã nguồn Do đó, lời khuyên nên dùng thêm nhiều giải lúc lập trình Các giải thường quan trọng cho người khác đọc hiểu mã nguồn

1.3 Các phương pháp lập trình 1.3.1 Lập trình gì?

Là việc viết chương trình để máy tính thực nhằm giải vấn đề (bài tốn) cho trước Q trình bao gồm: việc phân tích vấn đề, tìm thuật tốn giải; viết chương trình (diễn tả thuật tốn theo ngơn ngữ lập trình chọn); thử chương trình máy tính sửa lỗi chương trình chạy thơng máy, đáp ứng yêu cầu đặt

1.3.2 Lập trình thủ tục(lập trình có cấu trúc viết tắt LTCCT)

Phương pháp lập trình thủ tục (procedural programming) cách thực phương pháp hướng chức kể Phương pháp thủ tục chia chương trình (chức năng) lớn thành khối chức hay hàm (thủ tục) đủ nhỏ để dễ lập trình kiểm tra Mỗi hàm có điểm bắt đầu điểm kết thúc có liệu logic riêng Trong hệ thống chương trình, biến có phạm vi nhìn thấy định Trong chương trình, hàm làm việc độc lập với Dữ liệu chuyển đổi qua lại thông qua tham số gọi hàm Việc chia chương trình thành hàm cho phép nhiều người tham gia vào việc xây dựng chương trình Mỗi người xây dựng hay số hàm độc lập với Phương pháp dẫn đến khái niệm – trừu tượng hóa Sự trừu tượng hóa xem khả quan sát việc mà không cần xem xét đến chi tiết bên Trong chương trình thủ tục, cần biết hàm làm cơng việc cụ thể đủ Cịn làm để thực cơng việc khơng quan trọng, chừng hàm cịn tin cậy cịn dùng mà khơng cần phải biết thực đắn chức Điều gọi trừu tượng hóa theo chức (functional abstraction) (hay gọi chun mơn hóa) tảng lập trình thủ tục

(4)

cơ bản: tuần tự, rẽ nhánh, lặp khỏi lặp LTCCT sử dụng cách tiếp cận từ xuống, tức phân tách từ toàn thể đến phận, lại từ phận đến phận nhỏ Các đơn thể chương trình có cấu trúc có tính độc lập tương đối cao, giao tiếp với thông qua giao diện xác lập trước, LTCCT có số ưu điểm: dễ phân công nhiều người lập chương trình, dễ thử hiệu chỉnh chương trình

1.3.3 Lập trình hướng đối tượng

Lập trình hướng đối tượng (object-oriented programming viết tắt OOP), hay cịn gọi lập trình định hướng đối tượng, kĩ thuật lập trình hỗ trợ công nghệ đối tượng OOP xem là giúp tăng suất, đơn giản hóa độ phức tạp bảo trì mở rộng phần mềm cách cho phép lập trình viên tập trung vào đối tượng phần mềm bậc cao Ngoài ra, nhiều người cho OOP dễ tiếp thu cho người học lập trình phương pháp trước đó.Một cách giản lược, khái niệm nỗ lực nhằm giảm nhẹ thao tác viết mã cho người lập trình, cho phép họ tạo ứng dụng mà yếu tố bên ngồi tương tác với chương trình giống tương tác với đối tượng vật lý

Những đối tượng ngôn ngữ OOP kết hợp mã liệu mà chúng nhìn nhận đơn vị Mỗi đối tượng có tên riêng biệt tất tham chiếu đến đối tượng tiến hành qua tên Như vậy, đối tượng có khả nhận vào thơng báo, xử lý liệu (bên nó), gửi hay trả lời đến đối tượng khác hay đến mơi trường

Trong OOP, việc lập trình dựa chế kế thừa, tận dụng đặc trưng mơ tả cho lớp có sẵn để tạo lớp Các đối tượng OOP dùng thông báo gửi tới đối tượng khác để thực u cầu tính tốn cần thiết OOP quan tâm nhiều tới việc nhìn nhận khía cạnh tĩnh đối tượng - liệu, coi chương trình xử lí thành phần liệu phản ánh mặt động đối tượng

1.3.4 Lập trình logic(LTLG)

Một phương pháp tiếp cận việc biểu diễn tri thức giải tốn lơgic từ sở tri thức cho trước máy tính Một sở tri thức tập kiện luật biểu diễn quan hệ lôgic kiện LTLG xuất phát từ sở tri thức câu hỏi, tiến hành lập luận lơgic để tìm lời giải cho câu hỏi

1.4 Một số ngơn ngữ lập trình

(5)

có hiệu ưa chuộng để viết phần mềm hệ thống, dùng cho việc viết ứng dụng Ngoài ra, C thường dùng làm phương tiện giảng dạy khoa học máy tính ngôn ngữ không dược thiết kế dành cho người nhập môn

C++ (đọc "C cộng cộng" hay "xi-plus-plus") loại ngơn ngữ lập trình Đây một dạng ngơn ngữ đa mẫu hình tự có kiểu tĩnh hỗ trợ lập trình thủ tục, liệu trừu trượng, lập trình hướng đối tượng, lập trình đa hình Từ thập niên 1990, C++ trở thành ngôn ngữ thương mại phổ biến

Bjarne Stroustrup Bell Labs phát triển C++ (mà tên nguyên thủy "C với lớp" suốt thập niên 1980 nâng cao ngôn ngữ C Những bổ sung nâng cao bắt đầu với thêm vào khái niệm lớp, khái niệm hàm ảo, tốn tử tải, đa kế thừa, tiêu bản, xử lý ngoại lệ Tiêu chuẩn ngôn ngữ C++ thông qua năm 1998 ISO/IEC 14882:1998 Phiên lưu hành phiên 2003, ISO/IEC 14882:2003. Phiên tiêu chuẩn (được biết tên gọi khơng thức C++) xây dựng

C# ngôn ngữ lập trình hướng đối tượng phát triển Microsoft, phần khởi đầu cho kế hoạch NET họ Tên ngôn ngữ bao gồm ký tự thăng theo Microsoft theo ECMA C#, bao gồm dấu số thường Microsoft phát triển C# dựa C++ Java C# miêu tả ngơn ngữ có cân C++, Visual Basic, Delphi Java

Pascal ngơn ngữ lập trình cho máy tính thuộc dạng mệnh lệnh, Niklaus Wirth phát triển vào năm 1970 ngơn ngữ đặc biệt thích hợp cho kiểu lập trình có cấu trúc Pascal dựa ngơn ngữ lập trình Algol đặt tên theo nhà toán học triết học Blaise Pascal Wirth đồng thời xây dựng Modula-2 Oberon, ngôn ngữ tương đồng với Pascal Oberon hỗ trợ kiểu lập trình hướng đối tượng

Ban đầu, Pascal ngôn ngữ hướng để dùng giảng dạy lập trình có cấu trúc, nhiều hệ sinh viên "vào đời" thông qua việc học Pascal ngơn ngữ vỡ lịng chương trình học đại cương Nhiều biến thể Pascal ngày sử dụng phổ biến, giảng dạy lẫn công nghiệp phát triển phần mềm Phần lớn hệ điều hành Macintosh viết Pascal Hệ chữ TeX phổ biến viết ngôn ngữ tên Web ngôn ngữ mà Donald Knuth vay mượn nhiều yếu tố từ Pascal

(6)

sau mơi trường thực thi (runtime environment) chạy Bằng cách này, Java thường chạy nhanh ngơn ngữ lập trình thơng dịch khác Python, Perl, PHP,

Cú pháp Java vay mượn nhiều từ C & C++ có cú pháp hướng đối tượng đơn giản tính xử lý cấp thấp

1.5 Ngôn ngữ lập trình C#

Ngơn ngữ C# đơn giản, khoảng 80 từ khóa mười kiểu liệu xây dựng sẵn Tuy nhiên, ngôn ngữ C# có ý nghĩa cao thực thi khái niệm lập trình đại C# bao gồm tất 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 diện ngơn ngữ lập trình đại phát triển Microsoft, phần khởi đầu cho kế hoạch NET họ Tên ngôn ngữ bao gồm ký tự thăng theo Microsoft theo ECMA C#, bao gồm dấu số thường Microsoft phát triển C# dựa C++ Java C# miêu tả ngơn ngữ có cân C++, Visual Basic, Delphi Java

C#, theo hướng đó, ngơn ngữ lập trình phản ánh trực tiếp đến .NET Framework mà tất chương trình NET chạy, phụ thuộc mạnh mẽ vào Framework Các loại liệu sở đối tượng, hay gọi garbage-collected, nhiều kiểu trừu tượng khác chẳng hạn class, delegate, interface, exception, v.v, phản ánh rõ ràng đặc trưng NET runtime

So sánh với C C++, ngôn ngữ bị giới hạn nâng cao vài đặc điểm đó, khơng bao gồm giới hạn sau đây:

Các trỏ sử dụng chế độ khơng an tồn Hầu hết đối tượng tham chiếu an toàn, phép tính kiểm tra tràn đệm Các trỏ sử dụng để gọi loại kiểu giá trị; đối tượng thuộc thu rác (garbage-collector) gọi cách tham chiếu

+ Các đối tượng giải phóng tường minh

+ Chỉ có đơn kế thừa, cài đặt nhiều interface trừu tượng (abstract interfaces) Chức làm đơn giản hóa thực thi thời gian thực thi

+ C# an-toàn-kiểu (typesafe) C++

+ Cú pháp khai báo mảng khác nhau("int[] a = new int[5]" thay "int a[5]") + Kiểu thứ tự thay tên miền khơng gian (namespace)

+ C# khơng có tiêu

(7)

+ Có reflection

 Tại phải sử dụng ngôn ngữ C#

Nhiều người tin khơng cần thiết có ngơn ngữ lập trình Java, C++, Perl, Microsoft Visual Basic, ngôn ngữ khác nghĩ cung cấp tất chức cần thiết

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

- C# ngơn ngữ đơn giản - C# ngôn ngữ đại

- C# ngôn ngữ hướng đối tượng - C# ngôn ngữ mạnh mẽ mềm dẻo - C# ngơn ngữ có từ khóa

- C# ngôn ngữ hướng module - C# trở nên phổ biến

 C# ngôn ngữ đơn giản

C# loại bỏ vài phức tạp rối rắm ngôn ngữ Java c++, bao gồm việc loại bỏ macro, template, đa kế thừa, lớp sở ảo (virtual base class)

Chúng nguyên nhân gây nhầm lẫn hay dẫn đến vấn đề cho người phát triển C++ Nếu người học ngơn ngữ chắn ta khơng trải qua thời gian để học nó! Nhưng ta khơng biết hiệu ngôn ngữ C# loại bỏ vấn đề

(8)

 Ghi chú: Nếu sử dụng Java tin đơn giản, tìm thấy C# đơn giản Hầu hết người không tin Java ngôn ngữ đơn giản Tuy nhiên, C# dễ Java C++

 C# ngơn ngữ đại

Điều làm cho ngơn ngữ đại? Những đặc tính xử lý ngoại lệ, thu gom nhớ tự động, kiểu liệu mở rộng, bảo mật mã nguồn đặc tính mong đợi ngôn ngữ đại C# chứa tất đặc tính Nếu người học lập trình cảm thấy đặc tính phức tạp khó hiểu Tuy nhiên, đừng lo lắng tìm hiểu đặc tính qua chương sách

 Ghi chú: Con trỏ tích hợp vào ngơn ngữ C++ Chúng nguyên nhân gây rắc rối ngôn ngữ C# loại bỏ phức tạp rắc rối phát sinh trỏ Trong C#, thu gom nhớ tự động kiểu liệu an tồn tích hợp vào ngơn ngữ, loại bỏ vấn đề rắc rối C++

 C# ngôn ngữ hướng đối tượng

Những đặc điểm ngơn ngữ hướng đối tượng (Object-oriented language) đóng gói (encapsulation), kế thừa (inheritance), đa hình (polymorphism) C# hỗ trợ tất đặc tính Phần hướng đối tượng C# trình bày chi tiết chương riêng phần sau

 C# ngôn ngữ mạnh mẽ mềm dẻo

Như đề cập trước, với ngôn ngữ C# bị giới hạn thân trí tưởng tượng Ngôn ngữ không đặt ràng buộc lên việc làm C# sử dụng cho nhiều dự án khác tạo ứng dụng xử lý văn bản, ứng dụng đồ họa, tính, hay chí trình biên dịch cho ngơn ngữ khác

 C# ngơn ngữ từ khóa

(9)

 C# ngôn ngữ hướng module

Mã nguồn C# viết phần gọi lớp, lớp chứa phương thức thành viên Những lớp phương thức sử dụng lại ứng dụng hay chương trình khác Bằng cách truyền mẫu thông tin đến lớp hay phương thức tạo mã nguồn dùng lại có hiệu

 C# ngôn ngữ phổ biến

C# ngôn ngữ lập trình Vào thời điểm sách viết, khơng biết ngơn ngữ phổ biến Nhưng ngơn ngữ có số lý để trở thành ngôn ngữ phổ biến Một lý Microsoft cam kết NET Microsoft muốn ngôn ngữ C# trở nên phổ biến Mặc dù công ty làm sản phẩm trở nên phổ biến, hỗ trợ Cách khơng lâu, Microsoft gặp thất bại hệ điều hành Microsoft Bob Mặc dù Microsoft muốn Bob trở nên phổ biến thất bại C# thay tốt để đem đến thành công sơ với Bob Thật người công ty Microsoft sử dụng Bob công việc ngày họ Tuy nhên, với C# khác, sử dụng Microsoft Nhiều sản phẩm công ty chuyển đổi viết lại C# Bằng cách sử dụng ngôn ngữ Microsoft xác nhận khả C# cần thiết cho người lập trình

Micorosoft NET lý khác để đem đến thành công C# .NET thay đổi cách tạo thực thi ứng dụng Ngoài hai lý ngôn ngữ C# trở nên phổ biến đặc tính ngơn

ngữ đề cập mục trước như: đơn giản, hướng đối tượng, mạnh mẽ  Ngôn ngữ C# ngôn ngữ khác

(10)

nào trả lời thắc mắc Microsoft nói C# mang đến sức mạnh ngôn ngữ C++ với dễ dàng ngơn ngữ Visual Basic Có thể không dễ Visual Basic, với phiên Visual Basic.NET (Version 7) ngang Bởi chúng viết lại từ tảng Chúng ta viết nhiều chương trình với mã nguồn dùng C#

Mặc dù C# loại bỏ vài đặc tính C++, bù lại tránh lỗi mà thường gặp ngôn ngữ C++ Điều tiết kiệm hàng hay chí hàng ngày việc hồn tất chương trình Chúng ta hiểu nhiều điều chương giáo trình

Một điều quan trọng khác với C++ mã nguồn C# khơng địi hỏi phải có tập tin header Tất mã nguồn viết khai báo lớp

Như nói bên .NET runtime C# thực việc thu gom nhớ tự động Dođiều nên việc sử dụng trỏ C# quan trọng C++ Những trỏ sử dụng C#, đoạn mã nguồn đánh dấu khơng an tồn (unsafe code)

C# từ bỏ ý tưởng đa kế thừa C++ Và khác khác C# đưa thêm thuộc tính vào lớp giống Visual Basic Và thành viên lớp gọi toán tử “.” khác với C++ có nhiều cách gọi tình khác

Một ngôn ngữ khác mạnh phổ biến Java, giống C++ C# phát triển dựa C Nếu định học Java sau này, tìm nhiều mà học từ C# áp dụng

Điểm giống C# Java hai biên dịch mã trung gian: C# biên dịch MSIL cịn Java biên dịch bytecode Sau chúng thực cách thông dịch biên dịch just-in-time máy ảo tương ứng

Tuy nhiên, ngôn ngữ C# nhiều hỗ trợ đưa để biên dịch mã ngôn ngữ trung gian sang mã máy C# chứa nhiều kiểu liệu Java cho phép nhiều mở rộng với kiểu liệu giá trị Ví dụ, ngơn ngữ C# hỗ trợ kiểu liệt kệ (enumerator), kiểu giới hạn đến tập định nghĩa trước, kiểu liệu cấu trúc kiểu liệu giá trị người dùng định nghĩa Chúng ta tìm hiểu kỹ kiểu liệu tham chiếu kiểu liệu giá trị trình bày phần sau

Tương tự Java, C# từ bỏ tính đa kế thừa lớp, nhiên mơ hình kế thừa đơn mở rộng tính đa kế thừa nhiều giao diện

 Các bước chuẩn bị cho chương trình

(11)

phạm vi tìm hiểu ngơn ngữ viết chương trình nhỏ khơng địi hỏi khắt khe việc thực theo quy trình Nhưng để giải vấn đề cần phải thực theo bước sau Đầu tiên phải xác định vấn đề cần giải Nếu rõ vấn đề ta khơng thể tìm phương pháp giải Sau xác định vấn đề, nghĩ kế hoạch để thực Sau có kế hoạch, thực thi kế hoạch Sau kế hoạch thực thi, phải kiểm tra lại kết để xem vấn đề giải xong chưa Logic thường áp dụng nhiều lĩnh vực khác nhau, có lập trình

Khi tạo chương trình C# hay ngơn ngữ nào, nên theo bước sau:

- Xác định mục tiêu chương trình

- Xác định phương pháp giải vấn đề - Tạo chương trình để giải vấn đề - Thực thi chương trình để xem kết

Ví dụ mục tiêu để viết chương trình xử lý văn đơn giản, mục tiêu xây dựng chương trình cho phép soạn thảo lưu trữ chuỗi ký tự hay văn Nếu khơng có mục tiêu khơng thể viết chương trình hiệu

Bước thứ hai định đến phương pháp để viết chương trình Bước xác địnhn thơng tin cần thiết sử dụng chương trình, hình thức sử dụng Từ thơng tin rút phương pháp để giải vấn đề

Bước thứ ba bước cài đặt, bước dùng ngơn ngữ khác để cài đặt, nhiên, ngôn ngữ phù hợp để giải vấn đề cách tốt chọn Trong phạm vi sách mặc định dùng C#, đơn giản tìm hiểu nó!

Và bước cuối phần thực thi chương trình để xem kết Bài 2: Thuật tốn chương trình

2.1 Thuật toán cách biểu diễn thuật toán

a) Khái niệm

(12)

Tại lại "Thuật toán" ?

Từ thuật toán (Algorithm) xuất phát từ tên nhà toán học người Trung Á Abu Abd -Allah ibn Musa al’Khwarizmi, thường gọi al’Khwarizmi Ông tác giả sách số học, ơng dùng phương pháp mơ tả rõ ràng, mạch lạc cách giải toán Sau này, phương pháp mơ tả cách giải tốn ông xem chuẩn mực nhiều nhà toán học khác tuân theo Từ algorithm đời dựa theo cách phiên âm tên ông

Việc nghiên cứu thuật tốn có vai trị quan trọng khoa học máy tính máy tính giải vấn đề có hướng dẫn giải rõ ràng Nếu hướng dẫn giải sai khơng rõ ràng máy tính khơng thể giải tốn Trong khoa học máy tính, thuật tốn định nghĩa dãy hữu hạn bước khơng mập mờ thực thi được, trình hành động theo bước phải dừng cho kết mong muốn

Số bước hữu hạn thuật toán tính chất dừng gọi chung tính hữu hạn Số bước hữu hạn thuật tốn tính chất hiển nhiên Ta tìm đâu lời giải vấn đề - tốn có vơ số bước giải ? Tính "khơng mập mờ" "có thể thực thi được" gọi chung tính xác định Giả sử nhận lớp học mới, Ban Giám hiệu yêu cầu giáo viên chủ nhiệm chọn lớp trưởng theo bước sau :

Lập danh sách tất học sinh lớp Sắp thứ tự danh sách học sinh

Chọn học sinh đứng đầu danh sách để làm lớp trưởng

Khi nhận thông báo này, giáo viên chắn bối rối khơng hiểu danh sách học sinh cần có thơng tin gì? Danh sách cần họ tên, hay cần thêm ngày tháng năm sinh? Có cần thêm điểm trung bình khơng? u cầu lại gây nhiều thắc mắc Cần phải xếp danh sách theo chiều tăng dần giảm dần ? Sắp theo tiêu ? Theo tên, theo ngày tháng năm sinh hay theo điểm trung bình chung, Giả sử theo điểm trung bình có hai học sinh điểm trung bình học sinh trước, học sinh sau ?

Hướng dẫn vi phạm tính chất "khơng mập mờ" thuật tốn Nghĩa là, có q nhiều thơng tin cịn thiếu để làm cho bước 1,2 hiểu hiểu theo nghĩa Nếu sửa lại chút hướng dẫn trở nên rõ ràng nhiều gọi thuật tốn chọn lớp trưởng !

(13)

Sắp hạng học sinh theo điểm trung bình theo thứ tự giảm dần (từ điểm cao đến điểm thấp) Hai học sinh có điểm trung bình có hạng

Nếu có học sinh có hạng chọn học sinh làm lớp trưởng Trường hợp có nhiều học sinh đồng hạng chọn học sinh có điểm mơn Tốn cao làm lớp trưởng

Nếu nhiều học sinh đồng hạng có điểm mơn Tốn cao tiến hành bốc thăm

Ở cần phân biệt mập mờ chọn lựa có định Mập mờ thiếu thơng tin có nhiều chọn lựa khơng đủ điều kiện để định Cịn chọn lựa có định hồn toàn xác định điều kiện cụ thể vấn đề Chẳng hạn vấn đề chọn lớp trưởng trên, bước thể lựa chọn có định Tất nhiên, chưa lập danh sách, chưa xếp hạng theo điểm trung bình giáo viên biết chọn lớp trưởng theo cách Nhưng xong danh sách có phương án chọn

Tính "thực thi được" tính chất hiển nhiên Rõ ràng "thuật toán" tồn bước khơng thể thực thi ta có kết ý muốn? Tuy nhiên, cần phải hiểu "thực thi được" xét điều kiện tốn Chẳng hạn, nói "lấy bậc hai số âm" thực thi miền xác định tốn số thực, miền số phức thao tác "lấy bậc hai số âm" hoàn toàn thực thi Tương tự, ta đường cho người xe máy đến bưu điện đường ta đường cụt, đường cấm đường ngược chiều người khơng thể đến bưu điện

Tính "dừng" tính chất dễ bị vi phạm nhất, thường sai sót trình bày thuật tốn Dĩ nhiên, thuật tốn nhằm thực cơng việc nên sau thời gian thi hành hữu hạn thuật tốn phải cho kết mong muốn Khi khơng thỏa tính chất này, ta nói "thuật tốn" bị lặp vơ tận bị quẩn Ðể tính tổng số nguyên dương lẻ khoảng từ đến n ta có thuật tốn sau :

B1 Hỏi giá trị n B2 S =

B3 i =

B4 Nếu i = n+1 sang bước B8, ngược lại sang bước B5 B5 Cộng thêm i vào S

(14)

Ta ý đến bước B4 Ở ta muốn kết thúc thuật toán giá trị i vượt n Thay viết "nếu i lớn n" ta thay điều kiện "nếu i n+1" theo tốn học "i = n+1" suy "i lớn n" Nhưng điều kiện "i=n+1" lúc đạt Vì ban đầu i = số lẻ, sau bước, i tăng thêm nên i số lẻ Nếu n số chẵn n+1 số lẻ nên sau số bước định, i n+1 Tuy nhiên, n số lẻ n+1 số chẵn, i số lẻ nên dù có qua bước nữa, i khác n+1 Trong trường hợp đó, thuật tốn bị quẩn

Tính "đúng" tính chất hiển nhiên tính chất khó đạt tới Thực vậy, giải vấn đề-bài tốn, ta ln ln mong muốn lời giải cho kết lúc đạt Mọi học sinh làm kiểm tra muốn làm có đáp số thực tế, lớp học có số học sinh định có khả đưa lời giải đúng!

Thuật tốn cứng nhắc !

Các tính chất thuật tốn chặt chẽ cứng nhắc Nhưng điều có nghĩa khả giải vấn đề theo kiểu thuật toán bị giới hạn Sau này, người ta "làm mềm" hai tính chất quan trọng thuật tốn tính xác định tính đúng để giải vấn đề phức tạp mà với tính chất chặt chẽ thuật tốn khơng thể giải Ðó thuật tốn đệ quy thuật giải Ta tìm hiểu điều mục chương b) Các đặc trưng khác thuật toán

Bên cạnh đặc trưng xác định, hữu hạn đúng, thuật tốn cịn có thêm đặc trưng phụ khác

1 Ðầu vào đầu (input/output) : thuật tốn, dù có đơn giản đến phải nhận liệu đầu vào, xử lý cho kết cuối

2 Tính hiệu (effectiveness) : tính hiệu thuật toán đánh giá dựa số tiêu chuẩn khối lượng tính tốn, khơng gian thời gian thuật tốn thi hành Tính hiệu thuật toán yếu tố định để đánh giá, chọn lựa cách giải vấn đề-bài tốn thực tế Có nhiều phương pháp để đánh giá tính hiệu thuật tốn Trong mục chương , ta tìm hiểu tiêu chuẩn dùng rộng rãi độ phức tạp thuật tốn

(15)

bảo tính tổng quát Trong thực tế, có lúc người ta xây dựng thuật toán cho dạng đặc trưng tốn mà thơi

Thuật tốn giải phương trình bậc hai ax2+bx+c=0 (a0) 1 Yêu cầu cho biết giá trị hệ số a, b, c

2 Nếu a=0

2.1 Yêu cầu đầu vào khơng đảm bảo 2.2 Kết thúc thuật tốn

3 Trường hợp a khác 3.1 Tính giá trị D = b2-4ac

3.2 Nếu D >

3.2.1 Phương trình có hai nghiệm phân biệt x1 x2

3.2.2 Giá trị hai nghiệm tính theo cơng thức sau ; X1=−b+√Δ

2a X2=− b−Δ

2a 3.2.3 Kết thúc thuật toán 3.3 Nếu D =

3.3.1 Phương trình có nghiệm kép x0

3.3.2 Giá trị nghiệm kép X0=

− b

2a 3.3.3 Kết thúc thuật tốn 3.4 Nếu D <

3.4.1 Phương trình vơ nghiệm 3.4.2 Kết thúc thuật tốn

Thuật tốn tìm hộp có trọng lượng nặng

(16)

của A Bài toán toán học phức tạp thể thực tế lại dễ hiểu, và cách giải đơn giản Từ ta dễ dàng suy cách giải toán tổng quát

1 Nếu có hộp (n=1) thì

1.1 Hộp hộp nặng 1.2 Kết thúc thuật tốn

2 Ngược lại có từ hai hộp trở lên (n>1) 2.1 Chọn hai hộp đặt lên bàn cân

2.2 Giữ lại hộp nặng hơn, cất hộp nhẹ sang chỗ khác

3 Nếu hộp chưa cân thực bước sau, khơng cịn hộp nữa, sang bước

3.1 Chọn hộp để lên dĩa cân trống 3.2 Giữ lại hộp nặng hơn, cất hộp nhẹ sang chỗ khác

4 Trở lại bước

5 Hộp cịn lại cân hộp nặng Kết thúc Thuật tốn Euclid tìm ước số chung lớn nhất

Bài toán : Cho hai số nguyên dương a b Tìm ước số chung lớn a b

1 Yêu cầu cho biết giá trị a, b. 2 a0 = a

3 b0 = b

4 i =

5 Nếu khác bi thực thao tác sau, ngược lại qua bước 7. 5.1 Tăng i lên

5.2 Nếu ai-1 > bi-1 = ai-1 - bi-1 bi = bi-1 5.3 Ngược lại

(17)

7 Ước số chung lớn a, b c) Các phương pháp biểu diễn thuật toán

Khi chứng minh giải toán tốn học, ta thường dùng ngơn từ tốn học : "ta có", "điều phải chứng minh", "giả thuyết", sử dụng phép suy luận toán học phép suy ra, tương đương, Thuật toán phương pháp thể lời giải toán nên phải tuân theo số quy tắc định Ðể truyền đạt thuật tốn cho người khác hay chuyển thuật tốn thành chương trình máy tính, ta phải có phương pháp biểu diễn thuật tốn Có phương pháp biểu diễn thuật tốn :

1 Dùng ngơn ngữ tự nhiên

2 Dùng lưu đồ-sơ đồ khối (flowchart) Dùng mã giả (pseudocode)

 Ngôn ngữ tự nhiên

Trong cách biểu diễn thuật toán theo ngôn ngữ tự nhiên, người ta sử dụng ngôn ngữ thường ngày để liệt kê bước thuật tốn (Các ví dụ thuật tốn mục chương sử dụng ngôn ngữ tự nhiên) Phương pháp biểu diễn khơng u cầu người viết thuật tốn người đọc thuật toán phải nắm quy tắc Tuy vậy, cách biểu diễn thường dài dòng, khơng thể rõ cấu trúc thuật tốn, đơi lúc gây hiểu lầm khó hiểu cho người đọc Gần khơng có quy tắc cố định việc thể thuật tốn ngơn ngữ tự nhiên Tuy vậy, để dễ đọc, ta nên viết bước lùi vào bên phải đánh số bước theo quy tắc phân cấp 1, 1.1, 1.1.1, Bạn tham khảo lại ba ví dụ mục chương để hiểu cách biểu diễn thuật tốn theo ngơn ngữ tự nhiên

 Lưu đồ - sơ đồ khối

Lưu đồ hay sơ đồ khối công cụ trực quan để diễn đạt thuật toán Biểu diễn thuật toán lưu đồ giúp người đọc theo dõi phân cấp trường hợp trình xử lý thuật toán Phương pháp lưu đồ thường dùng thuật tốn có tính rắc rối, khó theo dõi q trình xử lý

Ðể biểu diễn thuật tốn theo sơ đồ khối, ta phải phân biệt hai loại thao tác Một thao tác thao tác chọn lựa dựa theo điều kiện Chẳng hạn : thao tác "nếu a = b thực thao tác B2, ngược lại thực B4" thao tác chọn lựa Các thao tác cịn lại khơng thuộc loại chọn lựa xếp vào loại hành động Chẳng hạn, "Chọn hộp để lên dĩa cân trống." thao tác thuộc loại hành động

(18)

Thao tác chọn lựa biểu diễn hình thoi, bên chứa biểu thức điều kiện

 Thao tác xử lý (process)

Thao tác xử lý biểu diễn hình chữ nhật, bên chứa nội dung xử lý

 Ðường (route)

Khi dùng ngôn ngữ tự nhiên, ta mặc định hiểu trình thực từ bước trước đến bước sau (trừ có yêu cầu nhảy sang bước khác) Trong ngôn ngữ lưu đồ, thể bước hình vẽ đặt hình vẽ vị trí nên ta phải có phương pháp để thể trình tự thực thao tác

Hai bước nối cung, cung có mũi tên để hướng thực Chẳng hạn hình dưới, trình tự thực B1, B2, B3

Từ thao tác chọn lựa có đến hai hướng đi, hướng ứng với điều kiện thỏa hướng ứng với điều kiện không thỏa Do vậy, ta dùng hai cung xuất phát từ đỉnh hình thoi, cung có ký hiệu Ð/Ðúng/Y/Yes để hướng ứng với điều kiện thỏa ký hiệu S/Sai/N/No để hướng ứng với điều kiện không thỏa

A = b  >

(19)

 Ðiểm cuối (terminator)

Ðiểm cuối điểm khởi đầu kết thúc thuật toán, biểu diễn hình ovan, bên có ghi chữ bắt đầu/start/begin kết thúc/end Ðiểm cuối có cung (điểm khởi đầu) cung vào (điểm kết thúc) Xem lưu đồ thuật toán giải phương trình bậc hai để thấy cách sử dụng điểm cuối

 Ðiểm nối (connector)

(20)

 Ðiểm nối sang trang (off-page connector)

Tương tự điểm nối, điểm nối sang trang dùng lưu đồ lớn, phải vẽ nhiều trang Bên điểm nối sang trang ta đặt ký hiệu để biết liên hệ điểm nối trang

Ở ký hiệu thường dùng Trong thực tế, lưu đồ có nhiều ký hiệu khác thường dùng lưu đồ lớn phức tạp Ðối với thuật toán sách này, ta cần sử dụng ký hiệu đủ

 Mã giả

(21)

Khi thể thuật toán mã giả, ta vay mượn cú pháp ngơn ngữ lập trình để thể thuật tốn Tất nhiên, ngơn ngữ lập trình có thao tác xử lý, rẽ nhánh lặp Dùng mã giả vừa tận dụng khái niệm ngơn ngữ lập trình, vừa giúp người cài đặt dễ dàng nắm bắt nội dung thuật toán Tất nhiên mã giả ta dùng phần ngôn ngữ tự nhiên Một vay mượn cú pháp khái niệm ngôn ngữ lập trình chắn mã giả bị phụ thuộc vào ngơn ngữ lập trình Chính lý này, chưa vội tìm hiểu mã giả (vì chưa biết ngơn ngữ lập trình!) Sau tìm hiểu xong thủ tục - hàm bạn hiểu mã giả !

Một đoạn mã giả thuật tốn giải phương trình bậc hai if (delta > 0) {

x1=(-b-sqrt(delta))/(2*a)

x2=(-b+sqrt(delta))/(2*a)

xuất kết : phương trình có hai nghiệm x1 x2

} else

if (delta == 0)

xuất kết : phương trình có nghiệm kép -b/(2*a) else {trường hợp delta < }

xuất kết : phương trình vơ nghiệm

* Các từ in đậm từ khóa ngơn ngữ C#  Sử dụng ngơn ngữ lập trình (Programming Language)

(22)

Khi có ngơn ngữ lập trình, việc lệnh cho máy tính thực thi câu lệnh khơng phải tuỳ ý ngôn ngữ tự nhiên mà phải tuân theo qui tắc ngơn ngữ qui định – Các qui tắc mà ngơn ngữ lập trình qui định gọi cú pháp - Syntax ngơn ngữ Mỗi ngơn ngữ lập trình có cú pháp riêng

Vậy: Ngơn ngữ lập trình chương trình có nhiệm vụ chuyển đổi thị người thành thị mà máy tính hiểu thực thi được.

Một số ngơn ngữ lập trình phổ biến Việt nam Thế giới bao gồm Ngôn ngữ lập trình Pascal, C, C++, C#, Basic, Foxpro, Perl, Java

Một số ví dụ chuyển đổi thị người dùng thành thị máy tính

Dưới đây, Ta lấy ví dụ hiển thị tổng số 100 200 lên hình Ngơn ngữ lập trình phổ biến Pascal, C#, C/C++, Basic:

a Trong Pascal : Begin

Writeln(100+200); End

b Trong C#

static void Main () {

Console.Write(100+200); }

c Trong Basic: Sub Main

MsgBox 100+200 End Sub

d Trong C/C++ void main () {

printf(“%d”,100+200); }

(23)

Giới thiệu

Máy tính dùng để giải tốn thực phép tính Tuy nhiên, để thực điều này, cần phải cung cấp giải pháp dạng câu lệnh cần thiết để giải tốn cụ thể

Nói cách khác, phải cung cấp cho máy tính dãy lệnh để giải toán Dãy lệnh gọi chương trình Khi viết chương trình để giải tốn cụ thể, chương trình sử dụng lại để giải tốn tương tự

Ví dụ, viết chương trình để tính điểm trung bình cho 100 sinh viên lớp, chương trình sử dụng để tính điểm trung bình cho 100 sinh viên khác

Các bước giải toán máy tính

Giải tốn q trình phức tạp địi hỏi phải suy nghĩ, lên kế hoạch, lập luận xác, kiên trì ý đến chi tiết

Máy tính khơng thể tự giải tốn lập trình viên không cung cấp giải pháp Giải pháp gọi thuật toán (algorithm)

Các bước để giải toán: Nghiên cứu chi tiết toán Tập hợp thơng tin thích hợp Xử lý thông tin

4 Đi đến kết

Ví dụ 1

Để kiểm tra số chẵn hay lẻ, cần thực bước sau:  Đọc vào số

 Chia số cho

 Nếu phần dư số chẵn  Ngược lại, số lẻ

Với bước theo thứ tự trên, tiến hành biểu diễn chúng thành lệnh ngơn ngữ lập trình cụ thể

Ví dụ 2

(24)

Các bước cần thực sau:

 Thông tin hành khách tên, tuổi, nơi xuất phát nơi đến hành trình, ngày đăng ký hành trình

 Người bán vé ghi nhận lại thông tin, kiểm tra lại số chỗ trống  Nếu đủ chỗ cho đặt vé

 Ngược lại, đưa vé chờ

 Vé chờ trả lời chuyễn thành thức có hành khách khác hủy vé

 Nếu khơng nhận trả lời có nghĩa hành khách khơng đặt vé thức Phân tích tốn theo thứ tự logic dễ dàng thực việc lập chương trình

Lưu đồ (flowchart)

Cơng cụ dùng để mơ tả thuật tốn gọi lưu đồ

Lưu đồ gì? Định nghĩa:

Lưu đồ biểu đồ minh họa cho dãy thao tác cần tiến hành để giải tốn.

Các câu lệnh mơ tả ký hiệu cụ thể Các ký hiệu nối với mũi tên để định rõ thứ tự thực

Lưu đồ công cụ sử dụng để viết chương trình để phục vụ cho mục đích sau:  Mơ tả trực quan dễ hiểu mô tả tường thuật

 Dựa vào lưu đồ xem lại gỡ rối chương trình cách dễ dàng  Cung cấp tài liệu chương trình

 Nhờ vẽ lưu đồ, dễ dàng hiểu chương trình thảo luận giải pháp Các ký hiệu sau sử dụng vẽ lưu đồ

Bắt đầu kết thúc chương trình

(25)

b) Một số tốn thơng dụng  Thuật tốn lặp

Trong thực tế giải toán, nhiều ta cần thực cơng việc tương tự nhiều lần, chẳng hạn nhập danh sách sinh viên hay tính điểm trung bình mơn học cho lớp v.v Khi ta thường phải sử dụng đến thuật tốn lặp Thuật tốn lặp mô tả sơ đồ khối sau

Dòng chảy

n n

Bắt đầu

Thực cơng việc

Có cần lặp lại cơng việc không ?

Thay đổi, cập nhật lại số thơng số

Khơng Một số công việc khởi

đầu (Khởi tạo) Các lệnh nhập xuất

Quyết định rẽ nhánh

(26)

Một lưu ý quan trọng : Khâu "Thực cơng việc" chứa nhiều thao tác khác, : Kiểm tra, nhập xuất chí lại thuật tốn lặp

Một số ví dụ:

Sau ta lấy số ví dụ minh hoạ cụ thể việc áp dụng thuật toán lặp mơ tả

Ví dụ 1: Viết lưu đồ nhập vào danh sách họ tên lớp có N sinh viên Ở gọi i vị trí SV thứ i Khi ta lưu đồ thuật toán sau:

(27)

Ở ví dụ này, khâu "Thực cơng việc" làm việc nhập họ tên cho sinh viên thứ i

Ví dụ 2: Vẽ lưu đồ thuật tốn để đếm xem có chữ số chia hết cho khoảng từ đến 1000

Gọi i số xét Tong_So tổng chữ số chia hết cho 3, ta có lưu đồ sau: Bắt đầu

Nhập Họ tên sinh viên thứ i

i <= N ?

Kết thúc i = i +

(Thực đến người tiếp theo)

Không (Đã nhập hết) i = 1

(28)

Nhận xét: Trong lưu đồ khâu "Thực cơng việc" phức tạp hơn, có chứa thêm thao tác xử lý kiểm tra khác

 Thuật tốn tìm kiếm

Nhiều tốn khoa học kỹ thuật có sử dụng nhiều đến kỹ thuật tìm kiếm Ngồi ra, khái niệm tìm kiếm quen thuộc đời sống thường ngày chúng ta, tìm kiếm thơng tin, tìm kiếm (tra cứu) từ điển, tìm học sinh có điểm thi cao lớp học, tìm số lớn dãy số v.v Để tìm kiếm thơng tin vậy, có nhiều phương pháp (thuật tốn) tìm kiếm khác nhau, phương pháp có ưu nhược điểm riêng Dưới đề cập đến thuật tốn tìm kiếm đơn giản thuật tốn tìm kiếm TUẦN TỰ

Bắt đầu

Lấy số i chia cho 3, phần dư R

i <= 1000 ?

Kết thúc i = i +

(Thực đến số tiếp theo)

Đúng

Sai (Đã đếm hết) i = 1

(Bắt đầu từ 1) Tong_So =

R = ?

Tăng Tong_So thêm đơn vị Khối

"Thực cơng việc"

(29)

Tình đặt : Có n mục thơng tin (n > 0), tìm mục thơng tin x, có thơng báo tìm thấy cho biết vị trí mục x, Trái lại thơng báo khơng tìm thấy

Ý tưởng giải toán sau : - Ta thử từ mục mục thứ n, - Qua lần thử ta so sánh mục x với mục thứ i

- Nếu mục thứ i x thơng báo thấy vị trí thấy i, trái lại ta thử tiếp với mục thứ i +

- Nếu thử hết mục (tức i > n ) mà chưa thấy thơng báo khơng tìm thấy Có thể mơ tả lưu đồ sau:

Ví dụ sử dụng thuật tốn tìm kiếm

Cho danh sách sinh viên lớp TinK33, Tổng số có 100 SV Hãy vẽ lưu đồ thuật tốn tìm xem sinh viên Phạm Văn An có danh sách khơng Nếu thấy thơng báo "Đã tìm thấy", Trái lại thơng báo "Không thấy"

Ta ký hiệu SV[i] sinh viên xét có số thứ tự thứ i danh sách, X = "Phạm Văn An" Khi lưu đồ thuật toán biểu diễn sau:

Bắt đầu

i = (Từ mục 1)

Mục i = x ?

i = i +

(Chuyển đến mục tiếp theo)

i > n ?

Kết thúc

Đã tìm thấy & Vị trí i

Sai

Đúng

Sai

(30)

Bắt đầu

i = (Từ SV 1)

SV[i] = X ?

i = i +

(Chuyển đến SV tiếp theo)

i > 100 ?

Kết thúc

Đã tìm thấy

Sai

Đúng

Sai

(31)

 Thuật toán xếp

Thuật toán xếp thuật toán cách thức để xếp danh sách thông tin theo tiêu chí Ví dụ ta có thuật toán xếp danh sách sinh viên lớp theo vần Alphabet họ tên, hay xếp thí sinh thi Đại học theo số báo danh v.v

Trong thực tế, tuỳ thuộc vào lượng thông tin cần xếp mà người ta sử dụng thuật tốn có độ phức tạp thời gian tính tốn khác Ở ta đề cập đến thuật toán xếp thường dùng toán đơn giản

Xét tốn: Một danh sách có n mục thông tin, mục chứa chữ Alphabet Hãy xếp danh sách theo trình tự chữ Alphabet

Để giải toán thuật toán nêu sau đây, trước hết cần nắm thuật toán khác gọi "thuật toán đổi chỗ"

+ Thuật tốn đổi chỗ:

Một tình thực tế: Có Can, đựng Xăng đựng Dầu Hãy chuyển Xăng từ can xăng sang can Dầu ngược lại, chuyển Dầu từ can dầu sang can Xăng

Ta thực theo sơ đồ mô tả đây:

Ở ta sử dụng can rỗng thứ 3, gọi Can trung gian - Bước 1: Đổ can xăng sang can Trung gian

- Bước 2: Đổ Dầu sang can xăng

- Bước 3: Đổ từ can trung gian sang can Dầu

Như ta thực yêu cầu toán đặt

Ta mở rộng tình Toán học Hãy hoán đổi giá trị hai số x y cho

Xăng Dầu

Trung gian Bước

Bước

(32)

Sử dụng ý tưởng trên, ta làm sau:

- Lưu giá trị x vào số trung gian, giả sử z: z = x - Thay x giá trị y: x = y

- Thay y giá trị z: y = z

Như ta đổi chỗ giá trị x y thông qua số trung gian z Sau đây, Ta lấy ví dụ xếp danh sách theo thứ tự tăng dần

Ví dụ, xếp danh sách gồm số 57, 33, 21, 84, 49, 50, 75 theo thứ tự tăng dần Các bước thực hiện:

- Ta qua danh sách để tìm phần tử nhỏ thấy vị trí 3: 67, 33, , 84, 49, 50, 75

- Ta hoán vị phần tử với phần tử xác định vị trí phần tử nhỏ đầu danh sách:

, 33, 67, 84, 49, 50, 75

- Ta lại qua danh sách gồm phần tử từ vị trí để tìm phần tử nhỏ :

21 , , 67, 84, 49, 50, 75

Trong dãy này, ta thấy 33 nhỏ ta thực hoán vị với Và phần tử nhỏ 33

21 , , 67, 84, 49, 50, 75

Cứ tiếp tục theo cách này, định vị phần tử nhỏ danh sách từ vị trí thực danh sách chứa phần tử cuối

21, 33 , 84 , 67, 49, 50, 75 21

33

33

49

(33)

21 33 49 67 84 75

21 33 49 50 84 75

21 33 49 50 67

Bây thảo luận chi tiết thuật toán Sắp xếp theo yêu cầu 67

(34)

START

i = (Duyệt từ vị trí đầu)

i < N ?

Muc[i+1] < Muc[i] ?

TG = Muc[i] Muc[i] = Muc[i+1] Muc[i+1] = TG (Hoán vị cho nhau)

END i = i +

(Số tiếp)

Đúng

Sai

(35)

2.2 Cấu trúc chương trình C# đơn giản

Để bắt đầu cho việc tìm hiểu ngơn ngữ C# tạo tiền đề cho chương sau, chương trình bày chương trình C# đơn giản

Ví dụ : Chương trình C# đầu tiên.

-class ChaoMung

{

static void Main( ) {

// Xuat man hinh

System.Console.WriteLine(“Hello World”); }

}

-Hello World

-Sau viết xong lưu dạng tập tin có phần mở rộng *.cs

(C sharp) Sau biên dịch chạy chương trình Kết chuỗi “Hello World” xuất hình console

Từ ví dụ ta nhận thấy chương trình C# đơn có lớp Mỗi lớp khố class kế tên lớp đặt, bên lớp khai báo các biến(thành phần liệu) hàm(phương thức) Trong số hàm bên lớp có hàm tên Main Hàm có đặc điểm chương trình C# gọi thực máy tiến hành thực từ câu lệnh hàm Main Main kết thúc chương trình C# kết thúc Điều chứng tỏ hàm Main hàm chương trình C# Một chương trình C# muốn thực phải có hàm Main có hàm Main tồn hệ thống chương trình hàm gọi hàm khác để thực yêu cầu toán Hàm Main khai báo sau:

(36)

// Các câu lệnh }

Chú ý: - Hàm Main có dạng thể khác tìm hiểu sau

- Nếu chương trình C# mà khơng có hàm Main đặt lớp chương trình C# khơng thể thực

Một số khái niệm bản

 Ghi chú: Một chương trình viết tốt cần phải có thích đoạn mã viết Các đoạn thích không biên dịch không tham gia vào chương trình Mục đích làm cho đoạn mã nguồn rõ ràng dễ hiểu

Trong ví dụ có dịng thích : // Xuat man hinh

Một chuỗi thích dịng bắt đầu ký tự “//” Khi trình biên dịch gặp hai ký tự bỏ qua dịng

Ngồi C# cịn cho phép kiểu thích cho hay nhiều dòng, ta phải khai báo “/*” phần đầu thích kết thúc thích ký tự “*/”

Ví dụ : Minh họa dùng thích nhiều dịng.

-class ChaoMung

{

static void Main() {

/* Xuat man hinh chuoi ‘chao mung’

Su dung ham WriteLine cua lop System.Console */

System.Console.WriteLine(“Hello World”); }

}

Hellp World

(37)

-Ngồi hai kiểu thích giống C/C++ C# cịn hỗ trợ thêm kiểu thứ ba kiểu cuối cùng, kiểu chứa định dạng XML nhằm xuất tập tin XML biên dịch để tạo sưu liệu cho mã nguồn

///XML Chú thích tài liệu dịng định dạng theo XML /**XML Chú thích nhiều dịng định dạng theo XML**/

 Ứng dụng Console: Là cách xây dựng ứng dụng giao tiếp với người dùng thông quan bàn phím khơng có giao diện người dùng (UI), giống ứng dụng thường thấy Windows Trong chương xây dựng ứng dụng nâng cao Windows hay Web ta dùng các giao diện đồ họa Cịn để tìm hiểu ngơn ngữ C# tuý cách tốt ta viết ứng dụng console

Trong hai ứng dụng đơn giản ta dùng phương thức WriteLine() lớp Console Phương thức xuất hình dịng lệnh hay hình DOS chuỗi tham số đưa vào, cụ thể chuỗi “Hello World”

 Từ khóa using: Để làm cho chương trình gọn hơn, khơng cần phải viết

namespace(ta tìm hiểu khai niệm sau) cho đối tượng, C# cung cấp từ khóa using, sau từ khóa namespace hay subnamespace với mô tả đầy đủ cấu trúc phân cấp Ta dùng dịng lệnh :

using System;

Ở đầu chương trình chương trình có dùng đối tượng Console khơng cần phải viết đầy đủ : System.Console mà cần viết Console thơi

Ví dụ: Dùng khóa using

-using System;

class ChaoMung {

static void Main() {

//Xuat man hinh chuoi thong bao Console.WriteLine(“Hello World”); }

}

(38)

Hello World

-Lưu ý phải đặt câu using System trước định nghĩa lớp ChaoMung

Mặc dù định sử dụng namespace System, không giống ngôn ngữ khác, định sử dụng đối tượng System.Console

Ví dụ : Khơng hợp lệ C#.

-using System.Console;

class ChaoMung {

static void Main() {

//Xuat man hinh chuoi thong bao WriteLine(“Hello World”);

} }

-Đoạn chương trình biên dịch thơng báo lỗi sau:

error CS0138: A using namespace directive can only be applied to namespace; ‘System.Console’ is a class not a namespace.

Cách biểu diễn namespace làm giảm nhiều thao tác gõ bàn phím, khơng đem lại lợi ích làm xáo trộn namespace có tên khơng khác Giải pháp chung sử dụng từ khóa using với namespace xây dựng sẵn, namespace tạo ra, namespace nắm sưu liệu Cịn namespace hãng thứ ba cung cấp khơng nên dùng

từ khóa using

 Dấu chấm phẩy(;) : Trong C# quy ước kết thúc câu lệnh ta phải dùng dấu chấm phẩy( ;)

(39)

- Tìm hiểu so sánh mơi trường phát triển ứng dụng Net với môi trường phát triển ứng dụng khác

- Cấu hình phần cứng, phần mềm để cài đặt phần mềm xây dựng phát triển ứng dụng .Net: Visual Stadio 2005, Visual Stadio 2007, Visual Stadio 2008, Sharp Develop 2.1,v.v…

- Tìm hiểu thành phần phần mềm

- Cách phát triển đóng gói dự án C# phần mềm Visual Stadio 2005, Visual Stadio 2007, Visual Stadio 2008 Sharp Develop 2.1

Bài 4: Các thành phần chương trình 4.1 Các phần tử ngơn ngữ lập trình 4.1.1 Bảng chữ cái

Mỗi ngơn ngữ lập trình xây dựng từ ký tự Các ký tự nhóm lại theo nhiều cách khác để lập lên từ Đến lượt từ liên kết theo quy tắc để tạo thành câu lệnh Một chương trình bao gồm nhiều câu lệnh diễn đạt thuật toán để giải tốn

Ngơn ngữ C# xây dựng ký tự sau: Các chữ hoa: A B C Z

Các chữ thường: a b c z Các chữ số:

Các kí hiệu tốn học: + - * / = < > Các dấu ngoặc: [ ] { } ( )

Các ký hiệu đặc biệt khác: , ; : / ? @ # $ % ^ & ‘ “

Các dấu ngăn cách khơng nhìn thấy dấu cách, dấu nhảy cách tab, dấu xuống dòng

Dấu gạch nối dưới: _ 4.1.2 Từ khoá

- Là từ có ý nghĩa hồn tồn xác định chương trình: Ví dụ: void struct class while

- Khơng dùng từ khoá để đặt tên cho hằng, biến, mảng, hàm - Từ khoá phải viết chữ thường

(40)

Ví dụ từ khố viết sai: Struct

4.1.3 Tên (định danh)

Tên gọi thành phần chương trình gọi định danh(Identifier) Định danh sử dụng để xác định thành phần biến , kiểu, phương thức(method) hay gọi hàm, đối tượng, lớp

Trong C# định danh dãy ký tự gồm chữ cái, chữ số số ký hiệu như: ký tự gạch nối câu ’_’ , ký hiệu tiền tệ $ không bắt đầu chữ số

Chú ý: C# phân biệt chữ hoa chữ thường, ví dụ HUE hue hai định danh khác Độ dài(số ký tự) định danh C# mặt lý thuyết khơng giới hạn

Ví dụ:

- Các định danh viết đúng: bai_1, hue, - Các định danh viết sai: 24gio bai tap,

Để trở thành nhà lập trình chuyên nghiệp, nên sử dụng cách đặt tên theo chuẩn định để dễ phân biệt loại khác thành phần sử dụng Chúng ta qui ước cách đặt tên thống sau:

+ Định danh cho lớp: chữ đầu từ định danh viết hoa, ví dụ MyClass, HocSinh

+ Định danh cho biến, phương thức, đối tượng: chữ đầu định danh viết hoa trừ từ đầu tiên, ví dụ bienTong, tinhTong,

+ Định danh cho ta viết hoa, ví dụ: MAX, PI 4.2 Các kiểu liệu bản

C# ngơn ngữ lập trình mạnh kiểu liệu, ngôn ngữ mạnh kiểu liệu phải khai báo kiểu đối tượng tạo (kiểu số nguyên, số thực, kiểu chuỗi, kiểu điều khiển ) trình biên dịch giúp cho người lập trình khơng bị lỗi cho phép loại kiểu liệu gán cho kiểu liệu khác Kiểu liệu đối tượng tín hiệu để trình biên dịch nhận biết kích thước đối tượng (kiểu int có kích thước byte) khả (như đối tượng button vẽ, phản ứng nhấn, )

(41)

C# phân tập hợp kiểu liệu thành hai loại: Kiểu liệu giá trị (value) kiểu liệu tham chiếu (reference) Việc phân chi khác lưu kiểu liệu giá trị kiểu liệu tham chiếu nhớ Đối với kiểu liệu giá trị lưu giữ kích thước thật nhớ cấp phát stack Trong địa kiểu liệu tham chiếu lưu stack đối tượng thật lưu nhớ heap

Nếu có đối tượng có kích thước lớn việc lưu giữ chúng nhớ heap có ích, chương trình bày lợi ích bất lợi làm việc với kiểu liệu tham chiếu, chương tập trung kiểu kiểu hay kiểu xây dựng sẵn

Ghi chú: Tất kiểu liệu xây dựng sẵn kiểu liệu giá trị ngoại trừ đối tượng chuỗi Và tất kiểu người dùng định nghĩa ngoại trừ kiểu cấu trúc kiểu liệu tham chiếu

Ngoài C# hỗ trợ kiểu trỏ C++, sử dụng, làm việc với đoạn mã lệnh không quản lý (unmanaged code) Mã lệnh không quản lý lệnh viết bên MS.NET, đối tượng COM

Kiểu liệu xây dựng sẵn: Ngôn ngữ C# đưa kiểu liệu xây dựng sẵn hữu dụng, phù hợp với ngôn ngữ lập trình đại, kiểu liệu ánh xạ đến kiểu liệu hỗ trợ hệ thống xác nhận ngôn ngữ chung (Common Language Specification: CLS) MS.NET Việc ánh xạ kiểu liệu nguyên thuỷ C# đến kiểu liệu NET đảm bảo đối tượng tạo C# sử dụng đồng thời với đối tượng tạo ngôn ngữ khác biên dịch NET, VB.NET Mỗi kiểu liệu có xác nhận kích thước không thay đổi, không giống

C++, int C# ln có kích thước byte ánh xạ từ kiểu Int32 NET Sau tìm hiểu chi tiết sơ kiểu liệu dựng sẵn có C#:

4.2.1 Kiểu nguyên

Dùng để lưu trữ giá trị nguyên giới hạn cho phép tuỳ thuộc vào kiểu liệu nguyên cụ thể Trong ngôn ngữ C# có số kiểu liệu nguyên sau:

Kiểu C# Số byte Kiểu NET Mô tả

Byte Byte Số nguyên dương không dấu từ 0-255

Char Char Ký tự Unicode

sbyte Sbyte Số nguyên có dấu ( từ -128 đến 127) short Int16 Số nguyên có dấu giá trị từ -32768 đến

32767

ushort Uint16 Số nguyên không dấu – 65.535

(42)

2.147.483.647

Uint Uint32 Số nguyên không dấu – 4.294.967.295

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

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

0xffffffffffffffff

Thông thường để chọn kiểu liệu nguyên để sử dụng short, int hay long thường dựa vào độ lớn giá trị muốn sử dụng Ví dụ, biến ushort lưu giữ giá trị từ đến 65.535, biến ulong lưu giữ giá trị từ đến 4.294.967.295, tùy vào miền giá trị phạm vi sử dụng biến mà chọn kiểu liệu thích hợp Kiểu liệu int thường sử dụng nhiều lập trình với kích thước byte đủ để lưu giá trị nguyên cần thiết

Kiểu số nguyên có dấu thường lựa chọn sử dụng nhiều kiểu số trừ có lý đáng để sử dụng kiểu liệu không dấu

Cách tốt sử dụng biến không dấu giá trị biến luôn dương, biến thường thể thuộc tính có miền giá trị dương Ví dụ cần khai báo biến lưu giữ tuổi người ta dùng kiểu byte (số nguyên từ 0-255) tuổi người khơng thể âm

4.2.2 Kiểu thực

Dùng để lưu trữ giá trị thực giới hạn cho phép tuỳ thuộc vào kiểu liệu thực cụ thể Trong ngôn ngữ C# có số kiểu liệu thực sau:

Kiểu C# Số byte Kiểu NET Mô tả

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

Double Double Kiểu dấu chấm động có độ 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

(43)

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

float soFloat = 24f; 4.2.3 Kiểu ký tự

Kiểu ký tự thể kiểu char, biểu diễn cho ký tự mã Unicode gồm chữ cái, chữ số ký tự đặc biệt Kiểu char có 65536(216) ký tự tập mã Unicode 16 bit Mã 128 ký tụ đầu tập Unicode hoàn toàn trùng với mã 128 ký tự tập mã ASCII 7-bit mã 256 ký tự ban đầu hoàn toàn tương ứng với 256 ký tự tập mã ISO Latin-1 8-bit

Kiểu C# Số byte Kiểu NET Mô tả

Char Char Ký tự Unicode

4.2.4 Kiểu logic

Dùng để biểu diễn giá trị logic chứa hai giá trị true false

Kiểu C# Số byte Kiểu NET Mô tả

Bool Boolean Giá trị logic true/ false

4.2.5 Kiểu xâu

Kiểu liệu chuỗi thân thiện với người lập trình ngơn ngữ lập trình nào, kiểu liệu chuỗi lưu giữ mảng ký tự Để khai báo chuỗi sử dụng từ khoá string tương tự cách tạo thể đối tượng nào:

string chuoi;

Một chuỗi tạo cách đặt chuỗi dấu nháy đôi: “Xin chao”

Đây cách chung để khởi tạo chuỗi ký tự với giá trị hằng: string chuoi = “Xin chao”;

Kiểu chuỗi đề cập sâu phần sau

4.3 Biến, cách khai báo 4.3.1 Biến

(44)

khác cất giữ giá trị khác Trước sử dụng biến phải khai báo Quy tắc khai báo:

( Khai báo biến khơng có giá trị khởi đầu Kiểu_dữ_liệu Tên_biến ;

Có thể khai báo nhiều biến kiểu hàng, tên biến phân cách dấu phẩy

Ví dụ:

int a,b; /*biến có kiểu nguyên*/ float f; /*biến thực*/

char ch; /*biến ký tự*/ ( Khai báo biến có giá trị khởi đầu

Kiểu_dữ_liệu Tên_biến=giá trị ; Ví dụ:

int a =5; float b=6;

char ch=’A’; char ch=’\u0041’

Chú ý: Trong C# trước muốn sử dụng biến ta phải khởi gán cho giá trị cụ thể, khơng chương trình dịch báo lỗi

Ví dụ:

-using System;

class VD {

static void Main() {

int a, b=1; float t; t = a + b; a = 2;

(45)

}

-Chương trình bị báo lỗi biến a chưa khởi tạo giá trị trước sử dụng Để chương trình chạy ta sửa lại sau:

-using System;

class VD {

static void Main() {

int a=2, b=1; float t; t = a + b;

Console.WriteLine("Tong {0}+{1}={2}", a, b,t); }

}

-4.3.2 Hằng

Hằng biến giá trị không thay đổi Biến công cụ mạnh, nhiên làm việc với giá trị định nghĩa không thay đổi, ta phải đảm bảo giá trị khơng thay đổi suốt chương trình Ví dụ, lập chương trình thí nghiệm hóa học liên quan đến nhiệt độ sôi, hay nhiệt độ đông nước, chương trình cần khai báo hai biến DoSoi DoDong, không cho phép giá trị hai biến 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

a/ Hằng số nguyên

- Hệ thập phân bình thường VD: 545

- Hệ số 16 (Hecxa)

Bắt đầu 0x, 0X Ví dụ: 0xAB = 16310 b/ Hằng số thực

(46)

- Dạng thập phân gồm: Phần nguyên, dấu chấm thập phân, phần thạp phân

Ví dụ: 34.2 -344.122

- Dạng khoa học(dạng mũ) gồm: Phần định trị phần mũ Phần định trị số nguyên hay số thực dạng thập phân, phần mũ bắt đầu E e theo sau số nguyên

Ví dụ: 1234.54E-122 c/ Hằng ký tự

Là ký hiệu bảng mã Unicode đặt hai dấu nháy đơn Giá trị kí tự mã Unicode kí hiệu

Ví dụ: Hằng ‘A’ có giá trị 65

Chú ý: Hằng ký tự biểu thị mã ký tự bảng mã Unicode Do ký tự tham gia vào phép tốn

Ví dụ:

‘A’+10 có giá trị (65+10=75)

Hằng ký tự cịn viết theo cách: ‘\uc1c2c3c4’

c1c2c3c4 số hệ 16 mà giá trị mã Unicode ký tự cần biểu diễn Ví dụ: ‘A’ hay ‘\u0041’

Một số ký tự đặc biệt:

Viết Diễn giải

\’ Dấu nháy đơn

\” Dấu nháy kép

\\ Dấu gạch chéo ngược

\n Xuống dòng

\0 Ký tự Null

\t Nhảy cách ngang, ký tự tab

\b Xoá trái

\r Về đầu dòng

\f Sang trang

d/ Hằng xâu ký tự

Là dãy ký tự đặt hay dấu nháy “ ” g) Khai báo hằng

(47)

Một phải khởi tạo khai báo, khởi tạo lần suốt chương trình khơng thay đổi

Ví dụ: const int DOSOI = 100;

Trong khai báo trên, 100 số DOSOI tên có kiểu nguyên Ví dụ: minh họa việc sử dụng biểu tượng

-class MinhHoa

{

static void Main() {

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 ); }

}

-Kết quả:

Do dong cua nuoc Do soi cua nuoc 100

-4.4 Các phép toán 4.4.1 Phép toán số học

Phép tốn ý nghĩa Ví dụ

- Đổi dấu số thực nguyên -12, -a + Phép cộng số thực nguyên 2+4=6

- Phép trừ 2-3=-1

* Phép nhân 4*2=8

(48)

% Phép lấy phần dư 6/2=0

11.5%2.5=1.5

Chú ý:

- Nếu phép chia hai toán hạng nguyên phép chia cho kết phần ngun thương hai tốn hạng đó, ví dụ: 5/3=1

- Nếu phép chia hai toán hạng nguyên với số chia phép chia sinh lỗi, ví dụ 5/0 phát sinh lỗi

- Nếu hai tốn hạng kiểu thực lúc kết phép chia cho ta giá trị đúng, ví dụ 5/2.0=2.5

- Nếu hai toán hạng kiểu thực với số chĩa bằnd kết phép chia infinity(dương vơ cùng) –infinity(âm vơ cùng)

- Phép tốn % trả phần dư phép chia 4.4.2 Phép toán quan hệ

Những toán tử quan hệ dùng để so sánh hai giá trị, sau trả kết giá trị logic kiểu bool (true hay false) Ví dụ tốn tử so sánh lớn (>) trả giá trị true giá trị bên trái toán tử lớn giá trị bên phải toán tử Do > trả giá trị true, > trả giá trị false

Các tốn tử quan hệ ngơn ngữ C# trình bày bảng bên

Phép toán ý nghĩa Ví dụ Kết quả

> So sánh lớn 1>2 false

>= So sánh lớn 2>=2 true

< So sánh nhỏ 3<3 false

<= So sánh nhỏ 4<2 false

== So sánh 4==5 false

!= So sánh không 2!=7 true

4.4.3 Phép tốn logic

Phép tốn logic ý nghĩa Ví dụ Kết quả

(49)

&&

Liên kết hai biểu thức logic Phép (and) Giá trị tốn hạng có giá trị

(2>1)&&(5=2) false

||

Liên kết hai biểu thức logic Phép (or) Giá trị biểu thức

khi hai toán hạng (4>3)||(1>8) true

Bảng giá trị phép toán logic

X Y X && Y X || Y ! X

True true true true false

True false false true false

false true false true true

false false false false true

4.4.4 Phép tốn tăng giảm

Trong ngơn ngữ lập trình C# đưa hai phép tốn ngơi để tăng giảm biến (nguyên thực) Toán tử tăng ++ thêm vào tốn hạng nó, tốn tử giảm – trừ

Dấu phép toán ++ đứng trước đứng sau tốn hạng Như ta viết: ++n, n++, n,

n Sự khác ++n n++ chỗ: Trong phép tốn n++ n tăng sau giá trị sử dụng, cịn ++n giá trị n tăng trước giá trị sử dụng Tương tự –n

n Ví dụ: giả sử trước phép tính int i=3, j=15;

Phép tốn Tương đương Kết quả

i=++j; tăng trước j=j+1; i=j; i=16 j=16

i=j++; tăng sau i=j; j=j+1; i=15 j=16

i++; i=i+1; i=4

j = ++i + 5; i=i+1; j=i+5; i=4 j=9

j = i++ +5; j=i+5; i=i+1; i=4 j=8

4.4.5 Thứ tự ưu tiên phép toán

(50)

var1 = 5+7*3;

Biểu thức có ba phép toán để thực bao gồm (=, +,*) Ta thử xét phép toán theo thứ tự từ trái sang phải, gán giá trị cho biến var1, sau cộng vào 12 cuối nhân với 3, kết trả 36, điều thật có vấn đề, khơng với mục đích yêu cầu Do việc xây dựng trình tự xử lý tốn tử cần thiết

Các luật độ ưu tiên xử lý bảo trình biên dịch biết toán tử thực trước biểu thức.Tương tự phép tốn đại số phép nhân có độ ưu tiên thực trước phép toán cộng, 5+7*3 cho kết 26 kết 36 Và hai phép toán cộng phép tốn nhân điều có độ ưu tiên cao phép gán Như trình biên dịch thực phép tốn sau thực phép gán bước cuối Kết câu lệnh biến var1 nhận giá trị 26

Trong ngôn ngữ C#, dấu ngoặc sử dụng để thay đổi thứ tự xử lý, điều giống tính tốn đại số Khi muốn kết 36 cho biến var1 viết:

var1 = (5+7) * 3;

(51)

Các phép tốn liệt kê loại có thứ tự theo mục thứ thự bảng: thứ tự trái tức độ ưu tiên phép toán từ bên trái sang, thứ tự phải phép tốn có độ ưu tiên từ bên phải qua trái Các tốn tử khác loại có độ ưu tiên từ xuống dưới, toán tử loại có độ ưu tiên cao phép tốn gán có độ ưu tiên thấp toán tử

4.5 Biểu thức

4.5.1 Biểu thức số học

Biểu thức số hcọ kết hợp tốn hạng với toán tử số học cho ta kết số(số thực số nguyên)

Ví dụ: (3+5)*6/4-2.4 4.5.2 Biểu thức logic

Biểu thức logic kết hợp tốn hạng với toán tử(toán tử số học, toán tử quan hệ, toán tử logic) kết cho ta giá trị logic Biểu thức logic ược dùng làm điều kiện cấu trúc điều khiển(if, while, ) số trường hợp khác

Ví dụ: (1>=2)&&(5==4+2) 4.5.3 Biểu thức điều kiện

Hầu hết toán tử địi hỏi có tốn hạng tốn tử (++, ) hay hai toán hạng (+,-,*,/, ) Tuy nhiên, C# cịn cung cấp thêm tốn tử có ba tốn hạng (?:) Tốn tử có cú pháp sử dụng sau:

<Biểu thức điều kiện > ? <Biểu thức thứ 1> : <Biểu thức thứ 2>

Toán tử xác định giá trị biểu thức điều kiện, biểu thức điều kiện phải trả giá trị kiểu bool Khi điều kiện <biểu thức thứ 1> thực hiện, cịn ngược lại điều kiện sai <biểu thức thứ 2> thực Có thể diễn giải theo ngơn ngữ tự nhiên tốn tử có ý nghĩa : “Nếu điều kiện làm cơng việc thứ nhất, cịn ngược lại điều kiện sai làm cơng việc thứ hai” Cách sử dụng tốn tử ba ngơi được

minh họa ví dụ sau

Ví dụ: Sử dụng tốn tử bao ngôi.

-using System;

class Tester {

(52)

int value1; int value2; int maxValue; value1 = 10; value2 = 20;

maxValue = value1 > value2 ? value1 : value2;

Console.WriteLine(“Gia tri thu nhat {0}, gia tri thu hai {1}, gia tri lon nhat {2}”, value1, value2, maxValue);

} }

Kết quả:

Gia tri thu nhat 10, gia tri thu hai 20, gia tri lon nhat 20

-Trong ví dụ minh họa tốn tử ba sử dụng để kiểm tra xem giá trị value1 có lớn giá trị value2, trả giá trị value1, tức gán giá trị value1 cho biến maxValue, ngược lại gán giá trị value2 cho biến maxValue

4.5.4 Biểu thức gán

Trong C# dùng dấu “=” làm dấu phép gán Biểu thức gán thể dạng sau:

Biến = Biểu_thức Biến op = Biểu_thức

Cách viết tương đương Biến = (biến) op (Biểu_thức) op tốn tử Giá trị Biểu_thức gán cho biến sau câu lệnh

Ví dụ: x + = y tương đương với x = x+y

Nếu ta thêm dấu ; vào sau biểu thức gán thu câu lệnh gán

Biểu thức gán sử dụng phép toán câu lệnh biểu thức thơng thường Chẳng hạn viết: a=b=5; điều có nghĩa gán giá trị biểu thức b=5 cho biến a Kết b=5 a=5 Tương tự sau câu lệnh: x = (a=5) * (b=10); gán cho a, 10 cho b sau gán tiếp 50 cho x

(53)

Những đối tượng kiểu liệu chuyển sang đối tượng kiểu liệu khác thông qua chế chuyển đổi tường minh hay ngầm định Chuyển đổi nhầm định thực cách tự động, trình biên dịch thực cơng việc Cịn chuyển đổi tường minh diễn gán ép giá trị cho kiểu liệu khác

Việc chuyển đổi giá trị ngầm định thực cách tự động đảm bảo không thông tin tuân theo quy tắc sau:

Ví dụ, gán ngầm định số kiểu short (2 byte) vào số kiểu int (4 byte) cách ngầm định Sau gán hồn tồn khơng liệu giá trị short thuộc int:

short x = 10;

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

Tuy nhiên, thực chuyển đổi ngược lại, chắn bị thông tin Nếu giá trị số ngun lớn 32.767 bị cắt chuyển đổi Trình biên dịch khơng thực 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 phải dùng lệnh gán tường minh, đoạn mã viết lại short x;

int y = 100;

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

Trong biểu thức mà có nhiều kiểu liệu khác nhau, trước tính tốn máy chuyển từ kiểu thâp lên kiểu cao theo sơ đồ

Ví dụ:

short x=1,y;

y=4-x; /*Khi biên dịch bị lỗi, 4-x cho kiểu int khơng thể gán cho biến kiểu short*/

Nếu ta viết

byte short

char

(54)

y=(short)(4-y);/* Khi biên dịch khơng bị lỗi, 4-x cho ta kiểu int sau chuyển thành kiểu short*/

Vì biểu thức ép kiểu tường minh là: (kiểu liệu)Biểu thức

Chú ý: Khi ép kiểu thân biểu thức không bị thay đối kiểu mà có giá trị biểu thức ép kiểu thay đổi

Bài 5: Một số hàm chức thường dùng chương trình 5.1 Một số hàm thường dùng

Các hàm toán học: Để sử dụng hàm tốn học trước hàm ta phải đưa thêm Math trước tên hàm cần sử dụng:

Hàm Chức năng

Abs(x) Trả giá trị tuyệt đối số thực, nguyên,

Cos(x) Trả giá trị Cos(x) Sin(x) Trả giá trị Sin(x) Exp(x) Trả giá trị ex Log(x) Trả giá trị Ln(x) Log10(x) Trả giá trị log10(x) Pow(x,y) Trả giá trị xy

Round(x,n) Làm tròn số thực x với độ xác n chữ số phập phân

Sqrt(x) Trả bậc hai x

Floor(x) Trả gía trị lớn hay giá trị đưa

Các hàm chuyển đổi: Để sử dụng hàm chuyển đổi trước hàm ta phải đưa thêm Convert trước tên hàm cần sử dụng:

Hàm Chức năng

ToDouble(x) Chuyển đối tượng x thành kiểu thực double ToInt32(x) Chuyển đối tươợng x thành kiểu int

(55)

Trên số hàm thường dùng nhất, ngồi cịn có nhiều hàm hữu dụng khác địi hỏi bạn phải tìm hiểu

5.2 Nhập/xuất liệu (bàn phím, hình) 5.2.1 Đưa liệu hình

Để đưa liệu hình dùng phương thức Write( ) WriteLine( ) lớp Console

- Ta đưa hình số nguyên, thực, ký tự, xâu ký tự, logic trực tiếp sau: int x=5;

Console.WriteLine(4); //Xuất số nguyên hình Console.WriteLine(4.6); //Xuất số thực hình Console.WriteLine(4.6+x);//Xuất biểu thức có gia trị thực hình

- Ta đưa hình kết hợp nhiều kiểu liệu khác nhau( nguyên, thực, ký tự, xâu ký, logic) theo cách khác thơng qua ví dụ sau:

hoặc ta viết sau:

ở cách thứ ta phát biểu cách tổng quát sau Console.Write(mục1+ mục2+ +mụcn);

Console.WriteLine(mục1+ mục2+ +mụcn);

Trong : mụci(i=1 n) hằng, biến, biểu thức, lời gọi hàm

ở cách thứ hai ta phát biểu cách tổng quát sau: Console.Write(dòng diều khiển[, danh sách đối]);

Console.WriteLine(dịng diều khiển[, danh sách đối]); Trong đó:

int a=4,b=5,c=2;

int max=(a>b?a:b)>c?(a>b?a:b):c;

Console.WriteLine(“Max(“ + b + “,” + a + “,” + c + “)=” + max);

int a=4,b=5,c=2;

int max=(a>b?a:b)>c?(a>b?a:b):c;

(56)

dòng diều khiển: xâu ký tự đặt hai dấu “ ”, bao gồm loại đối tượng sau: Các ký tự thông thường, ký tự đặc biệt đặc tả có dạng: {i,-j:dt } đặt vị trí xâu với: i thứ tự đối mà ta cần đưa giá trị chúng vị trí đặt đặc tả(các đối có thứ tự không), j độ rộng dành cho đối cần đưa ra(nếu j mà lớn độ dài liệu cần đưa giá trị phải, muốn trái ta thêm dấu trừ phía trước, cịn j mà nhỏ độ dài thực tế liệu cần đưa khơng có thay đổi), d định dạng liệu đưa ra, ví dụ định dạng C định dạng theo kiểu tiền tệ, N định dạng kiểu số, G định dạng chuẩn , t số chữ số thập phân(chỉ áp dụng cho số thực)

danh sách đối: đối hằng, biến, biểu thức đặt cách dấu phẩy Sự khác Write( ) WriteLine( ) là:

Write( ) sau viết liệu hình trỏ đặt cuối dịng

WriteLine( ) sau viết liệu hình trỏ đặt đầu dịng

Xét vị dụ1:

-using System;

class ViDu{

static void Main(){

double a, b, c,max;

a = 4.5643; b = 3.234; c = 2.724; max=(a>b?a:b)>c?(a>b?a:b):c;

Console.Write("\n\n\t\tCHUONG TRINH TIM MAX CUA BA SO\n");

Console.WriteLine("\tMax({0,-6:N2},{1,-6:N2},{2,-6:N2})={3,6:N2}", a, b, c, max); Console.ReadKey();

} }

-Xét vị dụ2:

-using System;

class ViDu{

static void Main(){

double a, b, c,max;

(57)

max=(a>b?a:b)>c?(a>b?a:b):c;

Console.Write("\n\n\t\tCHUONG TRINH TIM MAX CUA BA SO\n"); Console.WriteLine("\tMax( “ + a + ”,” + b + “,” + c +”)=”+ max); Console.ReadKey();

} }

5.2.2 Nhập liệu vào từ bàn phím

Để nhập liệu vào từ bàn phím dùng phương thức ReadLine có lớp Console sau:

Kiểudữliệu Tênbiến;

Tênbiến=Kiểudữliệu.Parse(Console.ReadLine());

Thông thường qua trình nhập liệu thương kết hợp phương thức Write với ReadLine lớp Console

Xét ví dụ:

-using System;

class ViDu{

static void Main(){ double a, b, c,max;

Console.Write("\n\n\t\tCHUONG TRINH TIM MAX CUA BA SO\n"); Console.Write("Nhap a="); a = double.Parse(Console.ReadLine()); Console.Write("Nhap b="); b = double.Parse(Console.ReadLine()); Console.Write("Nhap c="); c = double.Parse(Console.ReadLine()); max=(a>b?a:b)>c?(a>b?a:b):c;

Console.WriteLine("\n\tMax({0,-6:N2},{1,-6:N2},{2,-6:N2})={3,6:N2}", a, b, c, max); Console.ReadKey();

} }

(58)

-Bài 6: -Bài thực hành thành phần nhập/xuất C# Bài 7: Cấu trúc rẽ nhánh

7.1 Câu lệnh đơn, khối lệnh a) Khái niệm câu lệnh

Một câu lệnh (statement) xác định công việc mà chương trình phải thực để xử lý liệu mô tả khai báo Các câu lệnh ngăn cách với dấu chấm phẩy (;) b) Phân loại

Có hai loại lệnh: lệnh đơn lệnh có cấu trúc

Lệnh đơn lệnh không chứa lệnh khác Các lệnh đơn gồm: lệnh gán, câu lệnh nhập xuất liệu…

Lệnh có cấu trúc lệnh chứa lệnh khác Lệnh có cấu trúc bao gồm: cấu trúc điều kiện rẽ nhánh, cấu trúc điều kiện lựa chọn, cấu trúc lặp cấu trúc lệnh hợp thành Lệnh hợp thành (khối lệnh) nhóm bao gồm nhiều khai báo biến lệnh gom vào cặp dấu {}

c) Khối lệnh

Một dãy câu lệnh bao dấu { } gọi khối lệnh

Ví dụ:

{

a=2; b=3;

Console.Write(“a={0}\nb={1}},a,b); }

C# xem khối lệnh câu lệnh riêng lẻ Nói cách khác, chỗ viết câu lệnh có quyền đặt khối lệnh

Khai báo đầu khối lệnh :

Trong C# việc khai báo biến mảng chỗ chương trình miễn trước sử dụng phải khai báo chúng Nhưng thói quen lập trình tốt nên khai báo chúng đầu khôi lệnh, đầu hàm

{

(59)

x=5.5; y=a*x; z=b*x;

}

Sự lồng khối lệnh phạm vi hoạt động biến mảng:

Bên khối lệnh lại viết lồng khối lệnh khác Sự lồng theo cách không hạn chế

Khi máy bắt đầu làm việc với khối lệnh biến mảng khai báo bên hình thành cấp phát nhớ Các biến tồn thời gian máy làm việc bên khối lệnh chúng biến sau máy khỏi khối lệnh Vậy :

Giá trị biến hay mảng khai báo bên khối lệnh đưa sử dụng chỗ bên khối lệnh

Ở chỗ bên ngồi khối lệnh ta can thiệp đến biến mảng khai báo bên khối lệnh

Ví dụ :

Xét đoạn chương trình sau : {

double a=5,b=2; {

double c=4; b=c+b;

Console.Write(“\na ={0,3 :N2}\t b={1,3:N2}”,a,b} }

Console.Write("\n a ngoai ={0,3:N2\t b={1,3:N2}",a,b); Console.Write("\n c{0,3:N2}",c);// Câu lệnh sai }

7.2 Các cấu trúc rẽ nhánh 7.2.1 Cấu trúc rẽ nhánh if

a/ Cấu trúc rẽ nhánh if dạng khuyến - Cú pháp câu lệnh

if (btđk)

công_việc; Trong đó:

(60)

- btđk biểu thức cho giá trị logic

- Công_việc lệnh đơn, khối lệnh hay cấu trúc điều khiển

(61)

- Sơ đồ cú pháp

- Nguyên tắc hoạt động: Đầu tiên máy tính tốn giá trị btđk Nếu btđk có giá trị True máy tiến hành thực Cơng_việc sau tiến hành thực câu lệnh sau câu lệnh if Nếu btđk có giá trị False máy bỏ qua việc thực Công_việc câu lệnh if mà tiến hành thực câu lệnh sau câu lệnh if

c/ Cấu trúc rẽ nhánh if dạng đầy đủ

- Cú pháp câu lệnh

if (btđk)

công_việc1; else

cơng_việc2; Trong đó:

- if, else từ khoá

- btđk biểu thức cho giá trị logic

- Cơng_việc1,Cơng_việc2 lệnh đơn, cấu trúc điều khiển hay khối lệnh

- Sơ đồ thực hiện

btđk

True Công Việc;

False

btđk

True Công Việc

False

(62)

- Ngun tắc hoạt động: Đầu tiên máy tính tốn giá trị btđk Nếu btđk có giá trị True máy tiến hành thực Cơng_việc1 sau tiến hành thực câu lệnh sau câu lệnh if Nếu btđk có giá trị False máy tiến hành thực cơng_việc2 sau tiến hành thực câu lệnh sau câu lệnh if

Ví dụ: Lập chương trình giải phương trình bậc hai ax2+bx+c=0

-using System;

class PTB2 {

static void Main() {

float a, b, c, delta;

Console.WriteLine("Ban hay nhap vao ba so");

Console.Write("a="); a = float.Parse(Console.ReadLine()); Console.Write("b="); b = float.Parse(Console.ReadLine()); Console.Write("c="); c = float.Parse(Console.ReadLine()); if (a == 0)

{

Console.Write("Day la phuong trinh bac nhat Ax+C=0\n"); if (b != 0)

Console.WriteLine("Phuong trinh co nghien nhat x={0}", -b / c); else

if (c == 0)

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

Console.WriteLine("phuong trinh vo nghiem"); }

else {

(63)

if (delta < 0)

Console.Write(" Phuong trinh vo nghiem truong so thuc"); if (delta == 0)

Console.Write("Phuong trinh co nghiem kep x1=x2={0,8:N2", -b / (2 * a));

if (delta > 0) {

Console.WriteLine("Phuong trinh co hai nghiem phan biet:"); Console.WriteLine("x1={0,8:N2}\nx2={1,8:N2}",

(-b - Math.Sqrt(delta)) / (2 * a), (-b + Math.Sqrt(delta)) / (2 * a)); }

}

Console.ReadKey(); }

}

7.2.2 CÊu tróc rÏ nh¸nh switch

- Cú pháp câu lệnh

switch ( bieu_thuc)

{ case e1:Khối_lệnh_1;[break;] case e2: Khối_lệnh_2;[break;]

case en: Khối_lệnh_n;[break;] [default: Khối_lệnh_n+1; break;] }

Trong đó: + switch, case, default từ khố

+ bieu_thuc: biểu thức cho giá trị nguyên xâu + ei:là giá trị nguyên mà biểu thức nhận + Những phần đặt hai dấu [ ] có khơng

(64)

* Khi giá trị ei máy nhảy tới khối lệnh có nhãn case ei thực Khối_lệnh_i Nếu Khối_lệnh_i rỗng ta đặt break sau Khối_lệnh_i không, với trường hợp khơng có break máy tiến hành nhảy xuống thực Khối_lệnh_(i+1) Nếu Khối_lệnh_i khác rỗng(tức có cơng việc phải thực hiện) sau Khối_lệnh_i ta phải đặt câu lệnh break Khi máy gặp câu lệnh break máy thoát khỏi cấu trúc switch thực câu lệnh sau cấu trúc lệnh

* Khi giá trị bieu_thuc khác tất giá trị ei cách làm việc máy lại phụ thuộc vào có mặt hay khơng có mặt default Khi có default máy nhảy tới câu lệnh có nhãn default Khi khơng có default máy tiến hành thực câu lệnh sau cấu trúc

- Ví dụ áp dụng: Nhập vào tháng năm bất ký sau cho biết tháng có ngày:

-using System;

class Songay {

static void Main() {

int month, year,sumday;

Console.Write("Nhap thang="); month = int.Parse(Console.ReadLine()); Console.Write("Nhap year="); year = int.Parse(Console.ReadLine()); switch (month)

{

case 1: case 3: case 5: case 7: case 8: case 10:

case 12: sumday=31;break; case 4:

(65)

case 11: sumday = 30; break;

case 2: if (year % 400==0 || (year % == && year % 100 != 0)) sumday = 29;

else

sumday = 28; break;

default: sumday = 0; break; }

if (sumday > 0)

Console.Write("So cua {0}/{1} la {2} ngay", month, year, sumday); Console.ReadKey();

} }

-Bài 8: -Bài thực hành cấu trúc rẽ nhánh

Bài 9: Cấu trúc lặp while, while 9.1 Cấu trúc lặp while

- Cú pháp câu lệnh

while(btđk) Cơng_việc; Trong đó:

- while từ khoá

- btđk biểu thức cho giá trị logic

- Công_việc lệnh đơn, cấu trúc điều khiển hay khối lệnh

- Sơ đồ cú pháp

btđk True Công Việc

(66)

- Sự hoạt động của câu lệnh while tiến hành tiến hành theo bước sau:

Bước 1: Tiến hành tính tốn giá trị btđk

Bước 2: Nếu biểu thức điều kiện có giá trị False máy khỏi chu trình tiến hành thực câu lệnh sau câu lệnh while Nếu biểu thức điều kiện có giá trị True máy tiến hành thực Công_việc quay bước

- Ví dụ áp dụng

Ví dụ 1: Nhập vào hai số nguyên bất ký cho biết ước số chung lớn hai số nguyên

-using System; class VD {

static void Main() {

int a, b;

Console.Write("Nhap a="); a = int.Parse(Console.ReadLine()); Console.Write("Nhap b="); b = int.Parse(Console.ReadLine()); a=Math.Abs(a);b=Math.Abs(b);

while (a != b) {

if (a > b) a -= b; if (b > a) b -= a; }

Console.Write("Uscln la:{0}", a);// hoac Console.Write("Uscln la:{0}", b); Console.ReadKey();

} }

(67)

-9.2 Cấu trúc lặp while

- Cú pháp câu lệnh

do {

Công việc cần thực hiện; }while(btđk);

Trong đó:

- while ,do từ khoá

- btđk biểu thức cho giá trị logic

- Sơ đồ cú pháp

- Sự hoạt động câu lệnh while tiến hành theo bước sau: Bước 1: Thực Công_việc

Bước 2: Sau thực xong Cơng_việc máy tiến hành tính tốn giá trị btđk

Nếu btđk có giá trị True máy trở lại bước để tiếp tục thực vịng lặp chu trình Nếu btđk có giá trị False máy khỏi chu trình chuyển tới câu lệnh đứng sau cấu trúc while

- Ví dụ áp dụng

Ví dụ 1: Bài tốn gửi tiền tiết kiệm, giả sử ta có số tiền a gửi vào ngân hàng Hỏi sau tháng ta thu số tiền b(b>a) biết lãi xuất hàng tháng 5%

-using System;

class VD1 {

bt True

Cồn Việc

(68)

static void Main() {

double a, b; int t=0; {

Console.Write("Nhap so tien ban co:"); a = double.Parse(Console.ReadLine()); if (a < 0)

Console.Write("Ban nhap sai, hay nhap la"); } while (a < 0);

{

Console.Write("Nhap so tien ban du dinh muon co:"); b = double.Parse(Console.ReadLine());

if (b < a)

Console.Write("Ban nhap sai, hay nhap lai"); } while (b < a);

// Di tim thoi gian can thiet

{

a = a + a * 0.05; t = t + 1;

} while (a < b);

Console.Write("Ban phai mat {0} nam {1} thang", t / 12, t % 12); Console.ReadKey();

} }

-Ví dụ 2: Nhập vào số nguyên dương sau phân tích số ngun thừa số ngun tố

(69)

{

static void Main() {

int n, i;

i = 2;// la so nguyen to dau tien

Console.Write("Nhap n="); n = int.Parse(Console.ReadLine()); Console.Write("n=");

{

while (n % i == 0) {

Console.Write("{0}*", i); n = n / i;

}

if (i == 2) i = 3; else i = i + 2; } while (n != 1);

Console.Write("\b "); Console.ReadKey(); }

}

-Bài 10: Cấu trúc lặp for số lệnh điều khiển khác 10.1 Cấu trúc lặp for

- Cú pháp câu lệnh

for(bt1;btđk;bt2) Cơng_việc;

Trong đó:

- for từ khoá

- bt1,bt2 biểu gán, btđk biểu thức cho giá trị logic

(70)

- Sơ đồ cú pháp

- Sự hoạt động câu lệnh for tiến hành theo bước sau:

Bước 1: Xác định giá trị bt1 Bước 2: Xác định giá trị btđk

Bước 3: Tuỳ thuộc vào tính đúng, sai biểu thúc btđk máy tiến hành lựa chọn hai nhánh sau:

Nếu btđk có giá trị False, máy khỏi vịng lặp for chuyển tới câu lệnh sau cấu trúc for

Nếu btđk có giá trị True, máy tiến hành thực câu lệnh thân for Khi thực xong Công_việc hay gặp câu lệnh continue thân for máy chuyển sang buớc 4(khởi đầu lại)

Bước 4: Tính bt2 sau quay lại bước để bắt đầu lại vòng lặp chu trình

Chú ý:

+) Các bt1,bt2,btđk vắng mặt phải để lại dấu chấm phẩy.

+) Nếu btđk vắng mặt máy coi ln Khi muốn khỏi vịng lặp phải dùng câu lệnh return, break hay goto

+) Các bt1,bt2 gồm nhiều biểu thức cách dấu phẩy

+) Thông thường bt1 dùng để khởi gán giá trị cho biến vòng lặp, bt2 dùng để thay đổi giá trị biến điều khiển khong vòng lặp cho lúc đầu btđk cho giá trị True sau số hữu hạn bước thực btđk cho giá trị False

btđk True

bt2

False

(71)

Ví dụ 1: Nhập vào số nguyên dương n sau tính n!

-using System;

class VD6 {

static void Main() {

int n, i,s;

Console.Write("Nhap vao so nguyen n="); n = int.Parse(Console.ReadLine()); for (s = 1, i = 1; i <= n;++i)

s = s * i;

Console.Write("{0}!={1}", n, s); Console.ReadKey();

} }

-Ví dụ 2: Tính S=Sin(Sin( Sin(x)) )

-using System;

class VD6 {

static void Main() {

double x, s; int i, n;

Console.Write("Nhap vao so nguyen n="); n = int.Parse(Console.ReadLine()); Console.Write("Nhap x theo don vi do="); x = double.Parse(Console.ReadLine()); x = Math.PI * x / 180;

for (s=x,i=n; i>=1; i) s = Math.Sin(s);

(72)

} }

-Ví dụ 3: Lập chương trình tìm số có ba chữ số cho số tổng lập phương chữ số

-using System;

class VD8 {

static void Main() {

int n, a, b, c;

Console.WriteLine("Cac so thoa man yeu cau bai toan la:"); for (a = 1; a <= 9; ++a)

for (b = 0; b <= 9; ++b) for (c = 0; c <= 9; ++c)

if (a * 100 + b * 10 + c == a * a * a + b * b * b + c * c * c) Console.Write("{0}\t", a * 100 + b * 10 + c);

Console.ReadKey(); }

}

-10.2 break , continue a)Câu lênh break

Cho phép khỏi for, while, while switch Nếu có nhiều vịng lặp lồng nhau, câu lệnh break khỏi chu trình(hoặc switch bên chứa nó)

Ví dụ: Nhập vào số nguyên dương bất ký Sau kiểm tra xem số nguyên có phải số nguyên tố hay không

-using System;

(73)

{

static void Main() {

int n,i;

bool ok = true;

Console.Write("Nhap vao so nguyen n="); n = int.Parse(Console.ReadLine()); for(i=2;i<=n-1;++i)

if (n % i == 0) {

ok = false; break; }

if (ok && n != 1)

Console.Write("day la so nguyen to"); else

Console.Write("Day khong phai la so nguyen to"); Console.ReadKey();

} }

-b) Câu lệnh continue

Dùng để quay đầu vịng lặp chu trình bên chứa

Ví dụ: Nhập vào n số nguyên kiểu sau cho biết số nguyên dương lớn số số nguyên nhập vào

-using System;

class VD8 {

static void Main() {

int n,x,i,max;

(74)

Console.Write("Nhap vao n="); n = int.Parse(Console.ReadLine()); for (i = 1; i <= n; ++i)

{

Console.Write("Nhap vao so nguyen thu {0}:", i); x = int.Parse(Console.ReadLine()); if (x < 0) continue;

if (x > max) max = x; }

Console.Write("Max = {0}", max); Console.ReadKey();

} }

-Bài 11: Thảo luận cấu trúc điểu khiển khiển luồng

- Nhắc lại cú pháp điều khiển if nguyên tắc hoạt động Chỉ sử dụng cấu trúc điều khiển if cách vận dụng vào tập cụ thể

-Bài 12: -Bài thực hành cấu trúc lặp Bài 13: Chương trình con

13.1 Đặt vấn đề

Trong lập chương trình thường gặp đoạn chương trình lặp lặp lại nhiều lần chỗ khác Để tránh rườm rà, đoạn chương trình thay chương trình tương ứng cần, ta việc làm thủ tục gọi chương trình ra(với tham số tương ứng cần thiết) mà khơng phải viết lại khúc chương trình Thí dụ làm tốn lượng giác, thường xun ta cần tính sin giá trị hay biến x Như ta cần lập chương trình có tên sin tham số cần thiết x Những chương trình thơng dụng lập sẵn để “thư viên” Trong C#, chương trình chuẩn phân loại chứa lớp như: Lớp chứa hàm toán học Math, lớp chứa hàm xử lý thời gian Timer, …

(75)

nhỏ hơn(tương ứng với chương trình con) để dễ kiểm tra, gỡ rối khối sau ghép lại thành chương trình lớn

Trong ngơn ngữ lập trình C# chương trình tồn dạng hàm 13.2 Ví dụ chương trình có sử dụng chương trình con

Xây dựng chương trình tính giá trị biểu thức sau: S=x+x

2

2!+ x3

3!+ xn

n !

-using System;

class VD {

static double x; static int n; static void Nhap() {

Console.Write("Nhap x=");x=double.Parse(Console.ReadLine()); Console.Write("Nhap n=");n=int.Parse(Console.ReadLine()); }

statidc double Mu(double x,int n) {

double s; int i;

for(s=1,i=1;i<=n;++i) s=s*x;

return s; }

static int GiaiThua(int n) {

int s,i;

for(i=1,s=1;i<=n;++i) s=s*i;

(76)

static void Main() {

double s=0; int i;

Nhap();

for(i=1;i<=n;++i)

s=s+Mu(x,i)/GiaiThua(i); Console.Write("S={0:N2}",s); Console.ReadKey();

} }

-13.3 Phạm vi hoạt động biến

 Trong C# biến hàm phải khai báo bên lớp Những biến khai báo bên lớp bên hàm(trong lập trình hướng đối tượng(OOP) biến gọi dữ liệu lớp, hàm gọi phương thức, tạm gọi biến biến toàn cục một lớp) biến có phạm vi tác động tồn lớp nghĩa hàm bên lớp truy xuất Khi khai báo biến ta phải thêm từ khố static(việc tìm hiểu kỹ lập trình hướng đối tượng) cấp phát nhớ từ ta thực chương trình Ví dụ: Các biến static double x; static int n; ví dụ có phạm vi tác động toàn lớp, nghĩa tất phương thức lớp truy nhập

Chú ý: Thông thường biến dùng chung cho hàm lớp ta hay khai báo toàn cục

 Những biến khai báo bên hàm gọi biến cục bộ, phạm vi hoạt động biến bên hàm mà khai báo, biến cấp phát nhớ hàm mà có chứa biến gọi thực thực hiên xong bị giải phóng khỏi nhớ

Ví dụ: Các biến double s; int i; ví dụ

Chú ý: Những biến dùng để cài đặt thuật tốn cho hàm ta nên khai báo biến biến cục bộ, biến cục biến tồn cục mà trùng tên máy ưu tiến biến cục trước

 Các biến khai báo bên hai dấu “(“ ” )” sau tên hàm gọi đối hàm Trong C# có kiểu đối sau:

(77)

Kiểudữliệu TênHàm(Kiểudữ liệu Tênđối1,Kiểudữ liệu Tênđối1,…) Ví dụ: static double Mu(double x,int n)

 Đối kiểu tham chiếu

Kiểudữliệu TênHàm(ref Kiểudữ liệu Tênđối1,

ref Kiểudữ liệu Tênđối1,…) Ví dụ: static void HoanVi(ref int x, ref int y)  Đối kiểu tham chiếu nhận giá trị

Kiểudữliệu TênHàm(out Kiểudữ liệu Tênđối1,

out Kiểudữ liệu Tênđối1,…)

Ví dụ: static void Ham(int x,int y, out int phannguyenm, out int phandu)

Các đối hàm có nguyên tắc hoạt động giống biến cục Khi xây dựng hàm phải biết hàm cần đối, đối thuộc kiểu gì?

13.4 Cấu trúc chương trình con

Hàm đơn vị độc lập chương trình, định nghĩa hàm không định nghĩa hàm bên hàm khác Một hàm có dạng tổng quát sau:

KiểuDữLiệu TênHam(Danh sách đối) {

Các câu lệnh thâm hàm [return [Biểu thức];]

} Trong đó:

 Kiểu liệu hàm kiểu liệu sở, kiểu liệu người dùng định nghĩa Nếu hàm khơng có giá trị trả ta khai báo hàm trả kiểu void Nếu hàm trả giá trị thuộc kiểu liệu cụ thể trước kết thúc hàm ta phải gán giá trị cho hàm câu lệnh return BiểuThức Khi máy gặp cấu lệnh máy tính tốn giá trị biểu thức gán cho tên hàm thoát khỏi hàm

 Tên hàm tên người dùng định nghĩa phải tuân thủ theo nguyên tắc đặt tên đặt mang ý nghĩa phù hợp với công việc hàm

(78)

 Phần thân hàm bắt đầu dấu { kết thúc dấu } cấu lệnh thực yêu cầu hàm

13.5 Nguyên tắc hoạt động chương trình cách truyền tham số cho chương trình con

Như tìm hiểu hàm có đối khơng Nếu hàm có đối sau xây dựng xong gọi chúng thực Mỗi đối ta phải truyền cho tham số tương ứng tuỳ thuộc đối kiểu

 Nếu đối kiểu tham trị trước tiên máy cấp phát nhớ cho đối kiểu tham trị đó, sau tiến hành chép giá trị tham số thực thụ với đưa vào đối Từ ta thấy tham số thực thụ tương ứng với đối có kiểu tham trị hằng, biến, biểu thức có kiểu tương ứng Bởi đối kiểu tham trị mà hàm chứa đối gọi thực cấp phát nhớ riêng sau chép giá trị tham số thực thụ tương ứng với đưa vào sau máy tiến hành thao tác đối mà không làm ảnh hưởng tới tham số thực thụ tương ứng với chép giá trị tham số thực thụ tương ứng với tham số thực thụ tương ứng với cho giá trị Vì tham số thực thụ tương ứng với đối kiểu tham trị hàng, biến, biểu thức miễn có kiểu

Ghi chú: Theo phân tích đối nhằm mục đích cung cấp liệu đầu vào cho hàm khai báo đối đối kiểu tham trị

 Nếu đối kiểu tham chiếu đối tham chiếu tới tham số tương ứng với Nghĩa thân hàm ta thao tác đối tham chiều thực chất thao tác tham số truyền vào tương ứng với đối Do thay đổi giá trị đối tham chiếu đồng nghĩa với việc thay đổi giá trị tham số tương ứng truyền vào Điều chứng tỏ tham số tương ứng với đối kiểu tham chiểu phải biến hay phần tử mảng có kiểu tương ứng hàm chứa đối kiểu tham chiếu kết thúc tham số tương ứng với lưu lại thay đổi khỏi hàm

Trong C# có hai loại đối kiểu tham chiếu là: đối kiểu tham chiếu ref đối kiểu tham chiếu out Nếu đối kiểu tham chiếu ref tham số tương ứng với phải khởi gán giá trị trươc truyền vào tham gia tính tốn biểu thức Nếu đổi kiểu tham chiếu out tham số tương ứng với khơng cần khởi tạo giá trị ban đầu, lẽ dùng để nhận giá trị khơng tham gia tính tốn biểu thức

(79)

thì khai báo đối kiểu tham chiếu(ref) Những đối nhằm mục đích nhận giá trị khỏi hàm đối khai báo đối theo kiểu tham chiếu out

Tham số truyền vào cho đối tham chiếu phải kèm theo hai từ khoá ref out tượng ứng với đối kiểu tham chiếu ref đối kiểu tham chiếu out

Ví dụ: Nhâp vào ba số nguyên dương sau tiến hành xếp ba số nguyên theo thứ tự tăng dần

-using System;

class VD9 {

static void HoanVi(ref int x, ref int y) {

int tg = x; x = y; y = tg; }

static void Main() {

int a, b, c;

Console.Write("Nhap a="); a = int.Parse(Console.ReadLine()); Console.Write("Nhap b="); b = int.Parse(Console.ReadLine()); Console.Write("Nhap c="); c = int.Parse(Console.ReadLine()); if (a > b) HoanVi(ref a, ref b);

if (a > c) HoanVi(ref a, ref c); if (b > c) HoanVi(ref b, ref c);

Console.Write("a={0}\tb={1}\tc={2}", a, b, c); Console.ReadKey();

} }

-Ví dụ: Xây dựng chương trình giải phương trình bậc hai ax2+bx+c=0(a<>0) -using System;

(80)

static double a,b,c; static void Nhap() {

Console.Write("Nhap a=");a=double.Parse(Console.ReadLine()); Console.Write("Nhap b=");b=double.Parse(Console.ReadLine()); Console.Write("Nhap c=");c=double.Parse(Console.ReadLine()); }

static double Delta() {

return b*b-4*a*c; }

static void Giai(out double x1,out double x2,out bool ok) {

double d=Delta(); ok=true;

if(d<0)

{ok=false;x1=x2=0;} else

if(d==0)

x1=x2=-b/(2*a); else

{

x1=(-b-Math.Sqrt(d))/(2*a); x2=(-b+Math.Sqrt(d))/(2*a); }

}

static void Main() {

double x1,x2; bool ok; Nhap();

(81)

if(x1==x2)

Console.WriteLine("Phuong trinh co nghiem kep x1=x2={0}",x1); else

{

Console.WriteLine("Phuong trinh co hai nghiem phan biet"); Console.WriteLine("x1={0}\nx2={1}",x1,x2);

} else

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

} }

-13.6 Định nghĩa chồng hàm

Trong lớp định nghĩa hàm trùng tên nhau, ta gọi chồng hàm Nếu lớp hàm trùng tên để máy phân biệt hàm hàm phải khác số đối, kiểu đối giá trị trả Giả sử lớp hai hàm có tên max, có số lượng đối hai để máy phân biệt hai hàm gọi sử dụng hai hàm phải khác kiểu đối

Ví dụ: Nhập vào ba số nguyên a,b,c từ bàn phím Sau cho biết giá trị lớn hai số nguyên ba số nguyên

using System; class VD {

static int a,b,c; static void Nhap() {

Console.Write("Nhap a=");a=int.Parse(Console.ReadLine()); Console.Write("Nhap b=");b=int.Parse(Console.ReadLine()); Console.Write("Nhap c=");c=int.Parse(Console.ReadLine()); }

(82)

return x>y?x:y; }

static int Max(int x,int y,int z) {

int tg=Max(x,y);/*Đây gọi đệ quy mà gọi hàm tính Max hai số phía sử dụng*/

tg=Max(tg,z); return tg; }

static void Main() {

Nhap();

Console.WriteLine("Max({0},{1})={2}",a,b,Max(b,c));

Console.WriteLine("Max({0},{1},{2})={3}",a,b,c,Max(a,b,c)); Console.ReadKey();

} }

-13.7 Nguyên tắc sử dụng chương trình con.

Cách gọi hàm

Trong lớp hàm có quyền gọi hàm khác sử dụng(thứ tự hàm cùng lớp khơng quan trong), hàm gọi thực Ta gọi gọi đệ quy, đệ quy giải thuật đệ quy nghiên cứu tài liệu khác, đậy giới thiệu sơ cách gọi đệ quy việc xây dựng hàm C# thơng qua ví dụ sau: Ví dụ: Xây dựng chương trình tính giá trị biểu thức sau:

S=x+x

2

2!+ x3

3!+ xn n !

-using System; class VD

{

(83)

static void Nhap() {

Console.Write("Nhap x=");x=double.Parse(Console.ReadLine()); Console.Write("Nhap n=");n=int.Parse(Console.ReadLine()); }

static double Mu(double x,int n) {

if(n==0) return 1; else return x*Mu(x,n-1); }

static int GiaiThua(int n) {

if(n==0) return 1;

else return n*GiaiThua(n-1); }

static void Main() {

double s=0; int i; Nhap();

for(i=1;i<=n;++i)

s=s+Mu(x,i)/GiaiThua(i); Console.Write("S={0:N2}",s); Console.ReadKey();

} }

 Đệ qui

 Khái niệm chung đệ qui  Khái niệm

(84)

trong tin học, phần giới thiệu khía cạnh với ví dụ đơn giản vấn đề đệ qui

Trước tiên ta xem xét khái niệm đệ qui, sau kiểm tra vài chương trình có chứa hàm đệ qui Cách tiến hành giải toán đệ qui nhìn chung có điểm chung sau Trước tiên gọi hàm đệ qui để giải toán, hàm đệ qui thực biết cách giải toán trường hợp đơn giản (hay gọi trường hợp sở) Nếu hàm đệ qui gọi trường hợp sở, hàm cần đơn giản trả lại kết Nếu hàm gọi trường hợp phức tạp hơn, hàm đệ qui chia công việc cần giải thành hai phần Một phần hàm biết cách giải nào, phần cách giải nhiên để gọi có khả đệ qui, phần sau phải giống với toán ban đầu đơn giản hay nhỏ toán ban đầu Bởi tốn giống với tốn ban đầu nên hàm thực gọi để giải cơng việc đơn giản - lời gọi đệ qui hay gọi bước đệ qui Ðể đảm bảo việc đệ qui có kết thúc, lần gọi đệ qui toán phải đảm bảo đơn giản bước đệ qui thực tiếp cho dến toán đơn giản dần, đơn giản tới mức trở thành trường hợp sở Có thể nhận thấy hàm đệ qui xử lý trường hợp sở để trả lại kết tính cho hàm mức phức tạp hơn, đến lượt hàm lại tính trả lại kết cho hàm phức tạp lời gọi hàm ban đầu

 Ví dụ minh họa

Mới nghe so sánh với cách giải tốn thơng thường Nhưng trước nhận xét tiếp ta xem xét ví dụ tính n giai thừa ( n! )

Theo định nghĩa n! tích tất số tự nhiên từ đến n: n! = n* (n-1) *

Ví dụ 5! = * * * * = 120, 0! định nghĩa Ðể tính n! dùng vòng lặp sau :

factorial = 1;

for (i = n; i >= 1; i ) factorial *= i;

Tuy nhiên định nghĩa đệ qui hàm giai thừa sau : Nếu n>0 n! = n * (n-1)!

Nếu n=0 n! = 0! =

(85)

3! = 3*(2!) = 3*(2*(1!)) = 3*(2*(1*(0!))) 3! = 3*(2*(1*1))) = 3*(2*1) = 3*2 =

-/* Tính giai thừa theo phương pháp đệ qui */

using System; class Factorial {

static long factorial( long number) {

if ( number = ) return 1; else

return (number*factorial(number-1)); }

static void Main() {

int i;

for ( i=0; i<=10; i=i+2)

Console.Write(“{0}! = {1}\n", i, factorial(i)); }

}

-Kết quả

0! = 2! = 4! = 24 6! = 720 8! = 40320 10! = 3628800

(86)

bắt đầu từ hai số 1, tiếp sau số Fibonaci sau tổng số Fibonaci trước Dẫy Fibonaci gặp nhiều thực tế, đặc biệt mơ tả mơ hình xoắn ốc Tỉ số số Fibonaci liên tiếp khoảng 1,618 Số gặp nhiều thực tế gọi tỉ số vàng Các kiến trúc sư thường thiết kế kích thước cửa sổ, phịng, nhà có tỉ lệ chiều dài chiều rộng tỉ số vàng Các bưu thiếp thường có tỉ lệ chiều dài chiều rộng tỉ số vàng Dẫy Fibonaci định nghĩa đệ qui sau:

fibonaci(0) = 0; fibonaci(1) = 1;

fibonaci(n) = fibonaci(n-1) + fibonaci(n-2) (n>1 Chương trình hình tính đệ qui số Fibonaci thứ i cách dùng hàm fibonaci Chú ý dãy số Fibonaci tăng nhanh, chọn kiểu long cho tham số giá trị trả hàm fibonaci

/* Tính dãy số Fibonaci phương pháp đệ qui */ using System;

class Fibonaci {

static long fibonaci( long n) {

if ( n = || n = ) return n; else

return fibonaci(n-1) + fibonaci(n-2); }

static void Main() {

long result, number;

Console.Write("Hãy nhập vào số nguyên : "); number=long.Parse(Console.ReadLine());

result = fibonaci(number);

Console.Write("Fibonaci thứ {0} : {1}\n", number, result); Console.Readkey();

} }

(87)

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : Fibonaci thứ :

Hãy nhập vào số nguyên : 10 Fibonaci thứ 10 : 55

Hãy nhập vào số nguyên : 20 Fibonaci thứ 20 : 6765

Hãy nhập vào số nguyên : 35 Fibonaci thứ 35 : 9227465

Chương trình trên:Tạo số Fibonaci đệ qui Mỗi lần hàm fibonaci gọi, kiểm tra xem liệu có phải trường hợp sở, n hay hay không Nếu n trả lại, khơng, tức n>1, tạo hai lời gọi đệ qui đơn giản lời gọi đến hàm fibonaci ban đầu

So sánh đệ qui lặp

(88)

hợp sở, lặp thay đổi biến đếm vòng lặp làm cho điều kiện lặp sai cịn đệ qui làm cho lời gọi hàm đơn giản dần đơn giản tới trường hợp sở Cả hai phương pháp dẫn đến trường hợp chạy vơ hạn mãi, lặp khơng điều kiện lặp khơng sai cịn đệ qui khơng bước đệ qui khơng làm cho tốn đơn giản cuối hội tụ trường hợp sở Tuy nhiên đệ qui tồi hơn, liên tục đưa lời gọi hàm làm tốn thời gian xử lý vi xử lý không gian nhớ Mỗi lần gọi hàm, lại cần thêm hàm, tốn thêm nhớ (lưu biến hàm, địa trở hàm ) Vì phương pháp lặp chuộng Tuy nhiên tồn nhiều tốn giải bằbg đệ qui  Cách dùng đệ qui

 Các toán dùng Ðệ Qui

Thường áp dụng cho tốn phụ thuộc tham số có hai đặc điểm sau: Bài toán dễ dàng giải số trường hợp riêng ứng với giá trị đặc biệt tham số Ta gọi trường hợp suy biến Trong trường hợp tổng qt, tốn qui toán

dạng giá trị tham số bị thay đổi Và sau số hữu hạn bước biến đổi Ðệ Qui dẫn đến trường hợp suy biến Nhận xét: Bài toán tính n! thể rõ đặc điểm

 Cách xây dựng hàm Ðệ Qui

Hàm Ðệ Qui thường viết theo thuật toán sau: if ( trường hợp suy biến)

{

trình bầy cách giải tốn (giả định có cách giải) }

else /* trường hợp tổng quát*/ {

gọi đệ qui tới hàm (đang lập) với giá trị khác tham số

}

 Bài tập minh hoạ Bài 1

Viết hàm đệ qui để tính tổng sau: S=1+2+3+ +n

(89)

using System; class TinhTong {

static int tongs(int n) {

if (n==1) return 1; else

return n+tong(n-1); }

static void Main() {

int n;

Console.Write("Nhap vao so n de tinh tong: "); n=int.Parse(Console.ReadLine());

/*In ket qua */

Console.Write("\nTong S:={0}",tongs(n)); }

}

Bài 2

/*Chương trình minh họa tìm ước số chung lớn phương pháp đệ qui*/ using System;

class Uscln {

static int uscln(int n,int m) {

int r; r=n-m; if (r==0)

(90)

return uscln(m,r); }

static void Main() {

int so1,so2;

Console.Write("Nhap so thu nhat:"); so1=int.Parse(Console.ReadLine()); Console.Write("Nhap so thu hai :"); so2=int.Parse(Console.ReadLine()); Console.Write("USCLN la {0}",uscln(so1,so2));

Console.ReadKey(); }

}

Bài 14: Thiết kế tốn theo mơ hình hướng chức năng 14.1 Cách thiết kế tốn theo mơ hình hướng chức 14.2 Thảo luận

Bài 15: Bài tập áp dụng mơ hình thiết kế hướng chức năng Bài 16: Bài thực hành xây dựng chương trình

Bài 17: Khái niệm mảng, mảng chiều 17.1 Kiểu liệu tham chiếu kiểu liệu giá trị

C# phân tập hợp kiểu liệu thành hai loại: Kiểu liệu giá trị (value) kiểu liệu tham chiếu (reference) Việc phân chia khác lưu kiểu liệu giá trị kiểu liệu tham chiếu nhớ Đối với kiểu liệu giá trị lưu giữ kích thước thật nhớ cấp phát stack Trong địa kiểu liệu tham chiếu lưu stack đối tượng thật lưu nhớ heap

Ghi chú:

Tất kiểu liệu xây dựng sẵn kiểu liệu giá trị ngoại trừ đối tượng chuỗi Và tất kiểu người dùng định nghĩa ngoại trừ kiểu cấu trúc kiểu liệu tham chiếu

(91)

vào chồng lấy đĩa nằm lập trước, tức đĩa vào sau lấy trước

Trong C#, kiểu giá trị kiểu số nguyên cấp phát stack, vùng nhớ thiết lập để lưu giá trị, vùng nhớ tham chiếu tên biến

Kiểu tham chiếu đối tượng cấp phát heap Khi đối tượng cấp phát heap địa trả về, địa gán đến tham chiếu

Thỉnh thoảng chế thu gom hũy đối tượng stack sau vùng stack đánh dấu kết thúc Thông thường vùng stack định nghĩa hàm Do đó, khai báo biến cục hàm đối tượng đối tượng đánh dấu để hũy kết thúc hàm Những đối tượng heap thu gom sau tham chiếu cuối đến đối tượng gọi

17.2 Khái niệm mảng

Mảng tập hợp có thứ tự đối tượng, tất đối tượng kiểu hay nói cách khác mảng tập biến loại Mảng ngơn ngữ C# có vài khác biệt so với mảng ngôn ngữ C++ số ngơn ngữ khác, chúng đối tượng Điều cung cấp cho mảng sử dụng phương thức thuộc tính

17.3 Mảng chiều

 Chúng ta khai báo mảng chiều C# với cú pháp theo sau: <kiểu liệu>[] <tên mảng>;

Ví dụ ta có khai báo sau: int [] a;

float [] b;

Cặp dấu ngoặc vng ([]) báo cho trình biên dịch biết khai báo mảng Kiểu liệu kiểu thành phần chứa bên mảng Trong ví dụ bên a khai báo mảng số nguyên, b mảng số thực

Chúng ta tạo thể mảng cách sử dụng từ khóa new sau: a = new int[6];

b=new double[20];

(92)

mỗi vùng nhớ chứa số thực kiểu double tức vùng nhớ gồm byte liên tiếp, tổng máy cấp phát cho mảng b 120 byte liên tiếp

Ở cần phân biệt hai thành phần thân mảng thành phần mảng Như biết C# mảng kiểu liệu tham chiếu nên thân mảng ví dụ a thành phần mảng sáu số nguyên, thân mảng a cấp phát stack thành phần mảng cấp phát heap, thân mảng a chứa địa vùng nhớ cấp cho thành phần mảng heap mà thơi Ta minh hoạ sau:

 Ta vừa khai báo mảng vừa cấp phát nhớ cho phần tử mảng sau: <kiểu liệu>[] <tên mảng>=new <kiểu liệu>[kích thước];

Ví dụ:

int []a=new int[40];

double []b=new double[10];

 Ta khai báo mảng đồng thời khởi tạo cho phần tử mảng sau:

Chúng ta khởi tạo nội dung mảng lúc tạo thể mảng cách đặt giá trị bên dấu ngoặc ({}) C# cung cấp hai cú pháp để khởi tạo thành phần mảng, cú pháp dài cú pháp ngắn:

int[] myIntArray1 = new int[5] { 2, 4, 6, 8, 10}; int[] myIntArray2 = { 2, 4, 6, 8, 10};

Khơng có khác biệt hai cú pháp trên, hầu hết chương trình sử dụng cú pháp ngắn tự nhiên lười đánh nhiều lệnh người lập trình

Stack Heap

a

(93)

Khi khai báo mảng ta không khởi đầu giá trị cho chúng phần tử mảng tự động khởi tạo giá trị ngầm định theo bảng thống kê sau:

Ví dụ: Khi ta khia báo mảng int []a=new int[5];

Ta thu mảng a gồm phần tử phần tử mảng khởi đầu giá trị

 Mảng ngơn ngữ C# có vài khác biệt so với mảng ngôn ngữ C++ số ngôn ngữ khác, chúng đối tượng Điều cung cấp cho mảng sử dụng phương thức thuộc tính

Ngơn ngữ C# cung cấp cú pháp chuẩn cho việc khai báo đối tượng Array Tuy nhiên, thật tạo đối tượng kiểu System.Array Mảng ngôn ngữ C# kết hợp cú pháp khai báo mảng theo kiểu ngôn ngữ C kết hợp với định nghĩa lớp thể mảng truy cập phương thức thuộc tính System.Array

(94)

 Truy nhập vào phần tử mảng: Để truy nhập vào phần tử mảng truy nhập thông qua tên mảng số tương ứng Đặc biệt C# phần tử đầu tien mảng có số la Phần tử cuối mảng có số Tên_Mảng.Length-1 Nhớ số mảng phải giới hạn cho phép Ta truy nhập vào phần tử mảng thông qua công thức tổng quát sau: Tên_Mảng[chỉ số]

Ví dụ:

int []=new int[5];

a[0] // Truy nhập vào phần tử mảng

a[i] // Truy nhập vào phần tử thứ i mảng i [0, Tên_Mảng.Length-1]  Một số ví dụ áp dụng

Ví dụ 1: Nhập vào dãy số nguyên sau thực yêu cầu sau: a) Tính tổng phần tử mảng chia hết cho

(95)

c) Nhập vào từ bàn phím số nguyên x cho biết số nguyên xuất hiên mảng lần

d) Rút gọn mảng(nghĩa phần tử đcượ xuất lần)

-using System;

class VD {

static int[] a; static int n; static void Nhap() {

int i;

Console.Write("Nhap so phan tu cua mang n="); n = int.Parse(Console.ReadLine());

a = new int[n];

Console.WriteLine("Hay nhap cac phan tu cho mang"); for (i = 0; i < n; ++i)

{

Console.Write("a[{0}]=", i);

a[i] = int.Parse(Console.ReadLine()); }

}

static void Hien(int []x) {

int i;

for (i = 0; i < x.Length ; ++i) Console.Write("{0}\t", x[i]); Console.WriteLine();

}

static int Tong3() {

int i,t=0;

(96)

if(a[i]%3==0) t=t+a[i]; return t;

}

static int Max() {

int i,mx; mx = a[0];

for (i = 1; i < n; ++i) if (mx < a[i]) mx = a[i]; return mx;

}

static int Dem(int x) {

int i,d=0;

for (i = 0; i < n; ++i) if (a[i] == x) d++; return d;

}

static void RutGon(out int[] kq) {

int i,d=0,j;

int[] tmp = new int[n]; bool ok;

for (i = 0; i < n; ++i) {

ok = true; for(j=0;j<d;++j) if (tmp[j] == a[i]) { ok = false; break; } if (ok) tmp[d++] = a[i]; }

kq = new int[d];

(97)

}

static void Main() {

ConsoleKeyInfo kt; int x;

int []b=null; do{

Console.Clear();

Console.WriteLine("\t\t\tMain Menu"); Console.WriteLine("\t1 Nhap mang"); Console.WriteLine("\t2 Hien Mang");

Console.WriteLine("\t3 Cac phan tu cua mang chi het cho 3"); Console.WriteLine("\t4 Gia tri lon nhat cua mang");

Console.WriteLine("\t5 So lan xuat hien cua phan tu x mang"); Console.WriteLine("\t6 Rut gon mang");

Console.WriteLine("\t7 Thoat khoi chuong trinh");

Console.Write(" Ban hay chon mot cong viec tu 1->7:"); kt=Console.ReadKey();

Console.WriteLine(); switch(kt.KeyChar) {

case '1': Nhap();

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '2':

Console.WriteLine("Cac phan tu cua mang la:"); Hien(a);

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

(98)

case '3':

Console.WriteLine(" Ket qua la {0:8}",Tong3());

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '4':

Console.WriteLine(" Ket qua la {0,8}",Max());

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '5':

Console.Write("Nhap x=");x=int.Parse(Console.ReadLine()); Console.WriteLine(" Ket qua la {0:8}",Dem(x));

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '6':

Console.WriteLine("Cac phan tu cua mang sau rut gon:"); RutGon(out b);

Hien(b);

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '7':

Environment.Exit(0); break; }

} while (true); }

}

-Ví dụ 2: Cho hai dãy số a1, a2, ,an b1,b2, ,bm có phân tử số nguyên nhập vào từ bàn phím Sau thực yêu cầu sau:

(99)

b) Kiểm tra mảng c có lập thành cấp số cộng khơng c) Đưa phần tử mảng c xuất lần

d) Tách mảng c thành hai mảng: mảng chứa toán số chẵn, mảng chứa toàn số lẻ e) Sắp xếp mảng a,b theo thứ tự tăng dần Sau xây dựng mảng d cách chèn

phần tử mảng a,b cho ta thu mảng d có thứ tự tăng dần

-using System; class VD {

static void Nhap(char ten, out int []x) {

int i,n;

Console.WriteLine("Nhap thong tin cho cac phan tu cua mang {0}",ten); Console.Write("Nhap so phan tu cua mang:");

n = int.Parse(Console.ReadLine()); x = new int[n];

Console.WriteLine("Hay nhap cac phan tu cho mang"); for (i = 0; i < n; ++i)

{

Console.Write("{0}[{1}]=",ten,i); x[i] = int.Parse(Console.ReadLine()); }

}

static void Hien(int[] x) {

int i;

for (i = 0; i < x.Length; ++i) Console.Write("{0}\t", x[i]); Console.WriteLine();

}

static void GhepMang(int[] x, int[] y, out int[] kq) {

(100)

Array.Copy(x, kq, x.Length);

Array.Copy(y, 0, kq, x.Length, y.Length); }

static bool CapSoCong(int[] x) {

bool ok = true; int i;

for (i = 1; i < x.Length - 1; ++i) if (x[i] != (x[i - 1] + x[i + 1]) / 2) { ok = false; break; }

return ok; }

static void MotLan(int[] x, out int[] kq) {

int i,j,d=0;

int []tmp=new int[x.Length]; bool ok;

for (i = 0; i < x.Length; ++i) {

ok = true;

for(j=0;j<x.Length;++j) if (x[i] == x[j] && i != j) { ok = false; break; }; if(ok) tmp[d++]=x[i]; }

kq = new int[d];

Array.Copy(tmp, kq, d); }

static void Tach(int[] x, out int[] chan, out int[] le) {

int i,d1=0,d2=0;

(101)

for (i = 0; i < x.Length; ++i) if (x[i] % == 0)

tmp1[d1++] = x[i]; else

tmp2[d2++] = x[i];

chan = new int[d1]; Array.Copy(tmp1, chan, d1); le = new int[d2]; Array.Copy(tmp2, le, d2); }

static void Chen(int[] x, int[] y, out int[] kq) {

int i,n,k,j; Array.Sort(x); Array.Sort(y);

kq = new int[x.Length + y.Length]; Array.Copy(x, kq, x.Length); n=x.Length-1;

for (i = 0; i < y.Length; ++i) {

if (kq[n] < y[i]) kq[++n] = y[i]; else

{ j = 0;

while (y[i] >= kq[j]) j++; for (k = ++n; k > j; k) kq[k] = kq[k - 1]; kq[j] = y[i];

} } }

static void Main() {

(102)

int []c=null; int []d=null; int[] kq = null; int[] chan = null; int[] le = null; ConsoleKeyInfo kt;

{

Console.Clear();

Console.WriteLine("\t\t\tMain Menu");

Console.WriteLine("\t1 Nhap thong tin cho hai mang"); Console.WriteLine("\t2 Mang ghep la");

Console.WriteLine("\t3 Kiem tra day co la cap so cong ko?");

Console.WriteLine("\t4 Cac phan tu cua mang xuat hien dung mot lan"); Console.WriteLine("\t5 Tach mang(chan, le)");

Console.WriteLine("\t6 Chen mang");

Console.WriteLine("\t7 Thoat khoi chuong trinh"); Console.Write(" Ban hay chon mot cong viec tu 1->7:"); kt = Console.ReadKey();

Console.WriteLine(); switch (kt.KeyChar) {

case '1':

Nhap('A', out a);

Nhap('B', out b);

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '2':

Console.WriteLine("Mang ghep la"); GhepMang(a, b, out c);

Hien(c);

(103)

Console.ReadKey(); break;

case '3':

if(CapSoCong(c)==true )

Console.WriteLine(" Day da cho la cap so cong"); else

Console.WriteLine(" Day da cho kong phai la cap so cong"); Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '4':

Console.WriteLine("Cac phan tu cua mang xaut hien dung mot lan"); MotLan(c,out kq);

Hien(kq);

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '5':

Tach(c, out chan, out le);

Console.WriteLine("Cac phan tu chan"); Hien(chan);

Console.WriteLine("Cac phan tu le"); Hien(le);

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '6':

Console.WriteLine("Mang chen la:"); Chen(a, b,out d);

Hien(d);

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

(104)

case '7':

Environment.Exit(0); break; }

} while (true); }

}

- Câu lệnh lặp foreach

Câu lệnh lặp foreach với người học ngơn ngữ C, từ khóa sử dụng ngôn ngữ Visual Basic Câu lệnh foreach cho phép lặp qua tất mục mảng hay tập hợp

Cú pháp sử dụng lệnh lặp foreach sau:

foreach (<kiểu liệu thành phần> <tên truy cập> in <mảng/tập hợp> ) {

// thực thông qua <tên truy cập> tương ứng với // mục mảng hay tập hợp

}

Ví dụ: Nhập vào dãy số ngun sau đưa hình số chẵn dòng, số lể dòng

-using System;

class ViDu {

static int[] a; static void Nhap() {

int i=0,x;

ConsoleKeyInfo kt;

Console.WriteLine("Ban hay nhap vao mot day so nguyen");

{

(105)

Array.Resize(ref a, ++i); a[i - 1] = x;

Console.Write("Ban co nhap tiep C/K"); kt = Console.ReadKey(); Console.WriteLine();

} while (kt.KeyChar == 'c' || kt.KeyChar == 'C'); }

static void Hien() {

Console.WriteLine("Cac phan tu chan la:"); foreach (int i in a)

if(i%2==0)

Console.Write("{0}\t", i);

Console.WriteLine("\nCac phan tu le la:"); foreach (int i in a)

if(i%2!=0)

Console.Write("{0}\t", i); }

static void Main() {

Nhap(); Hien();

Console.ReadKey(); }

}

-Bài 18: Mảng đa chiều

18.1 Mảng đa chiều kích thước

Trong C# cho phép xây dựng mảng nhiều chiều Nhưng ta nghiên cứu mảng hai chiều

 Cách khai báo mảng hai chiều <kiểu liệu> [ , ] tên mảng; Ví dụ:

(106)

float [ , ]b;

Lý giải ta thấy để cấp phát nhớ cho phần tử mang ta dùng từ khoá new sau: a=new int[4,3]; // Khai báo mảng hai chiều a gồm hàng, cột phần tử mảng số nguyên kiểu int

b=new float[2,3];// Khai báo mảng hia chiều b gồm hàng, cột phần tử mảng số thực kiểu float

Một số thông tin khác lý giải mảng chiều

 Ta vừa khai báo mảng vừa cấp phát nhớ cho phần tử mảng sau: <kiểu liệu>[,] <tên mảng>=new <kiểu liệu>[kích thước hàng, kích thước cột];

Ví dụ:

int [,]a=new int[4,6];

double [,]b=new double[10,4];

 Ta khai báo mảng đồng thời khởi tạo cho phần tử mảng sau:

Chúng ta khởi tạo nội dung mảng lúc tạo thể mảng cách đặt giá trị bên dấu ngoặc ({}) C# cung cấp hai cú pháp để khởi tạo thành phần mảng, cú pháp dài cú pháp ngắn:

int[,] myIntArray1 = new int[2,3] { {2, 4, 6},{ 8, 10,9}}; int[,] myIntArray2 = { {2, 4, 1},{ 6, 8, 10}};

Khơng có khác biệt hai cú pháp trên, hầu hết chương trình sử dụng cú pháp ngắn tự nhiên lười đánh nhiều lệnh người lập trình

 Để truy nhập vào phần tử mảng truy nhập thông qua tên số tương ứng Cụ thể Tên_Mảng[chỉ số hàng, số cột]

chỉ số hàng nằm đoạn [0, Tên_Mảng.GetLength(0)-1] số cột nằm đoạn [0, Tên_Mảng.GetLength(1)-1]  Một số ví dụ áp dụng

Ví dụ 1: Cho ma tran a gồm m hàng, n cột có phần tử số nguyên nhập vào từ bàn phím Sau thực u cầu sau:

a) Tìm giá trị lớn số phần tử mảng b) Tính tổng phần tử số nguyên tố mảng

(107)

-using System; class VD {

static int[,] a; static int m, n; static void Nhap() {

int i, j;

Console.Write("Nhap so hang m="); m = int.Parse(Console.ReadLine()); Console.Write("Nhap so cot n="); n = int.Parse(Console.ReadLine()); a = new int[m, n];

Console.WriteLine("Nhap gia tri cho cac phan tu cua ma tran"); for (i = 0; i < m; ++i)

for (j = 0; j < n; ++j) {

Console.Write("a[{0},{1}]=", i, j); a[i, j] = int.Parse(Console.ReadLine()); }

}

static void Hien() {

int i, j;

for (i = 0; i < m; ++i) {

for (j = 0; j < n; ++j)

Console.Write("{0}\t", a[i, j]); Console.WriteLine();

} }

static int Max() {

(108)

for (j = 0; j < n; ++j)

if (mx < a[i, j]) mx = a[i, j]; return mx;

}

static bool Nt(int x) {

bool ok = true; int i;

for (i = 2; i < x - 1; ++i) if (x % i == 0) { ok = false; break; } return ok && x != 1; }

static void NtMang() {

int i, j;

Console.WriteLine("cac phan tu la so nguyen to cua mang"); for (i = 0; i < m; ++i)

for (j = 0; j < n; ++j) if (Nt(a[i, j]))

Console.Write("{0}\t", a[i, j]); Console.WriteLine();

}

static void Vet() {

int i, j, t = 1; if (m == n) {

for (i = 0; i < m; ++i) t = t * a[i, i];

Console.WriteLine("Tich cac phan tu tren duong cheo chinh la {0}", t); }

(109)

}

static void Main() {

ConsoleKeyInfo kt;

{

Console.Clear();

Console.WriteLine("\t\t\tMain Menu");

Console.WriteLine("\t1 Nhap thong tin cho mang"); Console.WriteLine("\t2 Hien mang");

Console.WriteLine("\t3 Gia tri lon nhat cua mang");

Console.WriteLine("\t4 Cac phan tu la so nguyen to cua mang"); Console.WriteLine("\t5 Tich cac phan tu tren duong cheo chinh"); Console.WriteLine("\t6 Thoat khoi chuong trinh");

Console.Write(" Ban hay chon mot cong viec tu 1->6:"); kt = Console.ReadKey();

Console.WriteLine(); switch (kt.KeyChar) {

case '1': Nhap();

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '2':

Console.WriteLine("Cac phan tu cua mang la"); Hien();

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '3':

Console.WriteLine(" Max cua mang {0}", Max());

(110)

Console.ReadKey(); break;

case '4': NtMang();

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '5': Vet();

Console.WriteLine("Ban hay nhan phim bat ky de tiep tuc "); Console.ReadKey();

break; case '6':

Environment.Exit(0); break; }

} while (true); }

}

-Ví dụ 2: Cho hai ma trận vng a,b cấp n có phần tử số ngun nhập vào từ bàn phím Sau thực yêu cầu sau:

a) Tính tổng hai ma trận a,b kết qua cho vào ma trận c

b) Tìm giá trị lớn hàng ma trận c kết cho vào ma trận chiều x c) Sắp xếp ma trận c tăng dần theo chiều xốy trơn ốc

-using System;

class VD {

static int n;

static void Nhap(char ten,out int [,]x) {

(111)

Console.WriteLine("Nhap gia tri cho cac phan tu cua ma tran {0}",ten); for (i = 0; i < n; ++i)

for (j = 0; j < n; ++j) {

Console.Write("{0}[{1},{2}]=",ten, i, j); x[i, j] =int.Parse(Console.ReadLine()); }

}

static void Hien(int [,]x) {

int i, j;

for (i = 0; i < n; ++i) {

for (j = 0; j < n; ++j)

Console.Write("{0}\t", x[i, j]); Console.WriteLine();

} }

static void Hien(int[] x) {

int i;

for (i = 0; i < n; ++i)

Console.Write("{0}\t", x[i]); Console.WriteLine(); }

static void Tong(int[,] x, int[,] y, out int[,] kq) {

int i, j;

(112)

}

static void MaxHang(int[,] x, out int[] kq) {

int i, j,mx,d=0; kq = new int[n]; for (i = 0; i < n; ++i) {

mx = x[i, 0];

for (j = 1; j < n; ++j)

if (mx < x[i, j]) mx = x[i, j]; kq[d++] = mx;

} }

static void TronOc(ref int[,] x) {

int i, j, d=0,k=0;

int[] tmp = new int[n * n]; for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) tmp[d++] = x[i, j]; Array.Sort(tmp); d = 0;

{

i = k;

for (j = k; j < n - - k; ++j) x[i, j] = tmp[d++]; j = n - - k;

for (i = k; i < n - - k; ++i) x[i, j] = tmp[d++]; i = n - - k;

(113)

j = k;

for (i = n - - k; i > k; i) x[i, j] = tmp[d++]; k++;

if (d == n * n - 1) x[n / , n / ] = tmp[d++]; } while (d < n * n);

}

static void Main() {

int [,]a=null; int [,]b=null; int [,]c=null; int []x=null;

Console.Write("Nhap cap cau ma tran n="); n = int.Parse(Console.ReadLine());

Nhap('A', out a); Nhap('B', out b); Tong(a, b, out c);

Console.WriteLine("Tong hai mang"); Hien(c);

MaxHang(c, out x);

Console.WriteLine("Gia tri lon nhat cua cac hang"); Hien(x);

TronOc(ref c);

Console.WriteLine("Mang c sau sap xep"); Hien(c);

Console.ReadKey(); }

}

-18.2 Mảng đa chiều không kích thước

(114)

thì hình dạng mảng đa chiều có khích thước khác khơng phải hình chữ nhật chiều chúng khơng điều

Khi tạo mảng đa chiều kích thước khác khai báo số dịng mảng trước Sau với dịng giữ mảng, có kích thước Những mảng khai báo riêng Sau khởi tạo giá trị thành phần mảng bên

 Cách khai báo

<kiểu liệu> [][] tên mảng=new <kiểu liệu>[kích thước hàng][] ;

<kiểu liệu> [][] tên mảng;

tên mảng=new <kiểu liệu>[kích thước hàng][] ;

Sau ta tiến hành cấp phát nhớ cho phần tử hàng tênmảng[chỉ số]=new <kiểu liệu>[số phần tử hàng] Ví dụ:

int [][]a;

a=new int[3][];

Tiếp ta cấp phát nhớ cho phần tử hàng a[0]=new int[6]; // Hàng thứ có phần tử

a[1]=new int[2]; // Hàng thứ hai có phần tử a[2]=new int[5]; // Hàng thứ ba có phần tử  Truy nhập vào phần tử mảng

Để truy nhập vào phần tử mảng đa chiều có kích khơng ta thực theo nguyên tắc sau:

Tênmảng[chí số 1][chỉ số 2]

chí số  [0 Tênmảng.Length-1]

chí số  [0 Tênmảng[chí số 1].Length-1]

Ví dụ: Nhập vào n dãy số ngun sau tìm giá trị lớn dãy lưu vào mảng chiều sẵp xếp chúng theo thứ tự tăng dần

-using System;

(115)

static int[][] a; static void Nhap() {

int i,j,n,m;

Console.Write("Ban muon nhap vao bao nhieu day so nguyen n="); n = int.Parse(Console.ReadLine());

a = new int[n][];

Console.WriteLine("Ban hay nhap thong tin cho moi day so nguyen"); for (i = 0; i < a.Length; ++i)

{

Console.Write("Ban hay nhap so phan tu cho day thu {0} m=", i); m = int.Parse(Console.ReadLine());

a[i] = new int[m];

Console.WriteLine("Nhap gia tri cho moi phan tu o day thu {0}", i); for (j = 0; j < a[i].Length; j++)

{

Console.Write("a[{0}][{1}]=", i, j); a[i][j] = int.Parse(Console.ReadLine()); }

} }

static void Tim(out int[] kq) {

int i, j, d=0,max; kq = null;

for (i = 0; i < a.Length; ++i) {

max = a[i][0];

for (j = 1; j < a[i].Length; ++j) if (max < a[i][j]) max = a[i][j]; Array.Resize(ref kq, ++d); kq[d - 1] = max;

(116)

}

static void Hien(int []x) {

int i;

for (i = 0; i < x.Length; ++i) Console.Write("{0}\t", x[i]); Console.WriteLine();

}

static void Main()s {

int[] kq; Nhap(); Tim(out kq); Array.Sort(kq);

Console.WriteLine("Cac phan tu lon nhat cua moi day da duoc sap xep la"); Hien(kq);

Console.ReadKey(); }

}

-Bài 19 -Bài tập kiểu liệu mảng

Bài 20: Bài thực hành kiểu liệu mảng Bài 21: Kiểu liệu xâu(chuỗi)

Có thời gian người ta ln nghĩ máy tính dành riêng cho việc thao tác giá trị dạng số Các máy tính thiết kế để sử dụng tính tốn số lượng lớn tính tốn quỹ đạo tên lửa quốc phịng Và ngơn ngữ lập trình giảng dạy khoa toán đại học lớn

Ngày nay, hầu hết chương trình liên quan đến nhiều chuỗi ký tự chuỗi số Thông thường chuỗi sử dụng cho việc xử lý từ ngữ, thao tác sưu liệu, tạo trang web

(117)

chuỗi đối tượng đóng gói tất thao tác, xếp, phương thức tìm kiếm thường áp dụng cho chuỗi ký tự

Những thao tác chuỗi phức tạp so khớp mẫu hỗ trợ việc sử dụng biểu thức quy tắc (regular expression) Ngôn ngữ C# kết hợp sức mạnh phức tạp cú pháp biểu thức quy tắc, (thơng thường tìm thấy ngôn ngữ thao tác chuỗi Awk, Perl), với thiết kế hướng đối tượng đầy đủ

Trong phần học cách làm việc với kiểu liệu string ngôn ngữ C#, kiểu string alias lớp System.String NET Framework Chúng ta thấy cách rút trích chuỗi con, thao tác nối chuỗi, xây dựng chuỗi với lớp StringBuilder Thêm vào đó, học cách sử dụng lớp Regex để so khớp chuỗi dựa biểu thức quy tắc phức tạp

Trong C# đưa hai loại chuỗi, chuỗi với nội dung thay đổi được(String), hai chuỗi với nội dung thay đổi (StringBuilder)

 Chuỗi với nội dung cố định (String)

C# xem chuỗi kiểu liệu tức lớp linh hoạt, mạnh mẽ, dễ sử dụng Mỗi đối tượng chuỗi dãy cố định ký tự Unicode Nói cách khác, phương thức dùng để làm thay đổi chuỗi thực trả thay đổi, chuỗi nguyên thủy không thay đổi Khi khai báo chuỗi C# cách dùng từ khóa string, khai báo đối tượng lớp System.String, kiểu liệu xây dựng sẵn cung cấp thư viện lớp NET (.NET Framework Class Library) Do kiểu liệu chuỗi C# kiểu liệu

System.String, suốt chương dùng hai tên hoán đổi lẫn

 Cách khai báo chuỗi: Để khai báo chuỗi theo kiểu ta thực sau: string Tênchuỗi;

Ví dụ:

string hoTen, queQuan; string s;

Như biết chuỗi kiểu liệu tham chiếu, chuỗi chẳng qua đối tượng thuộc lớp System.String Với khai báo ta thu tên đối tượng chuỗi đặt stack cịn nội dung cấp phát cho chưa có Để tạo nội dung cho chuỗi ta thực theo cách sau:

(118)

string hoTen= “Nguyen Huu Dong”; string donViCongTac;

Ta thấy khai báo hai chuỗi hoTen donViCongTac biến xấu cấp phát Stack, nội dung thực chuỗi cấp phát Heap Trong ví dụ từ đầu xâu hoTen đựơc cấp vùng nhớ với nội dung “Nguyen Huu Dong” Heap, cịn xâu donViCongTac có biến xâu Stack phần nội dung chưa có

Giả sử sau ta gán cho xau donViCongTac xâu ”Khoa CNTT” donViCongTac=”Khoa CNTT”

Sau gán cho xâu donViCongTac xâu “Khoa CNTT” lúc ta có

Như ta thấy chuỗi kiểu liệu tham chiếu với biến chuỗi đặt Stack nội dung thực chuỗi đặt Heap

 Chuỗi chứa ký tự đặc biệt: \t , \n, \b , Ví dụ:

string diaChi= “Nguyen Huu Dong\nKhoa CNTT-DHSPKTHY” Khi hiển thị ta nội dung sau:

Stack Heap

hoTen

donViCongTac

NgyenHuuDong

Stack Heap

hoTen

donViCongTac

NgyenHuuDong

(119)

Stack

Heap

hoTen1 Nguyen Van A

Nguyen Van B hoTen2

Nguyen Huu Dong

Khoa CNTT-DHSPKTHY

 Chuỗi tạo cách sử dụng chuỗi cố định hay nguyên văn (verbatim), tức ký tự chuỗi giữ nguyên không thay đổi Chuỗi bắt đầu với biểu tượng @ Biểu tượng bảo với hàm khởi dựng lớp String chuỗi theo sau ngun văn, chí chứa nhiều dòng bao gồm ký tự escape

Ví dụ:

string diaChi=@”Nguyen Huu Dong Khoa CNTT-DHSPKTHY”;

Khi hiển thịta thu nội dung sau: Nguyen Huu Dong

Khoa CNTT-DHSPKTHY  Cách truy nhập vào phần tử xâu

Để truy nhập vào phần tử xâu, thực theo nguyên tắc: TênXau[chỉ số] với số  [0 TênXau.Length-1]

 Thao tác chuỗi

 Lấy tổng chuỗi: Tổng hai hay nhiều chuỗi kết cho ta chuỗi string firstName= “Dong”;

string lastName=”Nguyen Huu”;

string fullName= lastName + “ “ +firstName;

Khi chuỗi fullName có nội dung là: Nguyen Huu Dong  Gán chuỗi

(120)

Stack

Heap

hoTen1 Nguyen Van A

Nguyen Van B hoTen2

Nếu ta thực hiện:

hoTen1=hoTen2; Lúc ta có:

Ta thấy sau gán xâu hoTen2 cho xâu hoTen1 hai xâu hoTen1 hoTen2 trỏ vào vùng nhớ Tức hai xâu hoTen1 hoTen2 có vai trị

 Chúng ta không lên so sánh trực tiếp hai xâu với nhau, hay gán trực tiếp hai xâu cho nhau.v.v mà ta sử dụng hàm lớp lớp string Lớp string cung cấp nhiều hàm để so sánh, tìm kiếm thao tác xâu, hàm trình bày bảng sau:

(121)(122)

 Ví dụ áp dụng

Ví dụ 1: Nhập vào xâu ký tự s sau thực yêu cầu sau: a) Đếm tổng số ký tự khơng phải ký tự chữ số có xâu s b) Đếm số lần xuất xâu “mua xuan” xâu s

c) Chỉ xâu s xâu có độ dài lớn chứa toàn ký tự chữ số

d) Đưa hình từ có xâu Biết từ đặt cách dấu: [‘.’ , ’ ‘ , ‘!’ , ‘?’ , ‘.’]

-using System;

class BaiXau {

static int demKhongChuSo(string s) {

int d=0;

for(int i=0;i<s.Length;++i)

if(!(s[i]>='0' && s[i]<='9')) d++; return d;

(123)

static int demXauCon(string con, string s) {

int d=0;

for(int i=0;i<s.Length-con.Length+1;++i)

if(string.Compare(con,s.Substring(i,con.Length))==0) d++; return d;

}

static string timXauLon(string s) {

string tmp=""; string max="";

for(int i=0;i<s.Length;++i) {

if(s[i]>='0' && s[i]<'9')

tmp=tmp+s.Substring(i,1); else if(tmp.Length>0)

{

if(max.Length<tmp.Length) max=string.Copy(tmp); tmp="";

} }

return max; }

static void hienTu(string s) {

Console.WriteLine("Cac tu co o xau"); char[]dau={' ','?','.','!'};

foreach(string in s.Split(dau)) if(con.Length>0)

Console.WriteLine(con); }

(124)

{

string s;

Console.Write("Nhap xau:");s=Console.ReadLine(); //Câu a

Console.WriteLine(" So ky tu la:" + demKhongChuSo(s)); //Câu b

Console.WriteLine("So cum tu mua xuan co xau:"

+demXauCon("mua xuan",s)); //Câu c

Console.WriteLine("Xau can tim la:" + timXauLon(s)); //Câu d

hienTu(s);

Console.ReadKey(); }

}

-Ví dụ 2: Tìm tất số tự nhiên khơng q n cho số trùng với phần cuối bình phương Chẳng hạn:62=36; 252=625

-using System;

class BaiXau {

static bool KiemTra(long i) {

bool ok;

string s=Convert.ToString(i*i); string con=i.ToString();

if(string.Compare(s.Substring(s.Length-con.Length,con.Length),con)==0) ok=true;

else

ok=false; return ok;

(125)

static void Main() {

long n;

Console.Write("Nhap n=");n=long.Parse(Console.ReadLine()); Console.WriteLine("Cac so thoa ma yeu cau bai toan:");

for(long i=1;i<=n;++i) if(KiemTra(i))

Console.WriteLine(i+ " >"+i*i ); Console.ReadKey();

} }

Ví dụ 3: Nhập vào xâu ký tự s Sau thực yêu cầu sau:

a) Xoá xâu s dấu cách thừa: bên trái, bên phải dấu cách thừa xâu, gữa từ để lại dấu cách

b) Xoá tất xâu có nội dung “mua xuan” có xâu s c) Sắp xếp từ xâu s theo thứ tự từ điển

d) Đếm tần xuất xuất từ có xâu s Chú ý: Từ ký tự viết liền cách dấu cách

-using System;

class BaiXau {

static string LTrim(string s) {

string tmp=string.Copy(s);

while(tmp[0]==' ') tmp=tmp.Remove(0,1); return tmp;

}

static string RTrim(string s) {

(126)

while(tmp[tmp.Length-1]==' ') tmp=tmp.Remove(tmp.Length-1,1); return tmp;

}

static string Trim(string s) {

string tmp=string.Copy(s);

tmp=LTrim(tmp);tmp=RTrim(tmp); while(tmp.IndexOf(" ")>0)

tmp=tmp.Remove(tmp.IndexOf(" "),1); return tmp;

}

static string Xoa(string con, string s) {

string tmp=string.Copy(s); while(tmp.IndexOf(con)>0)

tmp=tmp.Remove(tmp.IndexOf(con),con.Length); return tmp;

}

static void catTu(string s,ref string []tu) {

int d=0;

foreach(string in s.Split(' ')) if(con.Length>0)

{

Array.Resize(ref tu,++d); tu[d-1]= con;

} }

static string sapXep(string []tu) {

(127)

tmp=tmp+" "+tu[i]; return tmp;

}

static void tanXuat(string []tu) {

string []tmp=null; int i,j,d=0;

bool ok;

for(i=0;i<tu.Length;++i)

{

ok=true;

for(j=0;j<d;++j)

if(string.Compare(tmp[j],tu[i])==0) ok=false;

if(ok)

{

Array.Resize(ref tmp,++d);

tmp[d-1]=string.Copy(tu[i]);

}

}

Console.WriteLine("Tan xuat xuat hien cua cac tu la:"); for(j=0;j<tmp.Length;++j)

{

d=0;

for(i=0;i<tu.Length;++i)

if(string.Compare(tu[i],tmp[j])==0) d++;

if(d>0) Console.WriteLine("Tu {0} xuat hien {1} lan",tmp[j],d);

}

}

static void Main() {

string s,tmp;

Console.Write("Nhap xau:");s=Console.ReadLine();

(128)

tmp=Trim(s);

Console.WriteLine("Xau sau xoa:{0}",tmp);

//Cau b

tmp=Xoa("mua xuan",s);

Console.WriteLine("Xau sau xoa:{0}",tmp);

//Cau c

string []tu=null;

catTu(s,ref tu);

Console.WriteLine("Xau sau sap xep:"+sapXep(tu));

//Cau d

tanXuat(tu);

Console.ReadKey(); }

}

 Chuỗi với nội dung thay đổi (StringBuilder)

Như biết xâu kiểu string xấu có nội dung cố định, muốn thay đổi nội dung xâu chẳng qua tạo tác động sao, cịn nội dung xâu gốc khơng thay đổi Khác với xâu theo kiểu string, xâu kiểu StringBuilder nội dung thay đổi Muốn sử dụng StringBilder trước tiên ta phải khai báo : using System.Text;

 Cách khai báo chuỗi: Để khai báo chuỗi theo kiểu ta thực sau: StringBuilder Tênchuỗi=new StringBuilder();

Ngoài cách bạn tham khảo thêm tài liệu để biết thêm số cách khai báo khác Ví dụ:

StringBuilder s1=new StringBuilder();//Khai báo xâu s1 theo kiểu StringBuilder chưa có nội dung

StringBuilder s2=new StringBuilder(“Nguyen Huu Dong”); // Khai báo xâu s2 theo kiểu StringBuilder có nội dung khởi tạo nguyen Huu Dong

(129)

 Các thao tác chuỗi StringBuilder: Lớp StringBuilder sử dụng để tạo bổ sung chuỗi Hay nói lớp phần đóng gói khởi dựng cho String Một số hàm thành viên quan trọng StringBuilder tóm tắt bảng sau:

 Ví dụ áp dụng

Ví dụ 1: Nhập vào số nguyên n Sau chuyển số nguyên sang hệ đếm hexa.

-using System; using System.Text; class BaiXau {

static void Main() {

int n;

string x="0123456789ABCDEF";

Console.Write("Nhap n=");n=int.Parse(Console.ReadLine()); StringBuilder s=new StringBuilder();

while(n!=0) {

(130)

n=n/16; }

Console.Write("So hexa tuong ung:"+s); Console.ReadKey();

} }

-Ví dụ 2: Nhập từ bàn phím xâu ký tự s Sau viết hố ký tự từ.

-using System; using System.Text; class BaiXau {

static string LTrim(string s) {

string tmp=string.Copy(s);

while(tmp[0]==' ') tmp=tmp.Remove(0,1); return tmp;

}

static string RTrim(string s) {

string tmp=string.Copy(s);

while(tmp[tmp.Length-1]==' ') tmp=tmp.Remove(tmp.Length-1,1); return tmp;

}

static string Trim(string s) {

string tmp=string.Copy(s);

tmp=LTrim(tmp);tmp=RTrim(tmp); while(tmp.IndexOf(" ")>0)

(131)

}

static string chuanHoa(string s) {

string tmp=string.Copy(s);

tmp=tmp.ToLower();

tmp=Trim(tmp);

StringBuilder t=new StringBuilder(tmp); t[0]=char.ToUpper(t[0]);

for(int i=1;i<t.Length;++i)

if(t[i]==' ') t[i+1]=char.ToUpper(t[i+1]); tmp=t.ToString();

return tmp;

}

static void Main() {

string s;

Console.Write("Nhap xau:");s=Console.ReadLine();

s=chuanHoa(s);

Console.WriteLine("Xau sau chuan hoa:" +s); Console.ReadKey();

} }

-Ví dụ 3: Xây dựng chương trình tính tổng hai số ngun bất kỳ

-using System;

using System.Text; class BaiXau {

static void chuanHoaSo(ref string so1, ref string so2) {

(132)

if(s1.Length>s2.Length)

while(s2.Length<s1.Length) s2.Insert(0,"0"); else

if(s2.Length>s1.Length)

while(s1.Length<s2.Length) s1.Insert(0,"0"); so1=s1.ToString();

so2=s2.ToString(); }

static string tinhTong(string so1, string so2) {

string s;

int t,a,b,nho=0; int n;

chuanHoaSo(ref so1,ref so2);

StringBuilder kq=new StringBuilder(""); n=so1.Length-1;

while(n>=0) {

a= so1[n]-48; b= so2[n]-48; t=a+b+nho; s=t.ToString();

if(s.Length==1) s="0"+s; nho=s[0]-48;

kq.Insert(0,s[1]); n=n-1;

}

(133)

static void Main() {

string so1,so2;

StringBuilder x=new StringBuilder(""); StringBuilder y=new StringBuilder(""); StringBuilder s=new StringBuilder("");

Console.WriteLine("\t\t BAN HAY NHAP VAO HAI SO NGUYEN"); Console.Write(" ");so1=Console.ReadLine();

Console.WriteLine("+");

Console.Write(" ");so2=Console.ReadLine();

x.Append('-',so1.Length>so2.Length?so1.Length:so2.Length); y.Append(' ',Math.Abs(so1.Length-so2.Length));

s.AppendFormat("\t\t{0}\n\n","BAN HAY NHAP VAO HAI SO NGUYEN"); if(so1.Length<so2.Length)

s.AppendFormat(" {0}{1}\n",y.ToString(),so1); else

s.AppendFormat(" {0}\n",so1); s.AppendFormat("{0}\n","+");

if(so2.Length<so1.Length)

s.AppendFormat(" {0}{1}\n",y.ToString(),so2); else

s.AppendFormat(" {0}\n",so2); s.AppendFormat(" {0}\n",x.ToString()); s.AppendFormat(" {0}",tinhTong(so1,so2)); Console.Clear();

Console.WriteLine(s); Console.ReadKey(); }

}

(134)

-Bài 22: -Bài thực hành kiểu liệu xâu Bài 23: Kiểu liệu cấu trúc

23.1 Khái niệm cấu trúc

Trong thực tế lập trình, cần đến kiểu liệu phức tạp tạo thành từ kiểu liệu đơn giản mà biết Những kiểu liệu cho ta khả kết hợp nhóm biến thể đối tượng chung Chẳng hạn để lưu giữ thông tin liên quan đến đối tượng nhân viên, ta cần thiết đến biến có khả lưu trữ tên, địa chỉ, ngày sinh, lẫn mã số nhân viên, lương v.v Để xử lý biến phần tử thống nhất, thể thông tin nhân viên cụ thể Ngôn ngữ lập trình C# cho phép tự xây dựng kiểu liệu phức hợp sử dụng kiểu liệu để khai báo cho biến sử dụng sau Chúng ta gọi kiệu liệu cấu trúc Trong C# cấu trúc kiểu liệu đơn giản người dùng định nghĩa, kích thước nhỏ dùng để thay cho lớp Nhưng lớp cấu trúc có điểm khác mà nghiên cứu sau Điểm khác biệt chủ yếu cấu trúc kiểu liệu giá trị

23.2 Khai báo cấu trúc struct <TênCấuTrúc>

{

//Các thành phần cấu trúc }

Ví dụ:

struct HocSinh {

public string hoTen;

public double dt,dl,dh,dtong; }

 Khai báo biến cấu trúc

TênCẩuTrúc tênBiếnCấuTrúc = new TênCẩuTrúc(); Ví dụ:

(135)

Để truy nhập vào thành phần cấu trúc theo nguyên tắc tênBiếnCấuTrúc.tênThànhphần Ví dụ:

t.hoTen // Truy nhập vào thành phần hoTen cấu trúc t 23.4 Ví dụ áp dụng:

Viết chương trình ngôn ngữ C# để giúp trung tập ngoại ngữ quản lý kỳ thi cuối khố phịng thi sử dụng cấu trúc tương ứng Thơng tin thí sinh có cấu trúc sau:

- Tên sinh viên( Tên sinh viênlà xâu ký tự có độ dài 25) - Điểm viết(Điểm viết sinh viên số nguyên >=0 <=10) - Điểm nói (Điểm nói sinh viên số nguyên >=0 <=10) Yêu cầu:

a) Nhập thông tin họ tên điểm sinh viên với định dạng sau

Tên sinh viên: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Điểm viết :xx

Điểm nói :xx

Chú ý: Chương trình phải kiểm tra hợp lệ điểm thi

b) In bảng điểm phòng thi sau:

Stt Tên Điểm viết Điểm nói Tổng điểm xx xxxxxxxxxxxxxxx xx xx xx

c)In danh sách sinh viên thi qua( điều kiện để sinh viên thi qua môn thi phái >=5) Stt Tên Điểm viết Điểm nói Tổng điểm

xx xxxxxxxxxxxxxx xx xx xx

d) In sinh viên có tổng điểm cao Nếu nhiều thí sinh có điểm cao in tất cả Stt Tên Tổng điểm

xx xxxxxxxxxxxxxxxxxx xx

e) Sắp xếp sinh viên theo thứ tự giảm dần điểm viết in danh sách theo định dạng thứ hai

-using System;

(136)

public string HoTen; public int Viet,Doc; }

class CauTruc {

static KieuSV []DSSV; static int SoLuong; static void NhapDSSV() {

Console.Write("So TS can nhap :"); SoLuong=int.Parse(Console.ReadLine()); DSSV=new KieuSV[SoLuong];

for (int i=0; i < SoLuong; i++) {

Console.Write("Ho ten thi sinh : "); DSSV[i].HoTen=Console.ReadLine(); do {

Console.Write("Diem viet : ");

DSSV[i].Viet=int.Parse(Console.ReadLine()); } while (DSSV[i].Viet < || DSSV[i].Viet > 10);

do {

Console.Write("Diem doc : ");

DSSV[i].Doc=int.Parse(Console.ReadLine()); } while (DSSV[i].Doc < || DSSV[i].Doc > 10);

} }

static void DSDiem() {

int i;

Console.Write("STT Ho va Ten Viet Noi Tong diem \n"); for (i=0; i< SoLuong; ++i)

(137)

Console.Write("{0}\t{1}\t{2}\t{3}\t{4}", i+1, DSSV[i].HoTen, DSSV[i].Viet, DSSV[i].Doc, DSSV[i].Viet + DSSV[i].Doc);

Console.Write("\n"); }

}

/* In danh sach nhung sinh vien co diem dat ( deu >= 5) */ static void DSSVDat()

{

int i;

Console.Write("STT Ho va Ten Viet Noi Tong diem \n"); for (i=0; i < SoLuong; ++i)

{

if (DSSV[i].Viet >= && DSSV[i].Doc >= 5) {

Console.Write("{0}\t{1}\t{2}\t{3}\t{4}", i+1, DSSV[i].HoTen, DSSV[i].Viet, DSSV[i].Doc, DSSV[i].Viet + DSSV[i].Doc);

Console.Write("\n"); }

} }

static void TongDiemCaoNhat() {

int MAX, i;

/* Tinh tong diem cao nhat */

MAX = DSSV[0].Viet + DSSV[0].Doc; for (i=0; i< SoLuong ; i++)

{

if (DSSV[i].Viet + DSSV[i].Doc > MAX) MAX = DSSV[i].Viet + DSSV[i].Doc; }

(138)

for (i=0; i < SoLuong; i++) {

if (DSSV[i].Viet + DSSV[i].Doc == MAX) {

Console.Write("{0}\t{1}\t{2}\t{3}", DSSV[i].HoTen, DSSV[i].Viet, DSSV[i].Doc, DSSV[i].Viet + DSSV[i].Doc);

Console.Write("\n"); }

} }

static void SapXep() {

int i, j;

KieuSV TG=new KieuSV(); for (i=0; i < SoLuong - 1; i++) for (j=i+1; j < SoLuong; j++) if (DSSV[j].Viet > DSSV[i].Viet)

{

TG = DSSV[i]; DSSV[i] = DSSV[j]; DSSV[j] = TG; }

}

static int ChonMenu() {

Console.Write("\n\n\n\t\t\t1 Nhap danh sach sinh vien"); Console.Write("\n\t\t\t2 Hien thi danh sach sinh vien"); Console.Write("\n\t\t\t3 Danh sach sinh vien dat ");

(139)

Tam=int.Parse(Console.ReadLine()); return Tam;

}

static void Main() {

Console.Clear(); do

{

switch (ChonMenu()) {

case 1: NhapDSSV(); break;

case 2: DSDiem(); Console.ReadKey();break; case 3: DSSVDat();Console.ReadKey();break;

case 4: TongDiemCaoNhat(); Console.ReadKey();break; case 5: SapXep(); Console.Write("Da sap xong !");

Console.ReadKey();break; case 6: Environment.Exit(0);break;

/* Thoat khoi chuong trinh */ }

Console.Clear(); } while(true);

} }

-Bài 24: Một số tập áp dụng kiểu liệu cấu trúc

Bài 25: Kiểu liệu liệt kê & tập hợp 25.1 Kiểu liệu liệt kê

25.2 Kiểu liệu tập hợp

(140)

Bài 28: Xử lý ngoại lệ

28.1 Giới thiệu loại lỗi ngoại lệ

Ngôn ngữ C# giống ngôn ngữ hướng đối tượng khác, cho phép xử lý lỗi điều kiện khơng bình thường với ngoại lệ Ngoại lệ đối tượng đóng gói thơng tin cố chương trình khơng bình thường

Một điều quan trọng để phân chia bug, lỗi, ngoại lệ Một bug lỗi lập trình sửa chữa trước mã nguồn chuyển giao Những ngoại lệ khơng bảo vệ tương phản với bug Mặc dù bug nguyên nhân sinh ngoại lệ, không dựa vào ngoại lệ để xử lý bug chương trình, tốt nên sửa chữa bug Một lỗi có ngun nhân phía hành động người sử dụng Ví dụ, người sử dụng nhập vào số họ lại nhập vào ký tự chữ Một lần nữa, lỗi làm xuất ngoại lệ, ngăn ngừa điều cách bắt giữ lỗi với mã hợp lệ

Những lỗi đốn trước ngăn ngừa Thậm chí xóa tất bug dự đoán tất lỗi người dùng, gặp phải vấn đề không mong đợi, xuất trạng thái thiếu nhớ (out of memory), thiếu tài nguyên hệ thống, nguyên nhân chương trành khác hoạt động ảnh hưởng đến Chúng ta ngăn ngừa ngoại lệ này, xử lý chúng để chúng khơng thể làm tổn hại đến chương trình

Khi chương trình gặp tình ngoại lệ, thiếu nhớ tạo ngoại lệ Khi ngoại lệ tạo ra, việc thực thi chức hành bị treo việc xử lý ngoại lệ tương ứng tìm thấy

Điều có nghĩa chức hoạt động hành không thực việc xử lý ngoại lệ, chức bị chấm dứt hàm gọi nhận thay đổi đến việc xử lý ngoại lệ Nếu hàm gọi không thực việc xử lý ngoại lệ, ngoại lệ xử lý sớm CLR, điều dẫn đến chương trình kết thúc

Một trình xử lý ngoại lệ khối lệnh chương trình thiết kế xử lý ngoại lệ mà chương trình phát sinh Xử lý ngoại lệ thực thi trong câu lệnh catch Một cách lý tưởng ngoại lệ bắt xử lý, chương trình sửa chữa vấn đề tiếp tục thực hoạt động Thậm chí chương trình khơng tiếp tục, việc bắt giữ ngoại lệ có hội để in thơng điệp có ý nghĩa kết thúc chương trình cách rõ ràng

(141)

thể đặt đoạn mã khối finally, chắn thực chí có ngoại lệ xuất

28.2 Cách xử lý ngoại lệ

Một chương trình nên có chế xử lý ngoại lệ thích hợp Nếu khơng, chương trình bị ngắt ngoại lệ xảy Trong trường hợp đó, tất nguồn tài nguyên mà hệ thống cấp khơng giải phóng Điều gây lãng phí tài nguyên Để tránh trường hợp này, tất nguồn tài nguyên mà hệ thống cấp nên thu hồi lại Tiến trình địi hỏi chế xử lý ngoại lệ thích hợp Ví dụ, xét thao tác vào (I/O) tập tin Nếu việc chuyển đổi kiểu liệu không thực đúng, ngoại lệ xảy chương trình bị hủy mà khơng đóng tập tin lại Lúc tập tin dễ bị hư hại nguồn tài nguyên cấp phát cho tập tin không trả lại cho hệ thống

Một ngoại lệ (exception) chương trình C# dấu hiệu có xuất điều kiện khơng bình thường

Khi ngoại lệ xảy ra, đối tượng tương ứng với ngoại lệ tạo Đối tượng sau truyền cho phương thức nơi mà ngoại lệ xảy Đối tượng chứa thông tin chi tiết ngoại lệ Thơng tin nhận xử lý Các ngoại lệ ngoại lệ chuẩn C# ngoại lệ ta tạo

Sau bạn biết cách khai báo ném biệt lệ, phần việc quan trọng bắt xử lý biệt lệ Vấn đề người lập trình java phải biết đoạn mã gây lỗi Khi họ khoanh vùng đoạn mã gây lỗi họ đặt đoạn mã, có khả gây lỗi khối try ( thử làm), đặt đoạn mã xử lý lỗi khối catch ( bắt giữ)

28.3 Cấu trúc khối try …catch Khuôn dạng tổng quát sau:

try{

// Các lệnh có khả gây lỗi }

catch ( TypeException1 ex){

// Mã đựơc thực thi ngoại lệ TypeException1 đựơc phát sinh khối try }

catch ( TypeException2 ex){

// Mã đựơc thực thi ngoại lệ TypeException2 đựơc phát sinh khối try }

(142)

// Mã đựơc thực thi ngoại lệ TypeExceptionN đựơc phát sinh khối try

}

Nếu khơng có ngoại lệ phát sinh khối try mệnh đề catch bị bỏ qua, trường hợp câu lệnh bên khối try gây ngoại lệ thì, C# bỏ qua câu lệnh cịn lại khối try để tìm mã xử lý ngoại lệ, kiểu ngoại lệ so khớp với kiểu ngoại lệ mệnh đề catch, mã lệnh khối catch thực thi, khơng tìm thấy kiểu ngại lệ so khớp C# kết thúc phương thức chuyển biệt lệ phương thức gọi phương thức trình tiếp tục tìm thấy mã xử lý biệt lệ, khơng tìm thấy mã xử lý biệt lệ chuỗi phương thức gọi nhau, chương trình chấm dứt in thơng báo lỗi… Xem xét ví dụ sau:

using System; class Program { static void Main() { int a = 10; int b = 2;

int[] m ={ 1, 4, 6, }; try {

int c = a / b;//Co khả sinh lỗi mẫu số =0 Console.WriteLine("c={0}", c);

Console.WriteLine("m{0}={1}", c, m[c]);//m[c] có khả sinh lỗi vượt ngồi sơ mảng

} catch (DivideByZeroException ex) { Console.WriteLine(ex.Message);

} catch (IndexOutOfRangeException ex) { Console.WriteLine(ex.Message);

} catch (Exception ex) {

Console.WriteLine(ex.Message); }

Console.ReadKey(); }

(143)

Khối ‘finally’

Khi ngoại lệ xuất hiện, phương thức thực thi bị dừng mà khơng hồn thành Nếu điều xảy ra, đoạn mã phía sau (ví dụ đoạn mã có chức thu hồi tài nguyên, lệnh đóng tập viết cuối phương thức) không gọi Java cung cấp khối finally để giải việc Thông thường khối ‘finally’ chứa câu lệnh mang tính chất dọn dẹp như: đóng kết nối CSDL, đóng tệp tin,…

try{

// Các lệnh có khả gây lỗi }

catch ( TypeException1 ex){

// Mã đựơc thực thi ngoại lệ TypeException1 đựơc phát sinh khối try }

catch ( TypeException2 ex){

// Mã đựơc thực thi ngoại lệ TypeException2 đựơc phát sinh khối try }

catch ( TypeExceptionN ex){

// Mã đựơc thực thi ngoại lệ TypeExceptionN đựơc phát sinh khối try

} finally{

// khối lệnh thực cho dù ngoại lệ có xảy khối try hay không.

}

Khối ‘finally’ tuỳ chọn, khơng bắt buộc phải có Khối đặt sau khối ‘catch’ cuối Chương trình thực thi câu lệnh khối ‘finally’ sau gặp câu lệnh ‘return’ hay lệnh ‘break’ khối ‘try’

Khối ‘finally’ bảo đảm lúc thực thi, bất chấp có ngoại lệ xảy hay không 28.4 Luồng thực khối xử lý ngoại lệ

Luồng thực khối xử lý ngoại lệ minh hoa thơng qua sơ đồ khối sau:

(144)

28.5 Bài tập áp dụng

Bài 29: Bài thực hành xử lý ngoại lệ

Bài 30 : Hệ thống nhập xuất thường dùng C# 30.1 Giới thiệu hệ thống nhập xuất C#

Một chương trình thường xuyên làm việc với liệu, để lưu trữ lâu dài phải lưu trữ nhận lại liệu từ thiết bị lưu trữ ngồi, nguồn thơng tin ngồi khơng gồm liệu lưu trữ đĩa từ, đĩa CD mà liệu chương trình khác, có thể lưu trữ mạng… dù chúng lưu trữ đâu chúng có số dạng như: đối tượng, kí tự, hình ảnh âm thanh, dù liệu lưu trữ hình thức nào, lưu trữ đâu C# trừu tượng hố thành luồng(Streams), điều tinh vi làm cho ta không cần phải quan tâm liệu lưu trữ đâu, dạng thức nào, nó đồng nguồn liệu với nhau:

Để nhận thơng tin, chương trình mở luồng liên kết với đối tượng nguồn( tệp tin, nhớ, Socket) đọc thông tin tuần tự.

Tương tự để ghi thông tin thiết bị cách mở luồng đến đối tượng đích ghi thơng tin cách như

Luồng trừu tượng hoá mức cao, liệu đọc vào từ đâu ghi đâu, thuật toán đọc/ghi tựa sau:

Thực khối try

Tìm khối xử lý lỗi (khối catch) để

thực

Nếu ngoại lệ sinh khối try thể lớp ngoại

lệ ExceptionType1

Thực khối catch ứng với

ngoại lệ

Nếu ngoại lệ sinh khối try thể lớp ngoại

lệ ExceptionType2

Thực khối catch ứng với

ngoại lệ

false

true

true

false

…………

Nếu ngoại lệ sinh khối try thể lớp ngoại

lệ ExceptionTypeN

Thực khối catch ứng với

ngoại lệ

true

Có ngoại xẩy khối try

yes

no

(145)

Nhiều người nhầm lẫn khác tập tin luồng Một luồng đơn giản luồng thông tin, chứa thông tin chuyển qua, cịn tập tin để lưu trữ thông tin

Một luồng sử dụng để gởi nhận thông tin từ nhớ, từ mạng, web, từ chuỗi, Một luồng sử dụng để vào với tập tin liệu Thứ tự việc đọc tập tin

Khi đọc hay viết tập tin, cần thiết phải theo trình tự xác định Đầu tiên phải thực công việc mở tập tin Nếu tạo tập tin, việc mở tập tin lúc với việc tạo tập tin Khi tập tin mở, cần thiết phải tạo cho luồng để đặt thông tin vào tập tin lấy thông tin từ tập tin Khi tạo luồng, cần thiết phải thông tin trực tiếp qua luồng Sau tạo luồng gắn với tập tin, lúc thực việc đọc ghi liệu tập tin Khi thực việc đọc thông tin từ tập tin, cần thiết phải kiểm tra xem trỏ tập tin tới cuối tập tin chưa, tức đọc đến cuối tập tin hay chưa Khi hoàn thành việc đọc ghi thơng tin tập tin tập tin cần phải đóng lại

Tóm lại bước để làm việc với tậo tin là:

 Bước 1: Mở hay tạo tập tin

 Bước 2: Thiết lập luồng ghi hay đọc từ tập tin  Bước 3: Đọc hay ghi liệu lên tập tin

 Bước 4: Đóng lập tin lại 30.2 Làm việc với tệp thư mục 30.2.1 Làm việc với thư mục

Lớp Directory chứa đựng nhiều phương thức tĩnh cho phép tạo, dịch chuyển…thư mục Tất phương thức lớp Directory phương thức tĩnh Bởi gọi phương thưc mà không cần tạo thể lớp

Lớp DirectoryInfo giống lớp Directory, phương thức lớp

được thực qua thể lớp Lớp DirectoryInfo xuất phát

từ lớp FileSystemInfo Lớp

FileSystemInfo có chứa số thuộc tính phương thức file thư mục

(146)

Phương thức Cách sử dụng

CreateDirectory( ) Creates all directories and subdirectories specified by its path parameter

GetCreationTime( ) Returns and sets the time the specified directory was created.

GetDirectories( ) Gets named directories.

GetLogicalDrives( ) Returns the names of all the logical drives in the form <drive>:\.

GetFiles( ) Returns the names of files matching a pattern.

GetParent( )

Returns the parent directory for the specified path Move( )

Moves a directory and its contents to a specified path

Sau số phương thức thuộc tính lớp DirectoryInfo

Phương thức

thuộc tính Cách sử dụng

Attributes Inherits from FileSystemInfo; gets or sets the attributes of the current file

CreationTime Inherits from FileSystemInfo; gets or sets the creation time of the current file

Exists

(147)

Phương thức

thuộc tính Cách sử dụng

Extension Public property inherited from FileSystemInfo; i.e., the file extension

FullName Public property inherited from FileSystemInfo; i.e., the full path of the file or directory

LastAccessTime Public property inherited from FileSystemInfo; gets or sets the last access time

LastWriteTime Public property inherited from FileSystemInfo; gets or sets the time when the current file or directory was last written to

Name

Public property name of this instance of DirectoryInfo Parent

Public property parent directory of the specified directory Root

Public property root portion of the path Create( )

Public method that creates a directory CreateSubdirectory( )

Public method that creates a subdirectory on the specified path

Delete( ) Public method that deletes a DirectoryInfo and its contents from the path

GetDirectories( )

Public method that returns a DirectoryInfo array with subdirectories GetFiles( )

(148)

Phương thức

thuộc tính Cách sử dụng

GetFileSystemIn fos( )

Public method that retrieves an array of FileSystemInfo objects

MoveTo( ) Public method that moves a DirectoryInfo and its contents to a new path

Refresh( ) Public method inherited from FileSystemInfo; refreshes the state of the object

30.2.2 Làm việc với tệp

Để mở tập tin đĩa cho việc đọc viết tập tin văn bản, cần phải sử dụng hai lớp File FileInfo

Làm để biết sử dụng lớp File xác sử dụng lớp FileInfo chúng chứa phương thức tương tự với Thật hai lớp có nhiều khác biệt Lớp File chứa tất phương thức tĩnh, thêm vào lớp File tự động kiểm tra permission tập tin Trong muốn dùng lớp FileInfo phải tạo thể lớp Nếu muốn mở tập tin lần tốt sử dụng lớp File, tổ chức việc sử dụng tập tin nhiều lần bên chương trình, tốt ta dùng lớp FileInfo Hoặc khơng chắn cách sử dụng sử dụng lớp FileInfo

Sau số phương thức lớp file

Phương thức Cách sử dụng

AppendText( ) Creates a StreamWriter that appends text to the specified file

Copy( )

Copies an existing file to a new file Create( )

Creates a file in the specified path CreateText( )

(149)

Phương thức Cách sử dụng the specified file

Delete( )

Deletes the specified file Exists( )

Returns true if the specified file exists

GetAttributes(),

SetAttributes( ) Gets and sets the FileAttributes of the specified file

GetCreationTime( ),

SetCreationTime( ) Returns and sets the creation date and time of the file

GetLastAccessTime( ), SetLastAccessTime( )

Returns and sets the last time the specified file was accessed

GetLastWriteTime( ), SetLastWriteTime( )

Returns and sets the last time the specified file was written to

Move( )

Moves a file to a new location; can be used to rename a file

OpenRead( ) Public static method that opens a FileStream on the file

OpenWrite( )

Creates a read/write Stream on the specified path

(150)

Phương thức thuộc

tính Cách sử dụng

Attributes( ) Inherits from FileSystemInfo; gets or sets the attributes of the current file

CreationTime Inherits from FileSystemInfo; gets or sets the creation time of the current file

Directory

Public property that gets an instance of the parent directory Exists

Public property Boolean value that is TRue if the directory exists Extension

Public property inherited from FileSystemInfo; i.e., the file extension

FullName Public property inherited from FileSystemInfo; i.e., the full path of the file or directory

LastAccessTime Public property inherited from FileSystemInfo; gets or sets the last access time

LastWriteTime Public property inherited from FileSystemInfo; gets or sets the time when the current file or directory was last written to

Length

Public property that gets the size of the current file Name

Public property Name of this DirectoryInfo instance AppendText( )

Public method that creates a StreamWriter that appends text to a file CopyTo( )

(151)

Phương thức thuộc

tính Cách sử dụng

Create( )

Public method that creates a new file Delete( )

Public method that permanently deletes a file MoveTo( )

Public method to move a file to a new location; can be used to rename a file

Open( )

Public method that opens a file with various read/write and sharing privileges

OpenRead( )

Public method that creates a read-only FileStream

OpenText() Public method that creates a StreamReader that reads from an existing text file

OpenWrite( )

Public method that creates a write-only FileStream 30.3 Đọc ghi liệu

Stream hỗ trợ đọc ghi liệu đồng không đồng .Net Framework cung cấp số lớp dẫn xuất từ lớp Stream, bao gồm FileStream, MemoryStream, NetworkStream Có lớp

BufferedStream cung cấp vùng đệm I/O sử dụng cho luồng nhập xuất

Sau lớp I/O Net Framework

Lớp Cách sử dụng

Stream Abstract class that supports reading and writing bytes

BinaryReader/BinaryWri ter

(152)

Lớp Cách sử dụng

File, FileInfo,

Directory, DirectoryInfo

Provide implementations for the abstract FileSystemInfo classes, including creating, moving, renaming, and deleting files and directories

FileStream

For reading to and from File objects; supports random access to files Opens files synchronously by default; supports

asynchronous file access

Textreader,TextWriter, StringReader,

StringWriter

TexTReader and TextWriter are abstract classes designed for Unicode character I/O StringReader and

StringWriter write to and from strings, allowing your input and output to be either a stream or a string

BufferedStream

A stream that adds buffering to another stream such as a NetworkStream BufferedStreams can improve performance of the stream to which they are attached, but note that FileStream has buffering built in

MemoryStream A nonbuffered stream whose encapsulated data is directly

accessible in memory, and is most useful as a temporary buffer

NetworkStream A stream over a network connection

Thao tác tệp văn bản

Để đọc/ghi liệu vào tệp văn Net Framework cung cấp cho ta hai lớp dễ sử dụng lớp StreamWriter StreamReader có chừa phương thức để giúp ta dễ dàng thao tác tệp văn giống ta thao tác với việc đọc ghi liệu mà hình, bàn phím

(153)

using System; using System.IO; class ViDu {

static void Main() {

string fileName; string cauTho; string tenBaiTho; bool ok;

ConsoleKeyInfo kt; do{

Console.Write("Nhap vao ten tep chua bai tho:"); fileName = Console.ReadLine();

ok = false;

if(File.Exists(fileName)) {

Console.WriteLine("Tep da ton tai ban co muon ghi de C/K?"); kt=Console.ReadKey();

if (kt.KeyChar == 'c' || kt.KeyChar == 'C') ok = false; else ok = true;

}

}while(ok);

StreamWriter myfile=File.CreateText(fileName);

Console.WriteLine("\t\tBAN HAY NHAP VAO MOT BAI THO BAN YEU THICH\n"); Console.Write("Nhap vao ten bai tho:");tenBaiTho = Console.ReadLine();

myfile.WriteLine("\t\t{0}", tenBaiTho); myfile.WriteLine();

int i=0; {

(154)

myfile.WriteLine("{0}:{1}",i,cauTho);

Console.WriteLine("Ban co muon nhap tiep C/K"); kt = Console.ReadKey();

} while (kt.KeyChar == 'c' || kt.KeyChar == 'C'); myfile.Close();

} }

Ví dụ 2: Cho tệp có tên d:\dulieu.txt lưu trữ thông tin n dãy số Biết phần tử dãy lưu dòng, phần tử dãy đặt cách dấu cách Hãy đọc nơi dung tệp tìm giá trị lớn số phần tử dẫy ghi giá trị vào cuối tệp

using System; using System.IO; class ViDu1 {

static void Main() {

string xau;

int[][] a=new int[50][]; int d,n=0;

StreamReader f1=File.OpenText("D:/dulieu.txt"); xau = f1.ReadLine();

do{

d = 0;

foreach(string in xau.Split(' ')) if (con.Length > 0)

{

Array.Resize(ref a[n], ++d); a[n][d - 1] = int.Parse(con); }

(155)

}while(xau!=null); f1.Close();

int j,i,max=a[0][0]; for (i = 0; i < n; ++i)

for (j = 0; j < a[i].Length; ++j) if (max < a[i][j]) max = a[i][j];

StreamWriter f2 = File.AppendText("D:/dulieu.txt"); f2.WriteLine();

f2.WriteLine("Phan tu lon nhat cua cac day la {0}", max); f2.Close();

} }

Bài 31: Bài thực hành nhập xuất tệp tin C#

Bài 32: Thảo luận số toán khoa học kỹ thuật Bài 33: Bài thực hành toán tổng hợp

ngơn ngữ máy tính ngôn ngữ ngôn ngữ tựnhiên) dạng m người lập trình, máy tính khá biên dịch phần mềm o cú pháp c thị máy tính vùng nhớ). lập trình ứng dụng mệnh lệnh thập niên 1970 Ken Thompson Dennis Ritchie hệ điều hành UNIX. phần mềm hệ thống, m ứng dụng. khoahọc máy tính m ngơn ngữ lập trình. ngơn ngữ đa mẫu hình kiểu tĩnh lập trình thủ tục, liệu trừu trượng, lậptrình hướng đối tượng, lập trình đa hình. thập niên 1990, Bjarne Stroustrup Bell Labs thập niên 1980 C. hàm ảo, toán tử tải, đa kếthừa, tiêu bản, xử lý ngoại lệ. 1998 n 2003 Microsoft, NET ECMA C++ Java. , Visual Basic , Delphi và máy tính mệnh lệnh, Niklaus Wirth 1970 lập trình có cấu trúc. Algol Blaise Pascal. Modula-2 Oberon, Macintosh chữ TeX Web l Donald Knuth đã mã nguồn t mã máy hoặ thông dịch m nh bytecode, byt Python , Perl , PHP, Cú pháp J xử lý cấp thấp hơ

Ngày đăng: 29/03/2021, 13:34

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan