Bài giảng môn lập trình Windows 1
Gửi bởi: Khoa CNTT - HCEM 10 tháng 9 2020 lúc 9:50:34 | Được cập nhật: 6 tháng 5 lúc 4:58:31 Kiểu file: PDF | Lượt xem: 274 | Lượt Download: 4 | File size: 1.338611 Mb
Nội dung tài liệu
Tải xuống
Link tài liệu:
Các tài liệu liên quan
Có thể bạn quan tâm
Thông tin tài liệu
Bài giảng môn lập trình windows 1
MỤC LỤC
BÀI 1: MICROSOFT.NET ................................................................................................. 4
1.1 Microsoft.NET ............................................................................................................. 4
1.1.1 Tổng quan ............................................................................................................. 4
1.1.2 Giới thiệu về Visual Studio.NET.......................................................................... 4
1.2 Biên dịch và MSIL ...................................................................................................... 5
1.3 Ngôn ngữ C# ............................................................................................................... 6
BÀI 2: NGÔN NGỮ C# ....................................................................................................... 7
2.1 Tại sao phải sử dụng ngôn ngữ C# .............................................................................. 7
2.3 Các bước chuẩn bị cho chương trình ........................................................................... 8
2.4 Chương trình C# đơn giản ........................................................................................... 8
2.5 Bài tập ........................................................................................................................ 11
CHƢƠNG 3: CƠ BẢN VỀ C# .......................................................................................... 13
3.1 Kiểu dữ liệu ............................................................................................................... 13
3.2 Biến và hằng .............................................................................................................. 16
3.2.1 Biến..................................................................................................................... 16
3.2.2 Hằng ................................................................................................................... 16
3.3 Định danh (tên) .......................................................................................................... 16
3.4 Biểu thức.................................................................................................................... 16
3.5 Khoảng trắng ............................................................................................................. 17
3.6 Toán tử ....................................................................................................................... 17
3.7 Nhập xuất dữ liệu ...................................................................................................... 21
3.7.1 Xuất dữ liệu ra màn hình .................................................................................... 21
3.7.2 Nhập dữ liệu từ bàn phím ................................................................................... 21
3.7.3 Ví dụ ................................................................................................................... 22
3.8 Câu lệnh (statement) .................................................................................................. 23
3.8.1 Cấu trúc điều kiện ............................................................................................... 23
3.8.2 Cấu trúc lựa chọn switch… case ........................................................................ 25
3.8.3 Cấu trúc lặp for ................................................................................................... 28
3.8.4 Vòng lặp không xác định while .......................................................................... 31
3.8.5 Vòng lặp không xác định do … while ................................................................ 32
3.9 Namespace ................................................................................................................. 33
CHƢƠNG 4: PHƢƠNG THỨC ....................................................................................... 35
4.1 Khai báo phương thức ............................................................................................... 35
4.2 Phương thức trả về giá trị .......................................................................................... 35
4.3 Phương thức kiểu void............................................................................................... 36
4.4 Phạm vi của biến ....................................................................................................... 36
4.5 Một vài phương thức toán học thường dùng trong lớp Math .................................... 36
4.6 Ví dụ minh họa .......................................................................................................... 37
4.7 Truyền đối số kiểu tham chiếu có từ khóa ref hoặc out ............................................ 38
4.8 Bài tập ........................................................................................................................ 42
CHƢƠNG 5: XÂY DỰNG LỚP – ĐỐI TƢỢNG ........................................................... 43
5.1 Lớp và đối tượng ....................................................................................................... 43
5.1.1 Định nghĩa lớp .................................................................................................... 43
5.1.2 Thuộc tính truy cập ............................................................................................. 44
5.1.3 Tạo đối tượng ..................................................................................................... 45
5.1.4 Sử dụng đối tượng .............................................................................................. 45
5.2 Phương thức khởi tạo (Constructor) .......................................................................... 46
5.3 Hủy đối tượng ............................................................................................................ 48
5.3.1 Bộ hủy của C# .................................................................................................... 48
Tr
n
o
n n
n
N
–
M
–
u
–
N
1
Bài giảng môn lập trình windows 1
5.4 Nạp chồng phương thức ............................................................................................ 48
5.5 Đóng gói dữ liệu với thành phần thuộc tính .............................................................. 49
5.5.1 Truy cập lấy dữ liệu (get accessor) ..................................................................... 51
5.5.2 Bộ truy cập thiết lập dữ liệu (set accessor) ......................................................... 51
CHƢƠNG 6: MẢNG, CHỈ MỤC ..................................................................................... 52
6.1 Mảng một chiều ......................................................................................................... 52
6.1.1 Khai báo mảng: ................................................................................................... 52
6.1.2 Truy cập các thành phần trong mảng ................................................................. 53
6.1.3 Khởi tạo các thành phần của mảng ..................................................................... 54
6.1.4 Câu lệnh lặp foreach ........................................................................................... 54
6.1.5 Sử dụng từ khóa params ..................................................................................... 55
6.2 Mảng đối tượng ......................................................................................................... 56
6.3 Mảng đa chiều ( 2 chiều) ........................................................................................... 57
6.4 Bộ chỉ mục ................................................................................................................. 58
6.5 Bài tập ........................................................................................................................ 61
CHƢƠNG 7: KẾ THỪA – ĐA HÌNH ............................................................................. 63
7.1 Đặc biệt hóa và tổng quát hóa ................................................................................... 63
7.2 Sự kế thừa .................................................................................................................. 63
7.3 Đa hình ...................................................................................................................... 66
7.4 Lớp trừu tượng........................................................................................................... 68
7.5 Các lớp lồng nhau ...................................................................................................... 69
CHƢƠNG 8: NẠP CHỒNG TOÁN TỬ .......................................................................... 70
8.1 Sử dụng từ khóa operator .......................................................................................... 70
8.2 Sử dụng toán tử .......................................................................................................... 71
8.3 Toán tử so sánh bằng ................................................................................................. 72
8.4 Toán tử chuyển đổi .................................................................................................... 73
8.5 Bài tập ........................................................................................................................ 74
CHƢƠNG 9: THỰC THI GIAO DIỆN ........................................................................... 75
9.1 Thực thi giao diện ...................................................................................................... 75
9.2 Truy cập phương thức giao diện ................................................................................ 79
9.3 Thực thi phủ quyết giao diện ..................................................................................... 83
9.4 Thực thi giao diện tường minh .................................................................................. 83
9.5 Bài tập ........................................................................................................................ 84
CHƢƠNG 10: XỬ LÝ CHUỖI ........................................................................................ 85
10.1 Lớp string ................................................................................................................ 85
10.2 Tạo một chuỗi .......................................................................................................... 85
10.3 Tạo chuỗi bằng phương thức ToString() ................................................................. 85
10.4 Thao tác trên chuỗi .................................................................................................. 86
10.5 Các biểu thức quy tắt ............................................................................................... 88
10.6 Bài tập ...................................................................................................................... 90
CHƢƠNG 11: CƠ CHẾ ỦY QUYỀN – SỰ KIỆN ......................................................... 91
11.1 Cơ chế ủy quyền ...................................................................................................... 91
11.2 Các sự kiện .............................................................................................................. 92
11.3 Bài tập ...................................................................................................................... 95
CHƢƠNG 12: CÁC LỚP CƠ SỞ .NET .......................................................................... 96
12.1 Lớp đối tượng trong .NET ....................................................................................... 96
12.2 Các lớp cơ sở ........................................................................................................... 97
12.2.1. Lớp Timer ........................................................................................................ 97
12.2.2 Lớp Math .......................................................................................................... 99
12.2.3 Lớp thao tác tập tin ......................................................................................... 101
12.3 Bài tập .................................................................................................................... 106
Tr
n
o
n n
n
N
–
M
–
u
–
N
2
Bài giảng môn lập trình windows 1
TÀI LIỆU THAM KHẢO............................................................................................... 107
Tr
n
o
n n
n
N
–
M
–
u
–
N
3
Bài giảng môn lập trình windows 1
BÀI 1: MICROSOFT.NET
1.1 Microsoft.NET
1.1.1 Tổng quan
Microsoft.Net gồm 2 phần chính: Framework (khung cảnh) và IDE( Intergrated
Development Environment – Môi trường phát triển tích hợp). Framework cung cấp những
thứ cần thiết và căn bản, còn IDE cung cấp một môi trường giúp ta triển khai dễ dàng và
nhanh chóng những ứng dụng trên nền tảng .NET. Nếu không có IDE chúng ta cũng có thể
dùng một trình soạn thảo như Nodepad hay bất kỳ trình soạn thảo văn bản nào và sử dụng
command line để biên dịch và thực thi, tuy nhiên việc sử dụng các trình soạn thảo tương
đối mất nhiều thời gian. Cách tốt nhất và hiệu quả nhất là sử dụng IDE để phát triển ứng
dụng.
Microsoft.NET là nền tảng cho việc xây dựng và thực thi các ứng dụng phân tán thế
hệ kế tiếp. Bao gồm các ứng dụng từ client đến server và các dịch vụ khác. Một số tính
năng của Microsoft.Net cho phép nhà phát triển sử dụng như sau:
o Một mô hình lập trình cho phép nhà phát triển xây dựng các ứng dụng dịch
vụ web và ứng dụng client với XML.
o Tập hợp dịch vụ XML web cho phép nhà phát triển đơn giản và tích hợp
người dùng kinh nghiệm
o Cung cấp các server phục vụ bao gồm: Windows 2000, SQL Server,…
o Các phần mềm client như Windows XP giúp người phát triển phân phối sâu
và thuyết phục người dùng thông qua các dòng thiết bị.
o Nhiều công cụ hỗ trợ như Visual Studio.net để phát triển các dịch vụ web
XML, ứng dụng trên nền Windows hay trên nền web một cách dễ dàng và
hiệu quả.
1.1.2 Giới thiệu về Visual Studio.NET
Visual Studio .NET là môi trường tích hợp phát triển phần mềm (Integrated
Development Environment (IDE) ) của Microsoft ,là công cụ cho phép ta viết mã, gỡ rối và
biên dịch chương trình trong nhiều ngôn ngữ lập trình .NET khác nhau
.NET Framework: .NET được developed từ đầu năm 1998, lúc đầu có tên là
Next Generation Windows Services (NGWS). Nó được thiết kế hoàn toàn từ con số
không để dùng cho Internet. Ý tưởng của Microsoft là xây dựng một globally distributed
system, dùng XML (chứa những databases tí hon) làm chất keo để kết hợp chức năng của
những computers khác nhau trong cùng một tổ chức hay trên khắp thế giới.
Những computers này có thể là Servers, Desktop, Notebook hay Pocket Computers, đều có
thể chạy cùng một software dựa trên một platform duy nhất, độc lập với hardware và ngôn
Tr
n
o
n n
n
N
–
M
–
u
–
N
4
Bài giảng môn lập trình windows 1
ngữ lập trình. Đó là .NET Framework. Nó sẽ trở thành một phần của MS Windows và sẽ
được port qua các platform khác, có thể ngay cả Unix
Để cung cấp một môi trường lập trình hướng đối tượng vững chắc, trong đó
mã nguồn đối tượng được lưu trữ và thực thi một cách cục bộ. Thực thi cục bộ nhưng được
phân tán trên Internet, hoặc thực thi từ xa.
Để cung cấp một môi trường thực thi mã nguồn mà tối thiểu được việc đóng
gói phần mềm và sự tranh chấp về phiên bản.
Thư viện lớp, một thành phần chính khác của .NET Framework là một tập hợp
hướng đối tượng của các kiểu dữ liệu được dùng lại, nó cho phép ta có thể phát triển những
ứng dụng từ những ứng dụng truyền thông command-line hay những ứng dụng có giao
diện đồ họa (GUI) đến những ứng dụng mới nhất được cung cấp bởi ASP.NET.
Common Language Runtime(CLR)
CLR thực hiện quản lý bộ nhớ, quản lý thực thi tiểu trình, thực thi mã nguồn, xác
nhận mã nguồn an toàn, biên dịch và các dịch vụ hệ thống khác. Những đặc tính trên là nền
tảng cơ bản cho những mà nguồn được quản lý chạy trên CLR.
CLR thúc đẩy việc mã nguồn thực hiện việc truy cập được bảo mật. ví dụ người sử
dụng giái hạn rằng việc thực thi nhúng vào trong một trang web có thể chạy được hoạt hình
trên màn hình nhưng không thể truy cập được dữ liệu riêng, tập tin hệ thống, hay truy cập
mạng.
Thƣ viện lớp .NET Framework
Thư viện lớp .NET Framework là một tập hợp những kiểu dữ liệu được dùng lại và
được kết hợp chặt chẽ với CLR. Thư viện lớp là hướng đối tượng cung cấp những kiểu dữ
liệu mà mã nguồn được quản lý của ta có thể dẫn xuất.
1.2 Biên dịch và MSIL
Trong .NET Framework, chương trình không được biên dịch vào các tập tin thực thi
mà thay vào đó chúng được biên dịch vào những tập tin trung gian gọi là Microsoft
Intermediate Language ( MSIL). Những tập tin MSIL được tạo ra từ C# cũng tương tự như
các tập tin MSIL được tạo ra từ những ngôn ngữ khác của .NET.
Mã nguồn C# được biên dịch vào MSIL khi ta build project. Mã này được lưu vào
trong một tập tin trên đĩa. Khi ta chạy chương trình, thì MSIL được biên dịch một lần nữa,
sử dụng trình biên dịch Just – In – Time (JIT).
Do tất cả các ngôn ngữ .NET Framework cùng tạo ra sản phẩm MSIL giống nhau,
nên kết quả là một đối tượng được tạo ra từ ngôn ngữ này có thể được truy cập hay được
dẫn xuất từ một đối tượng của ngôn ngữ khác trong .NET.
Tr
n
o
n n
n
N
–
M
–
u
–
N
5
Bài giảng môn lập trình windows 1
1.3 Ngôn ngữ C#
Ngôn ngữ C# khá đơn giản nhưng nó có ý nghĩa cao khi thực thi khái niệm lập trình
hiện đại. C# bao gồm tất cả những hỗ trợ cho cấu trúc, thành phần component, lập trình
hướng đối tượng. Những tính chất đó hiện diện trong một ngôn ngữ lập trình hiện đại.
Trong ngôn ngữ C# mọi thứ liên quan đến khai báo lớp đều được tìm thấy trong phần
khai báo của nó. Định nghĩa một lớp trong ngôn ngữ C# không đòi hỏi phải chia ra tập tin
header và tập tin nguồn giống như trong ngôn ngữ C++.
C# cũng hỗ trợ giao diện interface, nó được xem như một cam kết với một lớp cho
những dịch vụ mà giao diện quy định. Trong ngôn ngữ C#, một lớp chỉ có thể kế thừa từ
duy nhất một lớp cha, tức là không cho đa kế thừa, nhưng một lớp có thể thực thi nhiều
giao diện. Khi một lớp thực thi một giao diện thì nó sẽ cung cấp chức năng thực thi giao
diện.
Trong ngôn ngữ C#, những cấu trúc cũng được hỗ trợ, nhưng khái niệm về ngữ nghĩa
của nó thay đổi khác với C++. Trong C#, một cấu trúc được giới hạn là kiểu dữ liệu nhỏ
gọn, và khi tạo thể hiện thì nó yêu cầu ít hơn về hệ điều hành với bộ nhớ so với một lớp.
Một cấu trúc thì không thể kế thừa từ một lớp hay được kế thừa nhưng một cấu trúc có thể
thực thi một giao diện.
Ngôn ngữ C# cung cấp những đặc tính hướng thành phần (component - oriented),
như là những thuộc tính, những sự kiện. Lập trình hướng thành phần được hỗ trợ bởi CLR
cho phép lưu trữ metadata với mã nguồn cho một lớp.
Tr
n
o
n n
n
N
–
M
–
u
–
N
6
Bài giảng môn lập trình windows 1
BÀI 2: NGÔN NGỮ C#
2.1 Tại sao phải sử dụng ngôn ngữ C#
Ngôn ngữ C# là một ngôn ngữ được dẫn xuất từ C và C++.
# l n ôn n ữ
n
ản
C# loại bỏ một vài sự phức tạp của các ngôn ngữ khác như C++, bao gồm loại bỏ
những macro, template, đa kế thừa, lớp cơ sở ảo vì chúng là nguyên nhân gây ra sự nhầm
lẫn.
C# là ngôn ngữ đơn giản vì nó dựa trên nền tảng C và C++, C# khá giống về diện
mạo, cú pháp, biểu thức, toán tử và những chức năng khác được lấy trực tiếp từ C và C++.
# l n ôn n ữ
n ạ
Điều gì làm cho một ngôn ngữ hiện đại? Những đặc tính như là xử lý ngoại lệ, thu
gom bộ nhớ tự động, những kiểu dữ liệu mở rộng, và bảo mật mã nguồn là những đặc tính
được mong đợi trong một ngôn ngữ hiện đại. C# chứa tất cả những đặc tính trên. Nếu là
người mới học lập trình có thể chúng ta sẽ cảm thấy những đặc tính trên phức tạp và khó
hiểu.
!Ghi chú: Con trỏ được tích hợp vào ngôn ngữ C++. Chúng cũng là nguyên nhân gây
ra những rắc rối của ngôn ngữ này. C# loại bỏ những phức tạp và rắc rối phát sinh bởi con
trỏ. Trong C#, bộ thu gom bộ nhớ tự động và kiểu dữ liệu an toàn được tích hợp vào ngôn
ngữ, sẽ loại bỏ những vấn đề rắc rối của C++.
# l n ôn n ữ
ớn
ố t ợn
Những đặc điểm chính của ngôn ngữ hướng đối tượng (Object-oriented language) là
sự đóng gói (encapsulation), sự kế thừa (inheritance), và đa hình (polymorphism). C# hỗ
trợ tất cả những đặc tính trên. Phần hướng đối tượng của C# sẽ được trình bày chi tiết trong
một chương riêng ở phần sau.
# l n ôn n ữ mạn mẽ v
ũn m m dẻo
Như đã đề cập trước, với ngôn ngữ C# chúng ta chỉ bị giới hạn ở chính bởi bản thân
hay là trí tưởng tượng của chúng ta. Ngôn ngữ này không đặt những ràng buộc lên những
việc có thể làm. C# được sử dụng cho nhiều các dự án khác nhau như là tạo ra ứng dụng xử
lý văn bản, ứng dụng đồ họa, bản tính, hay thậm chí những trình biên dịch cho các ngôn
ngữ khác.
# l n ôn n ữ ít từ k ó
C# là ngôn ngữ sử dụng giới hạn những từ khóa. Phần lớn các từ khóa được sử dụng
để mô tả thông tin. Chúng ta có thể nghĩ rằng một ngôn ngữ có nhiều từ khóa thì sẽ mạnh
hơn.
Tr
n
o
n n
n
N
–
M
–
u
–
N
7
Bài giảng môn lập trình windows 1
Điều này không phải sự thật, ít nhất là trong trường hợp ngôn ngữ C#, chúng ta có
thể tìm thấy rằng ngôn ngữ này có thể được sử dụng để làm bất cứ nhiệm vụ nào.
2.3 Các bƣớc chuẩn bị cho chƣơng trình
Khi tạo một chương trình trong C# hay bất kỳ ngôn ngữ nào khác, đều tuân theo các
bước tuần tự sau:
- Xác định mục tiêu của chương trình
- Xác định những phương pháp giải quyết vấn đề
- Tạo một chương trình để giái quyết vấn đề
- Thực thi chương trình để xem kết quả
2.4 Chƣơng trình C# đơn giản
Để bắt đầu tìm hiểu ngôn ngữ C# và tạo tiền đề cho các chương sau, ta sẽ xem
chương trình C# đơn giản sau:
Để bắt đầu với chương trình đầu tiên, ta phải cài đặt bộ Visual Studio.NET (2005),
sau đó thực hiện tuần tự các bước sau:
- Nhấn Start/ nhấn All Program
- Chọn Microsoft Visual Studio 2005
- Từ menu File chọn New, chọn Project thì hình 1 xuất hiện.
Từ hình 1
Tr
n
o
n n
n
N
–
M
–
u
–
N
8
Bài giảng môn lập trình windows 1
using System;
using System.Collections.Generic;
using System.Text;
namespace chuongtrinhdautien
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(" Welcome to C#");
}
}
}
Lớp, đối tƣợng và kiểu dữ liệu (type)
Điều cốt lõi của lập trình hướng đối tượng là tạo ra các kiểu mới, nó có thể là một
bảng dữ liệu, một tiểu trình, hay một nút lệnh trong cửa sổ. Kiểu được định nghĩa như một
dạng vừa có thuộc tính chung và các hành vi của nó.
Cũng như nhiều ngôn ngữ lập trình hướng đối tượng khác, kiểu trong C# được định
nghĩa là một lớp (class) và các thể hiện của từng lớp được gọi là đối tượng (object).
Để định nghĩa một lớp trong C#, ta sử dụng từ khóa class, sau đó đến tên lớp. Thân
của lớp được nằm trong dấu {}.
Chú ý: sau khai báo lớp trong C# không có dấu ;
Tr
n
o
n n
n
N
–
M
–
u
–
N
9
Bài giảng môn lập trình windows 1
Phƣơng thức
Hai thành phần chính cấu thành một lớp là thuộc tính hay phương thức. Phương thức
chính là các hàm thành viên trong một lớp. Về bản chất, phương thức trong C# cũng giống
như hàm trong C++. Trong ví dụ trên, chúng ta có một phương thức, nhưng đây là một
phương thức đặc biệt đó là phương thức Main().
Khi chương trình thực thi, CLR gọi hàm Main() đầu tiên, hàm Main() là đầu vào của
chương trình, và mỗi chương trình đều phải có một hàm Main().
Để khai báo một phương thức, ta phải xác định kiểu giá trị trả về, tên phương thức,
và các tham số càn thiết cho phương thức thực hiện.
Chú thích
Một chương trình tốt là một chương trình có các dòng chú thích kèm theo. Các đoạn
chú thích này sẽ không được biên dịch và cũng không tham gia vào chương trình. Mục
đích chính của nó là làm cho đoạn mã nguồn rõ ràng và dễ hiểu.
Cũng giống như trong C++, trong ngôn ngữ C# chúng ta có 2 cách chú thích. Để chú
thích trên một dòng thì ta bắt đầu bằng 2 ký tự “//”. Khi trình biên dịch gặp 2 ký tự này thì
sẽ bỏ qua dòng đó.
Ví dụ: // khởi tạo đối tượng
Để chú thích trên nhiều dòng thì ta bắt đầu bởi ký tự “/*” và kết thúc bởi “*/”.
Ứng dụng Console
Ví dụ đơn giản trên được gọi là ứng dụng Console, ứng dụng này giao tiếp với người
dùng thông qua bàn phím và không có giao diện người dùng (GUI). Trong các chương
trình xây dựng các ứng dụng nâng cao trên Windows hay trên Web thì ta mới sự dụng giao
diện đồ họa. Trong giáo trình này, sẽ sử dụng thuần túy các ứng dụng console.
Namespace
.NET cung cấp một thư viện các lớp đồ sộ và thư viện này có tên là FCL (
Framework Class Library), trong đó Console là một lớp nhỏ trong thư viện. Do đó sẽ nảy
sinh vấn đề là người lập trình không thể nhớ hết được tên của các lớp trong .NET
Framework. Đặc biệt là sau này ta có thể tạo ra một lớp mà lớp này lại trùng với lớp đã có
trong thư viện, điều này dẫn đến sự tranh chấp khi biên dịch vì C# chỉ cho phép một tên
duy nhất.
Giải pháp để giải quyết vấn đề là việc tạo ra một không gian tên namespace,
namespace sẽ hạn chế phạm vi của 1 tên, làm cho tên này chỉ có ý nghĩa trong vùng đã
định nghĩa.
Toán tử ‘.’
Tr
n
o
n n
n
N
–
M
–
u
–
N
10
Bài giảng môn lập trình windows 1
Toán tử „.‟ Được sử dụng để truy cập đến phương thức hay thuộc tính trong một lớp,
và ngăn cách giữa tên lớp đến một namespace. Việc thực hiện này được viết theo hướng từ
trên xuống (hay từ cao xuống thấp), trong đó mức đầu tiên là namespace, rồi đến lớp, đến
phương thức,…tuy nhiên nếu ta đã khai báo namespace rồi thì ta hoàn toàn có thể bỏ qua
không gian tên.
Từ khóa using
Để cho chương trình trở lên gọn hơn, không mất thời gian phải viết từng namespace
cho từng đối tượng, C# cung cấp từ khóa using, sau từ khóa này là một namespace với mô
tả đầy đủ trong cấu trúc phân cấp của nó.
Ví dụ, khi ta bắt đầu mở một dự án mới, luôn xuất hiện: using System;
C# là ngôn ngữ phân biệt chữ hoa và chữ thƣờng
Giống như C,C++, C# là ngôn ngữ phân biệt chữ hoa với chữ thường. Khi ta viết sai,
C# sẽ không tự sửa lỗi này, chúng chỉ báo cho ta biết đang bị lỗi tại vị trí đó khi chúng ta
đưa vào chương trình gỡ rối.
2.5 Bài tập
Bài 1: Nhập vào đoạn chương trình sau, hãy biên dịch nó, cho biết chương trình trên
thực hiện điều gì?
using System;
namespace vidu1
{
class vidu
{
static void Main(string[] args)
{
int bk = 4;
const double PI = 3.14;
double cvi, dtich;
dtich = PI * bk * bk;
cvi = 2 * bk * PI;
//in ket qua
Console.WriteLine(" Ban kinh = {0} la ", bk);
Console.WriteLine(" dien tich = {0} la ", dtich);
Console.WriteLine(" Chu vi = {0} la ", cvi);
}
}
}
Bài 2: Chương trình sau có lỗi, biên dịch và sửa lỗi
class test
{
Console.WriteLine(“ Xin chao”);
Consoile.Writeline(“Tam biet”);
Tr
n
o
n n
n
N
–
M
–
u
–
N
11
Bài giảng môn lập trình windows 1
}
Bài 3: Xuất ra màn hình bài thơ sau:
Rằm tháng giêng
Rằm xuân lồng lộng trăng soi
Sông xuân nước lẫn màu trời thêm xuân
Giữa dòng bàn bạc việc quân
Khuya về bát ngát trăng ngân đầy thuyền.
Tr
n
o
n n
n
N
–
M
–
u
–
N
12
Bài giảng môn lập trình windows 1
CHƢƠNG 3: CƠ BẢN VỀ C#
Trong chương 2 chúng ta đã tìm hiểu sơ qua về chương trình C# đơn giản nhất.
Trong chương này ta sẽ thảo luận về hệ thống kiểu dữ liệu, phân biệt kiểu dữ liệu xây dựng
sẵn với kiểu dữ liệu do người dùng định nghĩa. Một số vấn đề cơ bản về tạo và sử dụng
biến, hằng, biểu thức và câu lệnh.
3.1 Kiểu dữ liệu
C# là ngôn ngữ lập trình mạnh về kiểu dữ liệu. Một ngôn ngữ mạnh về kiểu dữ liệu
là ngôn ngữ phải khai báo kiểu của mỗi đối tượng khi khởi tạo và trình biên dịch sẽ giúp
cho người lập trình không bị lỗi khi chỉ cho phép một loại kiểu dữ liệu có thể được gán cho
các kiểu dữ liệu khác. Kiểu dữ liệu của một đối tượng là một tín hiệu để trình biên dịch
nhận biết kích thước của một đối tượng và khả năng hoạt động của nó.
Kiểu dữ liệu trong C# được chia thành 2 loại: kiểu xây dựng sẵn (built – in ) và kiểu
dữ liệu do người dùng định nghĩa (user – defined ).
C# phân tập hợp kiểu dữ liệu này thành 2 loại: kiểu dữ liệu giá trị và kiểu dữ liệu
tham chiếu. Lý do của việc phân chia này là do sự khác nhau khi lưu kiểu dữ liệu giá trị và
kiểu dữ liệu tham chiếu trong bộ nhớ. Đối với kiểu dữ liệu giá trị thì được lưu giữ kích
thước thật trong bộ nhớ đã cấp phát là stack, trong khi đó thì địa chỉ của kiểu dữ liệu tham
chiếu thì được lưu trong stack nhưng đối tượng thật thì lưu trong bộ nhớ heap.
Chú ý: Tất cả các kiểu dữ liệu xây dựng sẵn đều là kiểu dữ liệu giá trị (trừ các đối
tượng và chuỗi), còn tất cả các kiểu do người dùng định nghĩa (trừ kiểu cấu trúc) đều là
kiểu dữ liệu tham chiếu. Trong chương này chúng ta quan tâm đến kiểu dữ liệu xây dựng
sẵn.
C# đưa ra các kiểu dữ liệu xây dựng sẵn rất hữu ích, phù hợp với ngôn ngữ lập trình
hiện đại. Mỗi kiểu dữ liệu được ánh xạ đến một kiểu dữ liệu được hỗ trợ trong .NET. Việc
ánh xạ các kiểu dữ liệu nguyên thủy của C# đến các kiểu dữ liệu của .NET sẽ đảm bảo các
đối tượng được tạo ra trong C# có thể được sử dụng đồng thời với các đối tượng được tạo
bởi bất cứ ngôn ngữ khác được biên dịch bởi .NET.
Mỗi kiểu dữ liệu có môt sự xác nhận và kích thước không thay đổi.
Bảng mô tả các kiểu dữ liệu xây dựng sẵn
Kiểu C#
Số byte
Kiểu .NET
Mô tả
byte
1
Byte
Số nguyên dương không dấu: 0- 255
char
2
Char
Ký tự Unicode
bool
1
Boolean
Giá trị logic true/false
sbyte
1
Sbyte
Số nguyên có dấu: -128 đến 127
Tr
n
o
n n
n
N
–
M
–
u
–
N
13
Bài giảng môn lập trình windows 1
short
2
Int16
Số nguyên có dấu giá trị từ - 32768 đến 32767
ushort
2
Uint16
Số nguyên không dấu: 0 – 65.535
int
4
Int32
Số nguyên có dấu từ - 2.147.483.647 đến
2.147.483.647
uint
4
Uint32
Số nguyên không dấu: 0 – 4.294.967.295
float
4
Single
Kiểu chấm động, giá trị xấp xỉ từ 3,4E-38 đến
3,4E38 với 7 chữ số có nghĩa
double
8
Double
Kiểu chấm động có độ chính xác gấp đôi, giá trị từ
1,7E-308 đến 1,7E308, với 15 chữ số có nghĩa
decimal
8
Decimal
Có độ chính xác đến 28 chữ số, được dùng trong
tính toán tài chính, kiểu này đòi hỏi phải có hậu tố
“m” hay “M” theo sau giá trị.
long
8
Int64
Kiểu số nguyên có dấu có giá trị trong khoảng 9.223.370.036.854.808 đến
9.223.370.036.854.775.807
ulong
8
Uint64
Số nguyên không dấu: 0 đến 0xffffffffffffffff
Chú ý: khác với C++, kiểu giá trị logic trong C# chỉ có thể nhận giá trị true hay false,
chúng ta không thể gán một giá trị nguyên vào một biến kiểu logic trong C#.
Chọn kiểu dữ liệu
Chúng ta chọn kiểu dữ liệu dựa vào độ lớn của giá trị muốn sử dụng. Tùy vào miền
giá trị và phạm vi sử dụng biến mà chọn các kiểu dữ liệu thích hợp nhất. Thông thường,
kiểu dữ liệu int được sử dụng nhiều nhất trong lập trình vì với kích thước 4 byte thì nó
cũng đủ để lưu các giá trị nguyên cần thiết.
Kiểu số nguyên có dấu thường được lựa chọn sử dụng nhiều nhất trong kiểu số trừ( -)
Kiểu số nguyên không dấu được sử dụng với các giá trị của biến dương.
Kiểu float, double, decimal đưa ra nhiều mức độ khác nhau về kích thước cũng như
độ chính xác. Trong C#, trình biên dịch luôn hiểu bất cứ một số thực nào cũng là một số
kiểu double trừ khi chúng ta khai báo rõ ràng
Chú ý: để khai báo kiểu float thì sau giá trị phải cso ký tự „f‟ theo sau.
Ví dụ: float PI = 3.14f;
Kiểu dữ liệu ký tự thể hiện các ký tự Unicode, bao gồm các ký tự đơn giản, ký tự
theo mã Unicode và các ký tự thoát khác được bao trong dấu nháy đơn. Một số ký tự thoát
đặc biệt:
Tr
n
o
n n
n
N
–
M
–
u
–
N
14
Bài giảng môn lập trình windows 1
Ký tự
Ý nghĩa
\‟
Dấu nháy đơn
/‟‟
Dấu nháy kép
\\
Dấu chéo
\0
Ký tự null
\n
Dòng mới
\r
Đầu dòng
\t
Tab ngang
\v
Tab dọc
Chuyển đổi kiểu dữ liệu
Những đối tượng của một kiểu dữ liệu có thể được chuyển sang những đối tượng của
một kiểu dữ liệu khác thông qua chuyển đổi tường minh hay ngầm định. Chuyển đổi ngầm
định được thực hiện một cách tự động, trình biên dịch sẽ tự thực hiện công việc này. Còn
chuyển đổi tường minh diễn ra khi ta gán ép một giá trị cho kiểu dữ liệu khác.
Việc chuyển đổi giá trị ngầm định được thực hiện một cách tự động và đảm bảo
không mất mát thông tin.
Ví dụ: short x = 10;
int y=x; // chuyển đổi ngầm định
Tuy nhiên việc chuyển đổi ngược lại chắc chắn sẽ bị mất mát thông tin, vì nếu giá trị
của số nguyên đó lớn hơn 32.767 thì nó sẽ bị cắt khi chuyển đổi. Khi đó trình biên dịch sẽ
không thực hiện việc chuyển đổi ngầm định từ kiểu int sang kiểu short.
short x;
int y = 100;
x = y; // lỗi, không biên dịch
Để chương trình có thể thực hiện được, ta phải chuyển đổi tường minh:
short x;
int y = 300;
x = (short)y; //ép kiểu tường minh
Tr
n
o
n n
n
N
–
M
–
u
–
N
15
Bài giảng môn lập trình windows 1
3.2 Biến và hằng
3.2.1 Biến
Một biến là một vùng lưu trữ với một kiểu dữ liệu. Biến có thể được gán giá trị và
cũng có thể thay đổi giá trị khi thực hiện các lệnh trong chương trình.
Để tạo một biến ta phải khai báo kiểu của biến và gán cho biến một tên duy nhất.
Biến có thể được khởi tạo giá trị ngay khi được khai báo hay nó cũng có thể được gán với
giá trị mới vào bất cứ lúc nào trong chương trình.
Khai báo biến: = ;
Ví dụ: int x,y,z;
double f = 3.2;
C# đòi hỏi các biến phải được khởi tạo trước khi sử dụng. Việc sử dụng biến khi
chưa được khởi tạo là không hợp lệ trong C#. Tuy nhiên không nhất thiết lúc nào cũng
phải khởi tạo biến. Nhưng để dùng được thì bắt buộc phải gán giá trị cho biến trước khi có
một lệnh nào tham chiếu đến biến đó.
3.2.2 Hằng
Hằng là một biến nhưng giá trị của hằng không thay đổi. Biến là công cụ rất mạnh
nhưng khi làm việc với một giá trị được định nghĩa là không thay đổi trong suốt chương
trình khi đó chúng ta sẽ sử dụng hằng.
Để tạo một hằng, ta sử dụng từ khóa const và có cú pháp khai báo như sau:
= ;
Một hằng phải được khởi tạo khi khai báo và chỉ khởi tạo duy nhất một lần trong
suốt chương trình và không thay đổi.
Ví dụ ta khai báo hằng số pi trong toán học:
const double pi = 3.14;
3.3 Định danh (tên)
Định danh là tên mà người lập trình chỉ định cho các kiểu dữ liệu, các phương thức,
biến, hằng hay đối tượng… Một định danh phải bắt đầu với một ký tự chữ cái hay dấu
gạch dưới, các ký tự đi theo nó phải là các ký tự chữ cái, chữ số, dấu gạch dưới.
Các định danh không được trùng với các từ khóa mà C# đưa ra, ngoài ra C# cũng
phân biệt chữ hoa và chữ thường nên chú ý 2 biến PI và pi là khác nhau.
3.4 Biểu thức
Những câu lệnh thực hiện việc đánh giá một giá trị gọi là biểu thức. Một phép gán
một giá trị cho một biến cũng được gọi là một biểu thức.
Tr
n
o
n n
n
N
–
M
–
u
–
N
16
Bài giảng môn lập trình windows 1
Ví dụ:
x = 10;
Trong câu lệnh trên phép đánh giá chính là phép gán có giá trị 10 cho biến x. Chú ý
toán tử gán “=” không phải là toán tử so sánh nên khi sử dụng toán tử này thì giá trị bên
phải được gán cho biến bên trái.
Chúng ta cũng có thể thực hiện nhiều lệnh gán trong một biểu thức như
a=b=c=d=10;
Trong trường hợp này cả 4 biến đều nhận cùng một giá trị là 10.
3.5 Khoảng trắng
Trong C# những khoảng trắng, khoảng tab và các dòng được xem như là khoảng
trắng (whitespace). C# sẽ bỏ qua tất cả các khoảng trắng đó. Do đó 2 cách viết sau là như
nhau:
x=5;
Hay
x
=
5;
Tuy nhiên khoảng trắng trong một chuỗi sẽ không được bỏ qua.
Việc sử dụng khoảng trắng là tùy ý của người lập trình để làm cho chương trình dễ
nhìn hơn. Tuy nhiên cũng cần chú ý khi sử dụng khoảng trắng như sau:
int x = 24;
Khác với
intx = 24;
Trình biên dịch có thể bỏ qua khoảng trắng ở 2 bên của phép gán nhưng khoảng
trắng giữa khai báo kiểu và tên biến thì tối thiểu phải có một khoảng trắng.
Cũng giống như C++, trong C# câu lệnh hay biểu thức được kết thúc bởi dấu chấm
phẩy „;‟. Do vậy có thể viết một câu lệnh trên nhiều dòng hay nhiều câu lệnh trên một dòng
nhưng trong 2 câu lệnh nhất thiết phải cách nhau một dấu chấm phẩy.
3.6 Toán tử
Toán tử được ký hiệu bằng một biểu tượng dùng để thực hiện một hành động.
Toán tử gán (=)
Toán tử gán hay phép gán làm cho toán hạng bên trái thay đổi giá trị theo toán hạng
bên phải. Toán tử gán là toán tử 2 ngôi, đây là toán tử thông dụng nhất và dễ sử dụng nhất.
Toán tử toán học
Các phép toán số học cơ bản (+,-,*,/): các phép toán này không thể thiếu
trong bất cứ ngôn ngữ lập trình nào. Các phép toán số học đơn giản gồm:
phép cộng, trừ, nhân, chia. Chú ý trong phép chia 2 số nguyên, C# sẽ bỏ qua
phần dư, chỉ lấy phần nguyên.
Tr
n
o
n n
n
N
–
M
–
u
–
N
17
Bài giảng môn lập trình windows 1
Phép chia lấy dư (%): để tìm phần dư trong phép chia chúng ta sẽ sử dụng
toán tử chia lấy dư. Ví dụ ta có phép toán 8%5 thì kết quả trả về là 3. Phép
chia lấy dư rất có ý nghĩa đối với người lập trình. Thông thường ta hay sử
dụng nó trong các vòng lặp.
Toán tử tăng và giảm
Khi sử dụng các biến số ta thường có thao tác cộng hay trừ đi một giá trị vào biến đó,
hay thực hiện các tính toán thay đổi giá trị của biến sau đó gán giá trị mới vừa tính toán
cho chính biến đó. Ta có bảng liệt kê các phép toán tự gán sau:
Chúng ta cũng có phép tăng, giảm đi một đơn vị:
++: tăng 1 đơn vị
--: giảm 1 đơn vị
Toán tử quan hệ
Những toán tử quan hệ được dùng để so sánh giữa 2 giá trị, kết quả trả về kết quả là
một giá trị logic. Một số toán tử logic được trình bày trong bảng sau:
Tr
n
o
n n
n
N
–
M
–
u
–
N
18
Bài giảng môn lập trình windows 1
Lưu ý toán tử so sánh bằng được ký hiệu bởi 2 dấu = (==).
Toán tử logic
Trước khi tìm hiểu toán tử logic, chúng ta xem lại bảng chân lý sau:
a
b
a and b
a or b
True
True
True
True
True
False
False
True
False
True
False
True
False
False
False
False
Trong ngôn ngữ C# cũng có các toán tử logic and, or, not nhưng chúng được ký hiệu
bởi các ký tự:
Trong bảng trên, giả sử x = 5, y = 7.
Độ ƣu tiên của toán tử
Trong một biểu thức luôn luôn tồn tại nhiều toán tử, khi đó trình biên dịch phải xác
định xem toán tử nào được thực hiện trước, toán tử nào thực hiện sau. Khi đó chúng ta phải
xác định được độ ưu tiên của toán tử. Các luật về độ ưu tiên xử lý sẽ bảo trình biên dịch
biết được toán tử nào được thực hiện trước trong biểu thức.
Tr
n
o
n n
n
N
–
M
–
u
–
N
19
Bài giảng môn lập trình windows 1
Trong ngôn ngữ C#, dấu ngoặc được sử dụng để thay đổi thứ tự xử lý, nên trong một
vài trường hợp, chúng ta nên sử dụng dấu ngoặc để cho biểu thức được rõ ràng.
Bảng sau sẽ liệt kê độ ưu tiên của các phép toán trong C#
Các phép toán cùng loại được liệt kê cùng loại sẽ có thứ tự theo mục thứ tự của bảng:
thứ tự trái tức là độ ưu tiên của phép toán từ bên trái sang, thứ tự phải thì phép toán có độ
ưu tiên từ bên phải sang. Các toán tử khác loại thì có độ ưu tiên từ trên xuống dưới, do vậy
các toán tử loại cơ bản sẽ có độ ưu tiên cao nhất và phép gán sẽ có độ ưu tiên thấp nhất
trong các toán tử.
Toán tử điều kiện (toán tử 3 ngôi)
Hầu hết các toán tử đòi hỏi có một toán hạng (như toán tử ++, --) hay 2 toán hạng
(+.-,*,/) nhưng C# còn cung cấp thêm một toán tử có 3 toán hạng (?:). Toán tử trên có cú
pháp như sau:
? < biểu thức 1> :
Toán tử này sẽ xác định giá trị của một biểu thức điều kiện, biểu thức điều kiện này
phải trả về một giá trị kiểu bool. Khi điều kiện đúng (biểu thức điều kiện trả về giá trị true)
thì sẽ được thực hiện, ngược lại thì được thực hiện. Có thể
Tr
n
o
n n
n
N
–
M
–
u
–
N
20
Bài giảng môn lập trình windows 1
diễn giải toán tử này theo ngôn ngữ tự nhiên như sau: “ Nếu điều kiện đúng thì thực hiện
công việc thứ nhất, còn ngược lại điều kiện sai thì thực hiện công việc thứ 2”.
Ví dụ:
static void Main(string[] args)
{
int x = 10;
int y = 20;
int max;
max = x > y ? x : y;
Console.WriteLine(" Gia tri lon nhat trong 2 so {0} va {1} la
{2}", x, y, max);
}
Kết quả trả về: giá trị lớn nhất trong 2 số 10 và 20 là 20.
Trong ví dụ trên, toán tử điều kiện được sử dụng để kiểm tra xem giá trị x có lớn hơn
giá trị y không, nếu đúng thì trả về giá trị của x, tức là gán x cho biến max, còn ngược lại
thì gán giá trị của y cho biến max.
3.7 Nhập xuất dữ liệu
3.7.1 Xuất dữ liệu ra màn hình
Để xuất dữ liệu ra màn hình, ta sử dụng câu lệnh: Console.WriteLine(“ ”);
Để xuất thông tin kiểu chuỗi ký tự thì rất đơn giản, ví dụ muốn xuất ra dòng “
Welcome to C#” ra màn hình thì ta chỉ cần 1 dòng:
Console.WriteLine(“ Welcome to C#”);
Chú ý: phải có dấu ngoặc kép “”, nếu không, trình biên dịch sẽ báo lỗi.
Để xuất ra giá trị của biến, chúng ta có dạng như sau:
Ví dụ:
Console.WriteLine(" Gia tri lon nhat trong 2 so {0} va {1} la {2}",
x, y, max);
Chú ý: các số 0,1,2 ở trong dấu {} cho biết thứ tự in ra trên màn hình.
3.7.2 Nhập dữ liệu từ bàn phím
Ví dụ có khai báo
string s;
int x;
Để nhập vào một chuỗi:
s= Console.ReadLine();
Hay để nhập vào một số nguyên: x = Int32.Parse(Console.ReadLine());
Tr
n
o
n n
n
N
–
M
–
u
–
N
21
Bài giảng môn lập trình windows 1
Chúng ta thấy rằng, đối với mỗi một đối tượng khác nhau thì chúng ta sẽ nhập dữ
liệu vào từ bàn phím khác nhau. Sau đây ta có bảng tương ứng đối với một kiểu dữ liệu
khác nhau:
short a
a = Int16.Parse(Console.ReadLine());
ushort a
a= UInt16.Parse(Console.ReadLine());
uint a
a= UInt32.Parse(Console.ReadLine());
long a
a = Int64.Parse(Console.ReadLine());
ulong a
a= Uint64.Parse(Console.ReadLine());
string s
s = Console.ReadLine();
char ch
ch = Char.Parse(Console.ReadLine());
ch = char.Parse(Console.ReadLine());
float a
a = float.Parse(Console.ReadLine());
a = Single.Parse(Console.ReadLine());
double a
a = Double.Parse(Console.ReadLine());
a= double.Parse(Console.ReadLine());
3.7.3 Ví dụ
Ví dụ 1: Nhập vào bán kính của hình tròn, tính chu vi và diện tích của hình tròn đó.
static void Main(string[] args)
{
double r;
const double PI = 3.14;// khai báo hằng
double DT, CV;
Console.WriteLine("nhap vao ban kinh hinh tron: ");
r = Double.Parse(Console.ReadLine());//nhập vào bán kính
DT = PI * r * r;
CV = 2 * PI * r;
Console.WriteLine(" ban kinh hinh tron la :{0}", r);//in bk
Console.WriteLine("Chu vi hinh tron: {0} \nDien tich hinh
tron :{1}", CV, DT);//in ra chu vi và diện tích
}
Ví dụ 2: Nhập vào 2 số nguyên bất kỳ, hãy tính tổng, hiệu, tích, thương và số dư của
2 số đó.
static void Main(string[] args)
{
int a, b;
double tong, hieu, tich, thuong,du;
Console.WriteLine("Nhap vao 2 so nguyen ");
Console.Write(" Nhap so thu nhat:");
a = Int32.Parse(Console.ReadLine());
Console.Write("Nhap so thu 2:");
b = Int32.Parse(Console.ReadLine());
tong = a + b;
Tr
n
o
n n
n
N
–
M
–
u
–
N
22
Bài giảng môn lập trình windows 1
hieu = a - b;
tich = a * b;
thuong = (double)a / b;// chuyển đổi kiểu tường minh
du = a % b;
Console.WriteLine(" Tong a+b = {0}\nHieu a-b = {1}\nTich a*b
= {2}\nThuong a/b = {3}\nSo du a%b = {4}", tong, hieu, tich, thuong, du);
}
3.8 Câu lệnh (statement)
Trong C#, một chỉ dẫn lập trình đầy đủ được gọi là câu lệnh. Chương trình bao gồm
nhiều câu lệnh tuần tự với nhau. Mỗi câu lệnh phải kết thúc bởi dấu chấm phẩy „;‟.
3.8.1 Cấu trúc điều kiện
Câu lệnh phân nhánh điều kiện dựa trên một điều kiện, điều kiện là một biểu thức sẽ
được kiểm tra giá trị ngay khi bắt đầu gặp câu lệnh đó. Nếu điều kiện kiểm tra là đúng thì
câu lệnh hay khối câu lệnh bên trong câu lệnh if được thực hiện.
3.8.1.1 Cú pháp lệnh điều kiện
* Cấu trúc điều kiện if:
+ if (biểu thức điều kiện) lệnh 1;
+ if (biểu thức điều kiện )
{
Lệnh 1;
Lệnh 2;
}
* Cấu trúc điều kiện if
else:
+ if (biểu thức điều kiện ) lệnh 1;
else lệnh 2;
* Cấu trúc điều kiện if
else lồng nhau:
+ if (biểu thức điều kiện 1)
if ( biểu thức điều kiện 2)
if (biểu thức điều kiện n)
lệnh 1;
else lệnh 2;
else lệnh 3;
else lệnh 4;
Tr
n
o
n n
n
N
–
M
–
u
–
N
23
Bài giảng môn lập trình windows 1
3.8.1.2 Lƣu đồ thuật toán
Lưu đồ thuật toán cho lệnh if
đúng
BTĐK
Lệnh
sai
Lưu đồ thuật toán cho lệnh if … else
false
true
BTĐK
Lệnh 2
Lệnh 1
3.8.1.3 Ví dụ
Ví dụ 1: Tìm giá trị lớn nhất của 2 số
static void Main(string[] args)
{
int x, y, max;
Console.Write("Nhap so thu 1:");
x = Int32.Parse(Console.ReadLine());
Console.Write("Nhap so thu 2:");
y = Int32.Parse(Console.ReadLine());
if (x > y)
max = x;
else
max = y;
Console.WriteLine("Gia tri max = {0}", max);
}
Ví dụ 2: Giải phương trình bậc nhất có dạng: ax + b = 0 với a, b được nhập từ bàn
phím.
Tr
n
o
n n
n
N
–
M
–
u
–
N
24
Bài giảng môn lập trình windows 1
static void Main(string[] args)
{
double a, b;
Console.Write("nhap he so a:");
a = Double.Parse(Console.ReadLine());
Console.Write("nhap he so b:");
b = Double.Parse(Console.ReadLine());
if (a == 0)
if (b == 0)
Console.WriteLine(" Phuong trinh vo so nghiem");
else
Console.WriteLine(" Phuong trinh vo nghiem ");
else
Console.WriteLine(" Phuong trinh co 1 nghiem duy nhat la
{0}", -b / a);
}
3.8.1.4 Bài tập tự làm
Bài 1: Hãy nhập vào điểm trung bình, xếp loại hạnh kiểm theo thang điểm sau:
[0;5): yếu;
[5;7): trung bình
[7;8): khá
[8;10]: giỏi
Bài 2: Nhập vào 1 số, cho biết đó là số âm hay số dương
Bài 3: Nhập vào 1 số, cho biết đó là số chẵn hay số lẻ.
Bài 4: Nhập vào 3 số, tìm số lớn nhất?
Bài 5: Nhập vào 3 số, cho biết đó có phải là 3 cạnh của tam giác hay không? Nếu là
3 cạnh của tam giác thì đó là tam giác gì?(cân, đều hay vuông)
Bài 6: Nhập vào 1 ký tự bất kỳ, hãy cho biết ký tự đó thuộc loại nào?(chữ thường,
chữ hoa hay chữ số).
Bài 7: Nhập vào số nguyên n, kiểm tra xem n có phải là số chính phương không?(số
chính phương là bình phương của số nguyên)
Bài 8: Nhập vào họ tên và số điện các hộ tiêu dùng điện. Hãy in ra hóa đơn gồm họ
tên, số điện và số tiền phải trả của các hộ biết rằng số tiền được tính như sau: 100kw đầu
tiên giá 500đ/kw, 100kw tiếp theo giá 700đ/kw, trên 200kw giá 1000đ/kw.
3.8.2 Cấu trúc lựa chọn switch… case
Lệnh lựa chọn switch… case trong C# thường sử dụng biến lựa chọn chủ yếu là kiểu
nguyên.
Tr
n
o
n n
n
N
–
M
–
u
–
N
25
Bài giảng môn lập trình windows 1
Khi có quá nhiều điều kiện lựa chọn thì sử dụng cấu trúc điều kiện if …else trở lên
phức tạp, dễ gây khó khăn cho người lập trình. Khi đó chúng ta sẽ sử dụng câu lệnh switch
để liệt kê các giá trị và chỉ thực hiện các giá trị thích hợp.
3.8.2.2 Cú pháp
switch ( biểu thức lựa chọn)
{
case :
Lệnh 1;
break;
case :
Lệnh 2;
break;
…
case :
Lệnh n;
break;
[default:
lệnh khác;
break;]
}
Cũng tương tự như câu lệnh if, biểu thức để lựa chọn được đặt sau từ khóa switch
nhưng giá trị lựa chọn lại được đặt sau mỗi từ khóa case. Giá trị sau từ khóa case là các giá
trị hằng số nguyên.
Nếu một câu lệnh case được thích hợp tức là giá trị sau case bằng với giá trị của biểu
thức lựa chọn sau switch thì các câu lệnh liên quan đến câu lệnh case này được thực thi.
Tuy nhiên phải có một câu lệnh nhảy break để điều khiển nhảy qua các case khác. Nếu
không có các lệnh nhảy này thì khi đó chương trình sẽ thực hiện tất cả các case theo sau.
Nếu không có trường hợp nào thích hợp và trong câu lệnh switch có dùng lệnh
default thì các câu lệnh của trường hợp default sẽ được thực hiện. Ta thường dùng lệnh
default để cảnh báo một lỗi hay xử lý một trường hợp ngoài tất cả các trường hợp case
trong switch.
3.8.2.2 Ví dụ
Tr
n
o
n n
n
N
–
M
–
u
–
N
26
Bài giảng môn lập trình windows 1
Ví dụ 1:
Sử dụng cấu trúc switch… case để xếp loại học lực theo thang điểm như trong bài
tập 1 trong mục 3.8.1.4
static void Main(string[] args)
{
int diem;
Console.Write(" Nhap diem:");
diem = Int32.Parse(Console.ReadLine());
switch (diem)
{
case 0:
case 1:
case 2:
case 3:
case 4:
Console.WriteLine(" Xep loai yeu ");
break;
case 5:
case 6:
Console.WriteLine("Xep loai trung binh ");
break;
case 7:
Console.WriteLine("Xep loai kha ");
break;
case 8:
case 9:
case 10:
Console.WriteLine("Xep loai trung binh ");
break;
default:
Console.WriteLine(" Diem khong hop le");
break;
}
}
Ví dụ 2: Viết chương trình nhập vào tháng và năm. Hãy cho biết tháng đó có bao
nhiêu ngày?
static void Main(string[] args)
{
int thang,nam;
Console.WriteLine(" Nhap thang: ");
thang = Int32.Parse(Console.ReadLine());
Console.WriteLine(" Nhap nam: ");
nam = Int32.Parse(Console.ReadLine());
switch (thang)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
Console.WriteLine(" Co 31 ngay");
break;
case 4:
case 6:
case 9:
case 11:
Tr
n
o
n n
n
N
–
M
–
u
–
N
27
Bài giảng môn lập trình windows 1
Console.WriteLine(" Co 30 ngay");
break;
case 2:
if (nam % 4 == 0)
Console.WriteLine(" Co 29 ngay");
else
Console.WriteLine(" Co 28 ngay");
break;
default:
Console.WriteLine(" thang khong hop le");
break;
}
}
3.8.2.3 Bài tập tự làm
Bài 1: Viết chương trình nhập ngày, tháng, năm hiện tại. Hãy cho biết ngày, tháng,
năm của ngày tiếp theo.
Bài 2: Viết chương trình nhập ngày, tháng, năm hiện tại. Đưa ra ngày, tháng, năm
của ngày trước đó.
3.8.3 Cấu trúc lặp for
Vòng lặp for bao gồm 3 thành phần chính:
- Khởi tạo biến đếm vòng lặp
- Kiểm tra điều kiện biến đếm, nếu đúng thì sẽ thực hiện các lệnh bên trong vòng for
- Thay đổi bước lặp
3.8.3.1 Cú pháp
for ( biểu thức khởi tạo; biểu thức điều kiện; bước lặp)
{
Lệnh;
}
Đầu tiên, trình biên dịch sẽ duyệt biểu thức khởi tạo, kiểm tra xem biểu thức khởi tạo
có thỏa mãn biểu thức điều kiện hay không, nếu đúng sẽ thực hiện lệnh và thực hiện lặp.
Nếu không thỏa mãn sẽ thoát khỏi vòng lặp.
Chúng ta cùng xem ví dụ sau:
static void Main(string[] args)
{
int i;
for (i = 0; i <= 30; i++)
if (i % 10 == 0)
Console.WriteLine("{0} ", i);
else
Console.Write("{0} ", i);
Console.WriteLine();
}
Tr
n
o
n n
n
N
–
M
–
u
–
N
28
Bài giảng môn lập trình windows 1
Kết quả:
Trong đoạn chương trình trên ta sử dụng toán tử chia lấy dư để kiểm tra i % 10==0
hay không, nếu i là bội số của 10 thì sử dụng lệnh WriteLine() để xuất ra giá trị i và sau đó
đưa con trỏ về đầu dòng sau. Nếu không thì xuất giá trị i và không xuống dòng.
Đầu tiên biến i được khởi tạo giá trị ban đầu là 0, sau đó chương trình sẽ kiểm tra
điều kiện, do 0 <=30 nên điều kiện đúng khi đó câu lệnh trong vòng lặp for được thực hiện.
Sau khi thực hiện xong thì biến i tăng lên 1 đơn vị (i++).
3.8.3.2 Lƣu đồ thuật toán
Begin
Biến đk = giá trị khởi tạo
Biểu thức ĐK
Sai
End
Đúng
Lệnh
Thay đổi biến điều kiện
3.8.3.3 Ví dụ
Ví dụ 1: In ra dãy ký tự các chữ cái ra màn hình:
abc…xyz
ABC…XYZ
ZYX…CBA
zyx…cba
static void Main(string[] args)
{
Tr
n
o
n n
n
N
–
M
–
u
–
N
29
Bài giảng môn lập trình windows 1
char ch;
for (ch = 'a'; ch <= 'z'; ch++)
Console.Write("{0}", ch);
Console.WriteLine();
for (ch = 'A'; ch <= 'Z'; ch++)
Console.Write("{0}", ch);
Console.WriteLine();
for (ch = 'z'; ch >= 'a'; ch--)
Console.Write("{0}", ch);
Console.WriteLine();
for (ch = 'Z'; ch >= 'A'; ch--)
Console.Write("{0}", ch);
Console.WriteLine();
}
Kết quả:
Ví dụ 2: Tính trung bình cộng của n số tự nhiên đầu tiên
static void Main(string[] args)
{
int i, n;
double tong=0, tbc;
Console.Write("nhap n:");
n = Int32.Parse(Console.ReadLine());
for (i = 1; i <= n; i++)
tong = tong + i;
tbc = tong / n;
Console.WriteLine("trung binh cong = {0}", tbc);
}
Kết quả:
Ví dụ 3: Nhập vào 1 số nguyên, kiểm tra số đó có phải là số nguyên tố không?
static void Main(string[] args)
{
int n, i;
bool ng_to = true;
Console.Write("Nhap n = ");
n = Int32.Parse(Console.ReadLine());
for (i = 2; i <= Math.Sqrt(n); i++)
if (n % i == 0)
ng_to = false;
if (ng_to == true)
Console.WriteLine("{0} la so nguyen to ", n);
Tr
n
o
n n
n
N
–
M
–
u
–
N
30
Bài giảng môn lập trình windows 1
else
Console.WriteLine("{0} khong la so nguyen to", n);
}
3.8.3.4 Bài tập tự làm
Bài 1: Tính n!
Bài 2: Viết chương trình tính dân số của 1 thành phố sau 5 năm nữa biết rằng thành
phố này hiện nay có 1,5 triệu dân, tỉ lệ tăng dân số hằng năm là 1%.
Bài 3: Hãy sắp xếp 3 số được nhập vào từ bàn phím theo thứ tự tăng dần
Bài 4: Tính tổng
S = 1 + 1/2 + 1/3 + … + 1/n
Bài 5: Tìm tất cả các số a, b, c thỏa mãn: tổng lập phương của các chữ số bằng chính
số đó tức là :
a3 + b3 + c3 = abc
3.8.4 Vòng lặp không xác định while
Ý nghĩa của vòng lặp while là “ Trong khi điều kiện đúng thì thực hiện các công việc
này”.
3.8.4.1 Cú pháp
while (biểu thức điều kiện)
{
Lệnh;
}
Cách thực hiện: Chừng nào biểu thức còn đúng thì còn phải thực hiện công việc.
Biểu thức của vòng lặp while là điều kiện để các lệnh được thực hiện, biểu thức này
bắt buộc phải trả về một giá trị kiểu bool là true/false. Nếu có nhiều câu lệnh cần được thực
hiện trong vòng lặp while thì phải đặt các lệnh này trong khối lệnh.
3.8.4.2 Lƣu đồ thuật toán vòng lặp while
Tr
n
o
n n
n
N
–
M
–
u
–
N
31
Bài giảng môn lập trình windows 1
Begin
S
Biểu thức
End
Đ
Công việc
Chú ý: Vòng lặp while sẽ kiểm tra điều kiện trước khi thực hiện các lệnh bên trong,
điều kiện này đảm bảo nếu ngay từ đầu điều kiện sai thì vòng lặp sẽ không bao giờ thực
hiện.
3.8.5 Vòng lặp không xác định do … while
Đôi khi vòng lặp while không thỏa mãn yêu cầu, chúng ta muốn chuyển ngữ nghĩa
của while là “Chạy trong khi điều kiện đúng” thành ngữ nghĩa khác như “làm điều này
trong khi điều kiện vẫn còn đúng”. Nói cách khác tức là thực hiện 1 hành động rồi mới
kiểm tra điều kiện.
3.8.5.1 Cú pháp
do
{
Công việc;
} while (điều kiện);
Ở đây có sự khác biệt quan trọng giữa vòng lặp while và vòng lặp do… while là khi
dùng vòng lặp do…while thì tối thiểu sẽ có một lần các câu lệnh trong do…while được
thực hiện.
3.8.5.2 Lƣu đồ thuật toán vòng lặp do… while
Tr
n
o
n n
n
N
–
M
–
u
–
N
32
Bài giảng môn lập trình windows 1
Begin
Công việc
Biểu thức
Đ
S
End
3.9 Namespace
Trong chương 2 đã nói qua về sử dụng đặc tính namespace trong C# nhằm tránh sự
xung đột giữa việc sử dụng các thư viện khác nhau từ các nhà cung cấp. Ngoài ra
namespace được xem như là tập hợp các lớp đối tượng và cung cấp duy nhất các định danh
cho các kiểu dữ liệu và được đặt trong một cấu trúc phân cấp. Việc sử dụng namespace
trong lập trình là một thói quen tốt vì công việc này chính là cách lưu các mã nguồn để sử
dụng về sau. Ngoài thư viện namespace do MS.NET cung cấp, ta có thể tạo cho riêng
mình các namespace. C# đưa ra từ khóa using để khai báo sử dụng namespace trong
chương trình.
Để tạo một namespace ta dùng cú pháp sau:
namespace
{
<định nghĩa lớp A>
<định nghĩa lớp B>
….
}
Ví dụ tạo một namespace
namespace MyLib
{
using System;
public class Tester
{
public static int Main()
{
Tr
n
o
n n
n
N
–
M
–
u
–
N
33
Bài giảng môn lập trình windows 1
for (int i =0; i < 10; i++)
{
Console.WriteLine( “i: {0}”, i);
}
return 0;
}
}
}
Ví dụ trên tạo ra một namespace có tên là Mylib, bên trong namespace này chứa một
lớp có tên là Test. Trong C# cho phép trong một namespace có thể tạo một namespace
khác lồng bên trong và không giới hạn mức độ phân cấp này. Ví dụ:
namespace MyLib
{
namespace Demo
{
using System;
public class Tester
{
public static int Main()
{
for (int i =0; i < 10; i++)
{
Console.WriteLine( “i: {0}”, i);
}
return 0;
}
}
}
}
Lớp Tester trong ví dụ 3.21 được đặt trong namespace Demo do đó có thể tạo một
lớp Tester khác bên ngoài namespace Demo hay bên ngoài namespace MyLib mà không có bất
cứ sự tranh cấp hay xung đột nào. Để truy cập lớp Tester dùng cú pháp sau:
MyLib.Demo.Tester
Tr
n
o
n n
n
N
–
M
–
u
–
N
34
Bài giảng môn lập trình windows 1
CHƢƠNG 4: PHƢƠNG THỨC
Phương thức cũng giống như hàm trong C++, nó gồm có 2 loại chính: phương thức
trả về giá trị và phương thức kiểu void.
Trong chương 4 này tất cả các phương thức đều có từ khóa static đứng trước kiểu vì
tất cả các phương thức sử dụng ở đây đều thuộc phương thức tĩnh, không hướng đối tượng.
Thuật ngữ phương thức (method) có thể gọi là “hàm” mà vẫn không làm lệch nội
dung.
4.1 Khai báo phƣơng thức
(danh sách tham số)
{
}
Trong thân phương thức:
+ Chứa mã của phương thức
+ Chứa giá trị trả về nếu cần thiết
+ Được viết ở 1 vị trí khác ngoài phương thức Main()
Lý do phải sử dụng phương thức
+ Thực hiện chính sách “ chia để trị”
+ Sử dụng nhiều lần trong chương trình
+ Giảm việc lặp đi lặp lại, phương thức có thể được gọi từ bất kỳ chỗ nào trong
chương trình.
4.2 Phƣơng thức trả về giá trị
Phương thức này có kiểu float, double, int, string,… Bên trong phương thức luôn
luôn có lệnh return để trả về một giá trị.
static double Tong(double a,double b)
{
return a+b;
}
Do đó khi gọi phương thức cần khai báo 1 biến và gán tên phương thức cho biến.
int m;
Tr
n
o
n n
n
N
–
M
–
u
–
N
35
Bài giảng môn lập trình windows 1
m = Tong(a,b);
4.3 Phƣơng thức kiểu void
Có thể gọi phương thức kiểu void là phương thức không trả về giá trị, tuy nhiên nếu
phương thức có đối số là tham chiếu thì nó có thể trả về nhiều giá trị đồng thời. Có thể chia
phương thức kiểu void thành 4 loại:
* Kiểu void không có đối số: Được dùng để hiển thị thông báo
Ví dụ:
void Thong_bao()
{ }
* Kiểu void có đối số đưa vào nhưng không có đối số lây ra, nó thường dùng để hiển
thị các thông báo, tính toán một biểu thức nào đó rồi hiển thị kết quả ra màn hình
* Kiểu void không có đối số đưa vào nhưng có đối số lấy ra khỏi phương thức, nó
thường dùng để nhập dữ liệu từ bàn phím và đưa ra khỏi phương thức. Các đối số lấy ra
phải là đối số kiểu tham chiếu.
* Kiểu void có cả đối số vào và đối số ra: Các đối số lấy ra phải là đối số kiểu tham
chiếu.
4.4 Phạm vi của biến
Phạm vi của biến là khoảng không gian tác dụng của biến trong chương trình.
+ Biến toàn cục: được sử dụng cho tất cả các phương thức
+ Biến địa phương:
- Được tạo ra khi khai báo trong phương thức
- Bị hủy khi thoát khỏi khối chương trình
4.5 Một vài phƣơng thức toán học thƣờng dùng trong lớp Math
Cách dùng:
.([tham số])
Một số hằng số:
Math.PI = 3.1415…
Math.E = 2.71828….
Một số phương thức của lớp Math:
+ Abs(x): trả về trị tuyệt đối của x
+ Ceiling(x): làm tròn x tới số tự nhiên nhỏ nhất không nhỏ hơn x.
+ Cos(x): tính lượng giác cosx
+ Exp(x): tính ex
Tr
n
o
n n
n
N
–
M
–
u
–
N
36
Bài giảng môn lập trình windows 1
+ Floor(x): làm tròn tới số nguyên lớn nhất không vượt quá x
+ Log(x): tính logx
+ Max(x,y): Tìm giá trị lớn nhất giữa x và y
+ Min(x,y): tìm giá trị nhỏ nhất giữa x và y
+ Sin(x): tính sinx
+ Pow(x,y): tính xy
+ Sqrt(x): tính căn x
+ Tan(x): tính tgx
Ví dụ: Tìm giá trị lớn nhất của 3 số( sử dụng phương thức toán học)
static double Maximum(double x, double y, double z)
{
return Math.Max(x, Math.Max(y, z));
}
static void Main(string[] args)
{
double a, b, c, max;
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 = Maximum(a, b, c);
Console.WriteLine("gia tri max = {0}", max);
}
4.6 Ví dụ minh họa
Ví dụ 1: Tính n!
static double giai_thua(int n)
{
double gt=1;
for (int i = 1; i <= n; i++)
gt = gt * i;
return gt;
}
static void Main(string[] args)
{
int n;
Console.Write("Nhap n:");
n = Int32.Parse(Console.ReadLine());
Console.WriteLine(" n! = {0}", giai_thua(n));
}
Ví dụ 2: Viết phương thức tính n!, sử dụng phương thức trên hãy tính giá trị của biểu
thức sau:
S = (n!+1)/(n+1)!
Tr
n
o
n n
n
N
–
M
–
u
–
N
37
Bài giảng môn lập trình windows 1
Ckn = n!/ (k!*(n-k)!)
static double giai_thua(int n)
{
double gt=1;
for (int i = 1; i <= n; i++)
gt = gt * i;
return gt;
}
static void Main(string[] args)
{
int n,k;
Console.Write("Nhap n:");
n = Int32.Parse(Console.ReadLine());
Console.Write("Nhap k:");
k = Int32.Parse(Console.ReadLine());
double s, c;
s = (giai_thua(n) + 1) / giai_thua(n + 1);
c = giai_thua(n) / (giai_thua(k) * giai_thua(n - k));
Console.WriteLine(" s = {0}\n c = {1}", s, c);
}
4.7 Truyền đối số kiểu tham chiếu có từ khóa ref hoặc out
Như ta đã biết, tham số có kiểu dữ liệu là giát trị thì sẽ được truyền giá trị vào cho
phương thức. Điều này có nghĩa rằng khi một đối tượng có kiểu là giá trị được truyền vào
cho một phương thức, thì có một bản sao chép đối tượng đó được tạo ra bên trong phương
thức. Một khi phương thức được thực hiện xong thì đối tượng sao chép này sẽ được hủy.
Tuy nhiên, đây chỉ là trường hợp bình thường, ngôn ngữ C# còn cung cấp khả năng cho
phép ta truyền các đối tượng có kiểu giá trị dưới hình thức là tham chiếu. Ngôn ngữ C#
đưa ra một bổ sung tham số là ref cho phép truyền các đối tượng giá trị vào trong phương
thức theo kiểu tham chiếu. Và tham số bổ sung out trong trường hợp muốn truyền dưới
dạng tham chiếu mà không cần phải khởi tạo giá trị ban đầu cho tham số truyền. Ngoài ra
ngôn ngữ C# còn hỗ trợ bổ sung params cho phép phương thức chấp nhận nhiều số lượng
các tham số.
Tru n t
m
ếu
Những phương thức chỉ có thể trả về duy nhất một giá trị, mặc dù giá trị này có thể là
một tập hợp các giá trị. Nếu chúng ta muốn phương thức trả về nhiều hơn một giá trị thì
cách thực hiện là tạo các tham số dưới hình thức tham chiếu. Khi đó trong phương thức ta
sẽ xử lý và gán các giá trị mới cho các tham số tham chiếu này, kết quả là sau khi phương
thức thực hiện xong ta dùng các tham số truyền vào như là các kết quả trả về.
Để truyền theo tham biến:
- Gửi phương thức điểm quy chiếu thực sự của đối tượng
- Phương thức trả lại luôn ở dạng tham chiếu
- Từ khóa ref định nghĩa 1 tham chiếu
Tr
n
o
n n
n
N
–
M
–
u
–
N
38
Bài giảng môn lập trình windows 1
- Từ khóa out gọi tới 1 phương thức khi nó chưa khởi tạo giá trị ban đầu
Để thấy được ý nghĩa của từ khóa ref và out, đầu tiên ta xét ví dụ sau đây không sử
dụng tham chiếu với từ khóa ref và out:
static void hoandoi(int a, int b)
{
int tg;
tg = a;
a = b;
b = tg;
Console.WriteLine(" Trong ham hoan doi: a = {0}, b = {1}", a, b);
}
static void Main(string[] args)
{
int a = 10, b = 20;
Console.WriteLine(" Truoc khi hoan doi: a = {0}, b = {1}", a, b);
hoandoi(a, b);
Console.WriteLine(" Sau khi hoan doi: a = {0}, b = {1}", a, b);
}
Kết quả:
Từ kết quả trên cho thấy bên trong hàm hoán đổi thì các giá trị của a và b được hoán
đổi cho nhau, nhưng sau khi hoán đổi các giá trị của a và b lại như trước khi hoán đổi.
Điều này cho thấy hàm hoán đổi không có tác dụng hoán đổi. Lý do là vì các tham số của
hàm hoán đổi không sử dụng tham chiếu mà chỉ là các giá trị thông thường.
Để khắc phục tình trạng trên, ta sử dụng 2 từ khóa để ref và out.
* Từ khóa ref
Từ khóa ref chỉ định tham số truyền vào phương thức dưới dạng tham biến. Mọi sự
thay đổi về giá trị của tham số bên trong phương thức đều được giữ lại sau khi ra khỏi
phương thức.
Ví dụ:
static void hoandoi(ref int a,ref int b)
{
int tg;
tg = a;
a = b;
b = tg;
Console.WriteLine(" Trong ham hoan doi: a = {0}, b = {1}", a, b);
}
static void Main(string[] args)
{
Tr
n
o
n n
n
N
–
M
–
u
–
N
39
Bài giảng môn lập trình windows 1
int a = 10, b = 20;
Console.WriteLine(" Truoc khi hoan doi: a = {0}, b = {1}", a, b);
hoandoi(ref a,ref b);
Console.WriteLine(" Sau khi hoan doi: a = {0}, b = {1}", a, b);
}
Kết quả:
Nhận xét: bên trong hàm hoán đổi, các giá trị của a và b được hoán đổi cho nhau.
Mặt khác sau khi gọi hàm hoán đổi, các giá trị của a và b cũng được hoán đổi. Điều này có
nghĩa là hàm hoán đổi đã thực sự có tác dụng hoán đổi
* Từ khóa out
Từ khóa out cũng dùng để chỉ định tham số được truyền vào phương thức dưới dạng
tham biến. Tuy nhiên sự khác biệt với từ khóa ref là tham số truyền vào không cần phải
khởi tạo trước.
Ví dụ:
public class Time
{
public void DisplayCurrentTime()
{
Console.WriteLine(“{0}/{1}/{2} {3}:{4}:{5}”,
Date, Month, Year, Hour, Minute, Second);
}
public int GetHour()
{
return Hour;
}
public void SetTime(int hr, out int min, ref int sec)
{
// Nếu số giây truyền vào >30 thì tăng số Minute và Second = 0
if ( sec >=30 )
{
Minute++;
Second = 0;
Tr
n
o
n n
n
N
–
M
–
u
–
N
40
Bài giảng môn lập trình windows 1
}
Hour = hr; // thiết lập giá trị hr được truyền vào
// Trả về giá trị mới cho min và sec
min = Minute;
sec = Second;
}
public Time( System.DateTime dt)
{
Year = dt.Year;
Month = dt.Month;
Date = dt.Day;
Hour = dt.Hour;
Minute = dt.Minute;
Second = dt.Second;
}
// biến thành viên private
private int Year;
private int Month;
private int Date;
private int Hour;
private int Minute;
private int Second;
}
public class Tester
{
static void Main()
{
System.DateTime currentTime = System.DateTime.Now;
Time t = new Time(currentTime);
t.DisplayCurrentTime();
int theHour = 3;
int theMinute;
int theSecond = 20;
t.SetTime( theHour, out theMinute, ref theSecond);
Console.WriteLine(“The Minute is now: {0} and {1} seconds ”,
theMinute, theSecond);
theSecond = 45;
t.SetTime( theHour, out theMinute, ref theSecond);
Console.WriteLine(“The Minute is now: {0} and {1} seconds”,
Tr
n
o
n n
n
N
–
M
–
u
–
N
41
Bài giảng môn lập trình windows 1
theMinute, theSecond);
}
}
4.8 Bài tập
Làm các bài tập trong chương 3 bằng cách xây dựng dưới dạng các phương thức.
Tr
n
o
n n
n
N
–
M
–
u
–
N
42
Bài giảng môn lập trình windows 1
CHƢƠNG 5: XÂY DỰNG LỚP – ĐỐI TƢỢNG
5.1 Lớp và đối tƣợng
Trong chương 3 chúng ta đã được tìm hiểu về các kiểu dữ liệu cơ bản của C# như:
int, float, double, string, char, … Tuy nhiên trái tim và linh hồn của C# là khả năng tạo ra
những kiểu dữ liệu mới, phức tạp. Người lập trình tạo ra các kiểu dữ liệu mới bằng cách
xây dựng các lớp đối tượng.
Đây là khả năng để tạo ra những kiểu dữ liệu mới, một đặc tính quan trọng của ngôn
ngữ lập trình hướng đối tượng. Chúng ta có thể xây dựng những kiểu dữ liệu mới trong
ngôn ngữ C# bằng cách khai báo và định nghĩa lớp. Thể hiện của một lớp được gọi là
những đối tượng (object), những đối tượng này được tạo trong bộ nhớ khi chương trình
được thực hiện.
Sự khác nhau giữa một lớp và một đối tượng cũng giống như sự khác nhau giữa khái
niệm loài mèo và con mèo Mun. Chúng ta không thể đụng chạm hay tác động lên khái
niệm mèo nhưng chúng ta hoàn toàn có thể hoàn làm được đối với 1 con mèo cụ thể.
Một họ mèo mô tả những con mèo có các đặc tính: có trọng lượng, chiều cao, màu
mặt, màu lông,… chúng có hành động là: ăn, ngủ, leo trèo,…Một con mèo có trọng lượng
1,5kg, cao 15cm, mắt màu đen, lông màu đen…và nó cũng có khẳ năng ăn, ngủ, leo trèo.
Như vậy 1 đối tượng có đầy đủ các đặc tính và hành vi của 1 lớp.
Trong chương này sẽ trình bày các đặc tính của ngôn ngữ C# để xây dựng các lớp
đối tượng. Thành phần của 1 lớp bao gồm các hành vi và các thuộc tính được xem như là
thành viên của lớp (class member). Đặc tính mới của ngôn ngữ C# đưa ra để xây dựng lớp
là khái niệm thuộc tính (property), thành phần thuộc tính này hoạt động giống như phương
thức để tạo 1 lớp nhưng bản chất của phương thức này là tạo 1 lớp giao diện cho bên ngoài
tương tác với biến thành viên 1 cách gián tiếp.
5.1.1 Định nghĩa lớp
Để định nghĩa 1 kiểu dữ liệu mới hay 1 lớp đầu tiên ta phải khai báo rồi sau đó mới
định nghĩa các thuộc tính và phương thức của kiểu dữ liệu đó.
Cú pháp để khai báo 1 lớp (chú ý: tất cả các thành phần bên trong dấu [] có thể có
hoặc không có):
[thuộc tính truy cập] class tên_lớp [: lớp cơ sở]
{
}
Tr
n
o
n n
n
N
–
M
–
u
–
N
43
Bài giảng môn lập trình windows 1
5.1.2 Thuộc tính truy cập
Thuộc tính truy cập quyết định khả năng các phương thức của lớp bao gồm việc các
phương thức của lớp khác có thể nhìn thấy và sử dụng các biến thành viên hay những
phương thức bên trong lớp. Bảng dưới đây sẽ tóm tắt các thuộc tính truy cập của 1 lớp
trong C#:
Thuộc tính
Giới hạn truy cập
Không hạn chế, những thành viên được đánh dấu public có thể
được dùng bởi bất kỳ các phương thức của lớp bao gồm những
public
lớp khác
private
Thành viên trong một lớp A được đánh dấu là private thì chỉ được
truy cập bởi phương thức của lớp A
protected
Thành viên trong lớp A được đánh dấu là protected thì chỉ được
các phương thức bên trong lớp A và những phương thức dẫn xuất
từ lớp A truy cập
internal
Thành viên trong lớp A được đánh dấu là internal thì được truy
cập bởi những phương thức của bất cứ lớp nào trong cùng khối
hợp ngữ với A
Thành viên trong lớp A được đánh dấu là protected internal được
truy cập bởi các phương thức của lớp A, các phương thức của lớp
dẫn xuất của lớp A và bất cứ lớp nào trong cùng khối hợp ngữ
của A
protected internal
Mong muốn chung là thiết kế các thành viên của lớp ở thuộc tính private. Khi đó chỉ
có phương thức thành viên của lớp truy cập được giá trị của biến. C# xem thuộc tính
private là mặc định khi khai báo các thuộc tính của lớp.
Chú ý: Để lập trình tốt thì nên khai báo tường minh các thuộc tính truy cập của biến
thành viên hay các phương thức trong 1 lớp. Mặc dù các thành viên của lớp được khai báo
mặc định là private nhưng việc khai báo tường minh sẽ làm cho chương trình dễ hiểu, rõ
ràng và tự nhiên hơn.
Ví dụ tạo 1 lớp học sinh:
class Hoc_sinh
{
private string hoten;
private double diem;
public void nhap()
Tr
n
o
n n
n
N
–
M
–
u
–
N
44
Bài giảng môn lập trình windows 1
{}
public void xuat()
{}
}
5.1.3 Tạo đối tƣợng
Trong chương 3 đã đề cập đến sự khác nhau giữa kiểu dữ liệu giá trị và kiểu dữ liệu
tham chiếu. Những kiểu dữ liệu chuẩn như int, char, float, double,… là những kiểu dữ liệu
giá trị và các biến được tạo ra từ các kiểu dữ liệu này được lưu trên stack. Còn với các đối
tượng kiểu dữ liệu tham chiếu thì được tạo ra trên heap, sử dụng từ khóa new để tạo một
đối tượng.
Cú pháp:
= new < Tên lớp>([danh sách tham số]);
Ví dụ tạo 1 đối tượng thuộc lớp Hoc_sinh:
Hoc_sinh hs = new Hoc_sinh();
5.1.4 Sử dụng đối tƣợng
Sử dụng toán tử „.‟ để sử dung dụng đối tượng
Cú pháp:
.([danh sách tham số]);
Ví dụ:
hs.nhap();
hs.xuat();
Ví dụ minh họa:
Xây dựng lớp học sinh có các thuộc tính: tên, điểm toán, văn, điểm trung bình và có
các phương thức nhập vào điểm toán, văn và phương thức xuất ra điểm trung bình.
class Hoc_sinh
{
private string hoten;
private double toan, van, dtb;
public void nhap()
{
Console.Write("Nhap ten:");
hoten = Console.ReadLine();
Console.Write("Nhap diem toan:");
toan = Double.Parse(Console.ReadLine());
Console.Write("Nhap diem van:");
van = Double.Parse(Console.ReadLine());
}
public void xuat()
{
Tr
n
o
n n
n
N
–
M
–
u
–
N
45
Bài giảng môn lập trình windows 1
dtb = (toan + van) / 2;
Console.WriteLine("Diem trung binh = {0}", dtb);
}
}
class Test
{
static void Main(string[] args)
{
Hoc_sinh hs = new Hoc_sinh(); // tao doi tuong hs
hs.nhap();
hs.xuat();
}
}
Ví dụ tự làm: Viết 1 lớp HCN có các thuộc tính là độ dài 2 cạnh và có các phương
thức:
+ Nhập dữ liệu 2 cạnh cho hcn
+ Tính chu vi và diện tích hcn
+ In ra thông tin của hcn ra màn hình
5.2 Phƣơng thức khởi tạo (Constructor)
Phương thức khởi tạo là phương thức có tên trùng với tên lớp của nó, các phương
thức khởi tạo này sẽ tự động thực hiện khi đối tượng được sinh ra và chúng thường được
dùng để khởi tạo giá trị ban đầu cho đối tượng.
Các phương thức này được định nghĩa khi xây dựng lớp, nếu ta không tạo ra thì CLR
sẽ tạo ra phương thức khởi tạo một cách mặc định. Chức năng của phương thức khởi tạo là
tạo ra đối tượng xác định bởi một lớp và đặt trạng thái này hợp lệ. Trước khi phương thức
khởi tạo được thực hiện thì đối tượng chưa được cấp phát trong bộ nhớ, sau khi phương
thức này thực hiện hoàn thành thì bộ nhớ sẽ lưu giữ một thể hiện hợp lệ của lớp vừa khai
báo.
Thông thường khi muốn định nghĩa một phương thức khởi dựng riêng ta phải cung
cấp các tham số để hàm khởi dựng có thể khởi tạo các giá trị khác ngoài giá trị mặc định
cho các đối tượng.
Phương thức khởi dựng không có giá trị trả về và được khai báo là public, nếu
phương thức khởi tạo này được truyền tham số thì phải khai báo danh sách tham số giống
như khai báo với bất kỳ phương thức nào trong 1 lớp.
Một số đặc điểm của phương thức khởi tạo:
- Không có giá trị trả về
- Tên phương thức trùng với tên lớp
- Có thể có hoặc không có tham số
Tr
n
o
n n
n
N
–
M
–
u
–
N
46
Bài giảng môn lập trình windows 1
- Khi gọi sử dụng chúng phải dùng từ khóa new
Ví dụ minh họa:
class Program
{
class vidu
{
private int a, b;
public vidu()
{
a = 2;
b = 3;
}
public vidu(int x, int y)
{
a = x;
b = y;
}
public void show()
{
Console.WriteLine(" a = {0}\n b = {1}", a, b);
}
}
static void Main(string[] args)
{
vidu vd = new vidu();
vd.show();
vd = new vidu(8, 5);
vd.show();
}
}
Từ khóa this
Từ khóa this được dùng để tham chiếu đến thể hiện của một đối tượng, tham chiếu
this này được xem là con trỏ ẩn đến tất cả các phương thức không có thuộc tính tĩnh trong
một lớp. Mỗi phương thức có thể tham chiếu đến những phương thức khác và các biến
thành viên thông qua tham chiếu this này.
Tham chiếu this được sử dụng thường xuyên theo các cách sau:
* Sử dụng khi các biến thành viên bị che lấp bởi tham số đưa vào, tức là tên tham số
đưa vào trùng với tên của biến thành viên
Ví dụ:
class thoigian
{
private int ngay, thang, nam;
public void hienthi(int nam)
{
this.nam=nam;
Tr
n
o
n n
n
N
–
M
–
u
–
N
47
Bài giảng môn lập trình windows 1
}
}
Trong trường hợp này this.nam chỉ đến biến thành viên của đối tượng còn nam chỉ
đến tham số.
* Sử dụng tham chiếu this để truyền đối tượng hiện hành vào một tham số của
phương thức của đối tượng khác.
5.3 Hủy đối tƣợng
Ngôn ngữ C# cung cấp cơ chế thu dọn do đó không cần phải khai báo tường minh
các phương thức hủy. Tuy nhiên khi làm việc với các đoạn mã không được quản lý thì cần
phải khai báo tường minh các phương thức hủy để giải phóng tài nguyên. C# cung cấp
ngầm định một phương thức để thực hiện công việc này đó là phương thức Finalize().
Phương thức Finalize() sẽ được gọi bởi cơ chế thu dọn khi đối tượng bị hủy.
Phương thức hủy chỉ giải phóng các tài nguyên mà đối tượng nắm giữ, nó không
tham chiếu đến các đối tượng khác. Nếu trong những đoạn mã chứa các tham chiếu kiểm
soát được thì không cần thiết phải tạo và thực thi phương thức Finalize(), chúng ta chỉ làm
điều này khi xử lý các tài nguyên không kiểm soát được.
Chúng ta không gọi một phương thức Finalize() của 1 đối tượng một cách trực tiếp,
trình thu dọn sẽ thực hiện việc gọi Finalize().
5.3.1 Bộ hủy của C#
Cú pháp của phương thức hủy trong C# cũng giống như trong C++, ta có thể khai
báo 1 phương thức hủy trong C# như sau:
~class()
{}
Hoặc có thể viết
class.Finalize()
{
base.Finalize();
}
5.4 Nạp chồng phƣơng thức
Khi xây dựng các lớp ta mong muốn tạo ra nhiều hàm có cùng tên, ví dụ tạo ra nhiều
phương thức khởi tạo chẳng hạn. Việc tạo ra nhiều phương thức có cùng tên gọi là nạp
chồng phương thức.
Tr
n
o
n n
n
N
–
M
–
u
–
N
48