Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
1
Chương 1. NHẬP MÔN VỀ MÁY TÍNH VÀ LẬP TRÌNH
1.1 Phần cứng và phần mềm
1.1.1. Phần cứng (hardware)
Phần cứng, còn gọi là cương liệu (hardware), là các thành phần (vật lý) cụ thể của máy tính
hay hệ thống máy tính như là màn hình, chuột, bàn phím, máy in, máy quét, vỏ máy tính, bộ
nguồn, bộ vi xử lý CPU, bo mạch chủ, các loại dây nối, loa, ổ đĩa mềm, ổ đĩa cứng, ổ CDROM,
ổ DVD,
Dựa trên chức năng và cách thức hoạt động người ta còn phân biệt phần cứng ra thành:
- Nhập hay đầu vào (Input): Các bộ phận thu nhập dữ liệu hay mệnh lệnh như là bàn phím,
chuột
- Xuất hay đầu ra (Output): Các bộ phận trả lời, phát tín hiệu, hay thực thi lệnh ra bên ngoài
như là màn hình, máy in, loa,
Ngoài các bộ phận nêu trên liên quan tới phần cứng của máy tính còn có các khái niệm quan
trọng sau đây:
- Bus: chuyển dữ liệu giữa các thiết bị phần cứng.
- BIOS (Basic Input Output System): còn gọi là hệ thống xuất nhập cơ bản nhằm khởi động,
kiểm tra, và cài đặt các mệnh lệnh cơ bản cho phần cứng và giao quyền điều khiển cho hệ điều
hành
- CPU: bộ phân vi xử lý điều khiển toàn bộ máy tính
- Kho lưu trữ dữ liệu: lưu giữ, cung cấp, thu nhận dữ liệu
- Các loại chíp hỗ trợ: nằm bên trong bo mạch chủ hay nằm trong các thiết bị ngoại vi của
máy tính các con chip quan trọng sẽ giữ vai trò điều khiển thiết bị và liên lạc với hệ điều hành
qua bộ điều vận hay qua phần sụn
- Bộ nhớ: là thiết bị bên trong bo mạch chủ giữ nhiệm vụ trung gian cung cấp các mệnh lệnh
cho CPU và các dữ liệu từ các bộ phận như là BIOS, phần mềm, kho lưu trữ, chuột đồng thời
tải về cho các bộ phận vừa kể kết quả các tính toán, các phép toán hay các dữ liệu đã/đang
được xử lý.
Các phần mềm dịch mã: bao gồm trình biên dịch và trình thông dịch: các loại chương trình
này sẽ đọc các câu lệnh từ mã nguồn được viết bởi các lập trình viên theo một ngôn ngữ lập
trình và dịch nó sang dạng ngôn ngữ máy mà máy tính có thể hiểu đưọc, hay dịch nó sang một
dạng khác như là tập tin đối tượng (object file) và các tập tin thư viện (library file) mà các phần
mềm khác (như hệ điều hành chẳng hạn) có thể hiểu để vận hành máy tính thực thi các lệnh.
Theo khả năng ứng dụng: Những phần mềm không phụ thuộc, nó có thể được bán cho bất kỳ
khách hàng nào trên thị trường tự do. Ví dụ: phần mềm về cơ sở dữ liệu như Oracle, đồ họa
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
3
như Photoshop, Corel Draw, soạn thảo và xử lý văn bản, bảng tính Ưu điểm: Thông thường
đây là những phần mềm có khả năng ứng dụng rộng rãi cho nhiều nhóm người sử dụng.
Khuyết điểm: Thiếu tính uyển chuyển, tùy biến.
Những phần mềm được viết theo đơn đặt hàng hay hợp đồng của một khách hàng cụ thể
nào đó (một công ty, bệnh viện, trường học ). Ví dụ: phần mềm điều khiển, phần mềm hỗ trợ
bán hàng
Ưu điểm: Có tính uyển chuyển, tùy biến cao để đáp ứng được nhu cầu của một nhóm người
sử dụng nào đó. Khuyết điểm: Thông thường đây là những phần mềm ứng dụng chuyên ngành
hẹp.
+ Các loại khác: Cũng do con người viết nên để phục vụ mục đích nào đó, nhưng Virus (máy
tính) là virus, trojan được viết để chạy với những mục đích riêng của một một nhóm người
nhằn lừa đảo, quảng cáo, ăn cắp, phá hoại thông tin, phá hoại phần cứng hoặc chỉ là để trêu
chọc người dùng vi tính.
- Quá trình tạo phần mềm
Về mặt thiết kế
Tùy theo mức độ phức tạp của phần mềm làm ra, người thiết kế phần mềm sẽ ít nhiều dùng
đến các phương tiện để tạo ra mẫu thiết kế theo ý muốn (chẳng hạn như là các sơ đồ khối, các
lưu đồ, các thuật toán và các mã giả), sau đó mẫu này được mã hoá bằng các ngôn ngữ lập trình
và được các trình dịch chuyển thành các khối lệnh (module) hay/và các tệp khả thi. Tập hợp
các tệp khả thi và các khối lệnh đó làm thành một phần mềm. Thường khi một phần mềm được
chung chung, chính xác hơn là phần mềm MS Word thì rõ hơn đó là một chương trình ứng
dụng.)
Chữ lập trình dùng để chỉ thao tác của con người nhằm kiến tạo nên các chương trình máy
tính thông qua các ngôn ngữ lập trình. Người ta còn gọi quá trình lập trình đó là quá trình mã
hoá thông tin tự nhiên thành ngôn ngữ máy. Trong các trường hợp xác định thì chữ lập trình
còn được viết là "viết mã" (cho chương trình máy tính).
Như vậy, theo định nghĩa, mỗi ngôn ngữ lập trình cũng chính là một chương trình, nhưng
có thể được dùng để tạo nên các chương trình khác. Một chương trình máy tính được viết bằng
một ngôn ngữ lập trình thì những chỉ thị (của riêng ngôn ngữ ấy) góp phần tạo nên chương
trình được gọi là mã nguồn của chương trình ấy.
Thao tác chuyển dạng từ mã nguồn sang thành chuỗi các chỉ thị máy tính được thực hiện
hoàn toàn tương tự như là việc chuyển dịch giữa các ngôn ngữ tự nhiên của con người. Các
thao tác này gọi là biên dịch (hay ngắn gọn hơn là dịch). Người ta còn phân việc biên dịch làm
hai loại tùy theo quá trình dịch xảy ra trước quá trình thực thi các tính toán hay nó xảy ra cùng
lúc với quá trình tính toán:
Một phần mềm thông dịch là một phần mềm có khả năng đọc, chuyển dịch mã nguồn của
một ngôn ngữ và ra lệnh cho máy tính tiến hành các tính toán dựa theo cú pháp của ngôn ngữ.
Một phần mềm biên dịch hay ngắn gọn hơn trình dịch là phần mềm có khả năng chuyển
dịch mã nguồn của một ngôn ngữ ban đầu sang dạng mã mới thuộc về ngôn ngữ cấp thấp hơn.
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
5
Ngôn ngữ cấp thấp nhất là một chuỗi các chỉ thị máy tính mà có thể được thực hiện trực
tiếp bởi chính máy tính (thông qua các thao tác trên vùng nhớ). Trước đây, hầu hết các trình
dịch cũ thường phải thông dịch từ mã nguồn sang bộ mã phụ (các tệp có dang *.obj), rồi sau
đó, mới biên dịch tiếp sang các tập tin thi hành. Ngày nay, hầu hết các trình dịch đều có khả
năng biên dịch mã nguồn trực tiếp sang thành các tập tin thi hành hay biên dịch sang các dạng
mã khác thấp hơn tuỳ theo yêu cầu của người lập trình.
Điểm khác nhau giữa thông dịch và biên dịch là: Trình thông dịch sẽ dịch từng câu lệnh một
và chương trình đích sẽ không được lưu lại. Còn trình biên dịch sẽ dịch toàn bộ chương trình,
1965 bởi Ole-Johan Dahl và Kristen Nygaard trong ngôn ngữ Simula. So với phương pháp lập
trình cổ điển, thì triết lý chính bên trong loại ngôn ngữ loại này là để tái dụng các khối mã
nguồn và cung ứng cho các khối này một khả năng mới: chúng có thể có các hàm (gọi là các
phương thức) và các dữ liệu (gọi là thuộc tính) nội tại. Khối mã như vậy được gọi là đối tượng.
Các đối tượng thì độc lập với môi trường và có khả năng trả lời với yêu cầu bên ngoài tùy theo
thiết kế của người lập trình. Với cách xây dựng này, mỗi đối tượng sẽ tương đương với một
chương trình riêng có nhiều đặc tính mới mà quan trọng nhất là tính đa hình, tính đóng, tính
trừu tượng và tính thừa kế. (VD: Java, Ruby, C++ , C#, .v.v.)
Concurrency oriented programs (Lập trình hướng thành phần): Ý tưởng xây dựng các phần
mềm bằng các kết hợp các modul lại với nhau, giống như một nhà máy lắp ráp oto. (VD:
Java, )
Agent oriented programs (Lập trình hướng Agent): Mỗi chương trình khi tạo ra có khả năng
tự chủ, tự thực thi tùy thuộc vào môi trường mà nó tồn tại (VD: Java, C#,…)
Một ngôn ngữ không nhất thiết là chỉ được phép thuộc 1 trong các loại trên, mà có thể hỗ
trợ nhiều kiểu tư duy khác nhau.
1.3 Giải quyết vấn đề và phát triển phần mềm
- Các mô hình phát triển sản phẩm phần mềm
Quá trình phát triển phần mềm là tập hợp các thao tác và các kết quả tương quan để sản
xuất ra một sản phẩm phần mềm. Hầu hết các thao tác này được tiến hành bởi các kỹ sư phần
mềm. Các công cụ hỗ trợ máy tính về kỹ thuật phần mềm có thể được dùng để giúp trong một
số thao tác.
Có 4 thao tác là nền tảng của hầu hết các quá trình phần mềm là:
+ Đặc tả phần mềm: Các chức năng của phần mềm và điều kiện để nó hoạt động phải được
định nghĩa.
+ Sự phát triển phần mềm: Để phần mềm đạt được đặc tả thì phải có quá trình phát triển
này.
+ Đánh giá phần mềm: Phần mềm phải được đánh giá để chắc chắn rằng nó làm những gì
mà khách hàng muốn.
+ Sự tiến hóa của phần mềm: Phần mềm phải tiến hóa để thỏa mãn sự thay đổi các yêu cầu
của khách hàng.
yêu cầu và phân phối phần mềm dứt diểm. Sự phát triển nên bắt đầu với những phần nào đã được hiểu
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
8
rõ. Phần mềm sẽ được thêm vào các chức năng mới khi mà nó được đề nghị cho khách hàng (và nhận
về các thông tin).
+ Mẫu thăm dò: đối tượng của phát triển tiến hoá này là nhằm hiểu các yêu cầu của khách hàng và
do đó phát triển các định nghĩa yêu cầu tốt hơn cho phần mềm. Các mẫu tập trung trên các thí nghiệm
với những phần đòi hỏi nào của khách hàng mà có thể gây sự khó hiểu hay ngộ nhận. Phát triển phần mềm theo mô hình tiến hoá
Phân tích mô hình: Mô hình phát triển tiến hóa này hiệu quả hơn mô hình thác nước. Tuy nhiên,
nó vẫn còn các khuyết điểm:
+ Quá trình thì không nhìn thấy rõ được: Các nhà quản lý cần phân phối thường xuyên để đo lường
sự tiến bộ. Nó không kinh tế trong việc làm ra các hồ sơ cho phần mềm.
+ Phần mềm thường dược cấu trúc nghèo nàn: Sự thay đổi liên tục dễ làm đổ vỡ cấu trúc của phần
mềm, tạo ra sự khó khăn và tốn phí.
+ Thường đòi hỏi những kỹ năng đặc biệt: Hầu hết các hệ thống khả dĩ theo cách này được tiến
hành bởi các nhóm nhỏ có kỹ năng cao cũng như các cá nhân phải năng động.
Mô hình này thích hợp với:
+ Phát triển các loại phần mềm tương đối nhỏ
+ Phát triển các loại phần mềm có đời sống tương đối ngắn
+ Tiến hành trong các hệ thống lớn hơn ở những chỗ mà không thể biểu thị được các đặc tả chi tiết
trong lúc tiến hành. Thí dụ của trường hợp này là các hệ thống thông minh nhân tạo (AI) và các giao
diện cho người dùng.
- Mô hình xoắn ốc Boehm
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
9
hoạch lâu dài.
Một cách ngắn gọn các phuơng pháp này cung ứng hiệu quả cao nhất cho vốn đầu tư, nhưng lại
không định rõ hiệu quả gì.
Lập trình cực hạn, gọi tắt là XP, là loại quá trình linh hoạt được biết đến nhiều nhất. Trong XP, các
pha được xúc tiến trong các bước cực nhỏ (hay liên tục) nếu so với các quá trình kiểu cũ, gọi là các
"toán" xử lý. Bước đầu tiên (với chủ định là không hoàn tất) cho đến các bước có thể chỉ tốn một ngày
hay một tuần, thay vì phải tốn nhiều tháng như trong phương pháp thác nước. Đầu tiên, một người viết
các thử nghiệm tự động để cung cấp các mục tiêu cụ thể cho sự phát triển. Kế đến là giai đoạn viết mã
(bởi một cặp lập trình viên); giai đoạn này hoàn tất khi mà các mã viết qua được tất cả các thử nghiệm
và những người lập trình không tìm ra thêm được thử nghiệm cần thiết nào nữa. Thiết kế và kiến trúc
được điều chỉnh và nâng cao ngay sau giai đoạn viết mã này bởi người đã viết mã trong giai đoạn
trước. Hệ thống chưa hoàn tất nhưng hoạt động được này được khai thác hay được đem ra minh họa
cho (một phần) người tiêu dùng mà trong số đó có người trong đội phát triển phần mềm. Thời điểm này
những người thực nghiệm lại bắt đầu viết các thử nghiệm cho những phần quan trọng kế tiếp của hệ
thống.
1.4 . Giải thuật
Thuật toán, còn gọi là giải thuật, là một tập hợp hữu hạn của các chỉ thị hay phương cách được
định nghĩa rõ ràng cho việc hoàn tất một số sự việc từ một trạng thái ban đầu cho trước; khi các chỉ thị
này được áp dụng triệt để thì sẽ dẫn đến kết quả sau cùng như đã dự đoán.
Nói cách khác, thuật toán là một bộ các qui tắc hay qui trình cụ thể nhằm giải quyết một vấn đề
trong một số bước hữu hạn, hoặc nhằm cung cấp một kết quả từ một tập hợp của các dữ kiện đưa vào.
Ví dụ: thuật toán để giải phương trình bậc nhất P(x): ax + b = c, (a, b, c là các số thực), trong tập
hợp các số thực có thể là một bộ các bước sau đây:
1. Nếu a = 0
o b = c thì P(x) có nghiệm bất kì
o b ≠ c thì P(c) vô nghiệm
2. Nếu a ≠ 0
o P(x) có duy nhất một nghiệm x = (c - b)/a
Lưu ý
Khi một thuật toán đã hình thành thì ta không xét đến việc chứng minh thuật toán đó mà chỉ chú
phụ thuộc vào cỡ của bài toán, tức là độ lớn của đầu vào. Vì thế độ phức tạp thuật toán là một hàm
phụ thuộc đầu vào. Tuy nhiên trong những ứng dụng thực tiễn, chúng ta không cần biết chính xác hàm
này mà chỉ cần biết một ước lượng đủ tốt của chúng.
Để ước lượng độ phức tạp của một thuật toán ta thường dùng khái niệm bậc O-lớn và bậc Θ (bậc
Theta).
Bậc O-lớn
Gọi n là độ lớn đầu vào. Tùy thuộc từng bài toán mà n có thể nhận những giá trị khác nhau. Chẳng
hạn, bài toán tính giai thừa thì n chính là số cần tính giai thừa. Nhiều bài toán số trị, chẳng hạn tính sai
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
12
phân thì n là số chữ số có nghĩa cần đạt được. Trong các phép tính đối với ma trận thì n là số hàng hoặc
cột của ma trận.
Độ phức tạp của bài toán phụ thuộc vào n. Ở đây ta không chỉ đặc trưng độ phức tạp bởi số lượng
phép tính, mà dùng một đại lượng tổng quát là tài nguyên cần dùng R(n). Đó có thể là số lượng phép
tính (có thể tính cả số lần truy nhập bộ nhớ, hoặc ghi vào bộ nhớ); nhưng cũng có thể là thời gian thực
hiện chương trình (độ phức tạp về thời gian) hoặc dung lượng bộ nhớ cần phải cấp để chạy chương
trình (độ phức tạp về không gian).
Xét quan hệ giữa tài nguyên và độ lớn đầu vào, nếu như tìm được hằng số C > 0, C không phụ thuộc
vào n, sao cho với n đủ lớn, các hàm R(n),g(n) đều dương và
thì ta nói thuật toán có độ phức tạp cỡ O(g(n)).
Độ phức tạp không phải là độ đo chính xác lượng tài nguyên máy cần dùng, mà đặc trưng cho động
thái của hệ thống khi kích thước đầu vào tăng lên. Chẳng hạn với thuật toán có độ phức tạp tuyến tính
O(n) (xem phần dưới), nếu kích thước đầu vào tăng gấp đôi thì có thể ước tính rằng tài nguyên cần
dùng cũng tăng khoảng gấp đôi. Nhưng với thuật toán có độ phức tạp bình phương O(n
2
) thì tài nguyên
sẽ tăng gấp bốn. Mặt khác, với thuật toán có độ phức tạp hàm mũ O(2
n
đều dương và không phụ thuộc vào
n, sao cho với n đủ lớn, các hàm R(n),f(n) và h(n) đều dương và thì ta nói thuật toán có độ phức tạp cỡ lớn hơn Ω(n), và đúng bằng cỡ Θ(h(n)).
Như vậy nếu xét một cách chặt chẽ, kí hiệu Θ mới biểu thị độ phức tạp của thuật toán một cách chặt
chẽ. Tuy nhiên qua một thời gian dài kí hiệu O(n) cũng đã được dùng phổ biến.
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
14
Chương 2. KIỂU DỮ LIỆU, TOÁN TỬ VÀ PHÁT BIỂU
2.1 Giới thiệu về ngôn ngữ C++
C++ (C-plus-plus) là một loại ngôn ngữ lập trình. Đây là một dạng ngôn ngữ đa mẫu hình tự do có
kiểu tĩnh và hỗ trợ lập trình thủ tục, dữ liệu trừu trượng, lập trình hướng đối tượng, và lập trình đa hình.
Từ thập niên 1990, C++ đã trở thành một trong những ngôn ngữ thương mại phổ biến nhất.
Bjarne Stroustrup của Bell Labs đã phát triển C++ (mà tên nguyên thủy là "C with class" trong suốt
thập niên 1980 như là một bản nâng cao của ngôn ngữ C. Những bổ sung nâng cao bắt đầu với sự thêm
vào của khái niệm lớp, tiếp theo đó là các khái niệm hàm ảo, toán tử quá tải, đa kế thừa, tiêu bản, và xử
lý ngoại lệ. Tiêu chuẩn của ngôn ngữ C++ đã được thông qua trong năm 1998 như là ISO/IEC
14882:1998. Phiên bản hiện đang lưu hành là phiên bản 2003, ISO/IEC 14882:2003. Phiên bản tiêu
chuẩn mới hơn nữa (được biết dưới tên gọi không chính thức là C++0x) đang được xây dựng.
Tổng quan về kĩ thuật
Trong tiêu chuẩn 1998 của C++ có hai phần chính: phần ngôn ngữ cốt lõi và phần Thư viện chuẩn
C++(STL - Standard Template Library) . Phần thư viện này lại bao gồm hầu hết thư viện tiêu bản
chuẩn và phiên bản có điều chỉnh chút ít của thư viện chuẩn C. Nhiều thư viện C++ hiện hữu không
thuộc về tiêu chuẩn như là thư viện Boost. Thêm vào đó, nhiều thư viện không theo tiêu chuẩn được
viết trong C một cách tổng quát đều có thể sử dụng trong các chương trình C++.
Chức năng dẫn nhập trong C++
So với C, C++ tăng cường thêm nhiều tính năng, bao gồm: khai báo như mệnh đề, chuyển kiểu
bộ lịch sử kĩ nghệ, các thành phần của thư viện này được khuyến cáo sử dụng thay vì dùng những phần
viết tay bên ngoài hay những phương tiện cấp thấp khác. Thí dụ, dùng std:vector hay std::string
thay vì dùng kiểu mảng đơn thuần sẽ không những là cho "đời sống dễ thở hơn", mà còn là một cách
hữu hiệu để viết phần mềm được an toàn và linh hoạt hơn.
STL nguyên là một thư viện của hãng HP và sau đó là của SGI, trước khi nó được nhận vào thành
chuẩn C++. Tiêu chuẩn thì không tham chiếu nó bằng cái tên "STL", khi đa phần nó chỉ là bộ phận tiêu
chuẩn. Tuy vậy, nhiều người vẩn dùng khái niệm "STL" này để phân biệt nó với phần còn lại của thư
viện C++ như là IOstream, quốc tế hóa (kí tự và ngôn ngữ trình bày), chẩn đoán, thư viện C, v.v
Một đề án mang tên STLPort, dựa cơ sở trên SGI STL, bảo trì các thiết lập mới của STL,
IOStream và string. Các đề án khác cũng có những xây dựng đặc thù riêng của thư viện chuẩn với
các mục tiêu thiết kế khác nhau. Mỗi nơi sản xuất hay phổ biến nhà trình dịch C++ đều bao gồm một
sự thiết lập của thư viện, vì đây là phần quan trọng của tiêu chuẩn và lại là kỳ vọng của người lập trình
2.2 Câu chú thích
Các chú thích được các lập trình viên sử dụng để ghi chú hay mô tả trong các phần của chương
trình. Trong C++ có hai cách để chú thích
// Chú thích theo dòng
/* Chú thích theo khối */
Chú thích theo dòng bắt đầu từ cặp dấu xổ (//) cho đến cuối dòng. Chú thích theo khối bắt đầu bằng
/* và kết thúc bằng */ và có thể bao gồm nhiều dòng. Chúng ta sẽ thêm các chú thích cho chương
trình : Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
16
/* my second program in C++
with more comments */
#include <iostream.h>
int main ()
{
Nhân
/
Chia
%
Chia lấy phần dư
Giảm 1 đơn vị
++
Tăng 1 đơn vị
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
17
Tăng và giảm (++ và )
Toán tử ++ thêm 1 vào toán hạng của nó và – – trừ bớt 1. Nói cách khác:
Ví dụ:
x = x + 1 giống như ++x hay x++
x = x -1 giống như x - - hay x - -
Cả 2 toán tử tăng và giảm đều có thể tiền tố (đặt trước) hay hậu tố (đặt sau) toán hạng.
Tuy nhiên giữa tiền tố và hậu tố có sự khác biệt khi sử dụng trong 1 biểu thức. Khi 1 toán tử tăng
hay giảm đứng trước toán hạng của nó, C++ thực hiện việc tăng hay giảm trước khi lấy giá trị dùng
trong biểu thức. Nếu toán tử đi sau toán hạng, C++ lấy giá trị toán hạng trước khi tăng hay giảm nó.
Ví dụ:
x = 10;
y = ++x ; //y = 11, x=11
Tuy nhiên:
x = 10;
y = x++; //y = 10, x=11
Thứ tự ưu tiên của các toán tử số học: ++, sau đó là *, /, % rồi mới đến +, -
2) Các toán tử quan hệ và các toán tử Logic
Ý tưởng chính của toán tử quan hệ và toán tử Logic là đúng hoặc sai. Trong C++ mọi giá trị khác 0
q
p&&q
p||q
!p
0
0
0
0
1
0
1
0
1
1
1
0
0
1
0
1
1
1
1
0
Các toán tử quan hệ và Logic đều có độ ưu tiên thấp hơn các toán tử số học. Do đó một biểu thức như:
10 > 1+ 12 sẽ được xem là 10 > (1 + 12) và kết quả là sai (0).
Ta có thể kết hợp vài toán tử lại với nhau thành biểu thức như sau:
Ví dụ: (10>5)&&!(10<9)||3<=4 Kết quả là đúng
Thứ tự ưu tiên của các toán tử quan hệ là Logic : ! ; > ; >= ; < ; <= ; = = ;!= ; && ; ||
1
1
1
0
5) Toán tử con trỏ & và *
Một con trỏ là địa chỉ trong bộ nhớ của một biến. Một biến con trỏ là một biến được khai báo riêng
để chứa một con trỏ đến một đối tượng của kiểu đã chỉ ra nó.
Ta sẽ tìm hiểu kỹ hơn về con trỏ trong chương về con trỏ. Ở đây, chúng ta sẽ đề cập ngắn gọn đến hai
toán tử được sử dụng để thao tác với các con trỏ.
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
19
Toán tử thứ nhất là &, là một toán tử quy ước trả về địa chỉ bộ nhớ của hệ số của nó.
Ví dụ: m = &count;
Đặt vào biến m địa chỉ bộ nhớ của biến count.
Chẳng hạn, biến count ở vị trí bộ nhớ 2000, giả sử count có giá trị là
100. Sau câu lệnh trên m sẽ nhận giá trị 2000.
Toán tử thứ hai là *, là một bổ sung cho &; đây là một toán tử quy ước trả về
giá trị của biến được cấp phát tại địa chỉ theo sau đó.
Ví dụ: q = *m;
Sẽ đặt giá trị của count vào q. Bây giờ q sẽ có giá trị là 100 vì 100 được lưu trữ tại địa chỉ 2000.
6) Toán tử dấu “,” .
Toán tử dấu , được sử dụng để kết hợp các biểu thức lại với nhau. Bên trái của toán tử dấu , luôn
được xem là kiểu void. Điều đó có nghĩa là biểu thức bên phải trở thành giá trị của tổng các biểu thức
được phân cách bởi dấu phẩy.
Ví dụ: x = (y=3,y+1);
Trước hết gán 3 cho y rồi gán 4 cho x. Cặp dấu ngoặc đơn là cần thiết vì toán tử dấu , có độ ưu tiên
thấp hơn toán tử gán.
7) Xem các dấu ngoặc đơn và cặp dấu ngoặc vuông là toán tử
Trong C++, cặp dấu ngoặc đơn là toán tử để tăng độ ưu tiên của các biểu thức bên trong nó.
2.4.1. Biến
Một biến (variable) là một tên biểu thị cho một số lượng, một ký hiệu hay một đối tượng. Thêm
vào đó, một biến sẽ được dành sẵn chỗ (phần của bộ nhớ) để chứa số lượng, ký hiệu hay đối tượng đó.
Trong lúc chương trình được thi hành thì các biến của chương trình sẽ có thể thay đổi giá trị hoặc
không thay đổi gì cả. Hơn nữa, một biến có thể bị thay đổi cả lượng bộ nhớ mà nó đang chiếm hữu (do
người lập trình hay do phần mềm dịch ra lệnh).
Trường hợp biến này không được gán giá trị hay có gán giá trị nhưng không được sử dụng vào các
tính toán thì nó chỉ chiếm chỗ trong bộ nhớ một cách vô ích. Mỗi biến sẽ có tên của nó và có thể có
kiểu xác định. Tùy theo ngôn ngữ, một biến có thể được khai báo ở vị trí nào đó trong mã nguồn và
cũng tùy ngôn ngữ, tùy phần mềm dịch và cách thức lập trình mà một biến có thể được tạo nên (cùng
với chỗ chứa) hay bị xóa bỏ tại một thời điểm nào đó trong lúc thực thi chương trình. Việc các biến bị
xóa bỏ là để tiết kiệm bộ nhớ cũng như làm tốt hơn việc quản lý phần bộ nhớ mà đôi khi một chương
trình chỉ được cấp bởi đăng ký với hệ điều hành.
Quá trình tồn tại của một biến gọi là đời sống của biến. Trong nhiều trường hợp đời sống của một
biến chỉ xảy ra trong nội bộ một hàm, một thủ tục hay trong một khối mã.
2.4.2. Khai báo biến
- Cú pháp: <Kiểu dữ liệu> <danh sách biến>;
Mỗi biến được viết cách nhau bằng dấu “,”.
Ví dụ: int x , y;
float a , b , c;
- Trong C/C++ có thể khai báo biến ở bất cứ vị trí nào miễn là khai báo trước khi sử dụng.
2.5 Các kiểu dữ liệu cơ bản chuẩn
2.5.1. KiÓu ký tù (char)
Một giá trị kiểu char chiếm 1 byte (8bit) và biểu diễn được một ký tự thông qua bảng má
ASCII.
VÝ dô :
Ký tự
Mã ASCII
0
048
1 byte
Ví dụ sau minh hoạ sự khác nhau giữa hai kiểu dữ liệu trên : Xét đoạn ch-ơng trình sau :
char ch1;
unsigned char ch2;
ch1=200; ch2=200;
Khi đó thực chất :
ch1= - 56;
ch2= 200;
Nh-ng cả ch1 và ch2 đều biểu diễn cùng một ký tự có mã 200.
Phân loại ký tự:
Có thể chia 256 ký tự làm ba nhóm :
Nhóm 1: Nhóm các ký tự điều khiển có mã từ 0 đến 31. Chẳng hạn ký tự mã 13 dùng để chuyển con
trỏ về đầu dòng, ký tự 10 chuyển con trỏ xuống dòng d-ới ( trên cùng một cột ). Các ký tự nhóm này
nói chung không hiển thị ra màn hình.
Nhóm 2 : Nhóm các ký tự văn bản có mã từ 32 đến 126. Các ký tự này có thể đ-ợc đ-a ra màn hình
hoặc máy in.
Nhóm 3 : Nhóm các ký tự đồ hoạ có mã số từ 127 đến 255. Các ký tự này có thể đ-a ra màn hình
nh-ng không in ra đ-ợc (bằng các lệnh DOS).
2.5.2. Kiểu nguyên
Trong C++ cho phép sử dụng số nguyên kiểu int, số nguyên dài kiểu long và số nguyên không dấu
kiểu unsigned. Kích cỡ và phạm vi biểu diễn của chúng đ-ợc chỉ ra trong bảng d-ới đây :
Kiểu
Phạm vi biểu diễn
Kích th-ớc
int
-32768 đến 32767
2 byte
unsigned int
0 đến 65535
17 đến 18
10 byte
Giải thích: Máy tính có thể l-u trữ đ-ợc các số kiểu float có giá trị tuyệt đối từ 3.4E-38 đến 3.4E+38.
Các số có giá trị tuyệt đối nhỏ hơn3.4E-38 đ-ợc xem bằng 0. Phạm vi biểu diễn của số double đ-ợc
hiểu theo nghĩa t-ơng tự.
Ngoi ra ta cũn cú kiu d liu void, kiu ny mang ý ngha l kiu rng khụng cha giỏ tr gỡ c.
2.6 . Cu trỳc mt chng trỡnh C++
Trc khi núi n cu trỳc tng quỏt ca mt chng trỡnh ngun C, chỳng ta hóy xem
mt vớ d n gin sau õy chng trỡnh in xõu Chao cac ban! ra mn hỡnh
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
void main()
{
clrscr();
cout<<\n Chao cac ban !;
getch();
}
(trong on mó ngun trờn chỳng ta thờm cỏc s dũng v du: tin cho vic gii thớch, cũn trong
chng trỡnh thỡ khụng c cú chỳng).
Trong chng trỡnh trờn gm hai phn chớnh ú l :
- Cỏc dũng bao hm tp dũng 1, 2; ng ký s dng cỏc tp tiờu . Trong chng trỡnh ny
chỳng ta cn dựng hai file tiờu <stdio.h> v <conio.h>.
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
23
- Hàm main từ dòng 3 tới dòng 8. Đây là hàm chính của chương trình , dòng 3 là tiêu đề hàm cho
biết tên: main, kiểu hàm: void, và đối của hàm (trong ví dụ này không có đối). Thân của hàm main bắt
đầu ngay sau dấu { (dòng 4), và kết thúc tại dấu } (dòng 8).
Cấu trúc tổng quát:
}
Cài đặt các hàm
<Kiểu dữ liệu trả về> function1( các tham số)
{
Các khai báo cục bộ trong hàm.
Các câu lệnh dùng để định nghĩa hàm return
<kết quả trả về>;
}
Bài giảng Kỹ thuật lập trình
Biên soạn: ThS. Trần Xuân Thanh – Khoa CNTT – ĐH Thành Đô
24
…
Một chương trình C++ bắt đầu thực thi từ hàm main (thông thường là từ câu lệnh đầu tiên đến câu lệnh
cuối cùng).
Lưu ý: Những giải thích trong chương trình đặt sau dấu // lời giải thích hoặc trong dấu /* lời giải
thích */
Ví dụ 1: In ra màn hình dòng chữ “Hello world”
// my first program in C++
#include <iostream.h>
int main ()
{
cout << "Hello World!";
return 0;
}
Hello World!
Ví dụ 2: In ra màn hình dãy số giảm dần
// custom countdown using while
Một thuộc tính của toán tử gán trong C++ góp phần giúp nó vượt lên các ngôn ngữ lập trình khác là
việc cho phép vế phải có thể chứa các phép gán khác.
Ví dụ: a = 2 + (b = 5); tương đương với: b = 5; a = 2 + b;
Vì vậy biểu thức sau cũng hợp lệ trong C++: a = b = c = 5;
gán giá trị 5 cho cả ba biến a, b và .
Các toán tử gán phức hợp (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
Một đặc tính của ngôn ngữ C++ làm cho nó nổi tiếng là một ngôn ngữ súc tích chính là các toán tử
gán phức hợp cho phép chỉnh sửa giá trị của một biến với một trong những toán tử cơ bản sau:
value += increase; tương đương với value = value + increase;
a -= 5; t tương đương với a = a - 5;
a /= b; tương đương với a = a / b;
price *= units + 1; tương đương với price = price * (units + 1);
và tương tự cho tất cả các toán tử khác.
3.2 Định dạng số liệu để xuất ra
Trước khi dữ liệu được in ra màn hình cần định dạng dữ liệu. Sử dụng các công cụ định dạng có
sẵn như: xuống dòng ( \n ), dấu tab ( \t ), về đầu dòng ( \r ), … và một số định dạng số.
3.3 Cách dùng các hàm thư viện toán học
Các hàm toán học có trong thư viên <math.h>, <float.h>:
abs(int x): tính trị tuyệt đối của số nguyên x
fabs(double x): tính trị tuyệt đối của số thực x