SlideShare a Scribd company logo
Chương 1. Mở đầu
Chương này giói thiệu những phần cơ bản của một chương trình C++. Chúng ta sử dụng
những ví dụ đơn giản đế trình bày cấu trúc các chương trình C++ và cách thức biên dịch
chúng. Các khái niệm cơ bản như là hằng, biến, và việc lưu trữ chúng trong bộ nhớ cũng
sẽ được tháo luận trong chương này. Sau đây là một đặc tả sơ bộ về khái niệm lập trình.
Lập trình
Máy tính số là một công cụ để giải quyết hàng loạt các bài toán lớn. Một lời giải cho một
bài toán nào đó được gọi là một giải thuật (algorithm); nó mô tá một chuồi các bước cần
thực hiện đế giải quyết bài toán. Một ví dụ đơn giản cho một bài toán vả một giải thuật có
thể là:
Bài toán: sắp xếp một danh sách các số theo thứ tự tăng dần.
Giải thuật:Giả sử danh sách đã cho là listl; tạo ra một danh sách rỗng, list2,
để lưu danh sách đã sắp xếp. Lặp đi lặp lại công việc, tìm số nhỏ nhất trong
listl, xóa nó khỏi listl, và thêm vào phần tử kế tiếp trong danh sách list2, cho
đến khi lỉstl là rỗng.
Giải thuật được diễn giải bằng các thuật ngữ trừu tượng mang tính chất dề hiểu. Ngôn
ngữ thật sự được hiểu bởi máy tính là ngôn ngữ máy. Chương trình được diễn đạt bằng
ngôn ngữ máy được gọi là có thể thực thi. Một chương trình được viết bằng bất kỳ một
ngôn ngừ nào khác thì trước hết cần được dịch sang ngôn ngữ máy để máy tính có thể
hiếu và thực thi nó.
Ngôn ngữ máy cực kỳ khó hiểu đối với lập trình viên vì thế họ không thể sử dụng
trực tiếp ngôn ngữ máy đế viết chương trình. Một sự trừu tượng khác là ngôn ngữ
assembly. Nó cung cấp những tên dỗ nhớ cho các lệnh và một ký hiệu dễ hiếu hơn cho
dữ liệu. Bộ dịch được gọi là assembler chuyển ngôn ngữ assembly sang ngôn ngừ máy.
Ngay cả những ngôn ngữ assembly cũng khó sử dụng. Những ngôn ngữ cấp cao
như C++ cung cấp các ký hiệu thuận tiện hon nhiều cho việc thi hành các giải thuật.
Chúng giúp cho các lập trình viên không phải nghĩ nhiều về các thuật ngữ cấp thấp, và
giúp họ chỉ tập trung vào giải thuật. Trình biên dịch (compiler) sè đảm nhiệm việc dịch
chương trình viết bằng ngôn ngữ cấp cao sang ngôn ngữ assembly. Mã assembly được
tạo ra bởi trình biên dịch sau đó sẽ được tập hợp lại đế cho ra một chương trình có thể
thực thi.
Chương 1: Mởđầu 1
1.1. Một chưong trình C++ đon giản
Danh sách 1.1 trình bày chương trình C++ đầu tiên. Chương trình này khi
chạy sẽ xuất ra thông điệp HelloWorld.
Danh sách 1.1
1
2
3
4
5
Chú giải
1 Hàng này sử dụng chỉ thị tiền xử lý #include để chèn vào nội dung của tập
tin header iosteam.h trong chương trình, iostrcamli là tập tin header chuẩn
của C++ và chứa đựng các định nghĩa cho xuất và nhập.
2 Hàng này định nghĩa một hàm được gọi là main. Hàm có thế không có
hay có nhiều tham số (parameters); các tham số này luôn xuất hiện sau
tên hàm, giữa một cặp dấu ngoặc. Việc xuất hiện của từ void ở giữa dấu
n|oặc chi định rằng hàm main không có tham số. Hàm có thể có kiểu trả
về; kiểu trả về luôn xuất hiện trước tên hàm. Kiếu trả về cho hàm main là
int (ví dụ: một số nguyên). Tất cả các chương trình C++ phải có một hàm
main duy nhất.Việc thực thi chương trình luôn bắt đầu từ hàm main.
3 Dấu ngoặc nhọn bắt đầu thân của hàm mam.
4 Hàng này là một câu lệnh (statement). Một lệnh là một sự tính toán đế
cho ra một giá trị. Ket thúc một lệnh thì luôn luôn được đánh dấu bằng
dấu chấm phẩy (;). Câu lệnh này xuất ra chuỗi "Hello World®" đế gởi đến
dòng xuất cout Chuồi là một dãy các ký tự được đặt trong cặp nháy kép.
Ký tự cuối cùng trong chuồi này (n) là một ký tự xuống hàng (newline).
Dòng là một đối tượng được dùng đế thực hiện các xuất hoặc nhập, cout
là dòng xuất chuấn trong C++ (xuất chuấn thường được hiểu là màn hình
máy tính). Ký tự « là toán tử xuất, nó xem dòng xuất như là toán hạng
trái và xem biểu thức như là toán hạng phải, và tạo nên giá trị của biếu
thức được gởi đến dòng xuất. Trong trường hợp này, kết quả là chuồi
"Hello Worlđn" được gởi đến dòng cout, làm cho nó được hiến thị trên
màn hình máy tính.
5 Dấu ngoặc đóng kết thúc thân hàm main.
1.2. Biên dịch một chương trình C++
Bảng 1.1 trình bày chương trình trong danh sách 1.1 được biên dịch và chạy
trong môi trường UNIX thông thường. Phần in đậm được xem như là đầu vào
(input) của người dùng và phần in thường được xem như là đáp ứng của hệ
thống. Dấu nhắc ở hàng lệnh UNIX xuất hiện như là ký tự dollar($).
#inđude<iostream.h>
intmain(void)
{
cout« "HelloWorld'll";
1_________ ___________
Chương 1: Mởđầu 2
1
2
3
4
Bảng 1.1
Chú giải
1 Lệnh để triệu gọi bộ dịch AT&T của c++ trong môi trường UNIX là cc.
Đối số cho lệnh này (hello.cc) là tên của tập tin chứa đựng chương trình.
Theo qui định thì tên tập tin có phần mở rộng là .c, .c, hoặc là .cc. (Phần
mở rộng này có thể là khác nhau đối với những hệ điều hành khác nhau)
2 Ket quả của sự biên dịch là một tập tin có thế thực thi mặc định là a.out.
Đế chạy chương trình, chúng ta sử dụng a.out như là lệnh.
3 Đây là kết quả được cung cấp bởi chương trình.
4 Dấu nhắc ừở về hệ thống chỉ định rằng chương trình đã hoàn tất sự thực
thi của nó.
Lệnh cc chấp nhận các phần tùy chọn. Mồi tùy chọn xuất hiện như name,
trong đó name là tên cùa tùy chọn (thườnệ là một kỷ tự đơn). Một vài tùy
chọn yêu cầu có đối số. Ví dụ tùy chọn xuất (-o) cho phép chỉ định rõ tập tin
có thế được cung cấp bởi trình biên dịch thay vì là aout. Bảng 1.2 minh họa
việc sử dụng tùy chọn này bằng cách chỉ định rõ hello như là tên của tập tin có
thể thực thi.
Bảng 1.2
1
2
3
4
Mặc dù lệnh thực sự có thế khác phụ thuộc vào trình biên dịch, một thủ
tục biên dịch tương tự có thế được dùng dưới môi trường MS-DOS. Trình
biên dịch C++ dựa trên Windows dâng tặnẹ một môi trường thân thiện với
người dùng mà việc biên dịch rất đơn giản bằng cách chọn lệnh từ menu. Qui
định tên dưới MS-DOS và Windows là tên của tập tin nguồn C++ phải có
phần mở rộng là .cpp.
1.3. Viêc biên dich C++ diễn ra như thế nào• •
Biên dịch một chương trình C++ liên quan đến một số bước (hầu hết các bước
là trong suốt với người dùng):
• Đầu tiên, bộ tiền xử lý C++ xem qua mã trong chương trình và thực hiện
các chỉ thị được chỉ định bởi các chỉ thị tiền xử lý (ví dụ, #include). Ket
quả là một mã chương trình đã sửa đối mà không còn chứa bất kỳ một chi
thị tiền xử lý nào cả.
$ c c heflo.cc-oheDo
$ heBo
HelloWorld
$
$ c c hello.cc
$ a.out
HelloWorld
$
Chương 1: Mởđầu 3
• Sau đó, trình biên dịch C++ dịch các mã của chương trình. Trình biên
dịch có thế là một trình biên dịch C++ thật sự phát ra mã assembly hay
mã máy, hoặc chỉ là trình chuyển đổi dịch mã sang c. Ớ trường họp thứ
hai, mã c sau khi được dịch ra sè tạo thành mã assembly hay mã máy
thông qua trình biên dịch c. Trong cả hai trường hợp, đầu ra có thể
không hoàn chỉnh vì chương trình tham khảo tới các thủ tục trong thư
viện còn chưa được định nghĩa như một phần của chương trình. Ví dụ
Danh sách 1.1 tham chiếu tới toán tò « mà thực sự được định nghĩa
trong một thư viện 10 riêng biệt.
• Cuối cùng, trình liên kết hoàn tất mã đối tượng bằng cách liên kết nó với
mã đối tượng của bất kỳ các module thư viện mà chương trình đã tham
khảo tới. Ket quả cuối cùng là một tập tin thực thi.
Hình 1.1 minh họa các bước trên cho cả hai trình chuyến đối C++ và trình
biên dịch C++. Thực tế thì tất cả các bước trên được triệu gọi bởi một lệnh
đơn (như là CQ và người dùng thậm chí sẽ không thấy các tập tin được phát
ra ngay lập tức.
Hình 1.1 Việc biên dịch C++
c++
C++
c c
Program
17
►
TRANSLATOR
► Code
V
►
COMPILER
C++
Program
_J7
►
C++
NATIVE
COMPILER
1.4. Biến
Biến là một tên tượng trưng cho một vùng nhớ mà dữ liệu có thế được lưu trữ
trên đó hay là được sử dụng lại. Các biến được sử dụng đế giữ các giá tri dữ
liệu vì thế mà chúng có thế được dùng trong nhiều tính toán khác nhau trong
một chương trình. Tất cả các biến có hai thuộc tính quan trọng:
• Kiếu được thiết lập khi các biến được định nghĩa (ví dụ như: integer,
real, character). Một khi đã được định nghĩa, kiểu của một biến C++
không thể được chuyển đổi.
Chương 1: Mởđầu 4
• Giá trị có thể được chuyến đối bằng cách gán một giá trị mới cho biến.
Loại giá trị của biến có thể nhận phụ thuộc vào kiểu của nó. Ví dụ, một
biến số nguyên chỉ có thể giữ các giá trị nguyên (chắng hạn, 2, 100, -12).
Danh sách 1.2 minh họa sử dụng một vài biến đon giản.
Danh sách 1.2
2
3
4
5
6
7
8
9
10
11
Chú giải
4 Hàng này định nghĩa một biến int (kiếu số nguyên) tên là workDays, biến
này đại diện cho số ngày làm việc trong tuần. Theo như luật chung, trước
tiên một biến được định nghĩa bàng cách chi định kiểu của nó, theo sau
đó là tên biến và cuối cùng là được kết thúc bởi dấu chấm phấy.
5 Hàng này định nghĩa ba biến float (kiếu số thực) lần lượtthay cho số giờ
làm việc trong ngày, số tiền phải trả hàng giờ, và số tiền phải trả hàng
tuần. Như chúng ta thấy ở hàng này, nhiều biến của cùng kiếu có thế định
nghĩa một lượt qua việc dùng dấu phấy đế ngăn cách chúng.
6 Hàng này là một câu lệnh gán. Nó gán giá trị 5 cho biến workDays. Vì thế,
sau khi câu lệnh này được thực thi, workDays biểu thị giá trị 5.
7 Hàng này gán giá ứị 7.5 tới biến workHours.
8 Hàngnày gán giá trị 38.55 tới biến payRate.
9 Hàng này tính toán số tiền phải trá hàng tuần từ cácbiến workDays,
workHours, và payRate (* là toán tử nhân). Giá trị kết quả được lưu vào
biến weeklyPay.
10-12 Các hàng này xuất ba mục tuần tự là: chuồi "Weekly Pay = ", giá trị
của biến weeklyPay, và một ký tự xuống dòng.
Khi chạy, chương trình sẽ cho kết quả như sau:
WeeklyPay= 1445.625
Khi một biến được định nghĩa, giá trị của nó không được định nghĩa
cho đến khi nó được gán cho một giá trị thật sự. Ví dụ, weeklyPay có một giá
trị không được định nghĩa cho đến khi hàng 9 được thực thi. Việc gán giá trị
cho một biến ở lần đầu tiên được gọi là khỏi tạo. Việc chắc chắn rằng một
#mdude<iostream.h>
intmain(void)
{
int woikDays;
float workHoure,payRate,weeklyPay;
woikDays=5;
workHours_ 7.5;
payRate=38.55;
weeklyPay=woikDays *workHours*payRate;
cout« "WeeklyPay= " « weeklyPay«V;
Chương 1: Mởđầu 5
biến được khởi tạo tmớc khi 11Ó được sử dụng trong bất kỳ công việc tính
toán nào là rất quan trọng.
Một biến có thế được định nghĩa và khởi tạo cùng lúc. Điều này được
xem như là một thói quen lập trình tốt bởi vì nó giành trước khả năng sử dụng
biến trước khi nó được khởi tạo. Danh sách 1.3 là một phiên bản sửa lại của
danh sách 1.2 mà có sử dụng kỹ thuật này. Trong mọi mục đích khác nhau thì
hai chương trình là tương tương.
Danh sách 1.3
1
2
3
4
5
6
7
8
9
10
11
1.5. Xuất/nhập đơn giản
Cách chung nhất mà một chương trình giao tiếp với thế giới bên ngoài là
thông qua các thao tác xuất nhập hướng ký tự đơn giản. C++ cung cấp hai
toán tử hữu dụng cho mục đích này là » cho nhập và « cho xuất. Chúng ta
đã thấy ví dụ của việc sử dụng toán tử xuất « rồi. Danh sách 1.4 sê minh
họa thêm cho việc sử dụng toán tử nhập » .
Danh sách 1.4
1
2
3
4
5
6
7
8
9
10
11
12
13
#inelude<iostream.h>
intmain(void)
{
int woricDays=5;
float workHours=7.5;
float payRate,weeklyPay,
cout« "Whatisthehourlypayrate?
cin»payRate;
weeklyPay=workDays *woricHours*payRate;
cout« "WeeklyPay=
cout« weeklyPay;
cout«W;
#include<iostream.h>
intmain(void)
{
int woricDays=5;
float workHours=7.5;
float payRate=38.55;
float weeklyPay=woikDays*workHours*payRate;
cout« "WeeklyPay=";
cout« weeklyPay;
cout«n';
Chương 1: Mởđầu 6
7 Hàng này xuất ra lời nhắc nhở What is the hourly pay rate? để tìm dữ liệu
nhập của người dùng.
8 Hàng này đọc giá trị nhập được gõ bởi người dùng và sao chép giá trị này
tói biến payRatc. Toán tử nhập » lấy một dòng nhập như là toán hạng trái
(cán là dòng nhập chuấn của C++ mà tương ứng với dữ liệu được nhập
vào từ bàn phím) và một biến (mà dừ liệu nhập được sao chép tới) như là
toán hạng phải.
9-13 Phần còn lại của chương trình là như trước.
Khi chạy, chương trình sè xuất ra màn hình như sau (dữ liệu nhập của người
dùng được in đậm);
WhatLsthehourlypayrate?33.55
WeeklyPay= 1258.125
Cả hai « và » trả về toán hạng trái như là kết quá của chúng, cho phép
nhiều thao tác nhập hay nhiều thao tác xuất được kết họp trong một câu lệnh.
Điều này được minh họa trong danh sách 1.5 với trường hợp cho phép nhập
cả số giờ làm việc mỗi ngày và số tiền phải trả mỗi giờ.
Chú giải
Danh sách 1.5
2
3
4
5
6
7
8
9
10
Chú giải
7 Hàng này đọc hai giá trị nhập được nliập vào từ người dùng và chép
tương ứng chúng tới hai biến workHours và payRale. Hai giá trị cần được
tách biệt bởi một không gian trống (chắng hạn, một hay là nhiều khoản
trắng hay là các ký tự tab). Câu lệnh này tương đương với:
(cin» workHours)» payRale;
Vì kết quả của » là toán hạng trái, (cin»workHours) định giá cho cin mà
sau đó được sử dụng như là toán hạng trái cho toán tử » kế tiếp.
//include<iostream.h>
intmain(void)
{
int wotfcDays=5;
float workHouK,payRate,weeklyPay;
cout« "Whataretheworkhoursandthehourlypayrate?
cin» workHours» payRate;
weeklyPay=workDays*workHours*payRate;
cout« "WeeklyPay=" « weeklyPay« V;
j_________________ _________ _________________
Chương 1: Mởđầu 7
9 Hàng xiày là kết quả của việc kết hợp từ hàng 10 đến hàng 12 trong danli
sách 1.4. Nó xuất "Weekly Pay = ", theo sau đó là giá trị của biến
weeklyPay, và cuối cùng là một ký tự xuống dòng. Câu lệnh này tương
đương với:
((cout« 'WeeklyPay= " )« weeklyPay)« Vi';
Vì kết quả của « là toán hạng trái, (cout« "Weekly Pay = ") định giá cho
cout mà sau đó được sử dụng như là toán hạng trái của toán tử « ké tiếp.
Khi chạy, chương trình sẽ hiển thị như sau:
Whataretheworkhoursandthehouriypayrate?75 33.55
WeeklyPay= 1258.125
1.6. Chú thích
Chú thích thường là một đoạn văn bản. Nó được dùng đế giải thích một vài
khía cạnh của chương trình. Trình biên dịch bở qua hoàn toàn các chú thích
trong chương trình. Tuy nhiên các chú thích này là có ý nghĩa và đôi khi là rất
quan trọng đối với người đọc (người xem các mã chương trình có sẵn) và
người phát triển phần mềm. C++ cung cấp hai loại chú thích:
• Những gì sau // (cho đến khi kết thúc hàng mà nó xuất hiện) được xem
như là một chú thích.
• Những gì đóng ngoặc trong cặp dấu ỉ* và */ được xem như là một chú
thích.
Danh sách 1.6 minh họa việc sử dụng cả hai hình thức này.
Danh sách 1.6
2
3
4
5
6
7
8
9
10
11
12
13
Các chú thích nên được sử dụng đế tăng cường (không phải gây trở ngại)
việc đọc một chương trình. Một vài điếm sau nên được chú ý:
#inđude<iostream.h>
/*Chuongtrinhnaytinhtoantongsotienphaiteahangtuanchomotcongnhanđuatrentongsogio
lamviecvasotienphaitramoigió. */
intmain(void)
{
int workDays=5; //songay lamviectrongtuan
float workHours=7.5; //sogiolamviectrongngay
float payRate=33.50; //sotienphaitramoigio
float weeklyPay, //tongsotienphaitramoituan
weeklyPay=workDays*workHours*payRate;
cout<<"WeeklyPay- "« weeklyPay<<V;
}
Chương 1: Mởđầu 8
• Chú thích nên dễ đọc và dỗ hiếu hơn sự giải thícli thông qua mã chương
trình. Thà là không có chú thích nào còn hơn có một chú thích phức tạp
dễ gây lầm lẫn một cách không cần thiết.
• Sử dụng quá nhiều chú thích có thế dẫn đến khó đọc. Một chương trình
chứa quá nhiều chú thích làm bạn khó có thể thấy mã thì không thể nào
được xem như là một chương trình dỗ đọc và dỗ hiếu.
• Việc sử dụng các tên mô tả có ý nghĩa cho các biến và các thực thế khác
trong chương trình, và những chỗ thụt vào của mã có thế làm giảm đi
việc sử dụng chú thích một cách đáng kế, và cũng giúp cho lập trình viên
dỗ đọc và kiếm soát chương trình.
1.7. Bộ nhớ
Máy tính sử dụng bộ nhớ truy xuất ngấu nhiên (RAM) để lưu trữ mã chương
trình thực thi và dữ liệu mà chương trình thực hiện. Bộ nhớ này có thể được
xem như là một chuồi tuần tự các bit nhị phân (0 hoặc 1). Thông thường, bộ
nhớ được chia thành những nhóm 8 bit liên tiếp (gọi là byte). Các byte được
định vị liên tục. Vì thế mồi byte có thế được chỉ định duv nhất bởi địa chỉ
(xem Hình 1.2).
Hình 1.2 Các bit và các byte trong bộ nhó-
Byte Address
1211 1212 1213
▼
1214 1215 1216 1217
Byte Byte Byte Byte Byte Byte Byte
1 1 0 1 0 0 0 1
Ẳ
Bit
Trình biên dịch C++ phát ra mã có thể thực thi mà sắp xếp các thực thể
dữ liệu tới các vị trí bộ nhớ. Ví dụ, định nghĩa biến
int salary=65000;
làm cho trình biên dịch cấp phát một vài byte cho biến salary. So byte cần
được cấp phát và phương thức được sử dụng cho việc biếu diễn nhị phân của
số nguyên phụ thuộc vào sự thi hành cụ thể của C++. Trình biên dịch sử
dụng địa chỉ của byte đầu tiên của biến salary được cấp phát đế tham khảo tới
nó. Việc gán trên làm cho giá trị 65000 được lưu trữ như là một số nguyên
bù hai trong hai byte được cấp phát (xem Hình 1.3).
Hình 1.3 Biểu diễn của một số nguyên trong bộ nhó'.
Chương 1: Mởđầu 9
1211 1212 1213 1214 1215 1216 1217
Byte Byte Byte 10110011 10110011 Byte Byte
salary
một số nguyên 2 byte ở địa chỉ 1214
Trong khi việc biếu diễn nhị phân chính xác của một hạng mục dữ liệu là
ít khi được các lập trình viên quan tâm tới thì việc tố chức chung của bộ nhớ
và sử dụng các địa chỉ đế tham khảo tới các hạng mục dừ liệu là rất quan
trọng.
1.8. Số nguyên
Biến số nguyên có thể được định nghĩa là kiểu short, int, hay long. Chỉ khác
nhau là số int sử dụng nhiều hơn hoặc ít nhất bằng so byte như là một so short,
và một số long sử dụng nhiều hơn hoặc ít nhất cùng số bytc với một so int. Ví
dụ, trên máy tính cá nhân thì một so short sử dụng 2 byte, một sổ int cũng 2
bytc, và một số longlà 4 byte.
short age=20;
int salary=65000;
long price=4500000;
Mặc định, một biến số nguyên được giả sử là có dấu (chắng hạn, có một
sự biếu diễn dấu để mà nó có thể biếu diễn các giá trị dương cũng như là các
giá trị âm). Tuy nhiên, một sổ nguyên có thể được định nghĩa là không có dấu
bằng cách sử dụng tò khóa unsigned trong định nghĩa của nó. Từ khóa signed
cũng được cho phép nhưng hơi dư thừa.
unsignedshort age=20;
unsignedint salary=65000;
unsignedlong price=4500000;
Số nguyên (ví dụ, 1984) luôn luôn được giả sử là kiểu int,trừ khicó một
hậu tố L hoặc 1thì nó được hiểu là kiểu long. Một số nguyêncũngcó thểđược
đặc tả sử dụng hậu tố là u hoặc u., ví dụ:
1984L 19841 1984U 1984u 1984LU 1984ul
1.9. Số thưc
Biến số thực có thể được định nghĩa là kiểu float hay double. Kiểu double sử
dụng nhiều byte hơn và vì thế cho miền lớn hơn và chính xác hơn để biểu
diễn các số thực. Ví dụ, trên các máy tính cá nhân một so float sử dụng 4 byte
và một so double sử dụng 8 byte.
Chương 1: Mởđầu 10
float interestRate=0.06;
double pi=3.141592654;
Số thực (ví dụ, 0.06) luôn luôn được giả sử là kiểu double, trừ phi có một hậu
tố F hay f thì nó được hiểu là kiếu float, hoặc một hậu tố L hay 1thì nó được
hiểu là kiểu long double. Kiểu long double sử dụng nhiều byte hom kiểu double
cho độ chính xác tốt hơn (ví dụ, 10 byte trên các máy PC). Ví dụ:
0.06F 0.06f3.141592654L 3.1415926541
Các số thực cũng có thế được biếu diễn theo cách ký hiệu hóa khoa học.
Ví dụ, 0.002164 có thế được viết theo cách kỷ hiệu hóa khoa học như sau:
2.164E-3 or 2.164e-3
Ký tự E (hay e) thay cho số mũ (exponent). Cách ký hiệu hóa khoa học được
thông dịch như sau:
2.164E-3=2.164 X10r3= 0.002164
l.lO.Ký tự
Biến ký tự được định nghĩa là kiểu char. Một biến ký tự chiếm một byte đơn
đế lưu giữ mã cho kỷ tự. Mã này là một giá trị số và phụ thuộc hệ thong mã
ký tự đang được dùng (nghĩa là phụ thuộc máy). Hệ thống chung nhất là
ASCII (American Standard Code for Information Interchange). Ví dụ, ký tự A
có mã ASCII là 65, và ký tự a có mã ASCII là 97.
char ch='A';
Giống như số nguyên, biến kỷ tự có thế được chì định là có dấu hoặc
không dấu. Mặc định (trong hầu hết các hệ thống) char nghĩa là signed char.
Tuy nhiên, trên vài hệ thống thì nó có nghĩa là unsigned char. Biến kỷ tự có dấu
có thế giữ giá trị số trong miền giá trị từ -128 tới 127. Biến ký tự không dấu
có thể giữ giá trị số trong miền giá trị từ 0 tớ 255. Ket quả là, cả hai thường
được dùng để biểu diễn các số nguyên nhỏ trong chương trình (và có thế được
đánh dấu các giá trị số như là số nguyên):
signed char offset=-88;
unsignedchar row=2, column=26;
Ký tự được viết bằng cách đóng dấu ký tự giữa cặp nháy đơn (ví dụ, 'A').
Các ký tự mà không thể in ra được biểu diễn bằng việc sử dụng các mã
escape. Ví dụ:
'n' // xuống hàng mới
V // phím xuống dòng
Chương 1: Mởđầu
't' // phím tab ngang
'v' // phím tab dọc
'b' //phím lùi
Các dấu nháy đơn, nháy đôi và ký tự gạch chéo ngược cũng có thể sử dụng ký
hiệu escape:
'V' // trích dẫn đơn (')
'V" // trích dẫn đôi (")
'Y // dấu vạch chéo ngược ()
Ký tự cũng có thể được chỉ định rõ sử dụng giá trị mã số của chúng. Mã
escape tống quát ooo (nghĩa là, 3 ký tự số cơ số 8 theo sau một dấu gạch chéo
ngược) được sử dụng cho mục đích này. Ví dụ (giả sử ASCII):
'12' // hàng mới (mã thập phân =10)
M I' // tab ngang (mã thập phân = 9)
MOI' // 'A' (mã thập phân = 65)
'0' // rồng (mã thập phân = 0)
l.ll.ChuSỉ
Chuồi là một dãy liên tiếp các ký tự được kết thúc bằng một ký tự null. Biến
chuỗi được định nghĩa kiểu char* (nghĩa là, con trỏ ký tự). Con trỏ đon giản
chỉ là một vị trí trong bộ nhớ. (Các con trỏ sẽ được thảo luận trong chương 5).
Vì thế biến chuỗi chứa đựng địa chỉ của ký tự đầu tiên trong chuồi. Ví dụ,
xem xét định nghĩa:
char *str="HELLO";
Hình 1.4 minh họa biến chuồi và chuồi "HELLO" có thể xuất hiện như thế nào
trong bộ nhớ.
Hình 1.4 Chuỗi và biến chuỗi trong bộ nhó'
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
1212 ị 'H' 'E' 'L' 'L' 'O' •V0'
str
Chuỗi được viết bằng cách đóng ngoặc các ký tự của nó bên trong cặp
dấu nháy kép (ví dụ, "HELLO"). Trình biên dịch luôn luôn thêm vào một ký tự
null tới một hằng chuồi để đánh dấu điếm kết thúc. Các ký tự chuồi có thế
được đặc tả sử dụng bất kỳ ký hiệu nào dùng đế đặc tả các ký tự. Ví dụ:
"NametAddress'íTelephone'' //cáctừphâncách
"ASCÍI character65:101" //'A'đuọcđặctảnhư'10r
Chương 1: Mởđầu 12
Chuỗi dài có thế nới rộng qua khỏi một hàng đơn, trong trường hợp này
thì mồi hàng trước phải được kết thúc bằng một dấu vạch chéo ngược. Ví dụ:
"Exampletoshow
theuseofbackslashfor
writingalongstring"
Dấu  trong ngữ cảnh này có nghĩa là phần còn lại của chuỗi được tiếp tục
trên hàng kế tiếp. Chuỗi trên tương đương vói chuỗi được viết trên hàng đơn
như sau:
"Exampletoshowtheuseofbackslashforwritingalongstring"
Một lồi lập trình chung thường xảy ra là lập trình viên thường nhầm lẫn
một chuỗi ký tự đơn (ví dụ, "A") với một ký tự đơn (ví dụ, 'Ả'). Hai điều này là
không tương đương. Chuỗi ký tự đơn gồm 2 byte (ký tự 'A' được theo sau là
ký tự ơ),trong khi ký tự đơn gồm chỉ một byte duy nhất.
Chuồi ngắn nhất có thế có là chuồi rỗng ("") chỉ chứa ký tự null.
1.12.Tên
Ngôn ngữ lập trình sử dụng tên đề tham khảo tới các thực thế khác nhau dùng
để tạo ra chương trình. Chúng ta cũng đã thấy các ví dụ của một loại các tên
(nghĩa là tên biến) như thế. Các loại khác gồm: tên hàm, tên kiếu, và tên
macro.
Sử dụng tên rất tiện lợi cho việc lập trình, nó cho phép lập trình viên tổ
chức dữ liệu theo cách thức mà con người có thể hiểu được. Tên không được
đưa vào mã có thể thực thi được tạo ra bởi trình biên dịch. Ví dụ, một biến
temperature cuối cùng trở thành một vài byte bộ nhớ mà được tham khảo tới
bởi các mã có thế thực thi thông qua địa chỉ của nó (không thông qua tên của
nó).
C++ áp đặt những luật sau đế xây dựng các tên hợp lệ (cũng được gọi là
các định danh). Một tên chứa một hay nhiều ký tự, mồi ký tự có thể là một
chữ cái (nghĩa là, 'A'-'Z' và 'a'-'z'), một số (nghĩa là, '0'-'9'), hoặc một ký tự
gạch dưới ngoại trừ ký tự đầu tiên không thề là một số. Các ký tự viết
hoa và viết thường là khác nhau.Ví dụ:
salary //địnhdanhhọplệ
salaiy2 //địnhdanhhọplệ
Zsalary //địnhdanhkhônghọplệ(bắtđàuvới mộtsố)
_salary //địnhdanhhọplệ
Salary //họplệnhungkhácvói salary
Chương 1: Mởđầu 13
c++ kliông có giới hạn số ký tự của một định danh. Tuy nhiên, hầu hết
thi công lại áp đặt sự giới hạn này nhưng thường đủ lớn đế không gây bận
tâm cho các lập trình viên (ví dụ 255 ký tự).
Một số từ được giữ bởi c++ cho một số mục đích riêng và không thế
được dùng cho các định danh. Những từ này được gọi là từ khóa (keyword)
và được tổng kết trong bảng 1.3:
Bảng 1.3 Các từ khóa c++.
asm continue float new signed try
auto default for operator sizeof typedef
break delete friend private static union
case do goto protected struct unsigned
catch double if public switch virtual
char else inline register template void
class enum int return this volatile
const extern long short throw while
Bài tập cuối chương 1
1.1 Viết chương trình cho phép nhập vào một số đo nhiệt độ theo độ Fahrenheit
và xuất ra nhiệt độ tương đương cúa nó theo độ Celsius, sứ dụng công thức
chuyến đổi:
° C = - ( ° F - 32)
9
Biên dịch và chạy chương trình. Việc thực hiện của nó giống như thế này:
Nhiet do theo do Fahrenheit: 41
41 do Fahrenheit=5 do Celsius
1.2 Hàng nào trong các hàng sau biếu diễn việc định nghĩa biến là không hợp lệ?
int n=-100;
unsigned inti—-100;
signed int=2.9;
longm=2,p=4;
mt 2k;
doublex = 2 *m;
floaty=y *2;
unsigned doublez =0.0;
doubled=0.67F;
float Í-0.52L;
signed char=-1786;
charc = '$'+2;
sign charh=M il';
Chương 1: Mởđầu 14
char *name= "PeterPan'';
unsigned char *num= "276811";
1.3 Các định danh nào sau đây là không hợp lệ?
identifier
scvcn_l 1
_uniqụe_
gross-incomc
gross$income
2by2
default
avcragc_wcight_of_a_largc_pizza
variable
object-oriented
1.4 Định nghĩa các biến để biếu diễn các mục sau đây:
• Tuổi của một người.
• Thu nhập của một nhân viên.
• Số từ trong một từ điển.
• Một ký tự alphabet.
• Một thông điệp chúc mừng.
Chương 1: Mởđầu 15
Chương 2. Biểu thức
Chương này giới thiệu các toán tử xây dựng sẵn cho việc soạn thảo các biểu
thức. Một biểu thức là bất kỳ sự tính toán nào mà cho ra một giá trị.
Khi thảo luận về các biểu thức, chúng ta thường sử dụng thuật ngữ ước
lượng. Ví dụ, chúng ta nói rằng một biểu thức ước lượng một giá trị nào đó.
Thường thì giá trị sau cùng chỉ là lỵ do cho việc ước lượng biếu thức. Tuy
nhiên, trong một vài trường hợp, biểu thức cũng có thế cho các kết quả phụ.
Các kết quả này là sự thay đối lâu dài trong trạng thái của chương trình.
Trong trường hợp này, các biếu thức c++thì khác với các biếu thức toán học.
C++ cung cấp các toán tử cho việc soạn thảo các biểu thức toán học,
quan hệ, luận lý, trên bit, và điều kiện. Nó cũng cung cấp các toán tử cho ra
các kết quả phụ hữu dụng như là gán, tăng, và giảm. Chúng ta sẽ xem xét lần
lượt từng loại toán tử. Chúng ta cũng sẽ thảo luận về các luật ưu tiên mà ảnh
hưởng đến thứ tự ước lượng của các toán tử trong một biếu thức có nhiều
toán tứ.
2.1. Toán tử toán hoc
c++ cung cấp 5 toán tử toán học cơ bản. Chúng được tổng kết trong Bảng
2.1.
Bảng 2.1 Các toán tử toán học.
Toán tử Tên Ví dụ
+ Cộng 12+4.9 //cho 16.9
- Trừ 3.98-4 //cho-0.02
* Nhân 2*3.4 //cho 6.8
/ Chia 9/2.0 //cho 4.5
% Lấy phần dư 13% 3 //choi
Ngoại trừ toán tử lấy phần dư (%) thì tất cả các toán tử toán học có thế
chấp nhận pha trộn các toán hạng số nguyên và toán hạng số thực. Thông
thường, nếu cả hai toán hạng là số nguyên sau đó kết quả sẽ là một số
Chương 2: Biểu thức 17
nguyên. Tuy nhiên, một hoặc cả hai toán hạng là số thực thì sau đó kết quả sẽ
là một số thực (real hay double).
Khi cả hai toán hạng của toán tử chia là số nguyên thì sau đó phép chia
được thực hiện như là một phép chia số nguyên và không phải là phép chia
thông thường mà chúng ta sử dụng. Phép chia số nguyên luôn cho kết quả
nguyên (có nghĩa là luôn được làm tròn). Ví dụ:
9 /2 //được 4, khôngphải là4.5!
-9/2 //được -5, khôngphải là-4!
Các phép chia số nguyên không xác định thường là các lỗi lập trình
chun«. Đế thu được một phép chia số thực khi cả hai toán hạng là số nguyên,
bạn cần ép một trong hai số nguyên về số thực:
int cost=100;
int volume=80;
double unitPrice= cost/ (double)volume; //được 1.25
Toán tử lấy phần dư (%) yêu cầu cả hai toán hạng là số nguyên. Nó trả về
phần dư còn lại của phép chia. Ví dụ 13%3 được tính toán bằng cách chia số
nguyên 13 đi 3 đế được 4 và phần dư là 1; vì thế kết quả là 1.
Có thế có trường hợp một kết quả của một phép toán toán học quá lớn đế
lưu trữ trong một biến nào đó. Trường hợp này được gọi là tràn. Hậu quả của
tràn là phụ thuộc vào máy vì thế nó không được định nghĩa.Ví dụ:
uâsignedchar k=10*92; //tràn: 920 >255
Chia một số cho 0 là hoàn toàn không đúng luật. Ket quả của phép chia
này là một lỗi run-time gọi là lỗi division-by-zero thường làm cho chương
trình kết thúc.
2.2. Toán tử quan hệ
c++cung cấp 6 toán tử quan hệ để so sánh các số. Các toán tử này được tống
kết trong Bảng 2.2. Các toán từ quan hệ ước lượng về 1 (thay cho kết quả
đúng) hoặc 0 (thay cho kết quả sai).
Bảng 2.2 Các toán tử quan hệ.
Toán tử Tên Ví du
= So sánh băng 5 = 5 //choi
Ị= So sánh không băng 5!=5 //choO
< So sánh hỏ hơn 5<5.5 //choi
<= So sánh hỏ hơn hoặc băng 5<=5 //choi
> So sánh lớn hơn 5 >5.5 // cho 0
>= So sánh lớn hơn hoặc băng 6.3>=5 //choi
Chương 2: Biểu thức 18
Chú ý rằng các toán tử <= và >= chỉ được hỗ trợ trong hình tliức hiển thị.
Nói riêng cả hai =< và => đều không hợp lệ và không mang ý nghĩa gì cả.
Các toán hạng của một toán tử quan hệ phải ước lượng về một số. Các ký
tự là các toán hạng hợp lệ vì chúng được đại diện bởi các giá trị số. Ví dụ (giả
sử mã ASCII):
'A '< F //đưọc 1(giống như là 65 <70)
Các toán tử quan hệ không nên được dùng đế so sánh chuồi bởi vì điều
này sẽ dẫn đến các địa chỉ của chuồi được so sánh chứ không phải là nội dung
chuồi. Ví dụ, biếu thức
"HELLO"<"BYE"
làm cho địa chỉ của chuồi "HELLO" được so sánh với địa chi của chuỗi "BYE".
Vì các địa chỉ này được xác định bởi trình biên dịch, kết quả có thế là 0 hoặc
có thể là 1, cho nên chúng ta có thế nói kếtquả là không được địnhnghĩa.
C++ cung cấp các thư viện hàm (vídụ, strcmp) để thựchiện so sánh
chuồi.
2.3. Toán tử luận lý
C++ cung cấp ba toán tử luận lý cho việc kết nối các biếu thức luận lý. Các
toán tử này được tổng kết trong Bảng 2.3. Giống như các toán tử quan hệ, các
toán tử luận lý ước lượng tới 0 hoặc 1.
Bảng 2.3 Các toán tử luận lý.
Toán tử Tên Ví du
Ị Phủ định luận lý 1(5 — 5) // được 0
&& Và luận lý 5 < 6 && 6 < 6 // được 0
II Hoặc luận lý 5 < 6 II 6 < 5 // được 1
Phủ định luận lỷ là một toán tử đơn hạng chỉ phủ định giá trị luận lý toán
hạng đon của nó. Neu toán hạng của nó không là 0 thì được 0, và nếu nó là
không thì được 1.
Và luận lý cho kết quả 0 nếu một hay cả hai toán hạng của nó ước lượng
tới 0. Ngược lại, nó cho kết quả 1. Hoặc luận lý cho kết qua 0 nếu cả hai toán
hạng của nó ước lượng tới 0. Ngược lại, nó cho kết quả 1.
Chú ý rằng ở đây chúng ta nói các toán hạng là 0 và khác 0. Nói chung,
bất kỳ giá trị không là 0 nào có thể được dùng đế đại diện cho đúng (true),
trong khi chi có giá trị 0 là đại diện cho sai (false). Tuy nhiên, tất cả các hàng
sau đây là các biểu thức luận lý họp lệ:
Chương 2: Biểu thức 19
!20 //đượcO
10 && 5 //đuợcl
10II5.5 //đuọc 1
10&&0 //đượcO
C++ không có kiểu boolean xây dựng sẵn. Vì lẽ đó mà ta có thế sử dụng
kiếu int cho mục đích này. Ví dụ:
int sorted=0; //false
int balanced = 1; //true
2.4. Toán tử trên bit
C++ cung cấp 6 toán tử trên bit đe điều khiển các bit riêng lẻ trong một số
lượng số nguyên. Chúng được tống kết trong Bảng 2.4.
Bảng 2.4 Các toán tử trên bit.
Toán tử Tên Ví du
~ Phủ định bit ~011' //đuocMÚS
& Và bit w &  0 2 7 //đ ư ợ c W
Hoặc bit W IN 0 2 7 //đươc 02>T
A Hoặc exclusive bit W A027 //được ‘036’
« Dịch trái bit w « 2 //đươc ‘044’
» Dịch phải bit N 011'»2 //đưoc ’002'
Các toán tử trên bit mong đợi các toán hạng của chúng là các số nguyên
và xem chúng như là một chuồi các bit. Phủ định bit là một toán tử đon hạng
thực hiện đảo các bit trong toán hạng của nó. Và bit so sánh các bit tương ứng
của các toán hạng của nó và cho kết quả là 1 khi cả hai bit là 1, ngược lại là 0.
Hoặc bit so sánh các bit tương ứng của các toán hạng của nó và cho kết quả là
0 khi cả hai bit là 0, ngược lại là 1. XOR bit so sánh các bit tương ứng của
các toán hạng của nó và cho kết quả 0 khi cả hai bit là 1 hoặc cả hai bit là 0,
ngược lại là 1.
Cả hai toán tử dịch trái bit và dịch phải bit lấy một chuỗi bit làm toán
hạng trái của chúng và một số nguyên dương n làm toán hạng phải. Toán tử
dịch trái cho kết quả là một chuỗi bit sau khi thực hiện dịch n bit trong chuồi
bit của toán hạng trái về phía trái. Toán tử dịch phải cho kết quả là một chuỗi
bit sau khi thực hiện dịch n bit trong chuỗi bit của toán hạng trái về phía phải.
Các bit trống sau khi dịch được đặt tới 0.
Bảng 2.5 minh họa chuỗi các bit cho các toán hạng ví dụ và kết quả trong
Bảng 2.4. Đế tránh lo lắng về bit dấu (điều này phụ thuộc vào máy) thường
thì khai báo chuồi bit như là một số không dấu:
unsigned charx=l01 ĩ;
unsigned chary=*'027;
Chương 2: Biểu thức 20
Bảng 2.5 Các bít đưọc tính toán như thế nào.
Ví dụ Giá tri cơ số 8 Chuỗi bit
X 011 0 0 0 0 1 0 0 1
y 027 0 0 0 I 0 1 1 1
~x 366 1 1 1 1 0 1 1 0
x & y 001 0 0 0 0 0 0 0 1
X y 037 0 0 0 I 1 1 1 1
x A y 036 0 0 0 1 1 1 1 0
x « 2 044 0 0 1 0 0 1 0 0
x » 2 002 0 0 0 0 0 0 1 0
2.5. Toán tử tăng/giảm
Các toán tử tăng một (++) và giảm một (--) cung cấp các tiện lợi tương ứng
cho việc cộng thêm 1 vào một biến số hay trừ đi 1 từ một biến số. Các toán tử
này được tổng kết trong Bảng 2.6. Các ví dụ giả sử đã định nghĩa biến sau:
int k=5;
Bảng 2.6 Các toán tử tăng và giảm.
Toán tử Tên Ví du
++ Tăng một (tiên tô) -H-k+10 //đươc 16
++ Tăng một (hậu tô) k+ + + 10 //đươc 15
— Giảm một (tiên tô) -k + 1 0 //đươc 14
— Giảm một (hậu tô) k -+ 1 0 //được 15
Cả hai toán tử có thể được sử dụng theo hình thức tiền tố hay hậu tố là
hoàn toàn khác nhau. Khi được sử dụng theo hình thức tiền tố thì toán tò
được áp dụng trước và kết quả sau đó được sử dụng trong biểu thức. Khi
được sử dụng theo hình thức hậu tố thì biểu thức được ước lượng trước và sau
đó toán tô được áp dụng.
Cả hai toán tử có thế được áp dụng cho biến nguyên cũng như là biến
thực mặc dù trong thực tế thì các biến thực hiếm khi được dùng theo hình
thức này.
2.6. Toán tử khởi taoể
Toán tử khởi tạo được sử dụng để lưu trữ một biến. Toán hạng trái nên là một
giá trị trái và toán hạng phải có thế là một biếu thức bất kỳ. Biểu thức được
ước lượng và kết quả được lưu trữ trong vị trí được chi định bởi giá trị trái.
Giá trị trái là bất kỳ thứ gì chi định rõ vị trí bộ nhớ lưu trừ một giá trị.
Chỉ một loại của giá trị trái mà chúng ta được biết cho đến thời điếm này là
Chương 2: Biểu thức 21
biến. Các loại khác của giá trị trái (dựa trên con trỏ và tham chiếu) sẽ được
thảo luận sau.
Toán tử khởi tạo có một số biến thế thu được bằng cách kết nối nó với
các toán tử toán học và các toán tử trên bit. Chúng được tống kết trong Bảng
2.7. Các ví dụ giả sử rằng n là một biến số nguyên.
Bảng 2.7 Các toán tử khỏi tạo.
Toán tử Ví du Tương đương vói
= n=25
+= n+=25 n = n +25
- n-=25 n = n -2 5
*_ 11*=25 n= n*25
/= n/=25 n = n/25
%= n% =25 n= n% 25
&= n&=0xF2F2 n=n&QxF2F2
nỊ=0xF2F2 n=n|QxF2F2
Ạ= nA=0xF2F2 n = n AQxF2F2
« = n « = 4 n = n « 4
» = n » = 4 n = n » 4
Phép toán khởi tạo chính nó là một biểu thức mà giá trị của nó là giá trị
được lưu trong toán hạng trái của nó. Vì thế một phép toán khởi tạo có thế
được sử dụng như là toán hạng phải của một phép toán khởi tạo khác. Bất kỳ
số lượng khởi tạo nào có thề được kết nối theo cách này đế hình thành một
biểu thức. Ví dụ:
intm,ạp;
m=n=p=100; //nghĩalà:n=(m=(p= 100));
m=(n=p=100)+2; //nghĩalà:m=(n=(p = 100))+2;
Việc này có thể ứng dụng tương tự cho các hình thức khởi tạo khác. Ví dụ:
m=100;
m-H=n=p=10; //nghĩalà:m=m+(n=p=10);
2.7. Toán tử điều kiện
Toán tứ điều kiện yêu cầu 3 toán hạng. Hình thức chung cúa nó là:
toán hạng 1 ? toán hạng 2 :toán hạng 3
Toán hạng đầu tiên được ước lượng và được xem như là một điều kiện. Neu
kết quả không là 0 thìtoán hạng 2 được ước lượng và giá trị của nó là kết quả
sau cùng. Ngược lại, toán hạng 3 được ước lượng và giá trị của nó là kết quả
sau cùng. Ví dụ:
Chương 2: Biểu thức 22
intm —l,n —2;
intmin=(m<n?m:n); //minnhậngiátrị 1
Chú ý rằng trong các toán hạng thứ 2 và toán hạng thứ 3 của toán tử điều
kiện thì chỉ có một toán hạng được thực hiện. Điều này là quan trọng khi một
hoặc cả hai chứa hiệu ứng phụ (nghĩa là, việc ước lượng của chúng làm
chuyển đổi giá trị của biến). Ví dụ, với m=l và n=2 thì trong
intmin= (m < n ? nrrH-:n-H-);
m được tăng lên bởi vì m-H- được ước lượng nhưng n không tăng vì n-H-
không được ước lượng.
Bởi vì chính phép toán điều kiện cũng là một biểu thức nên nó có thể
được sử dụng như một toán hạng của phép toán điều kiện khác, có nghĩa là
các biếu thức điều kiện có thế được lồng nhau. Ví dụ:
intm=l,n=2,p=3;
intmin=(m<n ?(m<p?m:p)
:(n<p?n:p));
2.8. Toán tử phẩy
Nhiều biểu thức có thế được kết nối vào cùng một biểu thức sử dụng toán tử
phẩy. Toán tử phấy yêu cầu 2 toán hạng. Đầu tiên nó ước lượng toán hạng trái
sau đó là toán hạng phải, và trả về giá trị của toán hạng phải như là kết quả
sau cùng. Ví dụ:
intm=l,n=2,min;
intmCount=0, nCount=0;
//...
min=(m<n?mCount-H-,m :nCount++, n);
Ớ đây khi m nhỏ hon n, mCount-H- được ước lượng và giá trị của m được lưu
ừong min. Ngược lại, nCount-H- được ước lượng và giá trị của n được lưu
trong min.
2.9. Toán tử lấy kích thước
C++ cung cấp toán tử hữu dụng, sizeof, để tính toán kích thước của bất kỳ
hạng mục dữ liệu hay kiểu dữ liệu nào. Nó yêu cầu một toán hạng duy nhất có
thế là tên kiểu (ví dụ, int) hay một biếu thức (ví dụ, 100) và trả về kích thước
của những thực thể đã chỉ định theo byte. Ket quả hoàn toàn phụ thuộc vào
máy. Danh sách 2.1 minh họa việc sử dụng toán từ sizeof cho các kiểu có sẵn
mà chúng ta đã gặp cho đến thời điểm này.
Chương 2: Biểu thức 23
Danh sách 2.1
2
3
4
5
6
7
8
9
10
11
12
13
14
Khi chạy, chương trình sẽ cho kết quả sau (trên máy tính cá nhân):
char size= 1bytes
char* size=2 bytes
short size=2 bytes
int size=2 bytes
long size= 4 bytes
float size=4bytes
double size=8 bytes
1.55 size=8 bytes
1.55L size=10 bytes
HELLO size= 6 bytes
2.10.ĐÔ ưu tiên của các toán tử
Thứ tự mà các toán tử được ước lượng trong một biếu thức là rất quan trọng
và được xác định theo các luật ưu tiên. Các luật này chia các toán tử C++ ra
thành một số mức độ ưu tiên (xem Bảng 2.8). Các toán tử ở mức cao hơn sẽ
có độ ưu tiên cao hơn các toán tử có độ ưu tiên thấp hơn.
Bảng 2.8 Độ ưu tiên của các toán tử.
Mức Toán tử Loai Thứ tư
Cao nhât Đơn hạng Cà hai
1 n -> Nhị hạng Trái tới phải
+ ++ Ị *
&
new sizeof
delete 0
Đơn hạng Phải tới trái
->* * Nhị hạng Trái tới phải
* / % Nhị hạng Trái tới phải
+ - Nhị hạng Trái tới phải
« » Nhị hạng Trái tới phải
< <= > >= Nhị hạng Trái tới phải
= Ị= Nhị hạng Trái tới phải
& Nhị hạng Trái tới phải
#indude<iostneamii>
intmain(void)
{
cout«"char size="«sizeof(char)«"bytesn";
cout«"char* size= " « sizeoflchar*)« " bytes'-n";
cout« "short size= " « sizeof(short)« " bytesn";
cout« "int size= " « sizeof(int)« " bytesn";
cout« "long size= " « sizeofflong)« " bytesn";
cout« "float size=" « sizeof(float)« "bytesn";
cout« "double size= " « sizeoffdouble)« " bytesn";
cout« "1.55 size= " « sizeof(1.55)« " bytesn";
cout« "1.55L size= " « sizeof(1.55L)« " bytesn";
cout« "HELLO size=" « sizeof("HELLO")« " bytesn";
i _____________________________________________________
Chương 2: Biểu thức
A Nhị hạng Trái tới phải
1 Nhị hạng Trái tới phải
&& Nhị hạng Trái tới phải
II Nhị hạng Trái tới phải
? ; Tam hạng Trái tới phải
= += *= /s= &= « =
-= /= %= 1= » =
Nhị hạng Phải tới trái
Thấp nhất ? Nhị hạng Trái tới phải
Ví dụ, trong biểu thức
a= b + c * d
c * d được ước lượng trước bởi vì toán tử * có độ ưu tiên cao hơn toán từ + và
= . Sau đó kết quả được cộng tới b bởi vì toán tử + có độ ưu tiên cao hơn toán
tử = , và sau đó = được ước lượng. Các luật ưu tiên có thế được cho quyền
cao hơn thông qua việc sử dụng các dấu ngoặc. Ví dụ, viết lại biếu thức trên
như sau
a=(b+c)*d
sẽ làm cho toán tử + được ước lượng trước toán tử *.
Các toán tử với cùng mức độ ưu tiên được ước lượng theo thứ tự được
ước lượng trong cột cuối cùng trong Bảng 2.8. Ví dụ, trong biểu thức
a= b+ = c
thứ tự ước lượng là từ phải sang trái, vì thế b+=c được ước lượng trước và kế
đó là a=b.
2.11.Chuyển kiểu đơn giản
Một giá trị thuộc về những kiểu xây dựng sẵn mà chúng ta biết đến thời điếm
này đều có thể được chuyển về bất kỳ một kiếu nào khác. Ví dụ:
(int) 3.14 //chuyện 3.14 sang intđể đưọc 3
(long) 3.14 //chự/ện 3.14 sang longđể Ãiạc 3L
(double) 2 // chuyên 2 sang double đê đuọc 2.0
(char) 122 // chuyên 122 sang charcó mã là 122
(unsigned short) 3.14 //được 3 như làmộtunsigned short
Như đã được trình bày trong các ví dụ, các định danh kiếu xây dụng sẵn
có thể được sử dụng như các toán tử kiếu. Các toán tò kiểu là đơn hạng
(nghĩa là chỉ có một toán hạng) và xuất hiện bên trong các dấu ngoặc về bên
trái toán hạng của chúng. Điêu này được gọi là chuyển kiểu tường minh.
Khi tên kiểu chỉ là một từ thì có thế đặt dấu ngoặc xung quanh toán hạng:
int(3.14) //nhưlà:(int)3.14
Chương 2: Biểu thức 25
Trong một vài trường hợp, C++ cũng thực hiện chuyển kiểu không
tường minh. Điều này xảy ra khi các giá trị của các kiểu khác nhau được trộn
lẫn trong một biếu thức. Ví dụ:
double d= 1; //dnhậnl.o
int 1=10.5; // i nhận 10
i= i+ d ; //nghĩa là: i=int(double(i)+d)
Trong ví dụ cuối , i + d bao hàm các kiểu không họp nhau, vì thế trước tiên i
được chuyển thành double (thăng cấp) và sau đó được cộng vào d. Ket quả là
double không hợp kiếu với i trên phía trái của phép gán, vì thế nó được chuyển
thành int {hạ cấp) trước khi được gán cho i.
Luật trên đại diện cho một vài trường hợp chung đơn giản để chuyến
kiểu. Các trường hợp phức tạp hơn sẽ được trình bày ở phần sau của giáo
trình sau khi chúng ta thảo luận các kiểu dữ liệu khác.
Bài tập cuối chương 2
2.1 Viết các biểu thức sau đây:
• Kiếm tra một số n là chằn hay không.
• Kiếm tra một ký tự c là một số hay không.
• Kiếm tra một ký tự c là một mẫu tự hay không.
• Thực hiện kiếm tra: n là lẽ và dương hoặc n chẵn và âm.
• Đặt lại k bit của một sổ nguyên n tới 0.
• Đặt k bit của một số nguyên «tới 1.
• Cho giá trị tuyệt đối của một số n.
• Cho số ký tự trong một chuồi s được kết thúc bởi ký tự null.
2.2 Thêm các dấu ngoặc phụ vào các biếu thức sau để hiển thị rõ ràngthứ tự các
toán tô được ước lượng:
(n <= p + q && n >= p - q II n = 0)
(++n*q-/-Hp-q)
(n|p&qAp<<2+q)
(p<q?n<p?q*n-2:q/n+l :q-n)
2.3 Cho biết giá trị của mồi biến sau đây sau khi khởi tạo nó:
double d=2 *int(3.14);
long k=3.14-3;
chàr c='a'+2;
char c=lp'+'Á'-'a';
2.4 Viết một chương trình cho phép nhập vào một số nguyên dương n và xuất ra
giá trị của n mũ 2 và 2 mũ n.
Chương 2: Biểu thức 2 6
2.5 Viết một chương trình cho phép nhập ba số và xuất ra thông điệp Sorted nếu
các số là tăng dần và xuất ra Not sorted trong trường hợp ngược lại.
Chương 2: Biểu thức 27
Chương 3. Lệnh
Chương này giới thiệu các hình thức khác nhau của các câu lệnh C++ để soạn
thảo chương trình. Các lệnh trình bày việc xây dựng các khối ở mức độ thấp
nhất của một chương trình. Nói chung mồi lệnh trình bày một bước tính toán
có một tác động chính yếu. Bên cạnh đó cũng có thế có các tác độnẸ phụ
khác. Các lệnh là hữu dụng vì tác dụng chính yếu mà nó gây ra, sự kết nối của
các lệnh cho phép chương trình phục vụ một mục đích cụ thể (ví dụ, sắp xếp
một danh sách các tên).
Một chương trình đang chạy dành toàn bộ thời gian đế thực thi các câu
lệnh. Thứ tự mà các câu lệnh được thực hiện được gọi là dòng điều khiến
(flow control). Thuật ngữ này phản ánh việc các câu lệnh đang thực thi hiện
thời có sự điều khiển cúa CPU, khi CPU hoàn thành sẽ được chuyển giao tới
một lệnh khác. Đặc trưng dòng điều khiển trong một chương trình là tuần tự,
lệnh này đến lệnh kế, nhưng có thế chuyển hướng tới đườnẹ dần khác bởi các
lệnh rẽ nhánh. Dòng điều khiến là một sự xem xét trọng yểu bởi vì nó quyết
định lệnh nào được thực thi và lệnh nào không được thực thi trong quá trình
chạy, vì thế làm ảnh hưởng đến kết quả toàn bộ của chương trình.
Giống nhiều ngôn ngữ thủ tục khác, C++ cung cấp những hình thức khác
nhau cho các mục đích khác nhau. Các lệnh khai báo được sử dụng cho định
nghĩa các biến. Các lệnh như gán được sử dụng cho các tính toán đại số đơn
giản. Các lệnh rẽ nhánh được sử dụng để chỉ định đường dẫn của việc thực thi
phụ thuộc vào kết quả của một điều kiện luận lý. Các lệnh lặp được sử dụng
đế chỉ định các tính toán cần được lặp cho tới khi một điều kiện luận lý nào
đó được thỏa. Các lệnh điều khiến được sử dụng đế làm chuyến đường dần
thực thi tới một đường dần khác của chương trình. Chúng ta sẽ lần lượt thảo
luận tất cả những vấn đề này.
Chương 3:Lệnh 30
3.1. Lệnh đon và lệnh phức
Lệnh đơn là một sự tíirh toán được kết thúc bằng dấu chấm phấy. Các định
nghĩa biến và các biểu thức được kết thúc bằng dấu chấm phấy như trong ví
dụ sau:
Ví dụ cuối trình bày một lệnh không hữu dụng bởi vì nó không có tác động
chính yếu (d được cộng với 5 và kết quả bị vứt bỏ).
Lệnh đơn giản nhất là lệnh rồng chỉ gồm dấu chấm phấy mà thôi.
Mặc dầu lệnh rỗng không có tác động chính yếu nhưng nó có một vài
việc dùng xác thật.
Nhiều lệnh đơn có thề kết nối lại thành một lệnh phức bằng cách rào
chúng bên trong các dấu ngoặc xoắn. Ví dụ:
{intmin,i= 10,j=20;
m,n=(i<j?i:j);
cout«mỉn<<W;
}
Bời vì một lệnh phức có thế chứa các định nghĩa biến và định nghĩa một
phạm vi cho chúng, nó cũng được gọi một khối. Phạm vi của một biến C++
được giới hạn bên trong khối trực tiếp chứa nó. Các khối và các luật phạm vi
sẽ được mô tả chi tiết hơn lchi chúng ta thảo luận về hàm trong chương kế.
Đôi khi chúng ta muốn làm cho sự thực thi một lệnh phụ thuộc vào một điều
kiện nào đó cần được thỏa. Lệnh ifcung cấp cách đế thực hiện công việc này,
hình thức chung của lệnh này là:
if (biêu thức)
Trước tiên biểu thức được ước lượng. Nếu kết quả khác 0 (đúng) thì sau đó
lệnh được thực thi. Ngược lại, không làm gì cả.
Ví dụ, khi chia hai giá trị chúng ta muốn kiểm tra rằng mẫu số có khác 0
hay không.
if(count!=0)
int i;
++i;
//lệnhkhaibáo
//lệnhnàycómộttácđộngchínhyếu
//lệnhkhaibáo
//lệnhkhônghũuđụng
doubled= 10.5;
d+5;
//lệnhrỗng
3.2. Lệnh if
lệnh;
Chương 3:Lệnh 31
average—sum/count;
Đế làm cho nhiều lệnh phụ thuộc trên cùng điều kiện chúng ta có thể sử
dụng lệnh phức:
if(balance>0) {
interest- balance * creditRate;
balance += interest;
}
Một hình thức khác của lệnh if cho phép chúng ta chọn một trong hai
lệnh: một lệnh được thực thi nếu như điều kiện được thỏa và lệnh còn lại
được thực hiện nếu như điều kiện không thỏa. Hình thức này được gọi là lệnh
if-else và có hình thức chung là:
if{biểu thức)
lệnh 1;
else
lệnh 2;
Trước tiên biểu thức được ước lượng. Neu kết quả khác 0 thì lệnh 1 được
thực thi. Ngược lại, lệnh 2 được thực thi.
Ví dụ:
if(balance>0) {
interest—balance * creditRate;
balance += interest;
}else {
interest= balance * debitRate;
balance+=interest;
}
Trong cả hai phần có sự giống nhau ở lệnh balance-H=interest vì thế toàn bộ câu
lệnh có thế viết lại như sau:
if(balance>0)
interest—balance * creditRate;
else
interest= balance * debitRate;
balance+= interest;
Hoặc đơn giản hơn bằng việc sử dụng biếu thức điều kiện:
interest=balance*(balance>0?creditRate:debitRate);
balance -t= interest;
Hoặc chỉ là:
balance += balance * (balance> 0 ? creditRate:debitRate);
Các lệnh if có thế được lồng nhau bằng cách đế cho một lệnh if xuất hiện
bên trong một lệnh if khác. Ví dụ:
Chương 3:Lệnh 32
if(calIHour>6) {
if(callDuration<=5)
charge= callDuration *tarrifl;
else
charge=5 *tarrifl + (callDuration - 5) * tarrif2;
}else
charge=flatFee;
Một hình thức được sử dụng thường xuyên của những lệnh if lồng nhau
liên quan đến phần else gồm có một lệnh if-else khác. Ví dụ:
if(ch>='()'&&ch<=9')
kind=đỉgit;
clsc {
if(ch>='A'&&ch<='Z)
kind=upperLetter,
clsc {
if(ch>='a'&&ch<='f)
kind=lowerLetter,
else
kind= special;
}
>
Đe cho dễ đọc có thể sử dụng hình thức sau:
if(ch>='0'&&ch<=V)
kind=digit;
elseif(ch>='A'&&ch<=Z)
kind=capitalLetter,
elseif(ch>='a &&ch<=V)
kind=smallLetter,
else
kind=special;
3.3. Lênh switch
Lệnh switch cung cap phương thức lựa chọn giữa một tập các khả năng dựa
trên giá trị của biếu thức. Hình thức chung của câu lệnh switch là:
switch (biểụ thức) {
caschằng ¡:
các lệnh;
casehằng
các lệnh',
default:
các lệnh',
}
Biểu thức (gọi là thẻ switch) được ước lượng trước tiên và kết quả được so
sánh với mồi hằng số (gọi là các nhãn) theo thứ tự chúng xuất hiện cho đến
khi một so khớp được tìm thấy. Lệnh ngay sau khi so khớp được thực hiện
Chương 3:Lệnh 33
sau đó. Chú ý số nhiều: mỗi case có thế được theo sau bởi không hay nhiều
lệnh (không chỉ là một lệnh). Việc thực thi tiếp tục cho tới khi hoặc là bắt gặp
một lệnh hrcak hoặc tất cả các lệnh xen vào đến cuối lệnh switch được thực
hiện.Trường hợp default ở cuối cùng là một tùy chọn và được thực hiện nếu
như tất cả các case trước đó không được so khớp.
Ví dụ, chúng ta phải phân tích cú pháp một phép toán toán học nhị hạng
thành ba thành phần của nó và phải lưu trừ chúng vào các biến operator,
operandi, và opcrand2. Lệnh switch sau thực hiện phép toán và lưu trữ kết quả
vào result
switch(operator) {
case result=operandl +operand2;
break;
case result=operand1-operand2;
break;
case result=operand1*operand2;
break;
case'A result=operand1/operand2;
break;
default: cout«"unknownoperator "«operator« V;
break;
}
Như đã được minh họa trong ví dụ, chúng ta cần thiết chèn một lệnh
break ở cuối mồi case. Lệnh break ngắt câu lệnh switch bằng cách nhảy đến
điếm kết thúc của lệnh này. Ví dụ, nếu chúng ta mở rộng lệnh trên đế cho
phép X cũng có thế được sử dụng như là toán tử nhân, chúng ta sẽ có:
switch(operator) {
case result=operandl +operand2;
break;
c a s e re s u lt=operand1-operand2;
break;
casehi’:
case result=operand1*operand2;
break;
case 7: result=operandl / operand2;
break;
default: cout« "unknownoperator "«operator«Vi';
break;
}
Bởi vì case 'x' không có lệnh break nên khi case này được thỏa thì sự thực thi
tiếp tục thực hiện các lệnh trong case kế tiếp và phép nhân được thi hành.
Chúng ta có thể quan sát rằng bất kỳ lệnh switch nào cũng có thể được
viết như nhiều câu lệnh if-else. Ví dụ, lệnh trên có thế được viết như sau:
Chương 3:Lệnh 34
if(operator—- '+1)
result=operand1+operand2;
elseif(operator= -1)
result= operand1- operand2;
else if(operator= bc' IIoperator— '*')
result= operand1*operand2;
elseif(operator= 7)
result= operand1/ operand2;
else
cout« "unknownoperator "« ch« V;
người ta có thế cho rang phiên bản switch là rõ ràng hơn trong trường họp
này. Tiếp cận if-else nên được dành riêng cho tình huống mà trong đó switch
không thề làm được công việc (ví dụ, khi các điều kiện là phức tạp không thể
đơn giản thành các đẳng thức toán học hay khi các nhãn cho các case không
là các hằng số).
3.4. Lênh while
Lệnh while (cũng được gọi là vòng lặp while) cung cấp phương thức lặp một
lệnh cho tới khi một điều kiện được thỏa. Hình thức chung của lệnh lặp là:
while (biểu thức)
lệnh;
Biểu thức (cũng được gọi là điều kiện lặp) được ước lượng trước tiên. Nếu
kết quả khác 0 thì sau đó lệnh (cũng được gọi là thân vòng lặp) được thực
hiện và toàn bộ quá trình được lặp lại. Ngược lại, vòng lặp được kết thúc.
Ví dụ, chúng ta muốn tính tổng của tất cả các số nguyên từ 1 tới n. Điều
này có thể được diễn giải như sau:
i=l;
sum=0;
while(i<=n){
sum+=i;
H-+;
}
Trường họp n là 5, Bảng 3.1 cung cấp bảng phát họa vòng lặp bằng cách
liệt kê các giá trị của các biến có liên quan và điều kiện lặp.
Bảng 3.1 v ét của vòng lặp while.________________________________
Vòng lặp i n i <= n sum -H=i++
Một 1 5 1 1
Hai 'ìL 5 1 3
Ba 3 5 1 6
Bôn 4 5 1 10
Năm 5 5 1 15
Sáu 6 5 0
Chương 3:Lệnh 35
Đôi khi chúng ta có thế gặp vòng lặp while có thân rỗng (nghĩa là một
câu lệnh null). Ví dụ vòng lặp sau đặt n tới thừa số lẻ lớn nhất của nó.
while(n%2=0&&n/=2) ;
Ớ đây điều kiện lặp cung cấp tất cả các tính toán cần thiết vì thế không thật sự
cần một thân cho vòng lặp. Điều kiện vòng lặp không những kiếm tra n là
chằn hay không mà nó còn chia n cho 2 và chắc chắn rằng vòng lặp sẽ dừng.
3.5. Lênh do - while
Lệnh do (cũng được gọi là vòng lặp do) thì tương tự như lệnh while ngoại trừ
thân của nó được thực thi trước tiên và sau đó điều kiện vòng lặp mới được
kiếm tra. Hình thức chung của lệnh do là:
do
lệnh'
while (biểu thức)',
Lệnh được thực thi trước tiên và sau đó biếu thức được ước lượng. Neu kết
quả của biếu thức khác 0 thì sau đó toàn bộ quá trình được lặp lại. Ngược lại
thì vòng lặp kết thúc.
Vòng lặp do ít được sử dụng thường xuyên hơn vòng lặp while. Nó hữu
dụng trong những trường hợp khi chúng ta cần thân vòng lặp thực hiện ít nhất
một lần mà không quan tâm đến điều kiện lặp. Ví dụ, giả sử chúng ta muốn
thực hiện lặp đi lặp lại công việc đọc một giá trị và in bình phương của nó, và
dừng khi giá trị là 0. Điều này có thể được diễn giái trong vòng lặp sau đây:
do {
cin»n;
cout«n*n«rí;
}while(n!=0);
Không giống như vòng lặp while, vòng lặp do ít khi được sử dụng trong
những tình huống mà nó có một thân rồng. Mặc dù vòng lặp do với thân rồng
có thể là tương đương với một vòng lặp while tương tự nhưng vòng lặp while
thì luôn dễ đọc hơn.
3.6. Lênh for•
Lệnh for (cũng được gọi là vòng lặp for) thì tương tự như vòng lặp while
nhưng có hai thành phần thêm vào: một biếu thức được ước lượng chỉ một lần
trước hết và một biểu thức được ước lượng mồi lần ở cuối mỗi lần lặp. Hình
thức tổng quát của lệnh for là:
Chương 3:Lệnh 36
for(biểu thức¡; biểu thúc 2, biểu thứcì)
lệnh',
Biểu thứcỊ (thường được gọi là biểu thức khởi tạo) được ước lượng trước
tiên. Mồi vòng lặp biểu thức2 được ước lượng. Nếu kết quả không là 0 (đúng)
thì sau đó lệnh được thực thi và biểu thức3 được ước lượng. Ngược lại, vòng
lặp kết thúc. Vòng lặp for tổng quát thì tương đương với vòng lặp while sau:
biểu thứcJ,
while (biểu thức 2) {
ỉệnh;
biêu thức 3;
}
Vòng lặp for thường được sử dụng trong các trường hợp mà có một biến
được tăng hay giảm ở mồi lần lặp. Ví dụ, vòng lặp for sau tính toán tổng của
tất cả các số nguyên từ 1tới n.
sum=0;
for(i= l;i<=n;++i)
sum+=i;
Điều này được ưa chuộng hơn phiên bản của vòng lặp while mà chúng ta thấy
trước đó. Trong ví dụ này i thường được gọi là biến lặp.
C++ cho phép biểu thức đầu tiên trong vòng lặp for là một định nghĩa
biến. Ví dụ trong vòng lặp trên thì i có thế được định nghĩa bên trong vòng
lặp:
for(inti= l;i<=n;+-H)
sum+=i;
Trái với sự xuất hiện, phạm vi của i không ở trong thân của vòng lặp mà là
chính vòng lặp. Xét trên phạm vi thi ở trên tương đương với:
inti;
for(i=l;i<=n;-Hi)
sum+=i;
Bất kỳ biếu thức nào trong 3 biểu thức của vòng lặp for có thể rồng. Ví
dụ, xóa biếu thức đầu và biếu thức cuối cho chúng ta dạng giống như vòng
lặp while:
for(;i!=0;) //tưongđươngvói: while(i!=0)
something; // something
Xóa tất cả các biểu thức cho chúng ta một vòng lặp vô hạn. Điều kiện của
vòng lặp này được giả sử luôn luôn là đúng.
for(;;) //vòng lặpvô hạn
something;
Chương 3:Lệnh 37
Trường hợp vòng lặp với nhiều biến lặp thì hiếm dủng. Trong những
trường họp như thế, toán tử phẩy (,) được sử dụng đế phân cách các biếu thức
của chúng:
for(i=0,j =0; i+j <n;-Hi,++j)
something;
Bởi vì các vòng lặp là các lệnh nên chúng có thể xuất hiện bên trong các
vòng lặp khác. Nói các khác, các vòng lặp có thể lồng nhau. Ví dụ,
for(inti= 1;i<=3;++i)
for (intj = 1;j <=3;-H-j)
cout<< 'C« i<<7 « j « ")n";
cho tích so của tập hợp {1,2,3} với chính nó, kết quả như sau:
ị]’1)
ĩ?2,1
Ẹị)
23)
3,1)
§
(33)
3.7. Lệnh continue
Lệnh continue dừng lần lặp hiện tại cùa một vòng lặp và nhảy tới lần lặp ké
tiếp. Nó áp dụng tức thì cho vòng lặp gần với lệnh continue. Sử dụng lệnh
continue bên ngoài vòng lặp là lồi.
Trong vòng lặp while và vòng lặp do-while, vòng lặp kế tiếp mở đầu từ
điều kiện lặp. Trong vòng lặp for, làn lặp kế tiếp khởi đầu từ biểu thức thứ ba
của vòng lặp. Ví dụ, một vòng lặp thực hiện đọc một số, xử lý nó nhưng bỏ
qua những số âm, và dừng khi số là 0, có thể diễn giải như sau:
do {
cin»num;
if(num<0)continue;
//xửlýsôởđây...
}while(num!=0);
Điều này tương đương với:
do {
cin»num;
if(num>=0) {
//xửiýsổờđây...
}
}while(num!=0);
Chương 3:Lệnh 38
Một biến thế của vòng lặp này đế đọc chính xác một số n lần (hơn là cho
tới khi số đó là 0) có thế được diễn giải như sau:
for(i=0;i<n;+-H) {
cin»num;
if(num<0)continue; //làmchonhảytói:-Hi
//xửlýsốởđây...
}
Khi lệnh continue xuất hiện bên trong vòng lặp được lồng vào thì nó áp
dụng trực tiếp lên vòng lặp gần nó chứ không áp dụng cho vòng lặp bên
ngoài. Ví dụ, trong một tập các vòng lặp được lồng nhau sau đây, lệnh
continue áp dụng cho vòng lặp for và không áp dụng cho vòng lặp while:
while(more) {
for(i=0;i<n;-H-i) {
cin»num;
if(num<0)continue; //làmchonhảytói:++i
//processnumhere...
}
//etc...
>
3.8. Lênh break•
Lệnh break có thế xuất hiện bên trong vòng lặp (while, do, hay for) hoặc một
lệnh switch. Nó gây ra bước nhảy ra bên ngoài những lệnh này và vì thế kết
thúc chúng. Giống như lệnh continue, lệnh break chỉ áp dụng cho vòng lặp
hoặc lệnh switch gần nó. Sử dụng lệnh break bên ngoài vòng lặp hay lệnh
switch là lồi.
Ví dụ, chúng ta đọc vào một mật khấu người dùng nhưng không cho
phép một số hữu hạn lần thử:
for(i=0; i<attempts;++i) {
cout« "Pleaseenteryourpassword:
d n » password;
if(Veriiy(password)) //kiemtramậtkhẩuđúnghaysai
break; //Ihoátkhỏivònglặp
cout« "Incorrect!n";
}
Ỡ đây chúng ta phải giá sử rằng có một hàm được gọi Verify để kiểm tra một
mật khẩu và trả về true nếu như mật khấu đúng và ngược lại là false.
Chúng ta có thế viết lại vòng lặp mà không cần lệnh break bằng cách sử
dụng một biến luận lý được thêm vào (verified) và thêm nó vào điều kiện vòng
lặp:
verified=0;
for(i=0; i<attempts&&!verified;++i) {
Chương 3:Lệnh 39
cout« "Pleaseenteryourpassword:
cin» password;
verified=Verifylpassword));
if(!verified)
cout<<"Incorrect!n";
}
Người ta cho rang phiên bản của break thì đơn giản hơn nên thường được ưa
chuộng hơn.
3.9. Lệnh goto
Lệnh goto cung cấp mức thấp nhất cho việc nhảy. Nó có hình thức chung là:
goto nhãn',
trong đó nhãn là một định danh được dùtiẸ đế đánh dấu đích cần nhảy tới.
Nhãn cần được theo sau bởi một dấu hai chấm (:) và xuất hiện trước một lệnh
bên trong hàm như chính lệnh goto.
Ví dụ, vai trò của lệnh break trong vòng lặp for trong phần trước có thế
viết lại bởi một lệnh goto.
for(i=0; i<attempts;-Hi) {
cout«"Pleâseenteryourpassword:
cin» password;
if(Veriíỳ(passwoixi)) //checkpasswordforcorrectness
gotoout; //dropoutoftheloop
cout<<"Incorrect!n";
}
out:
//etc...
Bởi vì lệnh goto cung cấp một hình thức nhảy tự do không có cấu trúc
(không giống như lệnh break và continue) nên dỗ làm gãy đố chương trình.
Phần lớn các lập trình viên ngày nay tránh sử dụng nó đế làm cho chương
trình rõ ràng. Tuy nhiên, goto có một vài (dù cho hiếm) sử dụng chính đáng.
Vì sự phức tạp của những trường hợp như thế mà việc cung cấp những ví dụ
được trình bày ở những phần sau.
3.10.Lệnh return
Lệnh return cho phép một hàm trả về một giá trị cho thành phần gọi nó. Nó có
hình thức tổng quát:
return biểu thức',
Chương 3:Lệnh 40
trong đó biểu thức chỉ rõ giá trị được trả về bởi hàm. Kiểu của giá trị xiày nên
hợp với kiểu của hàm. Trường hợp kiếu trả về của hàm là void, biểu thức nên
rong:
return;
Hàm mà được chúng ta thảo luận đến thời điếm này chỉ có hàm main,
kiếu trả về của nó là kiểu int. Giá trị trả về của hàm main là những gì mà
chương trình trả về cho hệ điều hành khi nó hoàn tất việc thực thi. Chắng hạn
dưới UNIX qui ước là trả về 0 từ hàm main khi chương trình thực thi không
có lỗi. Ngược lại, một mã lỗi khác 0 được trả về. Ví dụ:
intmain(void)
{
cout« "HelloWorld'n";
return0;
}
Khi một hàm có giá trị trả về không là void (như trong ví dụ trên), nếu
không trả về một giá trị sẽ mang lại một cảnh báo trình biên dịch. Giá trị trả
về thực sự sẽ không được định nghĩa trong trường họp này (nghĩa là, nó sẽ là
bất cứ giá trị nào được giữ trong vị trí bộ nhớ tương ứng cùa nó tại thời điếm
đó).
Bài tập cuối chưong 3
3.1 Viết chương trình nhập vào chiều cao (theo centimet) và trọng lượng (theo
kilogram) của một người và xuất một trong những thông điệp: underweight,
normal, hoặc overweight, sử dụng điều kiện:
Underweight: weight < height/2.5
Normal: height/2.5 <= weight <= height/2.3
Overweight: height/2.3 < weight
3.2 Giả sử rằng n là 20, đoạn mã sau sẽ xuất ra cái gì khi nó được thực thi?
if(n>=0)
if(n< 10)
cout« "nissmall'n";
else
cout« "nisnegativen";
3.3 Viết chương trình nhập một ngày theo định dạng dd/mm/yy và xuất nó theo
định dạng monthdd,year. Ví dụ, 25/12/61 trở thành:
Thangmuoihai25,1961
3.4 Viết chương trình nhập vào một giá trị số nguyên, kiếm tra nó là dương hay
không và xuất ra giai thừa của nó, sử dụng công thức:
Chương 3:Lệnh 41
giaithua (0) = 1
giaithua (n) = n X giaithua (n-1)
3.5 Viết chương trình nhập vào một số cơ số 8 và xuất ra số thập phân tương
đương. Ví dụ sau minh họa các công việc thực hiện của chương trình theo
mong đợi:
Nhap vao so batphan: 214
BatPhan(2 14) = ThapPhan(140)
3.6 Viết chương trình cung cấp một bảng cửu chương đom giản của định dạng sau
cho các số nguyên từ 1 tới 9:
1x 1= 1
1x2=2
9x9=81
Chương 3:Lệnh 42
Chương 4. Hàm
Chương này mô tả những hàm do người dùng định nghĩa như là một trong
những khối chương trình C++. Hàm cung cấp một phương thức đế đóng gói
quá trình tính toán một cách dễ dàng đế được sử dụng khi cần. Định nghĩa
hàm gồm hai phần: giao diện và thân.
Phần giao diện hàm (cũng được gọi là khai báo hàm) đặc tả hàm có thể
được sử dụng như thế nào. Nó gồm ba phần:
• Tên hàm. Đây chỉ là một định danh duy nhất.
• Các tham số của hàm. Đây là một tập của không hay nhiều định danh
đã định kiểu được sử dụng đế truyền các giá trị tới và từ hàm.
• Kiểu trả về của hàm. Kiểu trả về của hàm đặc tả cho kiểu của giá trị mà
hàm trả về. Hàm không trả về bất kỳ kiếu nào thì nên trả về kiểu void.
Phần thân hàm chứa đựng các bước tính toán (các lệnh).
Sử dụng một hàm liên quan đến việc gọi nó. Một lòi gọi hàm gồm có tên
hàm, theo sau là cặp dấu ngoặc đon ‘0’, bên trong cặp dấu ngoặc là không,
một hay nhiều đối số được tách biệt nhau bằng dấu phẩy, số các đối số phái
khớp với số các tham số của hàm. Mồi đối số là một biểu thức mà kiểu của nó
phải khớp với kiểu của tham số tương ứng trong khai báo hàm.
Khi lời gọi hàm được thực thi, các đối số được ước lượng trước tiên và
các giá trị kết quả của chúng được gán tới các tham số tương ứng. Sau đó
thân hàm được thực hiện. Cuối cùng giá trị trả về của hàm được truyền tới
thành phần gọi hàm.
Vì một lời gọi tới một hàm mà kiểu trả về không là void sẽ mang lại một
giá trị trả về nên lời gọi là một biểu thức và có thề được sử dụnẹ trong các
biểu thức khác. Ngược lại một lời gọi tới một hàm mà kiều trả về của nó là
void thì lời gọi là một lệnh.
Chương 4: Hàm 45
4.1. Hàm đon giản
Danh sách 4.1 trình bày định nghĩa của một hàm đon giản để tính lũy thừa
của một số nguyên.
Danh sách A
1
2
3
4
5
6
7
Chú giải
A______________________________
intPower(intbase,unsignedintexponent)
{
int result= 1;
for(inti=0; i<exponent;++i)
result *=base;
returnresult;
1 Dòng này định nghĩa giao diện hàm. Nó bắt đầu với kiểu trả về của hàm
(là int trong trường hợp này). Ke tiếp là tên hàm, theo sau là danh sách
các tham so. Power có hai tham so (base và exponent) thuộc kiểu int và
unsigned int tương ứng. Chú ý là cú pháp cho các tham số là tương tự như
cú pháp cho định nghĩa biến: định danh kiểu được theo sau bởi tên tham
số. Tuy nhiên, không thể theo sau định danh kiểu với nhiều tham số phân
cách bởi dấu phẩy:
intPower(intbase,exponent) //Sai!
2 Dấu ngoặc này đánh dấu điểm bắt đầu của thân hàm.
3 Dòng này là định nghĩa một biến cục bộ.
4-5 Vòng lặp for này tăng ca so base lên lũy thừa của exponent và lim trừ kết
quả vào trong result.
6 Hàng này trả result về như là kết quả của hàm.
7 Dấu ngoặc này đánh dấu điểm kết thúc của thân hàm.
Danh sách 4.2 minh họa hàm được gọi như thế nào. Tác động của lời gọi
hàm này là đầu tiên các giá trị 2 và 8 tương ứng được gán cho các tham số
base va exponent, và sau đó thân hàm được ước lượng.
Danh sách 4.2
1 #include<iostreamh>
2 main(void)
3 {
4 cout« " 2 A8=" « Power(2,8)« V;
5 U ________________________________
Khi chạy chương trình này xuất ra kết quả sau:
2A8=256
Chương 4: Hàm 46
Nói chung, một hàm phải được kliai báo trước khi sử đụng nó. Khai báo
hàm (function declaration) đơn giản gồm có mẫu ban đầu của hàm gọi là
nguyên mẫu hàm (function prototype) chỉ định tên hàm, các kiếu tham số, và
kiểu trả về. Hàng 2 trong Danh sách 4.3 trình bày hàm Power có thể được khai
báo như thế nào cho chương trình trên. Nhưng một hàm cũng có thể được
khai báo mà không cần tên các tham số của nó,
intPower(int,unsigned int);
tuy nhiên chúng ta không nên làm điều đó trừ phi vai trò của các tham số là rõ
ràng.
Danh sách 4.3
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream.h>
intPower(intbase,unsignedintexponent); //khai baoham
main(void)
{
cout« "2A8=" « Power(2,8)« V;
}
intPower(intbase,unsignedintexponent)
{
int result=l;
for(inti=0; i< exponent;++i)
result *=base;
returnresult;
Bởi vì một định nghĩa hàm chứa đựng một nguyên mẫu (prototype) nên
nó cũng được xem như là một khai báo. Vì thế nếu định nghĩa của một hàm
xuất hiện trước khi sử dụng nó thì không cần khai báo thêm vào. Tuy nhiên
việc sử dụng các nguyên mầu hàm là khuyến khích cho mọi trường họp. Tập
hợp của nhiều hàm vào một tập tin header riêng biệt cho phép những lập trình
viên khác truy xuất nhanh chóng tới các hàm mà không cần phải đọc toàn bộ
các định nghĩa của chúng.
4.2. Tham số và đối số
C++ hỗ trợ hai kiểu tham số: giá trị và tham chiếu. Tham số giá trị nhận một
sao chép giá trị của đối số được truyền tới nó. Ket quả là, nếu hàm có bất kỳ
chuyến đối nào tới tham số thì vẫn không tác động đến đối số. Ví dụ, trong
#include<iostrearah>
voidFoo(intnum)
{
num=0;
Chương 4: Hàm 47
}
cout« "num- "« num « V;
intmam(void)
{
intx=10;
Foo(x);
cout<<"x=" « X « V;
return0;
}
thì tham số duy nhất của hàm Foo là một tham số giá trị. Đen lúc mà hàm này
được thực thi thì num được sử đụng như là một biến cục bộ bên trong hàm.
Khi hàm được gọi và Xđược truyền tới nó,num nhận một sao chépgiá trị của
X. Ket quả là mặc dù num được đặt về 0 bởihàm nhưng vẫnkhôngcó gìtác
động lên X. Chương trình cho kết quả như sau:
num=0;
x=10;
Trái lại, tham số tham chiếu nhận các đối số được truyền tới nó và làm
trực tiếp trên đối số đó. Bất kỳ chuyển đối nào được tạo ra bởi hàm tới tham
số tham chiếu đều tác động trực tiếp lên đối số.
Bên trong ngữ cảnh của các lời gọi hàm, hai kiểu truyền đối số tương ứng
được gọi là truyền-bằng-giá trị và truyền-bằng-tham cbiếu. Thật là hoàn
toàn hợp lệ cho một hàm truyền-bằng-giá trị đối với một vài tham số và
truyền-bằng-tham chiếu cho một vài tham số khác. Trong thực tế thì truyền-
bằng-giá trị thường được sử dụng nhiều hơn.
4.3. Phạm vi cục bộ và toàn cục• • • •
Mọi thứ được định nghĩa ở mức phạm vi chương trình (nghĩa là bên ngoài các
hàm và các lớp) được hiếu là có một phạm vi toàn cục ^global scope). Các
hàm ví dụ mà chúng ta đã thấy cho đến thòi điếm này đều có một phạm vi
toàn cục. Các biến cũng có thề định nghĩa ở phạm vi toàn cục:
intyear= 1994; //biếntoàncục
intMax(int, int); //hàmtoàncục
intmain(void) //hàmtoàncục
{
II...
}
Các biến toàn cục không được khởi tạo, sẽ được khởi tạo tự động là 0.
Vì các đầu vào toàn cục là có thể thấy được ở mức chương trình nên
chúng cũng phải là duy nhất ở mức chương trình. Điều này nghĩa là cùng các
biến hoặc hàm toàn cục có thế không được định nghĩa nhiều hơn một lần ở
Chương 4: Hàm 48
mức toàn cục. (Tuy nliiên chúng ta sẽ thấy sau này một tên hàm có thế được
sử dụng lại). Thông thường các biến hay hàm toàn cục có thế được truy xuất
từ mọi nơi trong chương trình.
Mồi khối trong một chương trình định nghĩa một phạm vi cục bộ. Thật
vậy, thân của một hàm trình bày một phạm vi cục bộ. Các tham số của một
hàm có cùng phạm vi như là thân hàm. Các biến được định nghĩa ở bên trong
một phạm vi cục bộ có thể nhìn thấy tới chỉ phạm vi đó. Do đó một biến chỉ
cần là duy nhất ở trong phạm vi của chính nó. Các phạm vi cục bộ cí thế lồng
nhau, trong trường hợp này các phạm vi bên trong chồng lên các phạm vi bên
ngoài. Ví dụ trong
intxyz; //xyz làtoàncục
voidFoo(intxyz) //xyzlàcụcbộchothâncủaFoo
{ . "
if(xyz>0) {
doublexyz: //xyz làcụcbộchokhốinày
//...
}
>
có ba phạm vi riêng biệt, mỗi phạm vi chứa đựng một xyz riêng.
Thông thường, thời gian sống của một biến bị giới hạn bởi phạm vi của
nó. Vì thế, ví dụ các biến toàn cục tồn tại suốt thời gian thực hiện chương
trình trong khi các biến cục bộ được tạo ra khi phạm vi của chúng bắt đầu và
mất đi khi phạm vi của chúng kết thúc. Không gian bộ nhớ cho các biến toàn
cục được dành riêng trước khi sự thực hiện của chương trinh bắt đầu nhưng
ngược lại không gian bộ nhớ cho các biến cục bộ được cấp phát ở thời điếm
thực hiện chương trình.
4.4. Toán tử phạm vi
Bởi vì phạm vi cục bộ ghi chồng lên phạm vi toàn cục nên một biến cục bộ có
cùng tên với biến toàn cục làm cho biến toàn cục không thế truy xuất được tới
phạm vi cục bộ. Ví dụ, trong
interior,
voidError(interror)
{
II...
}
biến toàn cục error là không thể truy xuất được bên trong hàm Eưor bởi vì nó
được ghi chồng bởi tham so error cục bộ.
Vấn đề này được giải quyết nhờ vào sử dụng toán tử phạm vi đơn hạng
(::),toán tử này lấy đầu vào toàn cục như là đối số:
Chương 4: Hàm 49
interror,
voidError(interror)
{
II...
if("error !=0) //thamkhảotói errortoàncục
//...
}
4.5. Biến tự động
Bởi vì thời gian sống của một biến cục bộ là có giới hạn và được xác định
hoàn toàn tự động nên những biến này cũng được gọi là tự động. Bộ xác định
lớp lưu trừ auto có thế được dùng đế chỉ định rõ ràng một biến cục bộ là tự
động. Ví dụ:
voidFoo(void)
{
auto intxyz; //nhưlà: intxyz;
//...
}
Điều này ít khi được sử dụng bởi vì tất cả các biến cục bộ mặc định là tự
động.
4.6. Biến thanh ghi
Như được đề cập trước đó, nói chung các biến biểu thị các vị trí bộ nhớ nơi
mà giá trị của biến được lưu trừ tới. Khi mã chương trình tham khảo tới một
biến (ví dụ, trong một biếu thức), trình biên dịch phát ra các mã máy truy xuất
tới vị trí bộ nhớ được biếu thị bởi các biến. Đối với các biến dùng thường
xuyên (ví dụ như các biến vòng lặp), hiệu xuất chương trình có thể thu được
bằng cách giữ biến trong một thanh ghi, bằng cách này có thể tránh được truy
xuất bộ nhớ tới biến đó.
Bộ lưu trữ thanh ghi có thế được sử dụng để chi định cho trình biên dịch
biến có thế được lưu trữ trong một thanh ghi nếu có thể. Ví dụ:
for(registerinti=0; i<n; ++i)
sum+=i;
Ớ đây mồi vòng lặp i được sử dụng ba lần: một lần khi nó được so sánh với n,
một lần khi nó được cộng vào sum, và một lần khi nó được tăng. Vì thế việc
giữ biến i trong thanh ghi trong suốt vòng lặp for là có ý nghĩa trong việc cải
thiện hiệu suất chương trình.
Chú ý rằng thanh ghi chỉ là một gọi ý cho trình biên dịch, và trong một vài
trường họp trình biên dịch có thế chọn không sử dụng thanh ghi khi nó được
Chương 4: Hàm 50
yêu cầu làm điều đó. Một lý đo đế lý giải là bất kỳ máy tính nào cũng có một
số hữu hạn các thanh ghi và nó có thế ở trong trường họp tất cả các thanh ghi
đang được sử dụng.
Thậm chí khi lập trình viên không khai báo thanh ghi, nhiều trình biên
dịch tối ưu cố gắng thực hiện một dự đoán thông minh và sử dụng các thanh
ghi mà chúng muốn để cải thiện hiệu suất của chương trình.
Ý tưởng sử dụng khai báo thanh ghi thường được đề xuất sau cùng; nghĩa
là sau khi viết mã chương trình hoàn tất lập trình viên có thể xem lại mã và
chèn các khai báo thanh ghi vào những nơi cần thiết.
4.7. Hàm nội tuyến
Giả sử một chương trình thường xuyên yêu cầu tìm giá trị tuyệt đối của một
số các số nguyên. Cho một giá trị được biếu thị bởi n, điều này có thể được
giải thích như sau:
(n>0?n:-n)
Tuy nhiên, thay vì tái tạo biếu thức này tại nhiều vị trí khác nhau trong
chương trình, tốt hơn hết là nên định nghĩa nó trong một hàm như sau:
intAbs(intn)
{
retumn>0?n:-n;
}
Phiên bản hàm có một số các thuận lợi. Thứ nhất, nó làm cho chương
trình dỗ đọc. Thứ hai, nó có thế được sử dụng lại. Và thứ ba, nó tránh được
hiệu ứng phụ không mong muốn khi đối số chính nó là một biểu thức có các
hiệu ứng phụ.
Tuy nhiên, bất lợi của phiên bản hàm là việc sử dụng thường xuyên có
thế dần tới sự bất lợi về hiệu suất đáng kể vì các tốn phí dành cho việc gọi
hàm. Ví dụ, nếu hàm Abs được sử dụng trong một vòng lặp được lặp đi lặp lại
một ngàn lần thì sau đó nó sẽ có một tác động trên hiệu suất. Tổn phí có thể
được tránh bằng cách định nghĩa hàm Abs như là hàm nội tuyến(inline);
inlineintAbs(intn)
{
retumn>0?n:-n;
}
Hiệu quả của việc sử dụng hàm nội tuyến là khi hàm Abs được gọi, trình
biên dịch thay vì phát ra mã đế gọi hàm Abs thì mở rộng và thay thế thân của
hàm Abs vào nơi gọi. Trong khi về bản chất thì cùng tính toán được thực hiện
nhưng không có liên quan đến lời gọi hàm vì thế mà không có cấp phát stack.
Chương 4: Hàm 51
Bởi vì các lời gọi tới hàm nội tuyến được mở xông nên không có vết của
chính hàm được đưa vào trong mã đã biên dịch. Vì thế, nếu một hàm được
định nghĩa nội tuyến ở trong một tập tin thì nó không sằn dùng cho các tập tin
khác. Do đó, các hàm nội tuyến thường được đặt vào trong các tập tin header
đế mà chúng có thể được chia sẻ.
Giống như tò khóa register, inline là một gợi ý cho trình biên dịch thực
hiện. Nói chung, việc sứ dụng inline nên có hạn chế chì cho các hàm đơn giản
được sử dụng thường xuỵên mà thôi. Việc sử dụng inline cho các hàm dài và
phức tạp quá thì chắc chắn bị bỏ qua bởi trình biên dịch.
4.8. Đệ qui
Một hàm gọi chính nó được gọi là đệ qui. Đệ qui là một kỹ thuật lập trình
tổng quát có thể ứng dụng cho các bài toán mà có thể định nghĩa theo thuật
ngữ của chính chúng. Chắng hạn bài toán giai thừa được định nghĩa như sau:
• Giai thừa của 0 là 1.
• Giai thừa của một số « là n lần giai thừa của 77-1.
Hàng thứ hai rõ ràng cho biết giai thừa được định nghĩa theo thuật ngữ của
chính nó và vì thế có thế được biểu diễn như một hàm đệ qui:
intFactorial(unsignedintn)
{
returnn = 0 ? 1:n *Factorial(n-1);
}
Cho n bằng 3, Bảng 4.1 cung cấp vết của các lời gọi Factorial. Các khung
stack cho các lời gọi này xuất hiện tuần tự từng cái một trên runtime stack.
Bảng 4.1 vết thực thi của Factorial(3).
Call n 11= 0 n * Factorial(n-l) Returns
Thứ nhât 3 0 3 * Factorial(2) 6
Thứ hai oẢ 0 2 * Factorial 1) 2
Thứ ba  0 1* Factorial(O) 1
Thứ tư 0 1 1
Một hàm đệ qui phải có ít nhất một điều kiện dừng có thể được thỏa.
Ngược lại, hàm sẽ gọi chính nó vô hạn định cho tới khi tràn stack. Ví dụ hàm
Factorial có điều kiện dừng là n = 0. (Chú ý đối với trường hợp n là số âm
thì điều kiện sẽ không bao giờ thỏa và Factorial sẽ thất bại).
Chương 4: Hàm 52
4.9. Đối số măc đinh• •
Đối số mặc định là một thuận lợi lập trình để bỏ bớt đi gánh nặng phải chỉ
định các giá trị đối số cho tất cả các tham số hàm. Ví dụ, xem xét hàm cho
việc báo cáo lỗi:
voidError(char*message, intseverity=0);
Ớ đây thì severity có một đối số mặc định là 0; vì thế cả hai lòi gọi sau đều hợp
lệ:
Error("Divisionbyzero",3);//severityđậttới 3
EiTOiC'Roundofferror”); //seventyđặttới 0
Như là lời gọi hàm đầu tiên minh họa, một đối số mặc định có thể được ghi
chồng bằng cách chỉ định rõ ràng một đối số.
Các đối số mặc định là thích hợp cho các trường hợp mà trong đó các
tham số nào đó của hàm (hoặc tất cả) thường xuyên lấy cùng giá trị. Ví dụ
trong hàm Error, severity 0 lỗi thì phố biến hơn là những trường hợp khác và
vì thế là một ứng cử viên tốt cho đối số mặc định. Một cách dùng các đối số ít
phù hợp có thế là:
intPower(intbase,unsignedintexponent=1);
Bởi vì 1 (hoặc bất kỳ giá trị nào khác) thì không chắc xảy ra thường xuyên
trong tình huống này.
Đế tránh mơ hồ, tất cả đổi số mặc định phải là các đối số theo đuôi. Vì
thế khai báo sau là không theo luật:
voidError(char*message= "Bomb", intseverity);//Trái quitắc
Một đối số mặc định không nhất thiết là một hằng. Các biểu thức tùy ý có
thế được sử dụng miễn là các biến được dùng trong các biếu thức là có sẵn
cho phạm vi định nghĩa hàm (ví dụ, các biến toàn cục).
Qui ước được chấp nhận dành cho các đối số mặc định là chỉ định chúng
trong các khai báo hàm chứ không ở trong định nghĩa hàm.
Khi một chương trình được thực thi dưới một hệ điều hành (như là DOS hay
UNIX) nó có thể nhận không hay nhiều đối số từ dòng lệnh. Các đối số này
xuất hiện sau tên chương trình có thể thực thi và được phân cách bởi các
khoảng trắng. Bởi vì chúng xuất hiện trên cùng hàng nơi mà các lệnh của hệ
điều hành phát ra nên chúng được gọi là các đối số hàng lệnh.
r r
Chương 4: Hàm 53
Ví dụ như xem xét một chương trình được đặt tên là sum đế in ra tổng của
tập họp các số được cung cấp tới nó như là các đối số hàng lệnh. Hộp thoại
4.1 minh họa hai số được truyền như là các đối số tới hàm sum như thế nào ($
là dấu nhắc UNIX).
Hộp thoại 4.1
’ 1
2
3
$sum 10.4 12.5
22.9
$____________
Các đối số hàng lệnh được tạo ra sẵn cho một chương trình C++ thông
qua hàm main. Có hai cách định nghĩa một hàm main:
intmain(void);
intmain(intargc, coastchar*argvQ);
Cách sau được sử dụng khi chương trình được dự tính để chấp nhận các đối
số hàng lệnh. Tham số đầu, argc, biếu thị số các đối số được truyền tới chương
trình (bao gồm cả tên của chính chương trình). Tham số thứ hai, argv, là một
mảng của các hằng chuồi đại diện cho các đối số. Ví dụ từ hàng lệnh đã cho
trong hộp thoại 4.1, chúng ta có:
aigc is 3
argv[0] is "sum"
argv[lj is "10.4"
argv[2] is "12.5"
Danh sách 4.4 minh họa một thi công đơn giản cho chương trình tính tổng
sum. Các chuỗi được chuyến đối sang số thực sử dụng hàm atof được định
nghĩa trong thư viện stdlibii
Danh sách 4.4
1
2
3
4
5
6
7
8
9
10
#inđude<iostnsamii>
#inđude <stdlib.h>
intmain (int aigc, const chai' *argvQ)
{
double sum=0;
for(inti= l;i<argc;-Bĩ)
sum += atoffargv[T]);
cout« sum << V;
return0;
J __________________________
Chương 4: Hàm 54
Bài tập cuối chưong 4
4.1 Viết chương trình trong bài tập 1.1 và 3.1 sử dụng hàm.
4.2 Chúng ta có định nghĩa của hàm Swap sau
void Swap(intX,inty)
{
inttemp=x;
x=y,
y=temp;
}
cho biết giá trị của Xvà y sau khi gọi hàm:
x=10;
y=20;
Swap(x,y);
4.3 Chương trình sau xuất ra kết quả gì khi được thực thi?
#include<iostreamií>
char*str="global";
voidPrint(char*str)
{
cout«str«V i';
{
char*str="local";
coirt«str«W ;
cout«::str<< V;
}
cout«str«V i';
}
int main (void)
{
Print(Tarameter”);
return0;
}
4.4 Viet hàm xuất ra tat cả các số nguyên tố từ 2 đến n (n là số nguyên dương);
voidPrimes(unsignedintn);
Một sổ là số nguyên tố nếu như nó chỉ chia hết cho chính nó và 1.
4.5 Định nghĩa một báng liệt kê gọi là Month cho tất cả các tháng trong năm và sử
dụng nó đề định nghĩa một hàm nhận một tháng như là một đối số và trả về
nó như là một hằng chuồi.
4.6 Định nghĩa một hàm inline IsAlpha, hàm trả về khác 0 khi tham số của nó là
một ký tự và trả về 0 trong các trường hợp khác.
Chương 4: Hàm 55
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao
Lap trinh c_tu_co_ban_den_nang_cao

More Related Content

What's hot

Lập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiểnLập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiển
Mr Giap
 
Giao trinh c++ aptech
Giao trinh c++ aptechGiao trinh c++ aptech
Giao trinh c++ aptechTấn Nhật
 
Chuong vb.net
Chuong vb.netChuong vb.net
Chuong vb.netkienbom
 
lap trinh c Phan2 chuong5
 lap trinh c Phan2 chuong5 lap trinh c Phan2 chuong5
lap trinh c Phan2 chuong5thanhyu
 
Bai tap lap trinh c
Bai tap lap trinh  cBai tap lap trinh  c
Bai tap lap trinh ctiểu minh
 
Giáo trình c++ full tiếng việt
Giáo trình c++ full tiếng việtGiáo trình c++ full tiếng việt
Giáo trình c++ full tiếng việt
Môi Trường Việt
 
Reverse Engineering .NET - Advanced Patching, Playing with IL
Reverse Engineering .NET - Advanced Patching, Playing with ILReverse Engineering .NET - Advanced Patching, Playing with IL
Reverse Engineering .NET - Advanced Patching, Playing with IL
Levis Nickaster
 
Thêm sửa-xóa-combobox - c#
Thêm sửa-xóa-combobox - c#Thêm sửa-xóa-combobox - c#
Thêm sửa-xóa-combobox - c#Văn Dũng
 
Chuong1 on tapc
Chuong1 on tapcChuong1 on tapc
Chuong1 on tapcHung Pham
 
Chuan viet code va thiet ke giao dien trong C#
Chuan viet code va thiet ke giao dien trong C#Chuan viet code va thiet ke giao dien trong C#
Chuan viet code va thiet ke giao dien trong C#Kuli An
 
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịchPhân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Levis Nickaster
 
Bài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPT
Bài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPTBài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPT
Bài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPT
MasterCode.vn
 
Những thuật ngữ thường gặp trong Reverse Engineering .NET
Những thuật ngữ thường gặp trong Reverse Engineering .NETNhững thuật ngữ thường gặp trong Reverse Engineering .NET
Những thuật ngữ thường gặp trong Reverse Engineering .NET
Levis Nickaster
 
Phan2 chuong5 ctrinhcon
Phan2 chuong5 ctrinhconPhan2 chuong5 ctrinhcon
Phan2 chuong5 ctrinhcon
Ly hai
 
Tài liệu lập trình PHP từ căn bản đến nâng cao
Tài liệu lập trình PHP từ căn bản đến nâng caoTài liệu lập trình PHP từ căn bản đến nâng cao
Tài liệu lập trình PHP từ căn bản đến nâng cao
ZendVN
 

What's hot (17)

Lập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiểnLập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiển
 
Giao trinh c++ aptech
Giao trinh c++ aptechGiao trinh c++ aptech
Giao trinh c++ aptech
 
Chuong vb.net
Chuong vb.netChuong vb.net
Chuong vb.net
 
lap trinh c Phan2 chuong5
 lap trinh c Phan2 chuong5 lap trinh c Phan2 chuong5
lap trinh c Phan2 chuong5
 
Bai tap lap trinh c
Bai tap lap trinh  cBai tap lap trinh  c
Bai tap lap trinh c
 
Phạm văn ất
Phạm văn ấtPhạm văn ất
Phạm văn ất
 
Giáo trình c++ full tiếng việt
Giáo trình c++ full tiếng việtGiáo trình c++ full tiếng việt
Giáo trình c++ full tiếng việt
 
Reverse Engineering .NET - Advanced Patching, Playing with IL
Reverse Engineering .NET - Advanced Patching, Playing with ILReverse Engineering .NET - Advanced Patching, Playing with IL
Reverse Engineering .NET - Advanced Patching, Playing with IL
 
Liên kết động trong linux và windows (phần 2)
Liên kết động trong linux và windows (phần 2)Liên kết động trong linux và windows (phần 2)
Liên kết động trong linux và windows (phần 2)
 
Thêm sửa-xóa-combobox - c#
Thêm sửa-xóa-combobox - c#Thêm sửa-xóa-combobox - c#
Thêm sửa-xóa-combobox - c#
 
Chuong1 on tapc
Chuong1 on tapcChuong1 on tapc
Chuong1 on tapc
 
Chuan viet code va thiet ke giao dien trong C#
Chuan viet code va thiet ke giao dien trong C#Chuan viet code va thiet ke giao dien trong C#
Chuan viet code va thiet ke giao dien trong C#
 
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịchPhân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
 
Bài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPT
Bài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPTBài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPT
Bài 5 Lập trình PHP (phần 3) Làm việc với dữ liệu của form - Giáo trình FPT
 
Những thuật ngữ thường gặp trong Reverse Engineering .NET
Những thuật ngữ thường gặp trong Reverse Engineering .NETNhững thuật ngữ thường gặp trong Reverse Engineering .NET
Những thuật ngữ thường gặp trong Reverse Engineering .NET
 
Phan2 chuong5 ctrinhcon
Phan2 chuong5 ctrinhconPhan2 chuong5 ctrinhcon
Phan2 chuong5 ctrinhcon
 
Tài liệu lập trình PHP từ căn bản đến nâng cao
Tài liệu lập trình PHP từ căn bản đến nâng caoTài liệu lập trình PHP từ căn bản đến nâng cao
Tài liệu lập trình PHP từ căn bản đến nâng cao
 

Viewers also liked

Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
MasterCode.vn
 
Bài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPT
Bài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPTBài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPT
Bài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPT
MasterCode.vn
 
csdl bai-thuchanh_02
csdl bai-thuchanh_02csdl bai-thuchanh_02
csdl bai-thuchanh_02
kikihoho
 
csdl - buoi1
csdl - buoi1csdl - buoi1
csdl - buoi1
kikihoho
 
CTDL&GT_01
CTDL&GT_01CTDL&GT_01
CTDL&GT_01
kikihoho
 
Ky thuat lap trinh nang cao
Ky thuat lap trinh nang caoKy thuat lap trinh nang cao
Ky thuat lap trinh nang cao
good food
 
Cơ sở dữ liệu (Buổi 1)
Cơ sở dữ liệu (Buổi 1)Cơ sở dữ liệu (Buổi 1)
Cơ sở dữ liệu (Buổi 1)
Hoài Phạm
 
Cam bien va ung dung
Cam bien va ung dungCam bien va ung dung
LED Vu-Metter LM3915 and LM386
LED Vu-Metter LM3915 and LM386LED Vu-Metter LM3915 and LM386
LED Vu-Metter LM3915 and LM386
Mr Giap
 
Cam bien tiem can
Cam bien tiem canCam bien tiem can
Nlp lap trinh ngon ngu tu duy
Nlp lap trinh ngon ngu tu duyNlp lap trinh ngon ngu tu duy
Nlp lap trinh ngon ngu tu duy
Đặng Vui
 
Giáo trình sql server 2000
Giáo trình sql server 2000Giáo trình sql server 2000
Giáo trình sql server 2000
https://www.facebook.com/garmentspace
 
15 Ghép nối 8255
15 Ghép nối 825515 Ghép nối 8255
15 Ghép nối 8255
Mr Giap
 
Email là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhất
Email là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhấtEmail là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhất
Email là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhất
Freelancer
 
Bài tập CTDL và GT 4
Bài tập CTDL và GT 4Bài tập CTDL và GT 4
Bài tập CTDL và GT 4
Hồ Lợi
 
KỸ NĂNG ĐIỆN THOẠI
KỸ NĂNG ĐIỆN THOẠIKỸ NĂNG ĐIỆN THOẠI
KỸ NĂNG ĐIỆN THOẠI
MasterSkills Institute
 
Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#
Thanhlanh nguyen
 
Python Beginner Class day-02-strings
Python Beginner Class day-02-stringsPython Beginner Class day-02-strings
Python Beginner Class day-02-strings
Khánh Nguyễn
 
Python Beginner Class day-11-12-13-database
Python Beginner Class day-11-12-13-databasePython Beginner Class day-11-12-13-database
Python Beginner Class day-11-12-13-database
Khánh Nguyễn
 
Tài Liệu Điều Khiển Từ Xa Bằng Hồng Ngoại
Tài Liệu Điều Khiển Từ Xa Bằng Hồng NgoạiTài Liệu Điều Khiển Từ Xa Bằng Hồng Ngoại
Tài Liệu Điều Khiển Từ Xa Bằng Hồng Ngoại
Mr Giap
 

Viewers also liked (20)

Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
 
Bài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPT
Bài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPTBài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPT
Bài 2: Các khái niệm trong CSDL quan hệ - Giáo trình FPT
 
csdl bai-thuchanh_02
csdl bai-thuchanh_02csdl bai-thuchanh_02
csdl bai-thuchanh_02
 
csdl - buoi1
csdl - buoi1csdl - buoi1
csdl - buoi1
 
CTDL&GT_01
CTDL&GT_01CTDL&GT_01
CTDL&GT_01
 
Ky thuat lap trinh nang cao
Ky thuat lap trinh nang caoKy thuat lap trinh nang cao
Ky thuat lap trinh nang cao
 
Cơ sở dữ liệu (Buổi 1)
Cơ sở dữ liệu (Buổi 1)Cơ sở dữ liệu (Buổi 1)
Cơ sở dữ liệu (Buổi 1)
 
Cam bien va ung dung
Cam bien va ung dungCam bien va ung dung
Cam bien va ung dung
 
LED Vu-Metter LM3915 and LM386
LED Vu-Metter LM3915 and LM386LED Vu-Metter LM3915 and LM386
LED Vu-Metter LM3915 and LM386
 
Cam bien tiem can
Cam bien tiem canCam bien tiem can
Cam bien tiem can
 
Nlp lap trinh ngon ngu tu duy
Nlp lap trinh ngon ngu tu duyNlp lap trinh ngon ngu tu duy
Nlp lap trinh ngon ngu tu duy
 
Giáo trình sql server 2000
Giáo trình sql server 2000Giáo trình sql server 2000
Giáo trình sql server 2000
 
15 Ghép nối 8255
15 Ghép nối 825515 Ghép nối 8255
15 Ghép nối 8255
 
Email là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhất
Email là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhấtEmail là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhất
Email là gì? 5 bí quyết giúp bạn giao tiếp qua email hiệu quả nhất
 
Bài tập CTDL và GT 4
Bài tập CTDL và GT 4Bài tập CTDL và GT 4
Bài tập CTDL và GT 4
 
KỸ NĂNG ĐIỆN THOẠI
KỸ NĂNG ĐIỆN THOẠIKỸ NĂNG ĐIỆN THOẠI
KỸ NĂNG ĐIỆN THOẠI
 
Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#Lap trinh-huong-doi-tuong-bang-c#
Lap trinh-huong-doi-tuong-bang-c#
 
Python Beginner Class day-02-strings
Python Beginner Class day-02-stringsPython Beginner Class day-02-strings
Python Beginner Class day-02-strings
 
Python Beginner Class day-11-12-13-database
Python Beginner Class day-11-12-13-databasePython Beginner Class day-11-12-13-database
Python Beginner Class day-11-12-13-database
 
Tài Liệu Điều Khiển Từ Xa Bằng Hồng Ngoại
Tài Liệu Điều Khiển Từ Xa Bằng Hồng NgoạiTài Liệu Điều Khiển Từ Xa Bằng Hồng Ngoại
Tài Liệu Điều Khiển Từ Xa Bằng Hồng Ngoại
 

Similar to Lap trinh c_tu_co_ban_den_nang_cao

Hàm và Chuỗi
Hàm và ChuỗiHàm và Chuỗi
Hàm và Chuỗi
pnanhvn
 
Giotrnhcfulltingvit 131128201133-phpapp02
Giotrnhcfulltingvit 131128201133-phpapp02Giotrnhcfulltingvit 131128201133-phpapp02
Giotrnhcfulltingvit 131128201133-phpapp02
Huy Nguyễn
 
Phong cach lap trinh c++
Phong cach lap trinh c++Phong cach lap trinh c++
Phong cach lap trinh c++
ptquang160492
 
Mapreduce simplified-data-processing
Mapreduce simplified-data-processingMapreduce simplified-data-processing
Mapreduce simplified-data-processing
Viet-Trung TRAN
 
Lua introduction Gioi thieu ve Lua
Lua introduction Gioi thieu ve LuaLua introduction Gioi thieu ve Lua
Lua introduction Gioi thieu ve LuaDa Mi
 
Bài giảng Lập trình cơ bản - truongkinhtethucpham.com
Bài giảng Lập trình cơ bản - truongkinhtethucpham.comBài giảng Lập trình cơ bản - truongkinhtethucpham.com
Bài giảng Lập trình cơ bản - truongkinhtethucpham.com
mai_non
 
Bài giảng ngôn ngữ lập trình c c++ phạm hồng thái[bookbooming.com]
Bài giảng ngôn ngữ lập trình c c++   phạm hồng thái[bookbooming.com]Bài giảng ngôn ngữ lập trình c c++   phạm hồng thái[bookbooming.com]
Bài giảng ngôn ngữ lập trình c c++ phạm hồng thái[bookbooming.com]bookbooming1
 
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)Tấn Nhật
 
86227349 giao-trinh-lap-trinh-c
86227349 giao-trinh-lap-trinh-c86227349 giao-trinh-lap-trinh-c
86227349 giao-trinh-lap-trinh-cHoa Cỏ May
 
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)Informatics and Maths
 
Ngon ngu lap trinh c&c++
Ngon ngu lap trinh c&c++Ngon ngu lap trinh c&c++
Ngon ngu lap trinh c&c++
Tiến Quang Phan
 
[C] giao trinh c dhbk - viet nhat
[C] giao trinh c   dhbk - viet nhat[C] giao trinh c   dhbk - viet nhat
[C] giao trinh c dhbk - viet nhatHoang Nguyen
 

Similar to Lap trinh c_tu_co_ban_den_nang_cao (20)

Chuong 01 mo dau
Chuong 01 mo dauChuong 01 mo dau
Chuong 01 mo dau
 
C++
C++C++
C++
 
Hàm và Chuỗi
Hàm và ChuỗiHàm và Chuỗi
Hàm và Chuỗi
 
Session 01 C
Session 01 CSession 01 C
Session 01 C
 
Session 01
Session 01Session 01
Session 01
 
Session 01
Session 01Session 01
Session 01
 
Giotrnhcfulltingvit 131128201133-phpapp02
Giotrnhcfulltingvit 131128201133-phpapp02Giotrnhcfulltingvit 131128201133-phpapp02
Giotrnhcfulltingvit 131128201133-phpapp02
 
Huong doi tuong
Huong doi tuongHuong doi tuong
Huong doi tuong
 
Phong cach lap trinh c++
Phong cach lap trinh c++Phong cach lap trinh c++
Phong cach lap trinh c++
 
Phong cach lap trinh c++
Phong cach lap trinh c++Phong cach lap trinh c++
Phong cach lap trinh c++
 
Mapreduce simplified-data-processing
Mapreduce simplified-data-processingMapreduce simplified-data-processing
Mapreduce simplified-data-processing
 
Lua introduction Gioi thieu ve Lua
Lua introduction Gioi thieu ve LuaLua introduction Gioi thieu ve Lua
Lua introduction Gioi thieu ve Lua
 
Bài giảng Lập trình cơ bản - truongkinhtethucpham.com
Bài giảng Lập trình cơ bản - truongkinhtethucpham.comBài giảng Lập trình cơ bản - truongkinhtethucpham.com
Bài giảng Lập trình cơ bản - truongkinhtethucpham.com
 
Bài giảng ngôn ngữ lập trình c c++ phạm hồng thái[bookbooming.com]
Bài giảng ngôn ngữ lập trình c c++   phạm hồng thái[bookbooming.com]Bài giảng ngôn ngữ lập trình c c++   phạm hồng thái[bookbooming.com]
Bài giảng ngôn ngữ lập trình c c++ phạm hồng thái[bookbooming.com]
 
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
 
86227349 giao-trinh-lap-trinh-c
86227349 giao-trinh-lap-trinh-c86227349 giao-trinh-lap-trinh-c
86227349 giao-trinh-lap-trinh-c
 
C++ dai hoc cong nghe
C++ dai hoc cong ngheC++ dai hoc cong nghe
C++ dai hoc cong nghe
 
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
Ngon ngu lap trinh c&c++ (pham hong thai coltech vnu)
 
Ngon ngu lap trinh c&c++
Ngon ngu lap trinh c&c++Ngon ngu lap trinh c&c++
Ngon ngu lap trinh c&c++
 
[C] giao trinh c dhbk - viet nhat
[C] giao trinh c   dhbk - viet nhat[C] giao trinh c   dhbk - viet nhat
[C] giao trinh c dhbk - viet nhat
 

More from Huy Nguyễn

Nmlt c16 ky_thuatlaptrinhdequy_in
Nmlt c16 ky_thuatlaptrinhdequy_inNmlt c16 ky_thuatlaptrinhdequy_in
Nmlt c16 ky_thuatlaptrinhdequy_in
Huy Nguyễn
 
Nmlt c15 ham_nangcao_phan2_in
Nmlt c15 ham_nangcao_phan2_inNmlt c15 ham_nangcao_phan2_in
Nmlt c15 ham_nangcao_phan2_in
Huy Nguyễn
 
Nmlt c15 ham_nangcao_phan1_in
Nmlt c15 ham_nangcao_phan1_inNmlt c15 ham_nangcao_phan1_in
Nmlt c15 ham_nangcao_phan1_in
Huy Nguyễn
 
Nmlt c14 cac_kythuatthaotactrenbit_in
Nmlt c14 cac_kythuatthaotactrenbit_inNmlt c14 cac_kythuatthaotactrenbit_in
Nmlt c14 cac_kythuatthaotactrenbit_in
Huy Nguyễn
 
Nmlt c13 con_tronangcao_in
Nmlt c13 con_tronangcao_inNmlt c13 con_tronangcao_in
Nmlt c13 con_tronangcao_in
Huy Nguyễn
 
Nmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_inNmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_in
Huy Nguyễn
 
Nmlt c11 con_trocoban_in
Nmlt c11 con_trocoban_inNmlt c11 con_trocoban_in
Nmlt c11 con_trocoban_in
Huy Nguyễn
 
Nmlt c10 cau_truc_in
Nmlt c10 cau_truc_inNmlt c10 cau_truc_in
Nmlt c10 cau_truc_in
Huy Nguyễn
 
Nmlt c09 chuoi_kytu_in
Nmlt c09 chuoi_kytu_inNmlt c09 chuoi_kytu_in
Nmlt c09 chuoi_kytu_in
Huy Nguyễn
 
Nmlt c08 mang2_chieu_in
Nmlt c08 mang2_chieu_inNmlt c08 mang2_chieu_in
Nmlt c08 mang2_chieu_in
Huy Nguyễn
 
Nmlt c07 mang1_chieu_in
Nmlt c07 mang1_chieu_inNmlt c07 mang1_chieu_in
Nmlt c07 mang1_chieu_in
Huy Nguyễn
 
Nmlt c06 ham_in
Nmlt c06 ham_inNmlt c06 ham_in
Nmlt c06 ham_in
Huy Nguyễn
 
Nmlt c05 cau_lenhlap_in
Nmlt c05 cau_lenhlap_inNmlt c05 cau_lenhlap_in
Nmlt c05 cau_lenhlap_in
Huy Nguyễn
 
Nmlt c04 cau_lenhdieukienvarenhanh_in
Nmlt c04 cau_lenhdieukienvarenhanh_inNmlt c04 cau_lenhdieukienvarenhanh_in
Nmlt c04 cau_lenhdieukienvarenhanh_in
Huy Nguyễn
 
Nmlt c03 cac_kieudulieucoso_in
Nmlt c03 cac_kieudulieucoso_inNmlt c03 cac_kieudulieucoso_in
Nmlt c03 cac_kieudulieucoso_in
Huy Nguyễn
 
Nmlt c02 gioi_thieunnltc_in
Nmlt c02 gioi_thieunnltc_inNmlt c02 gioi_thieunnltc_in
Nmlt c02 gioi_thieunnltc_in
Huy Nguyễn
 
Nmlt c01 cac_khainiemcobanvelaptrinh_in
Nmlt c01 cac_khainiemcobanvelaptrinh_inNmlt c01 cac_khainiemcobanvelaptrinh_in
Nmlt c01 cac_khainiemcobanvelaptrinh_in
Huy Nguyễn
 
Nmlt c00 gioi_thieumonhoc_in
Nmlt c00 gioi_thieumonhoc_inNmlt c00 gioi_thieumonhoc_in
Nmlt c00 gioi_thieumonhoc_in
Huy Nguyễn
 

More from Huy Nguyễn (18)

Nmlt c16 ky_thuatlaptrinhdequy_in
Nmlt c16 ky_thuatlaptrinhdequy_inNmlt c16 ky_thuatlaptrinhdequy_in
Nmlt c16 ky_thuatlaptrinhdequy_in
 
Nmlt c15 ham_nangcao_phan2_in
Nmlt c15 ham_nangcao_phan2_inNmlt c15 ham_nangcao_phan2_in
Nmlt c15 ham_nangcao_phan2_in
 
Nmlt c15 ham_nangcao_phan1_in
Nmlt c15 ham_nangcao_phan1_inNmlt c15 ham_nangcao_phan1_in
Nmlt c15 ham_nangcao_phan1_in
 
Nmlt c14 cac_kythuatthaotactrenbit_in
Nmlt c14 cac_kythuatthaotactrenbit_inNmlt c14 cac_kythuatthaotactrenbit_in
Nmlt c14 cac_kythuatthaotactrenbit_in
 
Nmlt c13 con_tronangcao_in
Nmlt c13 con_tronangcao_inNmlt c13 con_tronangcao_in
Nmlt c13 con_tronangcao_in
 
Nmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_inNmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_in
 
Nmlt c11 con_trocoban_in
Nmlt c11 con_trocoban_inNmlt c11 con_trocoban_in
Nmlt c11 con_trocoban_in
 
Nmlt c10 cau_truc_in
Nmlt c10 cau_truc_inNmlt c10 cau_truc_in
Nmlt c10 cau_truc_in
 
Nmlt c09 chuoi_kytu_in
Nmlt c09 chuoi_kytu_inNmlt c09 chuoi_kytu_in
Nmlt c09 chuoi_kytu_in
 
Nmlt c08 mang2_chieu_in
Nmlt c08 mang2_chieu_inNmlt c08 mang2_chieu_in
Nmlt c08 mang2_chieu_in
 
Nmlt c07 mang1_chieu_in
Nmlt c07 mang1_chieu_inNmlt c07 mang1_chieu_in
Nmlt c07 mang1_chieu_in
 
Nmlt c06 ham_in
Nmlt c06 ham_inNmlt c06 ham_in
Nmlt c06 ham_in
 
Nmlt c05 cau_lenhlap_in
Nmlt c05 cau_lenhlap_inNmlt c05 cau_lenhlap_in
Nmlt c05 cau_lenhlap_in
 
Nmlt c04 cau_lenhdieukienvarenhanh_in
Nmlt c04 cau_lenhdieukienvarenhanh_inNmlt c04 cau_lenhdieukienvarenhanh_in
Nmlt c04 cau_lenhdieukienvarenhanh_in
 
Nmlt c03 cac_kieudulieucoso_in
Nmlt c03 cac_kieudulieucoso_inNmlt c03 cac_kieudulieucoso_in
Nmlt c03 cac_kieudulieucoso_in
 
Nmlt c02 gioi_thieunnltc_in
Nmlt c02 gioi_thieunnltc_inNmlt c02 gioi_thieunnltc_in
Nmlt c02 gioi_thieunnltc_in
 
Nmlt c01 cac_khainiemcobanvelaptrinh_in
Nmlt c01 cac_khainiemcobanvelaptrinh_inNmlt c01 cac_khainiemcobanvelaptrinh_in
Nmlt c01 cac_khainiemcobanvelaptrinh_in
 
Nmlt c00 gioi_thieumonhoc_in
Nmlt c00 gioi_thieumonhoc_inNmlt c00 gioi_thieumonhoc_in
Nmlt c00 gioi_thieumonhoc_in
 

Recently uploaded

GIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdf
GIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdfGIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdf
GIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdf
Điện Lạnh Bách Khoa Hà Nội
 
BAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdf
BAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdfBAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdf
BAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdf
phamthuhoai20102005
 
Dẫn luận ngôn ngữ - Tu vung ngu nghia.pptx
Dẫn luận ngôn ngữ - Tu vung ngu nghia.pptxDẫn luận ngôn ngữ - Tu vung ngu nghia.pptx
Dẫn luận ngôn ngữ - Tu vung ngu nghia.pptx
nvlinhchi1612
 
AV6 - PIE CHART WRITING skill in english
AV6 - PIE CHART WRITING skill in englishAV6 - PIE CHART WRITING skill in english
AV6 - PIE CHART WRITING skill in english
Qucbo964093
 
Chương III (Nội dung vẽ sơ đồ tư duy chương 3)
Chương III (Nội dung vẽ sơ đồ tư duy chương 3)Chương III (Nội dung vẽ sơ đồ tư duy chương 3)
Chương III (Nội dung vẽ sơ đồ tư duy chương 3)
duykhoacao
 
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...
Nguyen Thanh Tu Collection
 
98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...
98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...
98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...
Nguyen Thanh Tu Collection
 
Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...
Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...
Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...
https://www.facebook.com/garmentspace
 
30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf
30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf
30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf
ngocnguyensp1
 
Ảnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nay
Ảnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nayẢnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nay
Ảnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nay
chinhkt50
 

Recently uploaded (10)

GIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdf
GIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdfGIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdf
GIÁO TRÌNH 2-TÀI LIỆU SỬA CHỮA BOARD MONO TỦ LẠNH MÁY GIẶT ĐIỀU HÒA.pdf
 
BAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdf
BAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdfBAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdf
BAI TAP ON HE LOP 2 LEN 3 MON TIENG VIET.pdf
 
Dẫn luận ngôn ngữ - Tu vung ngu nghia.pptx
Dẫn luận ngôn ngữ - Tu vung ngu nghia.pptxDẫn luận ngôn ngữ - Tu vung ngu nghia.pptx
Dẫn luận ngôn ngữ - Tu vung ngu nghia.pptx
 
AV6 - PIE CHART WRITING skill in english
AV6 - PIE CHART WRITING skill in englishAV6 - PIE CHART WRITING skill in english
AV6 - PIE CHART WRITING skill in english
 
Chương III (Nội dung vẽ sơ đồ tư duy chương 3)
Chương III (Nội dung vẽ sơ đồ tư duy chương 3)Chương III (Nội dung vẽ sơ đồ tư duy chương 3)
Chương III (Nội dung vẽ sơ đồ tư duy chương 3)
 
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...
CHUYÊN ĐỀ BỒI DƯỠNG HỌC SINH GIỎI KHOA HỌC TỰ NHIÊN 9 CHƯƠNG TRÌNH MỚI - PHẦN...
 
98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...
98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...
98 BÀI LUYỆN NGHE TUYỂN SINH VÀO LỚP 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ ...
 
Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...
Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...
Khoá luận tốt nghiệp ngành Truyền thông đa phương tiện Xây dựng kế hoạch truy...
 
30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf
30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf
30 - ĐỀ THI HSG - HÓA HỌC 9 - NĂM HỌC 2021 - 2022.pdf
 
Ảnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nay
Ảnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nayẢnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nay
Ảnh hưởng của nhân sinh quan Phật giáo đến đời sống tinh thần Việt Nam hiện nay
 

Lap trinh c_tu_co_ban_den_nang_cao

  • 1. Chương 1. Mở đầu Chương này giói thiệu những phần cơ bản của một chương trình C++. Chúng ta sử dụng những ví dụ đơn giản đế trình bày cấu trúc các chương trình C++ và cách thức biên dịch chúng. Các khái niệm cơ bản như là hằng, biến, và việc lưu trữ chúng trong bộ nhớ cũng sẽ được tháo luận trong chương này. Sau đây là một đặc tả sơ bộ về khái niệm lập trình. Lập trình Máy tính số là một công cụ để giải quyết hàng loạt các bài toán lớn. Một lời giải cho một bài toán nào đó được gọi là một giải thuật (algorithm); nó mô tá một chuồi các bước cần thực hiện đế giải quyết bài toán. Một ví dụ đơn giản cho một bài toán vả một giải thuật có thể là: Bài toán: sắp xếp một danh sách các số theo thứ tự tăng dần. Giải thuật:Giả sử danh sách đã cho là listl; tạo ra một danh sách rỗng, list2, để lưu danh sách đã sắp xếp. Lặp đi lặp lại công việc, tìm số nhỏ nhất trong listl, xóa nó khỏi listl, và thêm vào phần tử kế tiếp trong danh sách list2, cho đến khi lỉstl là rỗng. Giải thuật được diễn giải bằng các thuật ngữ trừu tượng mang tính chất dề hiểu. Ngôn ngữ thật sự được hiểu bởi máy tính là ngôn ngữ máy. Chương trình được diễn đạt bằng ngôn ngữ máy được gọi là có thể thực thi. Một chương trình được viết bằng bất kỳ một ngôn ngừ nào khác thì trước hết cần được dịch sang ngôn ngữ máy để máy tính có thể hiếu và thực thi nó. Ngôn ngữ máy cực kỳ khó hiểu đối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy đế viết chương trình. Một sự trừu tượng khác là ngôn ngữ assembly. Nó cung cấp những tên dỗ nhớ cho các lệnh và một ký hiệu dễ hiếu hơn cho dữ liệu. Bộ dịch được gọi là assembler chuyển ngôn ngữ assembly sang ngôn ngừ máy. Ngay cả những ngôn ngữ assembly cũng khó sử dụng. Những ngôn ngữ cấp cao như C++ cung cấp các ký hiệu thuận tiện hon nhiều cho việc thi hành các giải thuật. Chúng giúp cho các lập trình viên không phải nghĩ nhiều về các thuật ngữ cấp thấp, và giúp họ chỉ tập trung vào giải thuật. Trình biên dịch (compiler) sè đảm nhiệm việc dịch chương trình viết bằng ngôn ngữ cấp cao sang ngôn ngữ assembly. Mã assembly được tạo ra bởi trình biên dịch sau đó sẽ được tập hợp lại đế cho ra một chương trình có thể thực thi. Chương 1: Mởđầu 1
  • 2. 1.1. Một chưong trình C++ đon giản Danh sách 1.1 trình bày chương trình C++ đầu tiên. Chương trình này khi chạy sẽ xuất ra thông điệp HelloWorld. Danh sách 1.1 1 2 3 4 5 Chú giải 1 Hàng này sử dụng chỉ thị tiền xử lý #include để chèn vào nội dung của tập tin header iosteam.h trong chương trình, iostrcamli là tập tin header chuẩn của C++ và chứa đựng các định nghĩa cho xuất và nhập. 2 Hàng này định nghĩa một hàm được gọi là main. Hàm có thế không có hay có nhiều tham số (parameters); các tham số này luôn xuất hiện sau tên hàm, giữa một cặp dấu ngoặc. Việc xuất hiện của từ void ở giữa dấu n|oặc chi định rằng hàm main không có tham số. Hàm có thể có kiểu trả về; kiểu trả về luôn xuất hiện trước tên hàm. Kiếu trả về cho hàm main là int (ví dụ: một số nguyên). Tất cả các chương trình C++ phải có một hàm main duy nhất.Việc thực thi chương trình luôn bắt đầu từ hàm main. 3 Dấu ngoặc nhọn bắt đầu thân của hàm mam. 4 Hàng này là một câu lệnh (statement). Một lệnh là một sự tính toán đế cho ra một giá trị. Ket thúc một lệnh thì luôn luôn được đánh dấu bằng dấu chấm phẩy (;). Câu lệnh này xuất ra chuỗi "Hello World®" đế gởi đến dòng xuất cout Chuồi là một dãy các ký tự được đặt trong cặp nháy kép. Ký tự cuối cùng trong chuồi này (n) là một ký tự xuống hàng (newline). Dòng là một đối tượng được dùng đế thực hiện các xuất hoặc nhập, cout là dòng xuất chuấn trong C++ (xuất chuấn thường được hiểu là màn hình máy tính). Ký tự « là toán tử xuất, nó xem dòng xuất như là toán hạng trái và xem biểu thức như là toán hạng phải, và tạo nên giá trị của biếu thức được gởi đến dòng xuất. Trong trường hợp này, kết quả là chuồi "Hello Worlđn" được gởi đến dòng cout, làm cho nó được hiến thị trên màn hình máy tính. 5 Dấu ngoặc đóng kết thúc thân hàm main. 1.2. Biên dịch một chương trình C++ Bảng 1.1 trình bày chương trình trong danh sách 1.1 được biên dịch và chạy trong môi trường UNIX thông thường. Phần in đậm được xem như là đầu vào (input) của người dùng và phần in thường được xem như là đáp ứng của hệ thống. Dấu nhắc ở hàng lệnh UNIX xuất hiện như là ký tự dollar($). #inđude<iostream.h> intmain(void) { cout« "HelloWorld'll"; 1_________ ___________ Chương 1: Mởđầu 2
  • 3. 1 2 3 4 Bảng 1.1 Chú giải 1 Lệnh để triệu gọi bộ dịch AT&T của c++ trong môi trường UNIX là cc. Đối số cho lệnh này (hello.cc) là tên của tập tin chứa đựng chương trình. Theo qui định thì tên tập tin có phần mở rộng là .c, .c, hoặc là .cc. (Phần mở rộng này có thể là khác nhau đối với những hệ điều hành khác nhau) 2 Ket quả của sự biên dịch là một tập tin có thế thực thi mặc định là a.out. Đế chạy chương trình, chúng ta sử dụng a.out như là lệnh. 3 Đây là kết quả được cung cấp bởi chương trình. 4 Dấu nhắc ừở về hệ thống chỉ định rằng chương trình đã hoàn tất sự thực thi của nó. Lệnh cc chấp nhận các phần tùy chọn. Mồi tùy chọn xuất hiện như name, trong đó name là tên cùa tùy chọn (thườnệ là một kỷ tự đơn). Một vài tùy chọn yêu cầu có đối số. Ví dụ tùy chọn xuất (-o) cho phép chỉ định rõ tập tin có thế được cung cấp bởi trình biên dịch thay vì là aout. Bảng 1.2 minh họa việc sử dụng tùy chọn này bằng cách chỉ định rõ hello như là tên của tập tin có thể thực thi. Bảng 1.2 1 2 3 4 Mặc dù lệnh thực sự có thế khác phụ thuộc vào trình biên dịch, một thủ tục biên dịch tương tự có thế được dùng dưới môi trường MS-DOS. Trình biên dịch C++ dựa trên Windows dâng tặnẹ một môi trường thân thiện với người dùng mà việc biên dịch rất đơn giản bằng cách chọn lệnh từ menu. Qui định tên dưới MS-DOS và Windows là tên của tập tin nguồn C++ phải có phần mở rộng là .cpp. 1.3. Viêc biên dich C++ diễn ra như thế nào• • Biên dịch một chương trình C++ liên quan đến một số bước (hầu hết các bước là trong suốt với người dùng): • Đầu tiên, bộ tiền xử lý C++ xem qua mã trong chương trình và thực hiện các chỉ thị được chỉ định bởi các chỉ thị tiền xử lý (ví dụ, #include). Ket quả là một mã chương trình đã sửa đối mà không còn chứa bất kỳ một chi thị tiền xử lý nào cả. $ c c heflo.cc-oheDo $ heBo HelloWorld $ $ c c hello.cc $ a.out HelloWorld $ Chương 1: Mởđầu 3
  • 4. • Sau đó, trình biên dịch C++ dịch các mã của chương trình. Trình biên dịch có thế là một trình biên dịch C++ thật sự phát ra mã assembly hay mã máy, hoặc chỉ là trình chuyển đổi dịch mã sang c. Ớ trường họp thứ hai, mã c sau khi được dịch ra sè tạo thành mã assembly hay mã máy thông qua trình biên dịch c. Trong cả hai trường hợp, đầu ra có thể không hoàn chỉnh vì chương trình tham khảo tới các thủ tục trong thư viện còn chưa được định nghĩa như một phần của chương trình. Ví dụ Danh sách 1.1 tham chiếu tới toán tò « mà thực sự được định nghĩa trong một thư viện 10 riêng biệt. • Cuối cùng, trình liên kết hoàn tất mã đối tượng bằng cách liên kết nó với mã đối tượng của bất kỳ các module thư viện mà chương trình đã tham khảo tới. Ket quả cuối cùng là một tập tin thực thi. Hình 1.1 minh họa các bước trên cho cả hai trình chuyến đối C++ và trình biên dịch C++. Thực tế thì tất cả các bước trên được triệu gọi bởi một lệnh đơn (như là CQ và người dùng thậm chí sẽ không thấy các tập tin được phát ra ngay lập tức. Hình 1.1 Việc biên dịch C++ c++ C++ c c Program 17 ► TRANSLATOR ► Code V ► COMPILER C++ Program _J7 ► C++ NATIVE COMPILER 1.4. Biến Biến là một tên tượng trưng cho một vùng nhớ mà dữ liệu có thế được lưu trữ trên đó hay là được sử dụng lại. Các biến được sử dụng đế giữ các giá tri dữ liệu vì thế mà chúng có thế được dùng trong nhiều tính toán khác nhau trong một chương trình. Tất cả các biến có hai thuộc tính quan trọng: • Kiếu được thiết lập khi các biến được định nghĩa (ví dụ như: integer, real, character). Một khi đã được định nghĩa, kiểu của một biến C++ không thể được chuyển đổi. Chương 1: Mởđầu 4
  • 5. • Giá trị có thể được chuyến đối bằng cách gán một giá trị mới cho biến. Loại giá trị của biến có thể nhận phụ thuộc vào kiểu của nó. Ví dụ, một biến số nguyên chỉ có thể giữ các giá trị nguyên (chắng hạn, 2, 100, -12). Danh sách 1.2 minh họa sử dụng một vài biến đon giản. Danh sách 1.2 2 3 4 5 6 7 8 9 10 11 Chú giải 4 Hàng này định nghĩa một biến int (kiếu số nguyên) tên là workDays, biến này đại diện cho số ngày làm việc trong tuần. Theo như luật chung, trước tiên một biến được định nghĩa bàng cách chi định kiểu của nó, theo sau đó là tên biến và cuối cùng là được kết thúc bởi dấu chấm phấy. 5 Hàng này định nghĩa ba biến float (kiếu số thực) lần lượtthay cho số giờ làm việc trong ngày, số tiền phải trả hàng giờ, và số tiền phải trả hàng tuần. Như chúng ta thấy ở hàng này, nhiều biến của cùng kiếu có thế định nghĩa một lượt qua việc dùng dấu phấy đế ngăn cách chúng. 6 Hàng này là một câu lệnh gán. Nó gán giá trị 5 cho biến workDays. Vì thế, sau khi câu lệnh này được thực thi, workDays biểu thị giá trị 5. 7 Hàng này gán giá ứị 7.5 tới biến workHours. 8 Hàngnày gán giá trị 38.55 tới biến payRate. 9 Hàng này tính toán số tiền phải trá hàng tuần từ cácbiến workDays, workHours, và payRate (* là toán tử nhân). Giá trị kết quả được lưu vào biến weeklyPay. 10-12 Các hàng này xuất ba mục tuần tự là: chuồi "Weekly Pay = ", giá trị của biến weeklyPay, và một ký tự xuống dòng. Khi chạy, chương trình sẽ cho kết quả như sau: WeeklyPay= 1445.625 Khi một biến được định nghĩa, giá trị của nó không được định nghĩa cho đến khi nó được gán cho một giá trị thật sự. Ví dụ, weeklyPay có một giá trị không được định nghĩa cho đến khi hàng 9 được thực thi. Việc gán giá trị cho một biến ở lần đầu tiên được gọi là khỏi tạo. Việc chắc chắn rằng một #mdude<iostream.h> intmain(void) { int woikDays; float workHoure,payRate,weeklyPay; woikDays=5; workHours_ 7.5; payRate=38.55; weeklyPay=woikDays *workHours*payRate; cout« "WeeklyPay= " « weeklyPay«V; Chương 1: Mởđầu 5
  • 6. biến được khởi tạo tmớc khi 11Ó được sử dụng trong bất kỳ công việc tính toán nào là rất quan trọng. Một biến có thế được định nghĩa và khởi tạo cùng lúc. Điều này được xem như là một thói quen lập trình tốt bởi vì nó giành trước khả năng sử dụng biến trước khi nó được khởi tạo. Danh sách 1.3 là một phiên bản sửa lại của danh sách 1.2 mà có sử dụng kỹ thuật này. Trong mọi mục đích khác nhau thì hai chương trình là tương tương. Danh sách 1.3 1 2 3 4 5 6 7 8 9 10 11 1.5. Xuất/nhập đơn giản Cách chung nhất mà một chương trình giao tiếp với thế giới bên ngoài là thông qua các thao tác xuất nhập hướng ký tự đơn giản. C++ cung cấp hai toán tử hữu dụng cho mục đích này là » cho nhập và « cho xuất. Chúng ta đã thấy ví dụ của việc sử dụng toán tử xuất « rồi. Danh sách 1.4 sê minh họa thêm cho việc sử dụng toán tử nhập » . Danh sách 1.4 1 2 3 4 5 6 7 8 9 10 11 12 13 #inelude<iostream.h> intmain(void) { int woricDays=5; float workHours=7.5; float payRate,weeklyPay, cout« "Whatisthehourlypayrate? cin»payRate; weeklyPay=workDays *woricHours*payRate; cout« "WeeklyPay= cout« weeklyPay; cout«W; #include<iostream.h> intmain(void) { int woricDays=5; float workHours=7.5; float payRate=38.55; float weeklyPay=woikDays*workHours*payRate; cout« "WeeklyPay="; cout« weeklyPay; cout«n'; Chương 1: Mởđầu 6
  • 7. 7 Hàng này xuất ra lời nhắc nhở What is the hourly pay rate? để tìm dữ liệu nhập của người dùng. 8 Hàng này đọc giá trị nhập được gõ bởi người dùng và sao chép giá trị này tói biến payRatc. Toán tử nhập » lấy một dòng nhập như là toán hạng trái (cán là dòng nhập chuấn của C++ mà tương ứng với dữ liệu được nhập vào từ bàn phím) và một biến (mà dừ liệu nhập được sao chép tới) như là toán hạng phải. 9-13 Phần còn lại của chương trình là như trước. Khi chạy, chương trình sè xuất ra màn hình như sau (dữ liệu nhập của người dùng được in đậm); WhatLsthehourlypayrate?33.55 WeeklyPay= 1258.125 Cả hai « và » trả về toán hạng trái như là kết quá của chúng, cho phép nhiều thao tác nhập hay nhiều thao tác xuất được kết họp trong một câu lệnh. Điều này được minh họa trong danh sách 1.5 với trường hợp cho phép nhập cả số giờ làm việc mỗi ngày và số tiền phải trả mỗi giờ. Chú giải Danh sách 1.5 2 3 4 5 6 7 8 9 10 Chú giải 7 Hàng này đọc hai giá trị nhập được nliập vào từ người dùng và chép tương ứng chúng tới hai biến workHours và payRale. Hai giá trị cần được tách biệt bởi một không gian trống (chắng hạn, một hay là nhiều khoản trắng hay là các ký tự tab). Câu lệnh này tương đương với: (cin» workHours)» payRale; Vì kết quả của » là toán hạng trái, (cin»workHours) định giá cho cin mà sau đó được sử dụng như là toán hạng trái cho toán tử » kế tiếp. //include<iostream.h> intmain(void) { int wotfcDays=5; float workHouK,payRate,weeklyPay; cout« "Whataretheworkhoursandthehourlypayrate? cin» workHours» payRate; weeklyPay=workDays*workHours*payRate; cout« "WeeklyPay=" « weeklyPay« V; j_________________ _________ _________________ Chương 1: Mởđầu 7
  • 8. 9 Hàng xiày là kết quả của việc kết hợp từ hàng 10 đến hàng 12 trong danli sách 1.4. Nó xuất "Weekly Pay = ", theo sau đó là giá trị của biến weeklyPay, và cuối cùng là một ký tự xuống dòng. Câu lệnh này tương đương với: ((cout« 'WeeklyPay= " )« weeklyPay)« Vi'; Vì kết quả của « là toán hạng trái, (cout« "Weekly Pay = ") định giá cho cout mà sau đó được sử dụng như là toán hạng trái của toán tử « ké tiếp. Khi chạy, chương trình sẽ hiển thị như sau: Whataretheworkhoursandthehouriypayrate?75 33.55 WeeklyPay= 1258.125 1.6. Chú thích Chú thích thường là một đoạn văn bản. Nó được dùng đế giải thích một vài khía cạnh của chương trình. Trình biên dịch bở qua hoàn toàn các chú thích trong chương trình. Tuy nhiên các chú thích này là có ý nghĩa và đôi khi là rất quan trọng đối với người đọc (người xem các mã chương trình có sẵn) và người phát triển phần mềm. C++ cung cấp hai loại chú thích: • Những gì sau // (cho đến khi kết thúc hàng mà nó xuất hiện) được xem như là một chú thích. • Những gì đóng ngoặc trong cặp dấu ỉ* và */ được xem như là một chú thích. Danh sách 1.6 minh họa việc sử dụng cả hai hình thức này. Danh sách 1.6 2 3 4 5 6 7 8 9 10 11 12 13 Các chú thích nên được sử dụng đế tăng cường (không phải gây trở ngại) việc đọc một chương trình. Một vài điếm sau nên được chú ý: #inđude<iostream.h> /*Chuongtrinhnaytinhtoantongsotienphaiteahangtuanchomotcongnhanđuatrentongsogio lamviecvasotienphaitramoigió. */ intmain(void) { int workDays=5; //songay lamviectrongtuan float workHours=7.5; //sogiolamviectrongngay float payRate=33.50; //sotienphaitramoigio float weeklyPay, //tongsotienphaitramoituan weeklyPay=workDays*workHours*payRate; cout<<"WeeklyPay- "« weeklyPay<<V; } Chương 1: Mởđầu 8
  • 9. • Chú thích nên dễ đọc và dỗ hiếu hơn sự giải thícli thông qua mã chương trình. Thà là không có chú thích nào còn hơn có một chú thích phức tạp dễ gây lầm lẫn một cách không cần thiết. • Sử dụng quá nhiều chú thích có thế dẫn đến khó đọc. Một chương trình chứa quá nhiều chú thích làm bạn khó có thể thấy mã thì không thể nào được xem như là một chương trình dỗ đọc và dỗ hiếu. • Việc sử dụng các tên mô tả có ý nghĩa cho các biến và các thực thế khác trong chương trình, và những chỗ thụt vào của mã có thế làm giảm đi việc sử dụng chú thích một cách đáng kế, và cũng giúp cho lập trình viên dỗ đọc và kiếm soát chương trình. 1.7. Bộ nhớ Máy tính sử dụng bộ nhớ truy xuất ngấu nhiên (RAM) để lưu trữ mã chương trình thực thi và dữ liệu mà chương trình thực hiện. Bộ nhớ này có thể được xem như là một chuồi tuần tự các bit nhị phân (0 hoặc 1). Thông thường, bộ nhớ được chia thành những nhóm 8 bit liên tiếp (gọi là byte). Các byte được định vị liên tục. Vì thế mồi byte có thế được chỉ định duv nhất bởi địa chỉ (xem Hình 1.2). Hình 1.2 Các bit và các byte trong bộ nhó- Byte Address 1211 1212 1213 ▼ 1214 1215 1216 1217 Byte Byte Byte Byte Byte Byte Byte 1 1 0 1 0 0 0 1 Ẳ Bit Trình biên dịch C++ phát ra mã có thể thực thi mà sắp xếp các thực thể dữ liệu tới các vị trí bộ nhớ. Ví dụ, định nghĩa biến int salary=65000; làm cho trình biên dịch cấp phát một vài byte cho biến salary. So byte cần được cấp phát và phương thức được sử dụng cho việc biếu diễn nhị phân của số nguyên phụ thuộc vào sự thi hành cụ thể của C++. Trình biên dịch sử dụng địa chỉ của byte đầu tiên của biến salary được cấp phát đế tham khảo tới nó. Việc gán trên làm cho giá trị 65000 được lưu trữ như là một số nguyên bù hai trong hai byte được cấp phát (xem Hình 1.3). Hình 1.3 Biểu diễn của một số nguyên trong bộ nhó'. Chương 1: Mởđầu 9
  • 10. 1211 1212 1213 1214 1215 1216 1217 Byte Byte Byte 10110011 10110011 Byte Byte salary một số nguyên 2 byte ở địa chỉ 1214 Trong khi việc biếu diễn nhị phân chính xác của một hạng mục dữ liệu là ít khi được các lập trình viên quan tâm tới thì việc tố chức chung của bộ nhớ và sử dụng các địa chỉ đế tham khảo tới các hạng mục dừ liệu là rất quan trọng. 1.8. Số nguyên Biến số nguyên có thể được định nghĩa là kiểu short, int, hay long. Chỉ khác nhau là số int sử dụng nhiều hơn hoặc ít nhất bằng so byte như là một so short, và một số long sử dụng nhiều hơn hoặc ít nhất cùng số bytc với một so int. Ví dụ, trên máy tính cá nhân thì một so short sử dụng 2 byte, một sổ int cũng 2 bytc, và một số longlà 4 byte. short age=20; int salary=65000; long price=4500000; Mặc định, một biến số nguyên được giả sử là có dấu (chắng hạn, có một sự biếu diễn dấu để mà nó có thể biếu diễn các giá trị dương cũng như là các giá trị âm). Tuy nhiên, một sổ nguyên có thể được định nghĩa là không có dấu bằng cách sử dụng tò khóa unsigned trong định nghĩa của nó. Từ khóa signed cũng được cho phép nhưng hơi dư thừa. unsignedshort age=20; unsignedint salary=65000; unsignedlong price=4500000; Số nguyên (ví dụ, 1984) luôn luôn được giả sử là kiểu int,trừ khicó một hậu tố L hoặc 1thì nó được hiểu là kiểu long. Một số nguyêncũngcó thểđược đặc tả sử dụng hậu tố là u hoặc u., ví dụ: 1984L 19841 1984U 1984u 1984LU 1984ul 1.9. Số thưc Biến số thực có thể được định nghĩa là kiểu float hay double. Kiểu double sử dụng nhiều byte hơn và vì thế cho miền lớn hơn và chính xác hơn để biểu diễn các số thực. Ví dụ, trên các máy tính cá nhân một so float sử dụng 4 byte và một so double sử dụng 8 byte. Chương 1: Mởđầu 10
  • 11. float interestRate=0.06; double pi=3.141592654; Số thực (ví dụ, 0.06) luôn luôn được giả sử là kiểu double, trừ phi có một hậu tố F hay f thì nó được hiểu là kiếu float, hoặc một hậu tố L hay 1thì nó được hiểu là kiểu long double. Kiểu long double sử dụng nhiều byte hom kiểu double cho độ chính xác tốt hơn (ví dụ, 10 byte trên các máy PC). Ví dụ: 0.06F 0.06f3.141592654L 3.1415926541 Các số thực cũng có thế được biếu diễn theo cách ký hiệu hóa khoa học. Ví dụ, 0.002164 có thế được viết theo cách kỷ hiệu hóa khoa học như sau: 2.164E-3 or 2.164e-3 Ký tự E (hay e) thay cho số mũ (exponent). Cách ký hiệu hóa khoa học được thông dịch như sau: 2.164E-3=2.164 X10r3= 0.002164 l.lO.Ký tự Biến ký tự được định nghĩa là kiểu char. Một biến ký tự chiếm một byte đơn đế lưu giữ mã cho kỷ tự. Mã này là một giá trị số và phụ thuộc hệ thong mã ký tự đang được dùng (nghĩa là phụ thuộc máy). Hệ thống chung nhất là ASCII (American Standard Code for Information Interchange). Ví dụ, ký tự A có mã ASCII là 65, và ký tự a có mã ASCII là 97. char ch='A'; Giống như số nguyên, biến kỷ tự có thế được chì định là có dấu hoặc không dấu. Mặc định (trong hầu hết các hệ thống) char nghĩa là signed char. Tuy nhiên, trên vài hệ thống thì nó có nghĩa là unsigned char. Biến kỷ tự có dấu có thế giữ giá trị số trong miền giá trị từ -128 tới 127. Biến ký tự không dấu có thể giữ giá trị số trong miền giá trị từ 0 tớ 255. Ket quả là, cả hai thường được dùng để biểu diễn các số nguyên nhỏ trong chương trình (và có thế được đánh dấu các giá trị số như là số nguyên): signed char offset=-88; unsignedchar row=2, column=26; Ký tự được viết bằng cách đóng dấu ký tự giữa cặp nháy đơn (ví dụ, 'A'). Các ký tự mà không thể in ra được biểu diễn bằng việc sử dụng các mã escape. Ví dụ: 'n' // xuống hàng mới V // phím xuống dòng Chương 1: Mởđầu
  • 12. 't' // phím tab ngang 'v' // phím tab dọc 'b' //phím lùi Các dấu nháy đơn, nháy đôi và ký tự gạch chéo ngược cũng có thể sử dụng ký hiệu escape: 'V' // trích dẫn đơn (') 'V" // trích dẫn đôi (") 'Y // dấu vạch chéo ngược () Ký tự cũng có thể được chỉ định rõ sử dụng giá trị mã số của chúng. Mã escape tống quát ooo (nghĩa là, 3 ký tự số cơ số 8 theo sau một dấu gạch chéo ngược) được sử dụng cho mục đích này. Ví dụ (giả sử ASCII): '12' // hàng mới (mã thập phân =10) M I' // tab ngang (mã thập phân = 9) MOI' // 'A' (mã thập phân = 65) '0' // rồng (mã thập phân = 0) l.ll.ChuSỉ Chuồi là một dãy liên tiếp các ký tự được kết thúc bằng một ký tự null. Biến chuỗi được định nghĩa kiểu char* (nghĩa là, con trỏ ký tự). Con trỏ đon giản chỉ là một vị trí trong bộ nhớ. (Các con trỏ sẽ được thảo luận trong chương 5). Vì thế biến chuỗi chứa đựng địa chỉ của ký tự đầu tiên trong chuồi. Ví dụ, xem xét định nghĩa: char *str="HELLO"; Hình 1.4 minh họa biến chuồi và chuồi "HELLO" có thể xuất hiện như thế nào trong bộ nhớ. Hình 1.4 Chuỗi và biến chuỗi trong bộ nhó' 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1212 ị 'H' 'E' 'L' 'L' 'O' •V0' str Chuỗi được viết bằng cách đóng ngoặc các ký tự của nó bên trong cặp dấu nháy kép (ví dụ, "HELLO"). Trình biên dịch luôn luôn thêm vào một ký tự null tới một hằng chuồi để đánh dấu điếm kết thúc. Các ký tự chuồi có thế được đặc tả sử dụng bất kỳ ký hiệu nào dùng đế đặc tả các ký tự. Ví dụ: "NametAddress'íTelephone'' //cáctừphâncách "ASCÍI character65:101" //'A'đuọcđặctảnhư'10r Chương 1: Mởđầu 12
  • 13. Chuỗi dài có thế nới rộng qua khỏi một hàng đơn, trong trường hợp này thì mồi hàng trước phải được kết thúc bằng một dấu vạch chéo ngược. Ví dụ: "Exampletoshow theuseofbackslashfor writingalongstring" Dấu trong ngữ cảnh này có nghĩa là phần còn lại của chuỗi được tiếp tục trên hàng kế tiếp. Chuỗi trên tương đương vói chuỗi được viết trên hàng đơn như sau: "Exampletoshowtheuseofbackslashforwritingalongstring" Một lồi lập trình chung thường xảy ra là lập trình viên thường nhầm lẫn một chuỗi ký tự đơn (ví dụ, "A") với một ký tự đơn (ví dụ, 'Ả'). Hai điều này là không tương đương. Chuỗi ký tự đơn gồm 2 byte (ký tự 'A' được theo sau là ký tự ơ),trong khi ký tự đơn gồm chỉ một byte duy nhất. Chuồi ngắn nhất có thế có là chuồi rỗng ("") chỉ chứa ký tự null. 1.12.Tên Ngôn ngữ lập trình sử dụng tên đề tham khảo tới các thực thế khác nhau dùng để tạo ra chương trình. Chúng ta cũng đã thấy các ví dụ của một loại các tên (nghĩa là tên biến) như thế. Các loại khác gồm: tên hàm, tên kiếu, và tên macro. Sử dụng tên rất tiện lợi cho việc lập trình, nó cho phép lập trình viên tổ chức dữ liệu theo cách thức mà con người có thể hiểu được. Tên không được đưa vào mã có thể thực thi được tạo ra bởi trình biên dịch. Ví dụ, một biến temperature cuối cùng trở thành một vài byte bộ nhớ mà được tham khảo tới bởi các mã có thế thực thi thông qua địa chỉ của nó (không thông qua tên của nó). C++ áp đặt những luật sau đế xây dựng các tên hợp lệ (cũng được gọi là các định danh). Một tên chứa một hay nhiều ký tự, mồi ký tự có thể là một chữ cái (nghĩa là, 'A'-'Z' và 'a'-'z'), một số (nghĩa là, '0'-'9'), hoặc một ký tự gạch dưới ngoại trừ ký tự đầu tiên không thề là một số. Các ký tự viết hoa và viết thường là khác nhau.Ví dụ: salary //địnhdanhhọplệ salaiy2 //địnhdanhhọplệ Zsalary //địnhdanhkhônghọplệ(bắtđàuvới mộtsố) _salary //địnhdanhhọplệ Salary //họplệnhungkhácvói salary Chương 1: Mởđầu 13
  • 14. c++ kliông có giới hạn số ký tự của một định danh. Tuy nhiên, hầu hết thi công lại áp đặt sự giới hạn này nhưng thường đủ lớn đế không gây bận tâm cho các lập trình viên (ví dụ 255 ký tự). Một số từ được giữ bởi c++ cho một số mục đích riêng và không thế được dùng cho các định danh. Những từ này được gọi là từ khóa (keyword) và được tổng kết trong bảng 1.3: Bảng 1.3 Các từ khóa c++. asm continue float new signed try auto default for operator sizeof typedef break delete friend private static union case do goto protected struct unsigned catch double if public switch virtual char else inline register template void class enum int return this volatile const extern long short throw while Bài tập cuối chương 1 1.1 Viết chương trình cho phép nhập vào một số đo nhiệt độ theo độ Fahrenheit và xuất ra nhiệt độ tương đương cúa nó theo độ Celsius, sứ dụng công thức chuyến đổi: ° C = - ( ° F - 32) 9 Biên dịch và chạy chương trình. Việc thực hiện của nó giống như thế này: Nhiet do theo do Fahrenheit: 41 41 do Fahrenheit=5 do Celsius 1.2 Hàng nào trong các hàng sau biếu diễn việc định nghĩa biến là không hợp lệ? int n=-100; unsigned inti—-100; signed int=2.9; longm=2,p=4; mt 2k; doublex = 2 *m; floaty=y *2; unsigned doublez =0.0; doubled=0.67F; float Í-0.52L; signed char=-1786; charc = '$'+2; sign charh=M il'; Chương 1: Mởđầu 14
  • 15. char *name= "PeterPan''; unsigned char *num= "276811"; 1.3 Các định danh nào sau đây là không hợp lệ? identifier scvcn_l 1 _uniqụe_ gross-incomc gross$income 2by2 default avcragc_wcight_of_a_largc_pizza variable object-oriented 1.4 Định nghĩa các biến để biếu diễn các mục sau đây: • Tuổi của một người. • Thu nhập của một nhân viên. • Số từ trong một từ điển. • Một ký tự alphabet. • Một thông điệp chúc mừng. Chương 1: Mởđầu 15
  • 16. Chương 2. Biểu thức Chương này giới thiệu các toán tử xây dựng sẵn cho việc soạn thảo các biểu thức. Một biểu thức là bất kỳ sự tính toán nào mà cho ra một giá trị. Khi thảo luận về các biểu thức, chúng ta thường sử dụng thuật ngữ ước lượng. Ví dụ, chúng ta nói rằng một biểu thức ước lượng một giá trị nào đó. Thường thì giá trị sau cùng chỉ là lỵ do cho việc ước lượng biếu thức. Tuy nhiên, trong một vài trường hợp, biểu thức cũng có thế cho các kết quả phụ. Các kết quả này là sự thay đối lâu dài trong trạng thái của chương trình. Trong trường hợp này, các biếu thức c++thì khác với các biếu thức toán học. C++ cung cấp các toán tử cho việc soạn thảo các biểu thức toán học, quan hệ, luận lý, trên bit, và điều kiện. Nó cũng cung cấp các toán tử cho ra các kết quả phụ hữu dụng như là gán, tăng, và giảm. Chúng ta sẽ xem xét lần lượt từng loại toán tử. Chúng ta cũng sẽ thảo luận về các luật ưu tiên mà ảnh hưởng đến thứ tự ước lượng của các toán tử trong một biếu thức có nhiều toán tứ. 2.1. Toán tử toán hoc c++ cung cấp 5 toán tử toán học cơ bản. Chúng được tổng kết trong Bảng 2.1. Bảng 2.1 Các toán tử toán học. Toán tử Tên Ví dụ + Cộng 12+4.9 //cho 16.9 - Trừ 3.98-4 //cho-0.02 * Nhân 2*3.4 //cho 6.8 / Chia 9/2.0 //cho 4.5 % Lấy phần dư 13% 3 //choi Ngoại trừ toán tử lấy phần dư (%) thì tất cả các toán tử toán học có thế chấp nhận pha trộn các toán hạng số nguyên và toán hạng số thực. Thông thường, nếu cả hai toán hạng là số nguyên sau đó kết quả sẽ là một số Chương 2: Biểu thức 17
  • 17. nguyên. Tuy nhiên, một hoặc cả hai toán hạng là số thực thì sau đó kết quả sẽ là một số thực (real hay double). Khi cả hai toán hạng của toán tử chia là số nguyên thì sau đó phép chia được thực hiện như là một phép chia số nguyên và không phải là phép chia thông thường mà chúng ta sử dụng. Phép chia số nguyên luôn cho kết quả nguyên (có nghĩa là luôn được làm tròn). Ví dụ: 9 /2 //được 4, khôngphải là4.5! -9/2 //được -5, khôngphải là-4! Các phép chia số nguyên không xác định thường là các lỗi lập trình chun«. Đế thu được một phép chia số thực khi cả hai toán hạng là số nguyên, bạn cần ép một trong hai số nguyên về số thực: int cost=100; int volume=80; double unitPrice= cost/ (double)volume; //được 1.25 Toán tử lấy phần dư (%) yêu cầu cả hai toán hạng là số nguyên. Nó trả về phần dư còn lại của phép chia. Ví dụ 13%3 được tính toán bằng cách chia số nguyên 13 đi 3 đế được 4 và phần dư là 1; vì thế kết quả là 1. Có thế có trường hợp một kết quả của một phép toán toán học quá lớn đế lưu trữ trong một biến nào đó. Trường hợp này được gọi là tràn. Hậu quả của tràn là phụ thuộc vào máy vì thế nó không được định nghĩa.Ví dụ: uâsignedchar k=10*92; //tràn: 920 >255 Chia một số cho 0 là hoàn toàn không đúng luật. Ket quả của phép chia này là một lỗi run-time gọi là lỗi division-by-zero thường làm cho chương trình kết thúc. 2.2. Toán tử quan hệ c++cung cấp 6 toán tử quan hệ để so sánh các số. Các toán tử này được tống kết trong Bảng 2.2. Các toán từ quan hệ ước lượng về 1 (thay cho kết quả đúng) hoặc 0 (thay cho kết quả sai). Bảng 2.2 Các toán tử quan hệ. Toán tử Tên Ví du = So sánh băng 5 = 5 //choi Ị= So sánh không băng 5!=5 //choO < So sánh hỏ hơn 5<5.5 //choi <= So sánh hỏ hơn hoặc băng 5<=5 //choi > So sánh lớn hơn 5 >5.5 // cho 0 >= So sánh lớn hơn hoặc băng 6.3>=5 //choi Chương 2: Biểu thức 18
  • 18. Chú ý rằng các toán tử <= và >= chỉ được hỗ trợ trong hình tliức hiển thị. Nói riêng cả hai =< và => đều không hợp lệ và không mang ý nghĩa gì cả. Các toán hạng của một toán tử quan hệ phải ước lượng về một số. Các ký tự là các toán hạng hợp lệ vì chúng được đại diện bởi các giá trị số. Ví dụ (giả sử mã ASCII): 'A '< F //đưọc 1(giống như là 65 <70) Các toán tử quan hệ không nên được dùng đế so sánh chuồi bởi vì điều này sẽ dẫn đến các địa chỉ của chuồi được so sánh chứ không phải là nội dung chuồi. Ví dụ, biếu thức "HELLO"<"BYE" làm cho địa chỉ của chuồi "HELLO" được so sánh với địa chi của chuỗi "BYE". Vì các địa chỉ này được xác định bởi trình biên dịch, kết quả có thế là 0 hoặc có thể là 1, cho nên chúng ta có thế nói kếtquả là không được địnhnghĩa. C++ cung cấp các thư viện hàm (vídụ, strcmp) để thựchiện so sánh chuồi. 2.3. Toán tử luận lý C++ cung cấp ba toán tử luận lý cho việc kết nối các biếu thức luận lý. Các toán tử này được tổng kết trong Bảng 2.3. Giống như các toán tử quan hệ, các toán tử luận lý ước lượng tới 0 hoặc 1. Bảng 2.3 Các toán tử luận lý. Toán tử Tên Ví du Ị Phủ định luận lý 1(5 — 5) // được 0 && Và luận lý 5 < 6 && 6 < 6 // được 0 II Hoặc luận lý 5 < 6 II 6 < 5 // được 1 Phủ định luận lỷ là một toán tử đơn hạng chỉ phủ định giá trị luận lý toán hạng đon của nó. Neu toán hạng của nó không là 0 thì được 0, và nếu nó là không thì được 1. Và luận lý cho kết quả 0 nếu một hay cả hai toán hạng của nó ước lượng tới 0. Ngược lại, nó cho kết quả 1. Hoặc luận lý cho kết qua 0 nếu cả hai toán hạng của nó ước lượng tới 0. Ngược lại, nó cho kết quả 1. Chú ý rằng ở đây chúng ta nói các toán hạng là 0 và khác 0. Nói chung, bất kỳ giá trị không là 0 nào có thể được dùng đế đại diện cho đúng (true), trong khi chi có giá trị 0 là đại diện cho sai (false). Tuy nhiên, tất cả các hàng sau đây là các biểu thức luận lý họp lệ: Chương 2: Biểu thức 19
  • 19. !20 //đượcO 10 && 5 //đuợcl 10II5.5 //đuọc 1 10&&0 //đượcO C++ không có kiểu boolean xây dựng sẵn. Vì lẽ đó mà ta có thế sử dụng kiếu int cho mục đích này. Ví dụ: int sorted=0; //false int balanced = 1; //true 2.4. Toán tử trên bit C++ cung cấp 6 toán tử trên bit đe điều khiển các bit riêng lẻ trong một số lượng số nguyên. Chúng được tống kết trong Bảng 2.4. Bảng 2.4 Các toán tử trên bit. Toán tử Tên Ví du ~ Phủ định bit ~011' //đuocMÚS & Và bit w & 0 2 7 //đ ư ợ c W Hoặc bit W IN 0 2 7 //đươc 02>T A Hoặc exclusive bit W A027 //được ‘036’ « Dịch trái bit w « 2 //đươc ‘044’ » Dịch phải bit N 011'»2 //đưoc ’002' Các toán tử trên bit mong đợi các toán hạng của chúng là các số nguyên và xem chúng như là một chuồi các bit. Phủ định bit là một toán tử đon hạng thực hiện đảo các bit trong toán hạng của nó. Và bit so sánh các bit tương ứng của các toán hạng của nó và cho kết quả là 1 khi cả hai bit là 1, ngược lại là 0. Hoặc bit so sánh các bit tương ứng của các toán hạng của nó và cho kết quả là 0 khi cả hai bit là 0, ngược lại là 1. XOR bit so sánh các bit tương ứng của các toán hạng của nó và cho kết quả 0 khi cả hai bit là 1 hoặc cả hai bit là 0, ngược lại là 1. Cả hai toán tử dịch trái bit và dịch phải bit lấy một chuỗi bit làm toán hạng trái của chúng và một số nguyên dương n làm toán hạng phải. Toán tử dịch trái cho kết quả là một chuỗi bit sau khi thực hiện dịch n bit trong chuồi bit của toán hạng trái về phía trái. Toán tử dịch phải cho kết quả là một chuỗi bit sau khi thực hiện dịch n bit trong chuỗi bit của toán hạng trái về phía phải. Các bit trống sau khi dịch được đặt tới 0. Bảng 2.5 minh họa chuỗi các bit cho các toán hạng ví dụ và kết quả trong Bảng 2.4. Đế tránh lo lắng về bit dấu (điều này phụ thuộc vào máy) thường thì khai báo chuồi bit như là một số không dấu: unsigned charx=l01 ĩ; unsigned chary=*'027; Chương 2: Biểu thức 20
  • 20. Bảng 2.5 Các bít đưọc tính toán như thế nào. Ví dụ Giá tri cơ số 8 Chuỗi bit X 011 0 0 0 0 1 0 0 1 y 027 0 0 0 I 0 1 1 1 ~x 366 1 1 1 1 0 1 1 0 x & y 001 0 0 0 0 0 0 0 1 X y 037 0 0 0 I 1 1 1 1 x A y 036 0 0 0 1 1 1 1 0 x « 2 044 0 0 1 0 0 1 0 0 x » 2 002 0 0 0 0 0 0 1 0 2.5. Toán tử tăng/giảm Các toán tử tăng một (++) và giảm một (--) cung cấp các tiện lợi tương ứng cho việc cộng thêm 1 vào một biến số hay trừ đi 1 từ một biến số. Các toán tử này được tổng kết trong Bảng 2.6. Các ví dụ giả sử đã định nghĩa biến sau: int k=5; Bảng 2.6 Các toán tử tăng và giảm. Toán tử Tên Ví du ++ Tăng một (tiên tô) -H-k+10 //đươc 16 ++ Tăng một (hậu tô) k+ + + 10 //đươc 15 — Giảm một (tiên tô) -k + 1 0 //đươc 14 — Giảm một (hậu tô) k -+ 1 0 //được 15 Cả hai toán tử có thể được sử dụng theo hình thức tiền tố hay hậu tố là hoàn toàn khác nhau. Khi được sử dụng theo hình thức tiền tố thì toán tò được áp dụng trước và kết quả sau đó được sử dụng trong biểu thức. Khi được sử dụng theo hình thức hậu tố thì biểu thức được ước lượng trước và sau đó toán tô được áp dụng. Cả hai toán tử có thế được áp dụng cho biến nguyên cũng như là biến thực mặc dù trong thực tế thì các biến thực hiếm khi được dùng theo hình thức này. 2.6. Toán tử khởi taoể Toán tử khởi tạo được sử dụng để lưu trữ một biến. Toán hạng trái nên là một giá trị trái và toán hạng phải có thế là một biếu thức bất kỳ. Biểu thức được ước lượng và kết quả được lưu trữ trong vị trí được chi định bởi giá trị trái. Giá trị trái là bất kỳ thứ gì chi định rõ vị trí bộ nhớ lưu trừ một giá trị. Chỉ một loại của giá trị trái mà chúng ta được biết cho đến thời điếm này là Chương 2: Biểu thức 21
  • 21. biến. Các loại khác của giá trị trái (dựa trên con trỏ và tham chiếu) sẽ được thảo luận sau. Toán tử khởi tạo có một số biến thế thu được bằng cách kết nối nó với các toán tử toán học và các toán tử trên bit. Chúng được tống kết trong Bảng 2.7. Các ví dụ giả sử rằng n là một biến số nguyên. Bảng 2.7 Các toán tử khỏi tạo. Toán tử Ví du Tương đương vói = n=25 += n+=25 n = n +25 - n-=25 n = n -2 5 *_ 11*=25 n= n*25 /= n/=25 n = n/25 %= n% =25 n= n% 25 &= n&=0xF2F2 n=n&QxF2F2 nỊ=0xF2F2 n=n|QxF2F2 Ạ= nA=0xF2F2 n = n AQxF2F2 « = n « = 4 n = n « 4 » = n » = 4 n = n » 4 Phép toán khởi tạo chính nó là một biểu thức mà giá trị của nó là giá trị được lưu trong toán hạng trái của nó. Vì thế một phép toán khởi tạo có thế được sử dụng như là toán hạng phải của một phép toán khởi tạo khác. Bất kỳ số lượng khởi tạo nào có thề được kết nối theo cách này đế hình thành một biểu thức. Ví dụ: intm,ạp; m=n=p=100; //nghĩalà:n=(m=(p= 100)); m=(n=p=100)+2; //nghĩalà:m=(n=(p = 100))+2; Việc này có thể ứng dụng tương tự cho các hình thức khởi tạo khác. Ví dụ: m=100; m-H=n=p=10; //nghĩalà:m=m+(n=p=10); 2.7. Toán tử điều kiện Toán tứ điều kiện yêu cầu 3 toán hạng. Hình thức chung cúa nó là: toán hạng 1 ? toán hạng 2 :toán hạng 3 Toán hạng đầu tiên được ước lượng và được xem như là một điều kiện. Neu kết quả không là 0 thìtoán hạng 2 được ước lượng và giá trị của nó là kết quả sau cùng. Ngược lại, toán hạng 3 được ước lượng và giá trị của nó là kết quả sau cùng. Ví dụ: Chương 2: Biểu thức 22
  • 22. intm —l,n —2; intmin=(m<n?m:n); //minnhậngiátrị 1 Chú ý rằng trong các toán hạng thứ 2 và toán hạng thứ 3 của toán tử điều kiện thì chỉ có một toán hạng được thực hiện. Điều này là quan trọng khi một hoặc cả hai chứa hiệu ứng phụ (nghĩa là, việc ước lượng của chúng làm chuyển đổi giá trị của biến). Ví dụ, với m=l và n=2 thì trong intmin= (m < n ? nrrH-:n-H-); m được tăng lên bởi vì m-H- được ước lượng nhưng n không tăng vì n-H- không được ước lượng. Bởi vì chính phép toán điều kiện cũng là một biểu thức nên nó có thể được sử dụng như một toán hạng của phép toán điều kiện khác, có nghĩa là các biếu thức điều kiện có thế được lồng nhau. Ví dụ: intm=l,n=2,p=3; intmin=(m<n ?(m<p?m:p) :(n<p?n:p)); 2.8. Toán tử phẩy Nhiều biểu thức có thế được kết nối vào cùng một biểu thức sử dụng toán tử phẩy. Toán tử phấy yêu cầu 2 toán hạng. Đầu tiên nó ước lượng toán hạng trái sau đó là toán hạng phải, và trả về giá trị của toán hạng phải như là kết quả sau cùng. Ví dụ: intm=l,n=2,min; intmCount=0, nCount=0; //... min=(m<n?mCount-H-,m :nCount++, n); Ớ đây khi m nhỏ hon n, mCount-H- được ước lượng và giá trị của m được lưu ừong min. Ngược lại, nCount-H- được ước lượng và giá trị của n được lưu trong min. 2.9. Toán tử lấy kích thước C++ cung cấp toán tử hữu dụng, sizeof, để tính toán kích thước của bất kỳ hạng mục dữ liệu hay kiểu dữ liệu nào. Nó yêu cầu một toán hạng duy nhất có thế là tên kiểu (ví dụ, int) hay một biếu thức (ví dụ, 100) và trả về kích thước của những thực thể đã chỉ định theo byte. Ket quả hoàn toàn phụ thuộc vào máy. Danh sách 2.1 minh họa việc sử dụng toán từ sizeof cho các kiểu có sẵn mà chúng ta đã gặp cho đến thời điểm này. Chương 2: Biểu thức 23
  • 23. Danh sách 2.1 2 3 4 5 6 7 8 9 10 11 12 13 14 Khi chạy, chương trình sẽ cho kết quả sau (trên máy tính cá nhân): char size= 1bytes char* size=2 bytes short size=2 bytes int size=2 bytes long size= 4 bytes float size=4bytes double size=8 bytes 1.55 size=8 bytes 1.55L size=10 bytes HELLO size= 6 bytes 2.10.ĐÔ ưu tiên của các toán tử Thứ tự mà các toán tử được ước lượng trong một biếu thức là rất quan trọng và được xác định theo các luật ưu tiên. Các luật này chia các toán tử C++ ra thành một số mức độ ưu tiên (xem Bảng 2.8). Các toán tử ở mức cao hơn sẽ có độ ưu tiên cao hơn các toán tử có độ ưu tiên thấp hơn. Bảng 2.8 Độ ưu tiên của các toán tử. Mức Toán tử Loai Thứ tư Cao nhât Đơn hạng Cà hai 1 n -> Nhị hạng Trái tới phải + ++ Ị * & new sizeof delete 0 Đơn hạng Phải tới trái ->* * Nhị hạng Trái tới phải * / % Nhị hạng Trái tới phải + - Nhị hạng Trái tới phải « » Nhị hạng Trái tới phải < <= > >= Nhị hạng Trái tới phải = Ị= Nhị hạng Trái tới phải & Nhị hạng Trái tới phải #indude<iostneamii> intmain(void) { cout«"char size="«sizeof(char)«"bytesn"; cout«"char* size= " « sizeoflchar*)« " bytes'-n"; cout« "short size= " « sizeof(short)« " bytesn"; cout« "int size= " « sizeof(int)« " bytesn"; cout« "long size= " « sizeofflong)« " bytesn"; cout« "float size=" « sizeof(float)« "bytesn"; cout« "double size= " « sizeoffdouble)« " bytesn"; cout« "1.55 size= " « sizeof(1.55)« " bytesn"; cout« "1.55L size= " « sizeof(1.55L)« " bytesn"; cout« "HELLO size=" « sizeof("HELLO")« " bytesn"; i _____________________________________________________ Chương 2: Biểu thức
  • 24. A Nhị hạng Trái tới phải 1 Nhị hạng Trái tới phải && Nhị hạng Trái tới phải II Nhị hạng Trái tới phải ? ; Tam hạng Trái tới phải = += *= /s= &= « = -= /= %= 1= » = Nhị hạng Phải tới trái Thấp nhất ? Nhị hạng Trái tới phải Ví dụ, trong biểu thức a= b + c * d c * d được ước lượng trước bởi vì toán tử * có độ ưu tiên cao hơn toán từ + và = . Sau đó kết quả được cộng tới b bởi vì toán tử + có độ ưu tiên cao hơn toán tử = , và sau đó = được ước lượng. Các luật ưu tiên có thế được cho quyền cao hơn thông qua việc sử dụng các dấu ngoặc. Ví dụ, viết lại biếu thức trên như sau a=(b+c)*d sẽ làm cho toán tử + được ước lượng trước toán tử *. Các toán tử với cùng mức độ ưu tiên được ước lượng theo thứ tự được ước lượng trong cột cuối cùng trong Bảng 2.8. Ví dụ, trong biểu thức a= b+ = c thứ tự ước lượng là từ phải sang trái, vì thế b+=c được ước lượng trước và kế đó là a=b. 2.11.Chuyển kiểu đơn giản Một giá trị thuộc về những kiểu xây dựng sẵn mà chúng ta biết đến thời điếm này đều có thể được chuyển về bất kỳ một kiếu nào khác. Ví dụ: (int) 3.14 //chuyện 3.14 sang intđể đưọc 3 (long) 3.14 //chự/ện 3.14 sang longđể Ãiạc 3L (double) 2 // chuyên 2 sang double đê đuọc 2.0 (char) 122 // chuyên 122 sang charcó mã là 122 (unsigned short) 3.14 //được 3 như làmộtunsigned short Như đã được trình bày trong các ví dụ, các định danh kiếu xây dụng sẵn có thể được sử dụng như các toán tử kiếu. Các toán tò kiểu là đơn hạng (nghĩa là chỉ có một toán hạng) và xuất hiện bên trong các dấu ngoặc về bên trái toán hạng của chúng. Điêu này được gọi là chuyển kiểu tường minh. Khi tên kiểu chỉ là một từ thì có thế đặt dấu ngoặc xung quanh toán hạng: int(3.14) //nhưlà:(int)3.14 Chương 2: Biểu thức 25
  • 25. Trong một vài trường hợp, C++ cũng thực hiện chuyển kiểu không tường minh. Điều này xảy ra khi các giá trị của các kiểu khác nhau được trộn lẫn trong một biếu thức. Ví dụ: double d= 1; //dnhậnl.o int 1=10.5; // i nhận 10 i= i+ d ; //nghĩa là: i=int(double(i)+d) Trong ví dụ cuối , i + d bao hàm các kiểu không họp nhau, vì thế trước tiên i được chuyển thành double (thăng cấp) và sau đó được cộng vào d. Ket quả là double không hợp kiếu với i trên phía trái của phép gán, vì thế nó được chuyển thành int {hạ cấp) trước khi được gán cho i. Luật trên đại diện cho một vài trường hợp chung đơn giản để chuyến kiểu. Các trường hợp phức tạp hơn sẽ được trình bày ở phần sau của giáo trình sau khi chúng ta thảo luận các kiểu dữ liệu khác. Bài tập cuối chương 2 2.1 Viết các biểu thức sau đây: • Kiếm tra một số n là chằn hay không. • Kiếm tra một ký tự c là một số hay không. • Kiếm tra một ký tự c là một mẫu tự hay không. • Thực hiện kiếm tra: n là lẽ và dương hoặc n chẵn và âm. • Đặt lại k bit của một sổ nguyên n tới 0. • Đặt k bit của một số nguyên «tới 1. • Cho giá trị tuyệt đối của một số n. • Cho số ký tự trong một chuồi s được kết thúc bởi ký tự null. 2.2 Thêm các dấu ngoặc phụ vào các biếu thức sau để hiển thị rõ ràngthứ tự các toán tô được ước lượng: (n <= p + q && n >= p - q II n = 0) (++n*q-/-Hp-q) (n|p&qAp<<2+q) (p<q?n<p?q*n-2:q/n+l :q-n) 2.3 Cho biết giá trị của mồi biến sau đây sau khi khởi tạo nó: double d=2 *int(3.14); long k=3.14-3; chàr c='a'+2; char c=lp'+'Á'-'a'; 2.4 Viết một chương trình cho phép nhập vào một số nguyên dương n và xuất ra giá trị của n mũ 2 và 2 mũ n. Chương 2: Biểu thức 2 6
  • 26. 2.5 Viết một chương trình cho phép nhập ba số và xuất ra thông điệp Sorted nếu các số là tăng dần và xuất ra Not sorted trong trường hợp ngược lại. Chương 2: Biểu thức 27
  • 27. Chương 3. Lệnh Chương này giới thiệu các hình thức khác nhau của các câu lệnh C++ để soạn thảo chương trình. Các lệnh trình bày việc xây dựng các khối ở mức độ thấp nhất của một chương trình. Nói chung mồi lệnh trình bày một bước tính toán có một tác động chính yếu. Bên cạnh đó cũng có thế có các tác độnẸ phụ khác. Các lệnh là hữu dụng vì tác dụng chính yếu mà nó gây ra, sự kết nối của các lệnh cho phép chương trình phục vụ một mục đích cụ thể (ví dụ, sắp xếp một danh sách các tên). Một chương trình đang chạy dành toàn bộ thời gian đế thực thi các câu lệnh. Thứ tự mà các câu lệnh được thực hiện được gọi là dòng điều khiến (flow control). Thuật ngữ này phản ánh việc các câu lệnh đang thực thi hiện thời có sự điều khiển cúa CPU, khi CPU hoàn thành sẽ được chuyển giao tới một lệnh khác. Đặc trưng dòng điều khiển trong một chương trình là tuần tự, lệnh này đến lệnh kế, nhưng có thế chuyển hướng tới đườnẹ dần khác bởi các lệnh rẽ nhánh. Dòng điều khiến là một sự xem xét trọng yểu bởi vì nó quyết định lệnh nào được thực thi và lệnh nào không được thực thi trong quá trình chạy, vì thế làm ảnh hưởng đến kết quả toàn bộ của chương trình. Giống nhiều ngôn ngữ thủ tục khác, C++ cung cấp những hình thức khác nhau cho các mục đích khác nhau. Các lệnh khai báo được sử dụng cho định nghĩa các biến. Các lệnh như gán được sử dụng cho các tính toán đại số đơn giản. Các lệnh rẽ nhánh được sử dụng để chỉ định đường dẫn của việc thực thi phụ thuộc vào kết quả của một điều kiện luận lý. Các lệnh lặp được sử dụng đế chỉ định các tính toán cần được lặp cho tới khi một điều kiện luận lý nào đó được thỏa. Các lệnh điều khiến được sử dụng đế làm chuyến đường dần thực thi tới một đường dần khác của chương trình. Chúng ta sẽ lần lượt thảo luận tất cả những vấn đề này. Chương 3:Lệnh 30
  • 28. 3.1. Lệnh đon và lệnh phức Lệnh đơn là một sự tíirh toán được kết thúc bằng dấu chấm phấy. Các định nghĩa biến và các biểu thức được kết thúc bằng dấu chấm phấy như trong ví dụ sau: Ví dụ cuối trình bày một lệnh không hữu dụng bởi vì nó không có tác động chính yếu (d được cộng với 5 và kết quả bị vứt bỏ). Lệnh đơn giản nhất là lệnh rồng chỉ gồm dấu chấm phấy mà thôi. Mặc dầu lệnh rỗng không có tác động chính yếu nhưng nó có một vài việc dùng xác thật. Nhiều lệnh đơn có thề kết nối lại thành một lệnh phức bằng cách rào chúng bên trong các dấu ngoặc xoắn. Ví dụ: {intmin,i= 10,j=20; m,n=(i<j?i:j); cout«mỉn<<W; } Bời vì một lệnh phức có thế chứa các định nghĩa biến và định nghĩa một phạm vi cho chúng, nó cũng được gọi một khối. Phạm vi của một biến C++ được giới hạn bên trong khối trực tiếp chứa nó. Các khối và các luật phạm vi sẽ được mô tả chi tiết hơn lchi chúng ta thảo luận về hàm trong chương kế. Đôi khi chúng ta muốn làm cho sự thực thi một lệnh phụ thuộc vào một điều kiện nào đó cần được thỏa. Lệnh ifcung cấp cách đế thực hiện công việc này, hình thức chung của lệnh này là: if (biêu thức) Trước tiên biểu thức được ước lượng. Nếu kết quả khác 0 (đúng) thì sau đó lệnh được thực thi. Ngược lại, không làm gì cả. Ví dụ, khi chia hai giá trị chúng ta muốn kiểm tra rằng mẫu số có khác 0 hay không. if(count!=0) int i; ++i; //lệnhkhaibáo //lệnhnàycómộttácđộngchínhyếu //lệnhkhaibáo //lệnhkhônghũuđụng doubled= 10.5; d+5; //lệnhrỗng 3.2. Lệnh if lệnh; Chương 3:Lệnh 31
  • 29. average—sum/count; Đế làm cho nhiều lệnh phụ thuộc trên cùng điều kiện chúng ta có thể sử dụng lệnh phức: if(balance>0) { interest- balance * creditRate; balance += interest; } Một hình thức khác của lệnh if cho phép chúng ta chọn một trong hai lệnh: một lệnh được thực thi nếu như điều kiện được thỏa và lệnh còn lại được thực hiện nếu như điều kiện không thỏa. Hình thức này được gọi là lệnh if-else và có hình thức chung là: if{biểu thức) lệnh 1; else lệnh 2; Trước tiên biểu thức được ước lượng. Neu kết quả khác 0 thì lệnh 1 được thực thi. Ngược lại, lệnh 2 được thực thi. Ví dụ: if(balance>0) { interest—balance * creditRate; balance += interest; }else { interest= balance * debitRate; balance+=interest; } Trong cả hai phần có sự giống nhau ở lệnh balance-H=interest vì thế toàn bộ câu lệnh có thế viết lại như sau: if(balance>0) interest—balance * creditRate; else interest= balance * debitRate; balance+= interest; Hoặc đơn giản hơn bằng việc sử dụng biếu thức điều kiện: interest=balance*(balance>0?creditRate:debitRate); balance -t= interest; Hoặc chỉ là: balance += balance * (balance> 0 ? creditRate:debitRate); Các lệnh if có thế được lồng nhau bằng cách đế cho một lệnh if xuất hiện bên trong một lệnh if khác. Ví dụ: Chương 3:Lệnh 32
  • 30. if(calIHour>6) { if(callDuration<=5) charge= callDuration *tarrifl; else charge=5 *tarrifl + (callDuration - 5) * tarrif2; }else charge=flatFee; Một hình thức được sử dụng thường xuyên của những lệnh if lồng nhau liên quan đến phần else gồm có một lệnh if-else khác. Ví dụ: if(ch>='()'&&ch<=9') kind=đỉgit; clsc { if(ch>='A'&&ch<='Z) kind=upperLetter, clsc { if(ch>='a'&&ch<='f) kind=lowerLetter, else kind= special; } > Đe cho dễ đọc có thể sử dụng hình thức sau: if(ch>='0'&&ch<=V) kind=digit; elseif(ch>='A'&&ch<=Z) kind=capitalLetter, elseif(ch>='a &&ch<=V) kind=smallLetter, else kind=special; 3.3. Lênh switch Lệnh switch cung cap phương thức lựa chọn giữa một tập các khả năng dựa trên giá trị của biếu thức. Hình thức chung của câu lệnh switch là: switch (biểụ thức) { caschằng ¡: các lệnh; casehằng các lệnh', default: các lệnh', } Biểu thức (gọi là thẻ switch) được ước lượng trước tiên và kết quả được so sánh với mồi hằng số (gọi là các nhãn) theo thứ tự chúng xuất hiện cho đến khi một so khớp được tìm thấy. Lệnh ngay sau khi so khớp được thực hiện Chương 3:Lệnh 33
  • 31. sau đó. Chú ý số nhiều: mỗi case có thế được theo sau bởi không hay nhiều lệnh (không chỉ là một lệnh). Việc thực thi tiếp tục cho tới khi hoặc là bắt gặp một lệnh hrcak hoặc tất cả các lệnh xen vào đến cuối lệnh switch được thực hiện.Trường hợp default ở cuối cùng là một tùy chọn và được thực hiện nếu như tất cả các case trước đó không được so khớp. Ví dụ, chúng ta phải phân tích cú pháp một phép toán toán học nhị hạng thành ba thành phần của nó và phải lưu trừ chúng vào các biến operator, operandi, và opcrand2. Lệnh switch sau thực hiện phép toán và lưu trữ kết quả vào result switch(operator) { case result=operandl +operand2; break; case result=operand1-operand2; break; case result=operand1*operand2; break; case'A result=operand1/operand2; break; default: cout«"unknownoperator "«operator« V; break; } Như đã được minh họa trong ví dụ, chúng ta cần thiết chèn một lệnh break ở cuối mồi case. Lệnh break ngắt câu lệnh switch bằng cách nhảy đến điếm kết thúc của lệnh này. Ví dụ, nếu chúng ta mở rộng lệnh trên đế cho phép X cũng có thế được sử dụng như là toán tử nhân, chúng ta sẽ có: switch(operator) { case result=operandl +operand2; break; c a s e re s u lt=operand1-operand2; break; casehi’: case result=operand1*operand2; break; case 7: result=operandl / operand2; break; default: cout« "unknownoperator "«operator«Vi'; break; } Bởi vì case 'x' không có lệnh break nên khi case này được thỏa thì sự thực thi tiếp tục thực hiện các lệnh trong case kế tiếp và phép nhân được thi hành. Chúng ta có thể quan sát rằng bất kỳ lệnh switch nào cũng có thể được viết như nhiều câu lệnh if-else. Ví dụ, lệnh trên có thế được viết như sau: Chương 3:Lệnh 34
  • 32. if(operator—- '+1) result=operand1+operand2; elseif(operator= -1) result= operand1- operand2; else if(operator= bc' IIoperator— '*') result= operand1*operand2; elseif(operator= 7) result= operand1/ operand2; else cout« "unknownoperator "« ch« V; người ta có thế cho rang phiên bản switch là rõ ràng hơn trong trường họp này. Tiếp cận if-else nên được dành riêng cho tình huống mà trong đó switch không thề làm được công việc (ví dụ, khi các điều kiện là phức tạp không thể đơn giản thành các đẳng thức toán học hay khi các nhãn cho các case không là các hằng số). 3.4. Lênh while Lệnh while (cũng được gọi là vòng lặp while) cung cấp phương thức lặp một lệnh cho tới khi một điều kiện được thỏa. Hình thức chung của lệnh lặp là: while (biểu thức) lệnh; Biểu thức (cũng được gọi là điều kiện lặp) được ước lượng trước tiên. Nếu kết quả khác 0 thì sau đó lệnh (cũng được gọi là thân vòng lặp) được thực hiện và toàn bộ quá trình được lặp lại. Ngược lại, vòng lặp được kết thúc. Ví dụ, chúng ta muốn tính tổng của tất cả các số nguyên từ 1 tới n. Điều này có thể được diễn giải như sau: i=l; sum=0; while(i<=n){ sum+=i; H-+; } Trường họp n là 5, Bảng 3.1 cung cấp bảng phát họa vòng lặp bằng cách liệt kê các giá trị của các biến có liên quan và điều kiện lặp. Bảng 3.1 v ét của vòng lặp while.________________________________ Vòng lặp i n i <= n sum -H=i++ Một 1 5 1 1 Hai 'ìL 5 1 3 Ba 3 5 1 6 Bôn 4 5 1 10 Năm 5 5 1 15 Sáu 6 5 0 Chương 3:Lệnh 35
  • 33. Đôi khi chúng ta có thế gặp vòng lặp while có thân rỗng (nghĩa là một câu lệnh null). Ví dụ vòng lặp sau đặt n tới thừa số lẻ lớn nhất của nó. while(n%2=0&&n/=2) ; Ớ đây điều kiện lặp cung cấp tất cả các tính toán cần thiết vì thế không thật sự cần một thân cho vòng lặp. Điều kiện vòng lặp không những kiếm tra n là chằn hay không mà nó còn chia n cho 2 và chắc chắn rằng vòng lặp sẽ dừng. 3.5. Lênh do - while Lệnh do (cũng được gọi là vòng lặp do) thì tương tự như lệnh while ngoại trừ thân của nó được thực thi trước tiên và sau đó điều kiện vòng lặp mới được kiếm tra. Hình thức chung của lệnh do là: do lệnh' while (biểu thức)', Lệnh được thực thi trước tiên và sau đó biếu thức được ước lượng. Neu kết quả của biếu thức khác 0 thì sau đó toàn bộ quá trình được lặp lại. Ngược lại thì vòng lặp kết thúc. Vòng lặp do ít được sử dụng thường xuyên hơn vòng lặp while. Nó hữu dụng trong những trường hợp khi chúng ta cần thân vòng lặp thực hiện ít nhất một lần mà không quan tâm đến điều kiện lặp. Ví dụ, giả sử chúng ta muốn thực hiện lặp đi lặp lại công việc đọc một giá trị và in bình phương của nó, và dừng khi giá trị là 0. Điều này có thể được diễn giái trong vòng lặp sau đây: do { cin»n; cout«n*n«rí; }while(n!=0); Không giống như vòng lặp while, vòng lặp do ít khi được sử dụng trong những tình huống mà nó có một thân rồng. Mặc dù vòng lặp do với thân rồng có thể là tương đương với một vòng lặp while tương tự nhưng vòng lặp while thì luôn dễ đọc hơn. 3.6. Lênh for• Lệnh for (cũng được gọi là vòng lặp for) thì tương tự như vòng lặp while nhưng có hai thành phần thêm vào: một biếu thức được ước lượng chỉ một lần trước hết và một biểu thức được ước lượng mồi lần ở cuối mỗi lần lặp. Hình thức tổng quát của lệnh for là: Chương 3:Lệnh 36
  • 34. for(biểu thức¡; biểu thúc 2, biểu thứcì) lệnh', Biểu thứcỊ (thường được gọi là biểu thức khởi tạo) được ước lượng trước tiên. Mồi vòng lặp biểu thức2 được ước lượng. Nếu kết quả không là 0 (đúng) thì sau đó lệnh được thực thi và biểu thức3 được ước lượng. Ngược lại, vòng lặp kết thúc. Vòng lặp for tổng quát thì tương đương với vòng lặp while sau: biểu thứcJ, while (biểu thức 2) { ỉệnh; biêu thức 3; } Vòng lặp for thường được sử dụng trong các trường hợp mà có một biến được tăng hay giảm ở mồi lần lặp. Ví dụ, vòng lặp for sau tính toán tổng của tất cả các số nguyên từ 1tới n. sum=0; for(i= l;i<=n;++i) sum+=i; Điều này được ưa chuộng hơn phiên bản của vòng lặp while mà chúng ta thấy trước đó. Trong ví dụ này i thường được gọi là biến lặp. C++ cho phép biểu thức đầu tiên trong vòng lặp for là một định nghĩa biến. Ví dụ trong vòng lặp trên thì i có thế được định nghĩa bên trong vòng lặp: for(inti= l;i<=n;+-H) sum+=i; Trái với sự xuất hiện, phạm vi của i không ở trong thân của vòng lặp mà là chính vòng lặp. Xét trên phạm vi thi ở trên tương đương với: inti; for(i=l;i<=n;-Hi) sum+=i; Bất kỳ biếu thức nào trong 3 biểu thức của vòng lặp for có thể rồng. Ví dụ, xóa biếu thức đầu và biếu thức cuối cho chúng ta dạng giống như vòng lặp while: for(;i!=0;) //tưongđươngvói: while(i!=0) something; // something Xóa tất cả các biểu thức cho chúng ta một vòng lặp vô hạn. Điều kiện của vòng lặp này được giả sử luôn luôn là đúng. for(;;) //vòng lặpvô hạn something; Chương 3:Lệnh 37
  • 35. Trường hợp vòng lặp với nhiều biến lặp thì hiếm dủng. Trong những trường họp như thế, toán tử phẩy (,) được sử dụng đế phân cách các biếu thức của chúng: for(i=0,j =0; i+j <n;-Hi,++j) something; Bởi vì các vòng lặp là các lệnh nên chúng có thể xuất hiện bên trong các vòng lặp khác. Nói các khác, các vòng lặp có thể lồng nhau. Ví dụ, for(inti= 1;i<=3;++i) for (intj = 1;j <=3;-H-j) cout<< 'C« i<<7 « j « ")n"; cho tích so của tập hợp {1,2,3} với chính nó, kết quả như sau: ị]’1) ĩ?2,1 Ẹị) 23) 3,1) § (33) 3.7. Lệnh continue Lệnh continue dừng lần lặp hiện tại cùa một vòng lặp và nhảy tới lần lặp ké tiếp. Nó áp dụng tức thì cho vòng lặp gần với lệnh continue. Sử dụng lệnh continue bên ngoài vòng lặp là lồi. Trong vòng lặp while và vòng lặp do-while, vòng lặp kế tiếp mở đầu từ điều kiện lặp. Trong vòng lặp for, làn lặp kế tiếp khởi đầu từ biểu thức thứ ba của vòng lặp. Ví dụ, một vòng lặp thực hiện đọc một số, xử lý nó nhưng bỏ qua những số âm, và dừng khi số là 0, có thể diễn giải như sau: do { cin»num; if(num<0)continue; //xửlýsôởđây... }while(num!=0); Điều này tương đương với: do { cin»num; if(num>=0) { //xửiýsổờđây... } }while(num!=0); Chương 3:Lệnh 38
  • 36. Một biến thế của vòng lặp này đế đọc chính xác một số n lần (hơn là cho tới khi số đó là 0) có thế được diễn giải như sau: for(i=0;i<n;+-H) { cin»num; if(num<0)continue; //làmchonhảytói:-Hi //xửlýsốởđây... } Khi lệnh continue xuất hiện bên trong vòng lặp được lồng vào thì nó áp dụng trực tiếp lên vòng lặp gần nó chứ không áp dụng cho vòng lặp bên ngoài. Ví dụ, trong một tập các vòng lặp được lồng nhau sau đây, lệnh continue áp dụng cho vòng lặp for và không áp dụng cho vòng lặp while: while(more) { for(i=0;i<n;-H-i) { cin»num; if(num<0)continue; //làmchonhảytói:++i //processnumhere... } //etc... > 3.8. Lênh break• Lệnh break có thế xuất hiện bên trong vòng lặp (while, do, hay for) hoặc một lệnh switch. Nó gây ra bước nhảy ra bên ngoài những lệnh này và vì thế kết thúc chúng. Giống như lệnh continue, lệnh break chỉ áp dụng cho vòng lặp hoặc lệnh switch gần nó. Sử dụng lệnh break bên ngoài vòng lặp hay lệnh switch là lồi. Ví dụ, chúng ta đọc vào một mật khấu người dùng nhưng không cho phép một số hữu hạn lần thử: for(i=0; i<attempts;++i) { cout« "Pleaseenteryourpassword: d n » password; if(Veriiy(password)) //kiemtramậtkhẩuđúnghaysai break; //Ihoátkhỏivònglặp cout« "Incorrect!n"; } Ỡ đây chúng ta phải giá sử rằng có một hàm được gọi Verify để kiểm tra một mật khẩu và trả về true nếu như mật khấu đúng và ngược lại là false. Chúng ta có thế viết lại vòng lặp mà không cần lệnh break bằng cách sử dụng một biến luận lý được thêm vào (verified) và thêm nó vào điều kiện vòng lặp: verified=0; for(i=0; i<attempts&&!verified;++i) { Chương 3:Lệnh 39
  • 37. cout« "Pleaseenteryourpassword: cin» password; verified=Verifylpassword)); if(!verified) cout<<"Incorrect!n"; } Người ta cho rang phiên bản của break thì đơn giản hơn nên thường được ưa chuộng hơn. 3.9. Lệnh goto Lệnh goto cung cấp mức thấp nhất cho việc nhảy. Nó có hình thức chung là: goto nhãn', trong đó nhãn là một định danh được dùtiẸ đế đánh dấu đích cần nhảy tới. Nhãn cần được theo sau bởi một dấu hai chấm (:) và xuất hiện trước một lệnh bên trong hàm như chính lệnh goto. Ví dụ, vai trò của lệnh break trong vòng lặp for trong phần trước có thế viết lại bởi một lệnh goto. for(i=0; i<attempts;-Hi) { cout«"Pleâseenteryourpassword: cin» password; if(Veriíỳ(passwoixi)) //checkpasswordforcorrectness gotoout; //dropoutoftheloop cout<<"Incorrect!n"; } out: //etc... Bởi vì lệnh goto cung cấp một hình thức nhảy tự do không có cấu trúc (không giống như lệnh break và continue) nên dỗ làm gãy đố chương trình. Phần lớn các lập trình viên ngày nay tránh sử dụng nó đế làm cho chương trình rõ ràng. Tuy nhiên, goto có một vài (dù cho hiếm) sử dụng chính đáng. Vì sự phức tạp của những trường hợp như thế mà việc cung cấp những ví dụ được trình bày ở những phần sau. 3.10.Lệnh return Lệnh return cho phép một hàm trả về một giá trị cho thành phần gọi nó. Nó có hình thức tổng quát: return biểu thức', Chương 3:Lệnh 40
  • 38. trong đó biểu thức chỉ rõ giá trị được trả về bởi hàm. Kiểu của giá trị xiày nên hợp với kiểu của hàm. Trường hợp kiếu trả về của hàm là void, biểu thức nên rong: return; Hàm mà được chúng ta thảo luận đến thời điếm này chỉ có hàm main, kiếu trả về của nó là kiểu int. Giá trị trả về của hàm main là những gì mà chương trình trả về cho hệ điều hành khi nó hoàn tất việc thực thi. Chắng hạn dưới UNIX qui ước là trả về 0 từ hàm main khi chương trình thực thi không có lỗi. Ngược lại, một mã lỗi khác 0 được trả về. Ví dụ: intmain(void) { cout« "HelloWorld'n"; return0; } Khi một hàm có giá trị trả về không là void (như trong ví dụ trên), nếu không trả về một giá trị sẽ mang lại một cảnh báo trình biên dịch. Giá trị trả về thực sự sẽ không được định nghĩa trong trường họp này (nghĩa là, nó sẽ là bất cứ giá trị nào được giữ trong vị trí bộ nhớ tương ứng cùa nó tại thời điếm đó). Bài tập cuối chưong 3 3.1 Viết chương trình nhập vào chiều cao (theo centimet) và trọng lượng (theo kilogram) của một người và xuất một trong những thông điệp: underweight, normal, hoặc overweight, sử dụng điều kiện: Underweight: weight < height/2.5 Normal: height/2.5 <= weight <= height/2.3 Overweight: height/2.3 < weight 3.2 Giả sử rằng n là 20, đoạn mã sau sẽ xuất ra cái gì khi nó được thực thi? if(n>=0) if(n< 10) cout« "nissmall'n"; else cout« "nisnegativen"; 3.3 Viết chương trình nhập một ngày theo định dạng dd/mm/yy và xuất nó theo định dạng monthdd,year. Ví dụ, 25/12/61 trở thành: Thangmuoihai25,1961 3.4 Viết chương trình nhập vào một giá trị số nguyên, kiếm tra nó là dương hay không và xuất ra giai thừa của nó, sử dụng công thức: Chương 3:Lệnh 41
  • 39. giaithua (0) = 1 giaithua (n) = n X giaithua (n-1) 3.5 Viết chương trình nhập vào một số cơ số 8 và xuất ra số thập phân tương đương. Ví dụ sau minh họa các công việc thực hiện của chương trình theo mong đợi: Nhap vao so batphan: 214 BatPhan(2 14) = ThapPhan(140) 3.6 Viết chương trình cung cấp một bảng cửu chương đom giản của định dạng sau cho các số nguyên từ 1 tới 9: 1x 1= 1 1x2=2 9x9=81 Chương 3:Lệnh 42
  • 40. Chương 4. Hàm Chương này mô tả những hàm do người dùng định nghĩa như là một trong những khối chương trình C++. Hàm cung cấp một phương thức đế đóng gói quá trình tính toán một cách dễ dàng đế được sử dụng khi cần. Định nghĩa hàm gồm hai phần: giao diện và thân. Phần giao diện hàm (cũng được gọi là khai báo hàm) đặc tả hàm có thể được sử dụng như thế nào. Nó gồm ba phần: • Tên hàm. Đây chỉ là một định danh duy nhất. • Các tham số của hàm. Đây là một tập của không hay nhiều định danh đã định kiểu được sử dụng đế truyền các giá trị tới và từ hàm. • Kiểu trả về của hàm. Kiểu trả về của hàm đặc tả cho kiểu của giá trị mà hàm trả về. Hàm không trả về bất kỳ kiếu nào thì nên trả về kiểu void. Phần thân hàm chứa đựng các bước tính toán (các lệnh). Sử dụng một hàm liên quan đến việc gọi nó. Một lòi gọi hàm gồm có tên hàm, theo sau là cặp dấu ngoặc đon ‘0’, bên trong cặp dấu ngoặc là không, một hay nhiều đối số được tách biệt nhau bằng dấu phẩy, số các đối số phái khớp với số các tham số của hàm. Mồi đối số là một biểu thức mà kiểu của nó phải khớp với kiểu của tham số tương ứng trong khai báo hàm. Khi lời gọi hàm được thực thi, các đối số được ước lượng trước tiên và các giá trị kết quả của chúng được gán tới các tham số tương ứng. Sau đó thân hàm được thực hiện. Cuối cùng giá trị trả về của hàm được truyền tới thành phần gọi hàm. Vì một lời gọi tới một hàm mà kiểu trả về không là void sẽ mang lại một giá trị trả về nên lời gọi là một biểu thức và có thề được sử dụnẹ trong các biểu thức khác. Ngược lại một lời gọi tới một hàm mà kiều trả về của nó là void thì lời gọi là một lệnh. Chương 4: Hàm 45
  • 41. 4.1. Hàm đon giản Danh sách 4.1 trình bày định nghĩa của một hàm đon giản để tính lũy thừa của một số nguyên. Danh sách A 1 2 3 4 5 6 7 Chú giải A______________________________ intPower(intbase,unsignedintexponent) { int result= 1; for(inti=0; i<exponent;++i) result *=base; returnresult; 1 Dòng này định nghĩa giao diện hàm. Nó bắt đầu với kiểu trả về của hàm (là int trong trường hợp này). Ke tiếp là tên hàm, theo sau là danh sách các tham so. Power có hai tham so (base và exponent) thuộc kiểu int và unsigned int tương ứng. Chú ý là cú pháp cho các tham số là tương tự như cú pháp cho định nghĩa biến: định danh kiểu được theo sau bởi tên tham số. Tuy nhiên, không thể theo sau định danh kiểu với nhiều tham số phân cách bởi dấu phẩy: intPower(intbase,exponent) //Sai! 2 Dấu ngoặc này đánh dấu điểm bắt đầu của thân hàm. 3 Dòng này là định nghĩa một biến cục bộ. 4-5 Vòng lặp for này tăng ca so base lên lũy thừa của exponent và lim trừ kết quả vào trong result. 6 Hàng này trả result về như là kết quả của hàm. 7 Dấu ngoặc này đánh dấu điểm kết thúc của thân hàm. Danh sách 4.2 minh họa hàm được gọi như thế nào. Tác động của lời gọi hàm này là đầu tiên các giá trị 2 và 8 tương ứng được gán cho các tham số base va exponent, và sau đó thân hàm được ước lượng. Danh sách 4.2 1 #include<iostreamh> 2 main(void) 3 { 4 cout« " 2 A8=" « Power(2,8)« V; 5 U ________________________________ Khi chạy chương trình này xuất ra kết quả sau: 2A8=256 Chương 4: Hàm 46
  • 42. Nói chung, một hàm phải được kliai báo trước khi sử đụng nó. Khai báo hàm (function declaration) đơn giản gồm có mẫu ban đầu của hàm gọi là nguyên mẫu hàm (function prototype) chỉ định tên hàm, các kiếu tham số, và kiểu trả về. Hàng 2 trong Danh sách 4.3 trình bày hàm Power có thể được khai báo như thế nào cho chương trình trên. Nhưng một hàm cũng có thể được khai báo mà không cần tên các tham số của nó, intPower(int,unsigned int); tuy nhiên chúng ta không nên làm điều đó trừ phi vai trò của các tham số là rõ ràng. Danh sách 4.3 1 2 3 4 5 6 7 8 9 10 11 12 13 #include<iostream.h> intPower(intbase,unsignedintexponent); //khai baoham main(void) { cout« "2A8=" « Power(2,8)« V; } intPower(intbase,unsignedintexponent) { int result=l; for(inti=0; i< exponent;++i) result *=base; returnresult; Bởi vì một định nghĩa hàm chứa đựng một nguyên mẫu (prototype) nên nó cũng được xem như là một khai báo. Vì thế nếu định nghĩa của một hàm xuất hiện trước khi sử dụng nó thì không cần khai báo thêm vào. Tuy nhiên việc sử dụng các nguyên mầu hàm là khuyến khích cho mọi trường họp. Tập hợp của nhiều hàm vào một tập tin header riêng biệt cho phép những lập trình viên khác truy xuất nhanh chóng tới các hàm mà không cần phải đọc toàn bộ các định nghĩa của chúng. 4.2. Tham số và đối số C++ hỗ trợ hai kiểu tham số: giá trị và tham chiếu. Tham số giá trị nhận một sao chép giá trị của đối số được truyền tới nó. Ket quả là, nếu hàm có bất kỳ chuyến đối nào tới tham số thì vẫn không tác động đến đối số. Ví dụ, trong #include<iostrearah> voidFoo(intnum) { num=0; Chương 4: Hàm 47
  • 43. } cout« "num- "« num « V; intmam(void) { intx=10; Foo(x); cout<<"x=" « X « V; return0; } thì tham số duy nhất của hàm Foo là một tham số giá trị. Đen lúc mà hàm này được thực thi thì num được sử đụng như là một biến cục bộ bên trong hàm. Khi hàm được gọi và Xđược truyền tới nó,num nhận một sao chépgiá trị của X. Ket quả là mặc dù num được đặt về 0 bởihàm nhưng vẫnkhôngcó gìtác động lên X. Chương trình cho kết quả như sau: num=0; x=10; Trái lại, tham số tham chiếu nhận các đối số được truyền tới nó và làm trực tiếp trên đối số đó. Bất kỳ chuyển đối nào được tạo ra bởi hàm tới tham số tham chiếu đều tác động trực tiếp lên đối số. Bên trong ngữ cảnh của các lời gọi hàm, hai kiểu truyền đối số tương ứng được gọi là truyền-bằng-giá trị và truyền-bằng-tham cbiếu. Thật là hoàn toàn hợp lệ cho một hàm truyền-bằng-giá trị đối với một vài tham số và truyền-bằng-tham chiếu cho một vài tham số khác. Trong thực tế thì truyền- bằng-giá trị thường được sử dụng nhiều hơn. 4.3. Phạm vi cục bộ và toàn cục• • • • Mọi thứ được định nghĩa ở mức phạm vi chương trình (nghĩa là bên ngoài các hàm và các lớp) được hiếu là có một phạm vi toàn cục ^global scope). Các hàm ví dụ mà chúng ta đã thấy cho đến thòi điếm này đều có một phạm vi toàn cục. Các biến cũng có thề định nghĩa ở phạm vi toàn cục: intyear= 1994; //biếntoàncục intMax(int, int); //hàmtoàncục intmain(void) //hàmtoàncục { II... } Các biến toàn cục không được khởi tạo, sẽ được khởi tạo tự động là 0. Vì các đầu vào toàn cục là có thể thấy được ở mức chương trình nên chúng cũng phải là duy nhất ở mức chương trình. Điều này nghĩa là cùng các biến hoặc hàm toàn cục có thế không được định nghĩa nhiều hơn một lần ở Chương 4: Hàm 48
  • 44. mức toàn cục. (Tuy nliiên chúng ta sẽ thấy sau này một tên hàm có thế được sử dụng lại). Thông thường các biến hay hàm toàn cục có thế được truy xuất từ mọi nơi trong chương trình. Mồi khối trong một chương trình định nghĩa một phạm vi cục bộ. Thật vậy, thân của một hàm trình bày một phạm vi cục bộ. Các tham số của một hàm có cùng phạm vi như là thân hàm. Các biến được định nghĩa ở bên trong một phạm vi cục bộ có thể nhìn thấy tới chỉ phạm vi đó. Do đó một biến chỉ cần là duy nhất ở trong phạm vi của chính nó. Các phạm vi cục bộ cí thế lồng nhau, trong trường hợp này các phạm vi bên trong chồng lên các phạm vi bên ngoài. Ví dụ trong intxyz; //xyz làtoàncục voidFoo(intxyz) //xyzlàcụcbộchothâncủaFoo { . " if(xyz>0) { doublexyz: //xyz làcụcbộchokhốinày //... } > có ba phạm vi riêng biệt, mỗi phạm vi chứa đựng một xyz riêng. Thông thường, thời gian sống của một biến bị giới hạn bởi phạm vi của nó. Vì thế, ví dụ các biến toàn cục tồn tại suốt thời gian thực hiện chương trình trong khi các biến cục bộ được tạo ra khi phạm vi của chúng bắt đầu và mất đi khi phạm vi của chúng kết thúc. Không gian bộ nhớ cho các biến toàn cục được dành riêng trước khi sự thực hiện của chương trinh bắt đầu nhưng ngược lại không gian bộ nhớ cho các biến cục bộ được cấp phát ở thời điếm thực hiện chương trình. 4.4. Toán tử phạm vi Bởi vì phạm vi cục bộ ghi chồng lên phạm vi toàn cục nên một biến cục bộ có cùng tên với biến toàn cục làm cho biến toàn cục không thế truy xuất được tới phạm vi cục bộ. Ví dụ, trong interior, voidError(interror) { II... } biến toàn cục error là không thể truy xuất được bên trong hàm Eưor bởi vì nó được ghi chồng bởi tham so error cục bộ. Vấn đề này được giải quyết nhờ vào sử dụng toán tử phạm vi đơn hạng (::),toán tử này lấy đầu vào toàn cục như là đối số: Chương 4: Hàm 49
  • 45. interror, voidError(interror) { II... if("error !=0) //thamkhảotói errortoàncục //... } 4.5. Biến tự động Bởi vì thời gian sống của một biến cục bộ là có giới hạn và được xác định hoàn toàn tự động nên những biến này cũng được gọi là tự động. Bộ xác định lớp lưu trừ auto có thế được dùng đế chỉ định rõ ràng một biến cục bộ là tự động. Ví dụ: voidFoo(void) { auto intxyz; //nhưlà: intxyz; //... } Điều này ít khi được sử dụng bởi vì tất cả các biến cục bộ mặc định là tự động. 4.6. Biến thanh ghi Như được đề cập trước đó, nói chung các biến biểu thị các vị trí bộ nhớ nơi mà giá trị của biến được lưu trừ tới. Khi mã chương trình tham khảo tới một biến (ví dụ, trong một biếu thức), trình biên dịch phát ra các mã máy truy xuất tới vị trí bộ nhớ được biếu thị bởi các biến. Đối với các biến dùng thường xuyên (ví dụ như các biến vòng lặp), hiệu xuất chương trình có thể thu được bằng cách giữ biến trong một thanh ghi, bằng cách này có thể tránh được truy xuất bộ nhớ tới biến đó. Bộ lưu trữ thanh ghi có thế được sử dụng để chi định cho trình biên dịch biến có thế được lưu trữ trong một thanh ghi nếu có thể. Ví dụ: for(registerinti=0; i<n; ++i) sum+=i; Ớ đây mồi vòng lặp i được sử dụng ba lần: một lần khi nó được so sánh với n, một lần khi nó được cộng vào sum, và một lần khi nó được tăng. Vì thế việc giữ biến i trong thanh ghi trong suốt vòng lặp for là có ý nghĩa trong việc cải thiện hiệu suất chương trình. Chú ý rằng thanh ghi chỉ là một gọi ý cho trình biên dịch, và trong một vài trường họp trình biên dịch có thế chọn không sử dụng thanh ghi khi nó được Chương 4: Hàm 50
  • 46. yêu cầu làm điều đó. Một lý đo đế lý giải là bất kỳ máy tính nào cũng có một số hữu hạn các thanh ghi và nó có thế ở trong trường họp tất cả các thanh ghi đang được sử dụng. Thậm chí khi lập trình viên không khai báo thanh ghi, nhiều trình biên dịch tối ưu cố gắng thực hiện một dự đoán thông minh và sử dụng các thanh ghi mà chúng muốn để cải thiện hiệu suất của chương trình. Ý tưởng sử dụng khai báo thanh ghi thường được đề xuất sau cùng; nghĩa là sau khi viết mã chương trình hoàn tất lập trình viên có thể xem lại mã và chèn các khai báo thanh ghi vào những nơi cần thiết. 4.7. Hàm nội tuyến Giả sử một chương trình thường xuyên yêu cầu tìm giá trị tuyệt đối của một số các số nguyên. Cho một giá trị được biếu thị bởi n, điều này có thể được giải thích như sau: (n>0?n:-n) Tuy nhiên, thay vì tái tạo biếu thức này tại nhiều vị trí khác nhau trong chương trình, tốt hơn hết là nên định nghĩa nó trong một hàm như sau: intAbs(intn) { retumn>0?n:-n; } Phiên bản hàm có một số các thuận lợi. Thứ nhất, nó làm cho chương trình dỗ đọc. Thứ hai, nó có thế được sử dụng lại. Và thứ ba, nó tránh được hiệu ứng phụ không mong muốn khi đối số chính nó là một biểu thức có các hiệu ứng phụ. Tuy nhiên, bất lợi của phiên bản hàm là việc sử dụng thường xuyên có thế dần tới sự bất lợi về hiệu suất đáng kể vì các tốn phí dành cho việc gọi hàm. Ví dụ, nếu hàm Abs được sử dụng trong một vòng lặp được lặp đi lặp lại một ngàn lần thì sau đó nó sẽ có một tác động trên hiệu suất. Tổn phí có thể được tránh bằng cách định nghĩa hàm Abs như là hàm nội tuyến(inline); inlineintAbs(intn) { retumn>0?n:-n; } Hiệu quả của việc sử dụng hàm nội tuyến là khi hàm Abs được gọi, trình biên dịch thay vì phát ra mã đế gọi hàm Abs thì mở rộng và thay thế thân của hàm Abs vào nơi gọi. Trong khi về bản chất thì cùng tính toán được thực hiện nhưng không có liên quan đến lời gọi hàm vì thế mà không có cấp phát stack. Chương 4: Hàm 51
  • 47. Bởi vì các lời gọi tới hàm nội tuyến được mở xông nên không có vết của chính hàm được đưa vào trong mã đã biên dịch. Vì thế, nếu một hàm được định nghĩa nội tuyến ở trong một tập tin thì nó không sằn dùng cho các tập tin khác. Do đó, các hàm nội tuyến thường được đặt vào trong các tập tin header đế mà chúng có thể được chia sẻ. Giống như tò khóa register, inline là một gợi ý cho trình biên dịch thực hiện. Nói chung, việc sứ dụng inline nên có hạn chế chì cho các hàm đơn giản được sử dụng thường xuỵên mà thôi. Việc sử dụng inline cho các hàm dài và phức tạp quá thì chắc chắn bị bỏ qua bởi trình biên dịch. 4.8. Đệ qui Một hàm gọi chính nó được gọi là đệ qui. Đệ qui là một kỹ thuật lập trình tổng quát có thể ứng dụng cho các bài toán mà có thể định nghĩa theo thuật ngữ của chính chúng. Chắng hạn bài toán giai thừa được định nghĩa như sau: • Giai thừa của 0 là 1. • Giai thừa của một số « là n lần giai thừa của 77-1. Hàng thứ hai rõ ràng cho biết giai thừa được định nghĩa theo thuật ngữ của chính nó và vì thế có thế được biểu diễn như một hàm đệ qui: intFactorial(unsignedintn) { returnn = 0 ? 1:n *Factorial(n-1); } Cho n bằng 3, Bảng 4.1 cung cấp vết của các lời gọi Factorial. Các khung stack cho các lời gọi này xuất hiện tuần tự từng cái một trên runtime stack. Bảng 4.1 vết thực thi của Factorial(3). Call n 11= 0 n * Factorial(n-l) Returns Thứ nhât 3 0 3 * Factorial(2) 6 Thứ hai oẢ 0 2 * Factorial 1) 2 Thứ ba 0 1* Factorial(O) 1 Thứ tư 0 1 1 Một hàm đệ qui phải có ít nhất một điều kiện dừng có thể được thỏa. Ngược lại, hàm sẽ gọi chính nó vô hạn định cho tới khi tràn stack. Ví dụ hàm Factorial có điều kiện dừng là n = 0. (Chú ý đối với trường hợp n là số âm thì điều kiện sẽ không bao giờ thỏa và Factorial sẽ thất bại). Chương 4: Hàm 52
  • 48. 4.9. Đối số măc đinh• • Đối số mặc định là một thuận lợi lập trình để bỏ bớt đi gánh nặng phải chỉ định các giá trị đối số cho tất cả các tham số hàm. Ví dụ, xem xét hàm cho việc báo cáo lỗi: voidError(char*message, intseverity=0); Ớ đây thì severity có một đối số mặc định là 0; vì thế cả hai lòi gọi sau đều hợp lệ: Error("Divisionbyzero",3);//severityđậttới 3 EiTOiC'Roundofferror”); //seventyđặttới 0 Như là lời gọi hàm đầu tiên minh họa, một đối số mặc định có thể được ghi chồng bằng cách chỉ định rõ ràng một đối số. Các đối số mặc định là thích hợp cho các trường hợp mà trong đó các tham số nào đó của hàm (hoặc tất cả) thường xuyên lấy cùng giá trị. Ví dụ trong hàm Error, severity 0 lỗi thì phố biến hơn là những trường hợp khác và vì thế là một ứng cử viên tốt cho đối số mặc định. Một cách dùng các đối số ít phù hợp có thế là: intPower(intbase,unsignedintexponent=1); Bởi vì 1 (hoặc bất kỳ giá trị nào khác) thì không chắc xảy ra thường xuyên trong tình huống này. Đế tránh mơ hồ, tất cả đổi số mặc định phải là các đối số theo đuôi. Vì thế khai báo sau là không theo luật: voidError(char*message= "Bomb", intseverity);//Trái quitắc Một đối số mặc định không nhất thiết là một hằng. Các biểu thức tùy ý có thế được sử dụng miễn là các biến được dùng trong các biếu thức là có sẵn cho phạm vi định nghĩa hàm (ví dụ, các biến toàn cục). Qui ước được chấp nhận dành cho các đối số mặc định là chỉ định chúng trong các khai báo hàm chứ không ở trong định nghĩa hàm. Khi một chương trình được thực thi dưới một hệ điều hành (như là DOS hay UNIX) nó có thể nhận không hay nhiều đối số từ dòng lệnh. Các đối số này xuất hiện sau tên chương trình có thể thực thi và được phân cách bởi các khoảng trắng. Bởi vì chúng xuất hiện trên cùng hàng nơi mà các lệnh của hệ điều hành phát ra nên chúng được gọi là các đối số hàng lệnh. r r Chương 4: Hàm 53
  • 49. Ví dụ như xem xét một chương trình được đặt tên là sum đế in ra tổng của tập họp các số được cung cấp tới nó như là các đối số hàng lệnh. Hộp thoại 4.1 minh họa hai số được truyền như là các đối số tới hàm sum như thế nào ($ là dấu nhắc UNIX). Hộp thoại 4.1 ’ 1 2 3 $sum 10.4 12.5 22.9 $____________ Các đối số hàng lệnh được tạo ra sẵn cho một chương trình C++ thông qua hàm main. Có hai cách định nghĩa một hàm main: intmain(void); intmain(intargc, coastchar*argvQ); Cách sau được sử dụng khi chương trình được dự tính để chấp nhận các đối số hàng lệnh. Tham số đầu, argc, biếu thị số các đối số được truyền tới chương trình (bao gồm cả tên của chính chương trình). Tham số thứ hai, argv, là một mảng của các hằng chuồi đại diện cho các đối số. Ví dụ từ hàng lệnh đã cho trong hộp thoại 4.1, chúng ta có: aigc is 3 argv[0] is "sum" argv[lj is "10.4" argv[2] is "12.5" Danh sách 4.4 minh họa một thi công đơn giản cho chương trình tính tổng sum. Các chuỗi được chuyến đối sang số thực sử dụng hàm atof được định nghĩa trong thư viện stdlibii Danh sách 4.4 1 2 3 4 5 6 7 8 9 10 #inđude<iostnsamii> #inđude <stdlib.h> intmain (int aigc, const chai' *argvQ) { double sum=0; for(inti= l;i<argc;-Bĩ) sum += atoffargv[T]); cout« sum << V; return0; J __________________________ Chương 4: Hàm 54
  • 50. Bài tập cuối chưong 4 4.1 Viết chương trình trong bài tập 1.1 và 3.1 sử dụng hàm. 4.2 Chúng ta có định nghĩa của hàm Swap sau void Swap(intX,inty) { inttemp=x; x=y, y=temp; } cho biết giá trị của Xvà y sau khi gọi hàm: x=10; y=20; Swap(x,y); 4.3 Chương trình sau xuất ra kết quả gì khi được thực thi? #include<iostreamií> char*str="global"; voidPrint(char*str) { cout«str«V i'; { char*str="local"; coirt«str«W ; cout«::str<< V; } cout«str«V i'; } int main (void) { Print(Tarameter”); return0; } 4.4 Viet hàm xuất ra tat cả các số nguyên tố từ 2 đến n (n là số nguyên dương); voidPrimes(unsignedintn); Một sổ là số nguyên tố nếu như nó chỉ chia hết cho chính nó và 1. 4.5 Định nghĩa một báng liệt kê gọi là Month cho tất cả các tháng trong năm và sử dụng nó đề định nghĩa một hàm nhận một tháng như là một đối số và trả về nó như là một hằng chuồi. 4.6 Định nghĩa một hàm inline IsAlpha, hàm trả về khác 0 khi tham số của nó là một ký tự và trả về 0 trong các trường hợp khác. Chương 4: Hàm 55