&
VC
ộ
N i dung
BB
Khái niệm và cú pháp
1
Tầm vực
2
Tham số và lời gọi hàm
3
Đệ quy
4
11
NMLT Hàm (Function)
&
VC
ề
ặ ấ Đ t v n đ
BB
Viết chương trình tính S = a! + b! + c! với a, b, c
là 3 số nguyên dương nhập từ bàn phím.
Chương trình chính
Nhập a, b, c > 0 Tính S = a! + b! + c! Xuất kết quả S
22
NMLT Hàm (Function)
Nhập a > 0 Nhập b > 0 Nhập c > 0 Tính s1=a! Tính s2=b! Tính s3=c!
&
VC
ề
ặ ấ Đ t v n đ
BB
3 đoạn lệnh nhập a, b, c > 0
do {
printf(“Nhap mot so nguyen duong: ”); scanf(“%d”,&a);
} while (a <= 0);
do {
printf(“Nhap mot so nguyen duong: ”); scanf(“%d”,&b);
} while (b <= 0);
do {
printf(“Nhap mot so nguyen duong: ”); scanf(“%d”,&c);
33
NMLT Hàm (Function)
} while (c <= 0);
&
VC
ề
ặ ấ Đ t v n đ
BB
3 đoạn lệnh tính s1 = a!, s2 = b!, s3 = c!
{ Tính s1 = a! = 1 * 2 * … * a } s1 = 1; for (i = 2; i <= a ; i++) s1 = s1 * i;
{ Tính s2 = b! = 1 * 2 * … * b } s2 = 1; for (i = 2; i <= b ; i++) s2 = s2 * i;
44
NMLT Hàm (Function)
{ Tính s3 = c! = 1 * 2 * … * c } s3 = 1; for (i = 2; i <= c ; i++) s3 = s3 * i;
&
VC
ề
ặ ấ Đ t v n đ
BB
Giải pháp => Viết 1 lần và sử dụng nhiều lần Đoạn lệnh nhập tổng quát, với n = a, b, c
do {
printf(“Nhap mot so nguyen duong: ”); scanf(“%d”,&n);
} while (n <= 0);
Đoạn lệnh tính giai thừa tổng quát, n = a, b, c
{ Tính s = n! = 1 * 2 * … * n } s = 1; for (i = 2; i <= n ; i++)
55
NMLT Hàm (Function)
s = s * i;
&
VC
Hàm
BB
Khái niệm
Một đoạn chương trình có tên, đầu vào và
đầu ra.
Có chức năng giải quyết một số vấn đề chuyên biệt cho chương trình chính.
Được gọi nhiều lần với các tham số khác
nhau.
Được sử dụng khi có nhu cầu:
• Tái sử dụng. • Sửa lỗi và cải tiến.
66
NMLT Hàm (Function)
&
VC
Hàm
BB
Các đặc trưng của Hàm
Nằm trong hoặc ngoài văn bản có chương trình gọi đến hàm. Một văn bản có thể chứa nhiều hàm.
Được gọi từ chương trình chính (main), từ hàm
khác hoặc từ chính nó (đệ quy).
Không lồng nhau. Có 3 cách truyền giá trị: Truyền theo tham trị,
tham biến và tham trỏ.
Các biến cục bộ trong hàm được tạo ra khi hàm
được gọi và biến mất khi hàm thực thi xong.
77
NMLT Hàm (Function)
&
VC
Hàm
BB
88
NMLT Hàm (Function)
&
VC
Hàm
BB
Có 2 loại hàm trong NNLT “C/C++”: Hàm thư viện (library functions):
Do chương trình dịch “C/C++” cung cấp.
Để sử dụng các hàm này trong chương trình,
đầu chương trình phải chứa các khai báo và định
nghĩa hằng, biến, hàm nguyên mẫu, . . . bằng
các chỉ thị tiền xử lý #include
Ví dụ: #include
Hàm tự tạo:
Do người sử dụng định nghĩa thêm các hàm khác phục vụ cho nhu cầu lập trình của mình.
99
NMLT Hàm (Function)
&
VC
Hàm
BB
Cú pháp
Trong đó }
•
long, float,…). Nếu không trả về thì là void.
•
•
1010
NMLT Hàm (Function)
&
VC
ướ
ế
Các b
c vi
t hàm
BB
Cần xác định các thông tin sau đây:
Tên hàm. Hàm sẽ thực hiện công việc gì. Các đầu vào (nếu có). Đầu ra (nếu có).
Đầu vào 1
Đầu vào 2
Đầu ra (nếu có)
Đầu vào n
Các công việc sẽ thực hiện
1111
NMLT Hàm (Function)
Tên hàm
&
VC
Hàm
BB
Ví dụ 1
Tên hàm: XuatTong Công việc: tính và xuất tổng 2 số nguyên Đầu vào: hai số nguyên x và y Đầu ra: không có
void XuatTong(int x, int y) {
int s; s = x + y; printf(“%d+%dy=%dx“,x,y,s);
1212
NMLT Hàm (Function)
}
&
VC
Hàm
BB
Ví dụ 2
Tên hàm: TinhTong Công việc: tính và trả về tổng 2 số nguyên Đầu vào: hai số nguyên x và y Đầu ra: một số nguyên có giá trị x + y
int TinhTong(int x, int y) {
int s; s = x + y; return s;
1313
NMLT Hàm (Function)
}
&
VC
ươ
Ch
ng trình con Function
BB
Ví dụ 3
Tên hàm: NhapXuatTong Công việc: nhập và xuất tổng 2 số nguyên Đầu vào: không có Đầu ra: không có
void NhapXuatTong() {
int x, y; printf(“Nhap 2 so nguyen: ”); scanf(“%d%d”,&x,&y); printf(“%d+%dy=%dx“,x,y,x+y);
1414
NMLT Hàm (Function)
}
&
VC
ự
ầ
T m v c
BB
Khái niệm
Là phạm vi hoạt động của biến và hàm. Biến:
• Toàn cục: khai báo ngoài tất cả các hàm (kể cả hàm main) và có tác dụng lên toàn bộ chương trình.
• Cục bộ: khai báo trong hàm hoặc khối { } và chỉ có tác dụng trong bản thân hàm hoặc khối đó (kể cả khối con nó). Biến cục bộ sẽ bị xóa khỏi bộ nhớ khi kết thúc khối khai báo nó.
1515
NMLT Hàm (Function)
&
VC
ự
ầ
T m v c
BB
int a;
int Ham1() {
int a1;
}
int Ham2() {
int a2; {
int a21;
}
}
void main() {
int a3;
}
1616
NMLT Hàm (Function)
&
VC
BB
Hàm nguyên m uẫ (function prototype)
Hàm nguyên mẫu:
Được dùng để cung cấp thông tin cho chương trình dịch về tên hàm, kiểu giá trị trả về, số lượng, thứ tự và kiểu của các tham số của hàm.
Chương trình dịch căn cứ vào các thông tin này để kiểm
tra các lời gọi hàm trong chương trình.
Hàm nguyên mẫu được đặt sau phần khai báo toàn cục và ngay trước hàm main() hoặc có thể đặt trong tập tin khác. Khai báo:
[
1717
Ví dụ: Khai báo hàm nguyên mẫu có chức năng xác định
trị min giữa 2 số nguyên. int Min(int, int) ; int Min(int a, int b) ; // nên dùng cách khai báo này
&
VC
ứ
ổ
ộ
ươ
T ch c m t ch
ng trình “C/C++”
BB
PHẦN KHAI BÁO TOÀN CỤC
PHẦN KHAI BÁO VÀ ĐỊNH NGHĨA HÀM
HÀM main()
Cách 1: chương trình gồm 3 phần
PHẦN KHAI BÁO TOÀN CỤC
PHẦN KHAI BÁO HÀM NGUYÊN MẪU
HÀM main()
PHẦN ĐỊNH NGHĨA HÀM
1818
Cách 2: chương trình gồm 4 phần (nên dùng cách này)
&
VC
ứ
ổ
ộ
ươ
T ch c m t ch
ng trình “C/C++”
BB
Ví dụ: Cách 2
#include
//prototype
#include
void main() { int a=40, b=30;
if (a
int min1 = min(a,b); printf(“Min = %d“,min1);
} void main() { int a=40, b=30;
} int min(int a, int b) {
int min1 = min(a,b); printf(“Min = %d“,min1);
if (a
}
}
1919
Ví dụ: cách 1
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Có hai loại tham số: Tham số thực (actual parameter):là tham số trong lời gọi
hàm.
2020
Tham số hình thức (formal parameter): là tham số trong phần khai báo và định nghĩa. Tham số hình thức chỉ là tên đại diện cho tham số thực tương ứng. Kiểu của tham số hình thức sẽ qui định kiểu của tham số thực.
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Ví dụ:
int min(int a, int b) //a,b là tham số hình thức {
if(a
int minAB =min(7,10)//Gọi hàm
2121
} void main() { // a = 7, b=10 } // Lúc này a,b là tham số thực
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Có hai cách truyền tham số: 1. Truyền tham trị (call by value): Chương trình dịch cấp phát vùng nhớ riêng cho từng tham số hình thức, sau đó sao chép giá trị của tham số thực tương ứng vào các tham số hình thức.
Khi kết thúc thực hiện hàm, chương trình dịch sẽ thu hồi các vùng nhớ đã cấp phát cho các tham số hình thức, và các biến cục bộ khai báo bên trong hàm.
Như vậy, mọi sự thay đổi trị của các tham số hình thức đều
không ảnh hưởng đến các tham số thực bên ngoài hàm.
Cách truyền:
void F(int, int ); // truyền bằng trị
hay
2222
void F(int a, int b); // truyền bằng trị
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Truyền Giá trị (Call by Value)
Truyền đối số cho hàm ở dạng giá trị. Có thể truyền hằng, biến, biểu thức nhưng hàm
sẽ chỉ nhận giá trị.
Được sử dụng khi không có nhu cầu thay đổi giá
trị của tham số sau khi thực hiện hàm.
void TruyenGiaTri(int x) {
… x++;
2323
NMLT Hàm (Function)
}
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
#include
doubleNum(a); printf(“Bên trong hàm main:\n”); printf(“a = %d“, a);
} void doubleNum(int a) {
a = a*2; printf(“Inside doubleNum function. a = %d“,a);
}
2424
Ví dụ: Khảo sát chương trình sau
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
2. Truyền tham chiếu(call by reference): Chương trình dịch sẽ truyền địa chỉ của các tham số thực tương
ứng cho các tham số hình thức.
Nghĩa là ta có thể xem tham số hình thức cũng chính là tham số thực, hay nói cách khác tham số hình thức là tên gọi khác của tham số thực.
Mọi sự thay đổi trị của tham số hình thức bên trong hàm chính là
thay đổi trị của tham số thực bên ngoài hàm.
Cách truyền:
void Swap(int &,int &); // truyền bằng tham chiếu
hay
2525
void Swap(int & a,int & b); // truyền bằng tham chiếu
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Truyền Địa chỉ (Call by Address)
Truyền đối số cho hàm ở dạng địa chỉ (con
trỏ).
Không được truyền giá trị cho tham số này. Được sử dụng khi có nhu cầu thay đổi giá
trị của tham số sau khi thực hiện hàm.
void TruyenDiaChi(int *x) {
… *x++;
2626
NMLT Hàm (Function)
}
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Truyền Tham chiếu (Call by Reference) (C++)
Truyền đối số cho hàm ở dạng địa chỉ (con trỏ).
Được bắt đầu bằng & trong khai báo.
Không được truyền giá trị cho tham số này. Được sử dụng khi có nhu cầu thay đổi giá trị của
tham số sau khi thực hiện hàm.
void TruyenThamChieu(int &x) {
… x++;
2727
NMLT Hàm (Function)
}
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
#include
doubleNum(a); printf(“Inside main function:\n”); printf(“a =%d “ , a);
} void doubleNum(int &a) {
a = a*2; printf(“Inside doubleNum function. a = %d“, a);
}
2828
Ví dụ: Khảo sát chương trình sau
&
VC
ươ
ề
ố
Các ph
ng pháp truy n tham s
BB
Chú ý: Trong cách truyền tham chiếu, tham số thực tương ứng phải là một biến. Còn trong cách truyền trị, tham số thực tương ứng có thể là biến, hằng, lời gọi hàm, hoặc một biểu thức cùng kiểu với tham số hình thức.
2929
Các tham số hình thức trong cách truyền bằng giá trị được gọi là tham trị. Còn các tham số hình thức trong cách truyền bằng tham chiếu được gọi là tham biến.
&
VC
ố ố
ư
ề
L u ý khi truy n đ i s
BB
Lưu ý
Trong một hàm, các tham số có thể truyền
theo nhiều cách.
void HonHop(int x, int &y) {
… x++; y++;
3030
NMLT Hàm (Function)
}
&
VC
ố ố
ư
ề
L u ý khi truy n đ i s
BB
Lưu ý
Sử dụng tham chiếu là một cách để trả về
giá trị cho chương trình.
int TinhTong(int x, int y) {
return x + y;
} void TinhTong(int x, int y, int &tong) {
tong = x + y;
} void TinhTongHieu(int x, int y, int &tong, int &hieu) {
3131
NMLT Hàm (Function)
tong = x + y; hieu = x – y;
}
&
VC
ờ ọ
L i g i hàm
BB
Cách thực hiện
Gọi tên của hàm đồng thời truyền các đối số (hằng, biến, biểu thức) cho các tham số theo đúng thứ tự đã được khai báo trong hàm. Các biến hoặc trị này cách nhau bằng dấu , Các đối số này được được đặt trong cặp dấu
ngoặc đơn ( )
3232
NMLT Hàm (Function)
&
VC
ờ ọ
L i g i hàm
BB
Ví dụ
3333
NMLT Hàm (Function)
&
VC
ờ ọ
ươ
L i g i ch
ng trình con
BB
Ví dụ
3434
NMLT Hàm (Function)
&
VC
ệ
Đ quy
BB
3. Hàm gọi đệ qui: một lệnh trong thân hàm gọi đến chính nó. Số lần
gọi này phải có giới hạn (điểm dừng) Ví dụ: chương trình tính giai thừa của n.
int giaiThua(int n) {
#include
int gt; if(n==1) return(1); // goi de qui gt = giaiThua(n1)*n; return gt;
}
int gt4, gt7; gt4 = giaiThua(4); gt7 = giaiThua(7); cout << “4! =“ << gt4 << endl; cout << “7! =“ << gt7 << endl;
3535
}
&
VC
ệ
Đ quy
BB
Đặc điểm của hàm đệ qui: Chương trình viết rất gọn, Việc thực hiện gọi đi gọi lại hàm rất nhiều lần phụ thuộc vào độ lớn của đầu vào. Do đó chương trình sẽ mất thời gian để lưu giữ các thông tin của hàm gọi trước khi chuyển điều khiển đến thực hiện hàm được gọi. Mặt khác các thông tin này được lưu trữ nhiều lần trong ngăn xếp sẽ dẫn đến tràn ngăn xếp nếu n lớn.
3636
Tuy nhiên, đệ qui là cách viết rất gọn, dễ viết và đọc chương trình, mặt khác có nhiều bài toán hầu như tìm một thuật toán lặp cho nó là rất khó trong khi viết theo thuật toán đệ qui thì lại rất dễ dàng.
&
VC
ệ
Đ quy
BB
Lớp các bài toán giải được bằng đệ qui Giải quyết được dễ dàng trong các trường hợp riêng gọi là trường hợp suy biến hay cơ sở, trong trường hợp này hàm được tính bình thường mà không cần gọi lại chính nó,
3737
Đối với trường hợp tổng quát, bài toán có thể giải được bằng bài toán cùng dạng nhưng với tham đối khác có kích thước nhỏ hơn tham đối ban đầu. Và sau một số bước hữu hạn biến đổi cùng dạng, bài toán đưa được về trường hợp suy biến.
&
VC
ệ
Đ quy
BB
Các ví dụ Ví dụ 1 : Tìm UCLN của 2 số a, b. Bài toán có thể được định
nghĩa dưới dạng đệ qui như sau: − nếu a = b thì UCLN = a − nếu a > b thì UCLN(a, b) = UCLN(a-b, b) − nếu a < b thì UCLN(a, b) = UCLN(a, b-a)
Chương trình đệ qui để tính UCLN của a và b như sau.
int UCLN(int a, int b) // qui uoc a, b > 0 { if (a < b) UCLN(a, b-a); if (a == b) return a; if (a > b) UCLN(a-b, b);
3838
}
&
VC
ệ
Đ quy
BB
Ví dụ 2 : Tính số hạng thứ n của dãy Fibonaci là dãy f(n) được
− f(0) = f(1) = 1
− f(n) = f(n-1) + f(n-2) với n ≥ 2.
định nghĩa:
{ long kq;
if (n==0 || n==1) kq = 1; else kq = Fib(n-1) + Fib(n-2);
return kq;
}
3939
long Fib(int n)
&
VC
(Function overloading)
ạ
ồ N p ch ng hàm
BB
Nạp chồng hàm là dùng chung một danh hiệu để đặt tên cho các
hàm khác nhau.
void main() {
double x = 20.0; int y = 10; F(x, y); // mơ hồ! chương trình dịch không biết gọi hàm nào
}
Chỉ nạp chồng hàm đối với những hàm giống nhau về bản chất, nhưng khác nhau ở số lượng, và kiểu dữ liệu của các tham số. Khả năng nạp chồng hàm kết hợp với hàm có tham số với giá trị
4040
ngầm định có thể gây ra tình trạng nhập nhằng, mơ hồ void F(int, double) { …. } void F(int) { …. } void F(double) { … }
&
VC
ộ ố ợ
ế ế
M t s g i ý khi thi
t k hàm
BB
Xác định rõ chức năng, nhiệm vụ của hàm. Chỉ nên thiết kế hàm theo phương châm “mỗi hàm chỉ thực hiện một nhiệm vụ duy nhất”, và nên thiết kế sao cho có thể sử dụng lại hàm để hổ trợ cho các việc khác (reusable).
4141
Đặt tên hàm sao cho có tính gợi nhớ (Memonic) Nên đặt chú thích, ghi rõ các thông tin về hàm như chức năng, điều kiện dữ liệu vào, xác định dữ liệu ra của hàm, . . . Xác định trị trả về: hàm có cần trả về giá trị? Nếu có, xác định rõ kiểu trả về. Đối với các hàm có chức năng nhập/xuất dữ liệu, trị trả về thường là void. Còn đối với loại hàm kiểm tra một tính chất P nào đó, ta thường trả về giá trị 0 hoặc 1, i.e. trả về trị của một biểu thức logic.
&
VC
ộ ố ợ
ế ế
M t s g i ý khi thi
t k hàm
BB
Xác định số lượng tham số và kiểu của từng tham số: hàm có nhận tham số hay không? Bao nhiêu tham số? Kiểu của từng tham số?
4242
Xác định rõ phương pháp truyền tham số: nếu không có nhu cầu làm thay đổi trị của tham số thực truyền vào cho hàm thì áp dụng phương pháp truyền bằng giá trị. Còn ngược lại thì áp dụng cách truyền bằng tham chiếu.
&
VC
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
BB
Phạm vi là vùng chương trình mà đối tượng được nhận biết và có
thể được sử dụng.
Phạm vi của một đối tượng trải dài từ nơi nó được khai báo đến
cuối khối, hàm, hay tập tin chứa đối tượng đó. Có các loại phạm vi sau:
− Phạm vi khối (Block scope) − Phạm vi hàm (Function scope)
Phạm vi cục bộ (local scope)
− Phạm vi tập tin (File scope) − Phạm vi chương trình (Program scope)
4343
Phạm vi toàn cục (global scope)
&
VC
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
BB
Phạm vi khối: Trong C, một khối được giới hạn bởi ngoặc {}. Biến khai báo trong khối đó có phạm vi khối, nghĩa là nó chỉ hoạt động trong khối đó mà thôi. Phạm vi này còn gọi là cục bộ, và biến đưọc gọi là biến cục bộ.
Ví dụ: int main()
4444
{ int i; /* block scope */ . . . return 0; }
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Ví dụ: 1: /* Scopes in nested block */
2: #include
3:
4: main()
5: {
6: int i = 32; /* block scope 1*/
7:
8: cout<<"Within the outer block: i=“<
Kết quả:
Within the outer block:
i=32
Within the inner block:
i= 0, j=10
i= 1, j= 9
i= 2, j= 8
i= 3, j= 7
i= 4, j= 6
i= 5, j= 5
i= 6, j= 4
i= 7, j= 3
i= 8, j= 2
i= 9, j= 1
i=10, j= 0
Within the outer block:
i=32
4545
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Phạm vi hàm: chỉ định một biến có phạm vi hoạt động từ đầu
đến cuối một hàm (không nhầm lẫn với biến có phạm vi khối).
Trong C, chỉ có nhãn (label) đối với lệnh goto là có phạm vi
hàm.
Ví dụ : int main()
.
.
.
.
{ int i; /* block scope */
start: /* A goto label has function scope */
goto start; /* the goto statement */
.
.
4646
return 0;
}
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Phạm vi chương trình: Biến có phạm vi chương trình khi nó
được khai báo bên ngoài các hàm.
Ví dụ:
int i; /* block scope */
.
.
return 0;
int x = 0; /* program scope */
float y = 0.0; /* program scope */
int main()
{
}
4747
Biến này còn gọi là biến toàn cục
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Ví d :ụ
ế
ả
K t qu :
From function_1:
x=1234, y=1.234567
Within the main block:
x=4321, y=1.234567
From function_1:
x=1234, y=1.234567
Within the nested block:
x=4321, y=7.654321
1: /* Program scope vs block scope */
2: #include
4: int x = 1234; /* program scope */
5: double y = 1.234567; /* program scope */
7: void function_1()
8: {
9: cout<<"From function_1: x=,”<
4848
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Phạm vi tập tin: Trong C, biến được khai báo là toàn cục và
static được gọi là có phạm vi tập tin.
4949
int x = 0; /* program scope */
static int y = 0; /* file scope */
static float z = 0.0; /* file scope */
int main()
{ int i; /* block scope */
.
.
.
return 0;
}
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Ví dụ:
cout<<”Y = “<
bị hủy, không thể truy
xuất
#include
int x=3; // biến x toàn cục
const int MAX = 10;
void fct(int x);
void main()
{
cout<<”X của hàm main() = “<
int x=1; // x cục bộ của hàm main()
fct(x);
“<
}
{
int y=4;
x += y;
5050
}
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Biến toàn cục (local variable) Biến cục bộ (Global variable)
Biến cục bộ là biến khai báo bên
trong khối hay hàm của khối. Biến toàn cục là biến khai báo
bên ngoài mọi hàm
Có thể được truy xuất ở mọi nơi
trong chương trình.
Chỉ có thể được truy xuất bên
trong phạm vi khối hay hàm đó mà
thôi.
Các biến toàn cục có thời gian
tồn tại là thời gian của chương
trình
5151
Các biến cục bộ có thời gian tồn tại
tương đối ngắn. Chúng sẽ bị hủy
mỗi khi ra khỏi khối hay kết thúc
thực hiện hàm chứa nó.
&
VC
ấ ư
ố ượ
BB
ữ ủ
C p l u tr c a các đ i t
ng
Cấp lưu trữ (storage class) là cách thức NNLT cấp phát vùng nhớ và
lưu trữ biến. Cấp lưu trữ của một biến được xác định bằng các từ khóa
sau: auto, register, static, extern.
Biến auto (còn gọi là biến tự động, biến cục bộ):
Mọi biến khai báo bên trong một khối hay hàm mặc nhiên
5252
có tính chất auto, trừ khi xác định rõ cấp lưu trữ khác.
Ví dụ, khai báo int x; tương đương với khai báo auto int x;.
Biến auto có phạm vi cục bộ bên trong hàm hay khối và có
thời gian tồn tại ngắn, do được cấp phát trong vùng nhớ
STACK.
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
Để tăng tốc độ truy xuất biến, chương trình dịch lưu
trữ biến trong thanh ghi. Chương trình dịch có thể bỏ
qua không đáp ứng lời yêu cầu này nếu có quá nhiều
lời đề nghị loại này hoặc nếu không còn đủ thanh ghi
để cấp phát.
Ví dụ: int main()
Biến register (ít dùng)
{ /* block scope with the register specifier */
register int i;
. . .
for (i=0; i
*/}
5353
. . .
return 0;
}
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
Là biến được cấp phát trong vùng nhớ DATA do
đó có tính chất cố định, lâu dài.
Biến static khai báo bên trong một khối, hay hàm
sẽ không bị hủy khi ra khỏi khối hay hàm đó, và
vẫn lưu giữ giá trị cũ của lần gọi hàm trước.
Biến static phải được khởi tạo giá trị khi khai báo.
Chương trình dịch sẽ chỉ khởi tạo giá trị cho biến
static duy nhất một lần trong lần gọi hàm đầu tiên.
5454
Biến static (còn gọi là biến tĩnh)
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
Ví d : Bi n Static
static int lanthu = 0;
lanthu++;
i = 2 * i;
ạ ầ
ứ
cout << "Hàm ch y l n th " << lanthu << ", i = " << i ;
…
}
main()
{
ạ ầ
ạ ầ
ạ ầ
ứ
ứ
ứ
ham(); // Hàm ch y l n th 1, i = 2
ham(); // Hàm ch y l n th 2, i = 4
ham(); // Hàm ch y l n th 3, i = 6
…}
5555
ế
ụ
int i = 1;
void ham()
{
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
Biến extern
Phạm vi của một biến extern trong chương trình có thể
được trải dài trên nhiều tập tin.
Chương trình dịch sẽ không cấp phát thêm vùng nhớ cho
biến có khai báo extern mà sử dụng chung vùng nhớ đã
cấp phát trước đó.
Ví dụ: int x = 0; /* a global variable */
5656
extern int y; /* an allusion to a global variable y */
int main()
{ extern int z; /* an allusion to a global variable z */
int i; /* a local variable */
.
.
return 0;
}
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
Ví d : Bi n Extern
int i = 1;
in();
ế
ụ
void in();
void main()
{ void in();
void main()
{
extern i = 1;
in();
}
void in()
{
}
void in()
{
cout << i ;
cout << i ;
}
Lỗi (cú pháp) vì i là biến cục bộ trong main(), trong in() không nhận biết i,
nếu trong hoặc trước in() khai báo thêm i thì lỗi ngữ nghĩa (tức chương trình
in giá trị i khác không theo ý muốn của lập trình viên).
5757
}
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
Ví dụ: Biến Extern
/* program2.cpp */
void in()
{
Giả thiết 2 chương trình trên nằm trong 2 tệp khác nhau. Để liên
kết (link) biến i giữa 2 chương trình cần định nghĩa tổng thể i
trong một và khai báo extern trong chương trình kia.
extern i;
cout << i ;
/* program1.cpp*/
void in();
int i;
void main()
{
}
i = 1;
in();
5858
}
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
5959
ắ ề ấ ư Tóm t t v c p l u tr bi n ( ữ ế Storage class)
&
VC
Các ch ỉ th ị tiền x ử lý
BB
a. Chỉ thị bao hàm tệp #include
Cho phép ghép nội dung các tệp đã có khác vào chương trình
trước khi dịch. Các tệp cần ghép thêm vào chương trình
thường là các tệp chứa khai báo nguyên mẫu của các hằng,
biến, hàm … có sẵn trong C hoặc các hàm do lập trình viên tự
viết.
Có hai dạng viết chỉ thị này.
1: #include
Các tập tin nguyên mẫu của thư viện C++, chứa trong thư
mục Borlandc\Include
2: #include “đường dẫn\tệp”
6060
Tìm tệp theo đường dẫn, nếu không có đường dẫn sẽ tìm
trong thư mục hiện tại. Tệp thường là các tệp (thư viện) được
tạo bởi lập trình viên và được đặt trong cùng thư mục chứa
chương trình.
&
VC
Các ch ỉ th ị tiền x ử lý
BB
#define tên_macro xaukitu
b. Chỉ thị macro #define
Cú pháp:
Trước khi dịch bộ tiền xử lý sẽ tìm trong chương trình và thay
thế bất kỳ vị trí xuất hiện nào của tên_macro bởi xâu kí tự. Ta
thường sử dụng macro để định nghĩa các hằng hoặc thay cụm
từ này bằng cụm từ khác dễ nhớ hơn.
if (i < MAX) then
begin
Viết
Ok = TRUE;
cout << i ;
end
if (i < 100 then
{
Ví dụ:
Ct dịch
Ok = 1;
cout << i ;
}
6161
#define then // thay then bằng dấu cách
#define begin { // thay begin bằng dấu {
#define end } // thay end bằng dấu }
#define MAX 100 // thay MAX bằng 100
#define TRUE 1 // thay TRUE bằng 1
&
VC
Các ch ỉ th ị tiền x ử lý
BB
c. Các chỉ thị biên dịch có điều kiện #if, #ifdef, #ifndef
Chỉ thị:
#if dãy lệnh … #endif
#if dãy lệnh … #else dãy lệnh … #endif,
Báo cho chương trình dịch biết đoạn lệnh giữa #if (điều kiện) và
#endif chỉ được dịch nếu điều kiện đúng.
const int M = 10;
void main() {
int i = 5;
#if M > 8
cout << i+i ;
Ví dụ:
#else
const int M = 1;
void main() {
int i = 5;
#if M ==1
cout << i*i ;
cout << i ;
#endif
}
#endif
6262
}
&
VC
Các ch ỉ th ị tiền x ử lý
BB
d. Chỉ thị #ifdef và #ifndef
Chỉ thị này báo cho chương trình dịch biết đoạn lệnh có được dịch
hay không khi một tên gọi đã được định nghĩa hay chưa.
Để định nghĩa một tên gọi ta dùng chỉ thị #define tên.
Chỉ thị này đặc biệt có ích khi chèn các tệp thư viện vào để sử
6363
dụng. Một tệp thư viện có thể được chèn nhiều lần trong văn bản
do vậy nó có thể sẽ được dịch nhiều lần, điều này sẽ gây ra lỗi vì
các biến được khai báo nhiều lần.
&
VC
Các ch ỉ th ị tiền x ử lý
BB
ủ
d. Chỉ thị #ifdef và #ifndef
Thư viện 1. tên tệp: MYLIB.H
ươ
ả
int max(int a, int b)
{
return (a>b? a: b);
}
Thư viện 2. tên tệp: MATHFUNC.H
>> b >> c;
ậ
Hàm main c a chúng ta nh p 3
ặ ố
ủ ừ
ố
s , in ra max c a t ng c p s và
ố
ả
ủ
ng trình
max c a c 3 s . Ch
ư ệ
ả ử ụ
ầ
c n ph i s d ng c 2 th vi n.
#include "mylib.h"
#include "mathfunc.h"
main()
{
int a, b, c;
cout << "a, b, c = " ; cin >> a
cout << max(a,b) << max(b,c)
<< max(a,c) << max(a,b,c) ;
#include "mylib.h"
int max(int a, int b)
{
return (a>b? a: b);
}
C++ sẽ báo lỗi (do hàm int max(inta, int b) được khai báo hai lần
6464
}
&
VC
Các ch ỉ th ị tiền x ử lý
BB
// tệp mylib.h
#ifndef _MYLIB_ // nếu chưa định nghĩa tên gọi _MYLIB_
#define _MYLIB_ // thì định nghĩa nó
int max(int a, int b) // và các hàm khác
{
return (a>b? a: b);
}
#endif
6565
Khắc phục
&
VC
ỏ
BB
ậ
Câu h i và bài t p
1. Nêu cách khai báo hàm, định nghĩa hàm, cách gọi hàm.
2. Phạm vi của một đối tượng (biến, hằng) trong chương trình ?
3. Trình bày các phương pháp truyền tham số cho hàm (truyền
bằng giá trị, bằng tham chiếu, và bằng tham trỏ)
4. Nêu cách thiết kế hàm mà theo Anh (Chị) cho là đạt yêu cầu.
5. Cho ví dụ về hàm xuất/nhập.
6. Cho ví dụ về hàm kiểm tra một giá trị nguyên thỏa tính chất “P”
nào đó.
7. Cho ví dụ về hàm xác định giá trị nguyên thỏa tính chất “P” nào
đó.
6666
8. Trình bày cách tổ chức một chương trình “C/C++”.
&
VC
ỏ
BB
ậ
Câu h i và bài t p
8. Trình bày cấp lưu trữ của một đối tượng (auto, register,
static, extern).
− Giải phương trình bậc 2 ax2 + bx + c = 0
− In bảng cửu chương theo chiều dọc, ngang.
− Kiểm tra 1 bộ ngày, tháng, năm có hợp lệ hay không ?
− Vẽ hình tam giác với chiều cao h dạng …
− Phân tích số n > 0 thành tích các thừa số nguyên tố theo
9. Khai báo các hàm nguyên mẫu sau:
dạng n = 120 = 2*2*2*3*5.
6767
− Kiểm tra số tự nhiên n > 0 có phải là số nguyên tố ?
− Tính trị max của 2 số nguyên.
− Tính trị min của 2 số nguyên.
− Tính USCLN của 2 số tự nhiên.
&
VC
ỏ
BB
ậ
Câu h i và bài t p
10 Chọn câu sai trong các câu sau đây:
A: Hàm không trả lại giá trị thì không cần khai báo kiểu giá trị
của hàm.
B: Các biến được khai báo trong hàm là cục bộ, tự xoá khi hàm
thực hiện xong
C: Hàm không trả lại giá trị sẽ có kiểu giá trị ngầm định là void.
D: Hàm là đơn vị độc lập, không được khai báo hàm lồng nhau.
11 Chọn câu đúng nhất trong các câu sau đây:
A: Hàm phải được kết thúc với 1 câu lệnh return
B: Phải có ít nhất 1 câu lệnh return cho hàm
C: Các câu lệnh return được phép nằm ở vị trí bất kỳ trong thân
hàm
D: Không cần khai báo kiểu giá trị trả lại của hàm nếu hàm
6868
không có lệnh return
&
VC
Câu hỏi và bài tập
BB
12. Chọn câu sai trong các câu sau đây:
A: Số tham số thực sự phải bằng số tham số hình thức trong lời
gọi hàm
B: Các biến cục bộ trong thân hàm được chương trình dịch cấp
phát bộ nhớ
C: Các tham số hình thức sẽ được cấp phát bộ nhớ tạm thời khi
hàm được gọi
D: Kiểu của tham số thực sự phải bằng kiểu của tham số hình
thức tương ứng với nó trong lời gọi hàm
13. Để thay đổi giá trị của tham biến, các đối của hàm cần khai
6969
báo dưới dạng:
A: biến bình thường và tham đối được truyền theo giá trị
B: biến con trỏ và tham đối được truyền theo giá trị
C: biến bình thường và tham đối được truyền theo địa chỉ
D: biến tham chiếu và tham đối được truyền theo giá trị
&
VC
Câu hỏi và bài tập
BB
ế
ươ
ế ị
Hãy cho bi
ng tr
àn hình c a củ ác bi n x, y, v
à z c a củ ác ch
ình sau:
t tr in ra m
#include
void mul(int&,int,int&);
int main( ) {
int x = 4, y = 3, z = 2;
mul( y, z, x );
cout << "\nX = " << x;
cout << "\nY = " << y;
cout << "\nZ = " << z;
return 0;
}
void mul( int & x,int y, int & z ) {
x *= y;
y *= z;
z *= x;
}
7070
&
VC
ỏ
BB
ậ
Câu h i và bài t p
ế
ươ
ế ị
Hãy cho bi
ng tr
àn hình c a củ ác bi n x, y, v
à z c a củ ác ch
ình sau:
t tr in ra m
#include
void f( int x, int & y, int z );
void g( int & x, int y, int & z );
int main() {
void f( int x, int & y, int z )
{
g( z, y, x );
x += y;
y += z;
z += x;
}
void g( int & a, int b, int &
c ) {
int x = 2, y = 3, z = 4;
f( y, z, x );
cout << "\nX = " << x;
cout << "\nY = " << y;
cout << "\nZ = " << z;
return 0;
7171
a *= b;
b *= c;
c *= a; } }
&
VC
ự
ậ
Bài t p th c hành
BB
5. Bài 4, 5, 6, 7, 8 trang 140-141 chương 8 (Câu lệnh
điều kiện và rẽ nhánh)
a. Viết hàm đổi một ký tự hoa sang ký tự thường.
b. Viết thủ tục giải phương trình bậc nhất.
c. Viết thủ tục giải phương trình bậc hai.
d. Viết hàm trả về giá trị nhỏ nhất của 4 số
nguyên.
e. Viết thủ tục hoán vị hai số nguyên.
f. Viết thủ tục sắp xếp 4 số nguyên tăng dần.
7272
NMLT Hàm (Function)
&
VC
ự
ậ
Bài t p th c hành
BB
6. Bài tập 3 trang 155 chương 9 (Câu lệnh lặp). Hàm
nhận vào một số nguyên dương n và thực hiện:
a. Trả về số đảo của số đó.
b. Có phải là số đối xứng (Trả về True/False)
c. Có phải là số chính phương.
d. Có phải là số nguyên tố.
e. Tổng các chữ số lẻ.
f. Tổng các chữ số nguyên tố.
g. Tổng các chữ số chính phương.
7373
NMLT Hàm (Function)
&
VC
ự
ậ
Bài t p th c hành
BB
7. Bài tập 4 trang 156 chương 9 (Câu lệnh lặp). Hàm
nhận vào một số nguyên dương n và thực hiện:
a. S = 1 + 2 + … + n
b. S = 12 + 22 + … + n2
c. S = 1 + 1/2 + … + 1/n
d. S = 1 * 2 * … * n
e. S = 1! + 2! + … + n!
7. Hàm trả về USCLN của 2 số nguyên.
In ra n phần tử của dãy Fibonacy.
8.
7474
NMLT Hàm (Function)
Kết quả: Within the outer block: i=32 Within the inner block: i= 0, j=10 i= 1, j= 9 i= 2, j= 8 i= 3, j= 7 i= 4, j= 6 i= 5, j= 5 i= 6, j= 4 i= 7, j= 3 i= 8, j= 2 i= 9, j= 1 i=10, j= 0 Within the outer block: i=32
4545
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Phạm vi hàm: chỉ định một biến có phạm vi hoạt động từ đầu đến cuối một hàm (không nhầm lẫn với biến có phạm vi khối). Trong C, chỉ có nhãn (label) đối với lệnh goto là có phạm vi hàm.
Ví dụ : int main()
. .
. .
{ int i; /* block scope */ start: /* A goto label has function scope */ goto start; /* the goto statement */
. .
4646
return 0;
}
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Phạm vi chương trình: Biến có phạm vi chương trình khi nó
được khai báo bên ngoài các hàm.
Ví dụ:
int i; /* block scope */
. . return 0;
int x = 0; /* program scope */ float y = 0.0; /* program scope */ int main() { }
4747
Biến này còn gọi là biến toàn cục
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
Ví d :ụ
ế
ả K t qu : From function_1: x=1234, y=1.234567 Within the main block: x=4321, y=1.234567 From function_1: x=1234, y=1.234567 Within the nested block: x=4321, y=7.654321
1: /* Program scope vs block scope */
2: #include 4848 Phạm vi tập tin: Trong C, biến được khai báo là toàn cục và static được gọi là có phạm vi tập tin. 4949 int x = 0; /* program scope */
static int y = 0; /* file scope */
static float z = 0.0; /* file scope */
int main()
{ int i; /* block scope */
.
.
.
return 0;
} Ví dụ: cout<<”Y = “< bị hủy, không thể truy
xuất #include cout<<”X của hàm main() = “< int x=1; // x cục bộ của hàm main()
fct(x); “< } { int y=4;
x += y; 5050 } Biến toàn cục (local variable) Biến cục bộ (Global variable) Biến cục bộ là biến khai báo bên
trong khối hay hàm của khối. Biến toàn cục là biến khai báo
bên ngoài mọi hàm Có thể được truy xuất ở mọi nơi
trong chương trình. Chỉ có thể được truy xuất bên
trong phạm vi khối hay hàm đó mà
thôi. Các biến toàn cục có thời gian
tồn tại là thời gian của chương
trình 5151 Các biến cục bộ có thời gian tồn tại
tương đối ngắn. Chúng sẽ bị hủy
mỗi khi ra khỏi khối hay kết thúc
thực hiện hàm chứa nó. Cấp lưu trữ (storage class) là cách thức NNLT cấp phát vùng nhớ và
lưu trữ biến. Cấp lưu trữ của một biến được xác định bằng các từ khóa
sau: auto, register, static, extern. Biến auto (còn gọi là biến tự động, biến cục bộ): Mọi biến khai báo bên trong một khối hay hàm mặc nhiên 5252 có tính chất auto, trừ khi xác định rõ cấp lưu trữ khác.
Ví dụ, khai báo int x; tương đương với khai báo auto int x;.
Biến auto có phạm vi cục bộ bên trong hàm hay khối và có
thời gian tồn tại ngắn, do được cấp phát trong vùng nhớ
STACK. Để tăng tốc độ truy xuất biến, chương trình dịch lưu
trữ biến trong thanh ghi. Chương trình dịch có thể bỏ
qua không đáp ứng lời yêu cầu này nếu có quá nhiều
lời đề nghị loại này hoặc nếu không còn đủ thanh ghi
để cấp phát. Ví dụ: int main() Biến register (ít dùng) { /* block scope with the register specifier */
register int i;
. . .
for (i=0; i */} 5353 . . .
return 0;
} Là biến được cấp phát trong vùng nhớ DATA do đó có tính chất cố định, lâu dài. Biến static khai báo bên trong một khối, hay hàm
sẽ không bị hủy khi ra khỏi khối hay hàm đó, và
vẫn lưu giữ giá trị cũ của lần gọi hàm trước. Biến static phải được khởi tạo giá trị khi khai báo.
Chương trình dịch sẽ chỉ khởi tạo giá trị cho biến
static duy nhất một lần trong lần gọi hàm đầu tiên. 5454 Biến static (còn gọi là biến tĩnh) Ví d : Bi n Static static int lanthu = 0;
lanthu++;
i = 2 * i; ạ ầ ứ
cout << "Hàm ch y l n th " << lanthu << ", i = " << i ; … }
main()
{ ạ ầ
ạ ầ
ạ ầ ứ
ứ
ứ ham(); // Hàm ch y l n th 1, i = 2
ham(); // Hàm ch y l n th 2, i = 4
ham(); // Hàm ch y l n th 3, i = 6 …} 5555 ế
ụ
int i = 1;
void ham()
{ Biến extern Phạm vi của một biến extern trong chương trình có thể được trải dài trên nhiều tập tin. Chương trình dịch sẽ không cấp phát thêm vùng nhớ cho
biến có khai báo extern mà sử dụng chung vùng nhớ đã
cấp phát trước đó. Ví dụ: int x = 0; /* a global variable */ 5656 extern int y; /* an allusion to a global variable y */
int main()
{ extern int z; /* an allusion to a global variable z */
int i; /* a local variable */
.
.
return 0;
} Ví d : Bi n Extern int i = 1;
in(); ế
ụ
void in();
void main()
{ void in();
void main()
{ extern i = 1;
in(); }
void in()
{ }
void in()
{ cout << i ; cout << i ; } Lỗi (cú pháp) vì i là biến cục bộ trong main(), trong in() không nhận biết i,
nếu trong hoặc trước in() khai báo thêm i thì lỗi ngữ nghĩa (tức chương trình
in giá trị i khác không theo ý muốn của lập trình viên). 5757 } Ví dụ: Biến Extern /* program2.cpp */
void in()
{ Giả thiết 2 chương trình trên nằm trong 2 tệp khác nhau. Để liên
kết (link) biến i giữa 2 chương trình cần định nghĩa tổng thể i
trong một và khai báo extern trong chương trình kia. extern i;
cout << i ; /* program1.cpp*/
void in();
int i;
void main()
{ } i = 1;
in(); 5858 } 5959 ắ ề ấ ư Tóm t t v c p l u tr bi n ( ữ ế Storage class) a. Chỉ thị bao hàm tệp #include
Cho phép ghép nội dung các tệp đã có khác vào chương trình
trước khi dịch. Các tệp cần ghép thêm vào chương trình
thường là các tệp chứa khai báo nguyên mẫu của các hằng,
biến, hàm … có sẵn trong C hoặc các hàm do lập trình viên tự
viết. Có hai dạng viết chỉ thị này. 1: #include Các tập tin nguyên mẫu của thư viện C++, chứa trong thư
mục Borlandc\Include 2: #include “đường dẫn\tệp” 6060 Tìm tệp theo đường dẫn, nếu không có đường dẫn sẽ tìm
trong thư mục hiện tại. Tệp thường là các tệp (thư viện) được
tạo bởi lập trình viên và được đặt trong cùng thư mục chứa
chương trình. #define tên_macro xaukitu b. Chỉ thị macro #define
Cú pháp:
Trước khi dịch bộ tiền xử lý sẽ tìm trong chương trình và thay
thế bất kỳ vị trí xuất hiện nào của tên_macro bởi xâu kí tự. Ta
thường sử dụng macro để định nghĩa các hằng hoặc thay cụm
từ này bằng cụm từ khác dễ nhớ hơn. if (i < MAX) then
begin Viết Ok = TRUE;
cout << i ; end if (i < 100 then
{ Ví dụ: Ct dịch Ok = 1;
cout << i ; } 6161 #define then // thay then bằng dấu cách
#define begin { // thay begin bằng dấu {
#define end } // thay end bằng dấu }
#define MAX 100 // thay MAX bằng 100
#define TRUE 1 // thay TRUE bằng 1 c. Các chỉ thị biên dịch có điều kiện #if, #ifdef, #ifndef
Chỉ thị: #if dãy lệnh … #endif
#if dãy lệnh … #else dãy lệnh … #endif, Báo cho chương trình dịch biết đoạn lệnh giữa #if (điều kiện) và #endif chỉ được dịch nếu điều kiện đúng. const int M = 10;
void main() {
int i = 5;
#if M > 8 cout << i+i ; Ví dụ: #else const int M = 1;
void main() {
int i = 5;
#if M ==1 cout << i*i ; cout << i ; #endif } #endif 6262 } d. Chỉ thị #ifdef và #ifndef
Chỉ thị này báo cho chương trình dịch biết đoạn lệnh có được dịch hay không khi một tên gọi đã được định nghĩa hay chưa. Để định nghĩa một tên gọi ta dùng chỉ thị #define tên.
Chỉ thị này đặc biệt có ích khi chèn các tệp thư viện vào để sử 6363 dụng. Một tệp thư viện có thể được chèn nhiều lần trong văn bản
do vậy nó có thể sẽ được dịch nhiều lần, điều này sẽ gây ra lỗi vì
các biến được khai báo nhiều lần. ủ d. Chỉ thị #ifdef và #ifndef
Thư viện 1. tên tệp: MYLIB.H ươ ả int max(int a, int b)
{
return (a>b? a: b);
} Thư viện 2. tên tệp: MATHFUNC.H >> b >> c; ậ
Hàm main c a chúng ta nh p 3
ặ ố
ủ ừ
ố
s , in ra max c a t ng c p s và
ố
ả
ủ
ng trình
max c a c 3 s . Ch
ư ệ
ả ử ụ
ầ
c n ph i s d ng c 2 th vi n.
#include "mylib.h"
#include "mathfunc.h"
main()
{
int a, b, c;
cout << "a, b, c = " ; cin >> a cout << max(a,b) << max(b,c)
<< max(a,c) << max(a,b,c) ; #include "mylib.h"
int max(int a, int b)
{
return (a>b? a: b);
} C++ sẽ báo lỗi (do hàm int max(inta, int b) được khai báo hai lần 6464 } // tệp mylib.h
#ifndef _MYLIB_ // nếu chưa định nghĩa tên gọi _MYLIB_
#define _MYLIB_ // thì định nghĩa nó
int max(int a, int b) // và các hàm khác
{ return (a>b? a: b); }
#endif 6565 Khắc phục 1. Nêu cách khai báo hàm, định nghĩa hàm, cách gọi hàm.
2. Phạm vi của một đối tượng (biến, hằng) trong chương trình ?
3. Trình bày các phương pháp truyền tham số cho hàm (truyền bằng giá trị, bằng tham chiếu, và bằng tham trỏ) 4. Nêu cách thiết kế hàm mà theo Anh (Chị) cho là đạt yêu cầu.
5. Cho ví dụ về hàm xuất/nhập.
6. Cho ví dụ về hàm kiểm tra một giá trị nguyên thỏa tính chất “P” nào đó. 7. Cho ví dụ về hàm xác định giá trị nguyên thỏa tính chất “P” nào đó. 6666 8. Trình bày cách tổ chức một chương trình “C/C++”. 8. Trình bày cấp lưu trữ của một đối tượng (auto, register, static, extern). − Giải phương trình bậc 2 ax2 + bx + c = 0
− In bảng cửu chương theo chiều dọc, ngang.
− Kiểm tra 1 bộ ngày, tháng, năm có hợp lệ hay không ?
− Vẽ hình tam giác với chiều cao h dạng …
− Phân tích số n > 0 thành tích các thừa số nguyên tố theo 9. Khai báo các hàm nguyên mẫu sau: dạng n = 120 = 2*2*2*3*5. 6767 − Kiểm tra số tự nhiên n > 0 có phải là số nguyên tố ?
− Tính trị max của 2 số nguyên.
− Tính trị min của 2 số nguyên.
− Tính USCLN của 2 số tự nhiên. 10 Chọn câu sai trong các câu sau đây: A: Hàm không trả lại giá trị thì không cần khai báo kiểu giá trị của hàm. B: Các biến được khai báo trong hàm là cục bộ, tự xoá khi hàm thực hiện xong C: Hàm không trả lại giá trị sẽ có kiểu giá trị ngầm định là void.
D: Hàm là đơn vị độc lập, không được khai báo hàm lồng nhau. 11 Chọn câu đúng nhất trong các câu sau đây: A: Hàm phải được kết thúc với 1 câu lệnh return
B: Phải có ít nhất 1 câu lệnh return cho hàm
C: Các câu lệnh return được phép nằm ở vị trí bất kỳ trong thân hàm D: Không cần khai báo kiểu giá trị trả lại của hàm nếu hàm 6868 không có lệnh return 12. Chọn câu sai trong các câu sau đây: A: Số tham số thực sự phải bằng số tham số hình thức trong lời gọi hàm B: Các biến cục bộ trong thân hàm được chương trình dịch cấp phát bộ nhớ C: Các tham số hình thức sẽ được cấp phát bộ nhớ tạm thời khi hàm được gọi D: Kiểu của tham số thực sự phải bằng kiểu của tham số hình thức tương ứng với nó trong lời gọi hàm 13. Để thay đổi giá trị của tham biến, các đối của hàm cần khai 6969 báo dưới dạng:
A: biến bình thường và tham đối được truyền theo giá trị
B: biến con trỏ và tham đối được truyền theo giá trị
C: biến bình thường và tham đối được truyền theo địa chỉ
D: biến tham chiếu và tham đối được truyền theo giá trị ế ươ ế ị Hãy cho bi ng tr àn hình c a củ ác bi n x, y, v à z c a củ ác ch ình sau: t tr in ra m
#include int x = 4, y = 3, z = 2;
mul( y, z, x );
cout << "\nX = " << x;
cout << "\nY = " << y;
cout << "\nZ = " << z;
return 0; }
void mul( int & x,int y, int & z ) { x *= y;
y *= z;
z *= x; } 7070 ế ươ ế ị Hãy cho bi ng tr àn hình c a củ ác bi n x, y, v à z c a củ ác ch ình sau: t tr in ra m
#include void f( int x, int & y, int z )
{ g( z, y, x );
x += y;
y += z;
z += x; }
void g( int & a, int b, int &
c ) { int x = 2, y = 3, z = 4;
f( y, z, x );
cout << "\nX = " << x;
cout << "\nY = " << y;
cout << "\nZ = " << z;
return 0; 7171 a *= b;
b *= c;
c *= a; } } 7272 NMLT Hàm (Function) 7373 NMLT Hàm (Function) 7474 NMLT Hàm (Function)&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
&
VC
BB
ố ượ
ủ
ạ
Ph m vi (scope) c a các đ i t
ng
&
VC
ấ ư
ố ượ
BB
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
BB
ấ ư
ố ượ
ữ ủ
C p l u tr c a các đ i t
ng
&
VC
Các ch ỉ th ị tiền x ử lý
BB
&
VC
Các ch ỉ th ị tiền x ử lý
BB
&
VC
Các ch ỉ th ị tiền x ử lý
BB
&
VC
Các ch ỉ th ị tiền x ử lý
BB
&
VC
Các ch ỉ th ị tiền x ử lý
BB
&
VC
Các ch ỉ th ị tiền x ử lý
BB
&
VC
ỏ
BB
ậ
Câu h i và bài t p
&
VC
ỏ
BB
ậ
Câu h i và bài t p
&
VC
ỏ
BB
ậ
Câu h i và bài t p
&
VC
Câu hỏi và bài tập
BB
&
VC
Câu hỏi và bài tập
BB
&
VC
ỏ
BB
ậ
Câu h i và bài t p
&
VC
ự
ậ
Bài t p th c hành
BB
5. Bài 4, 5, 6, 7, 8 trang 140-141 chương 8 (Câu lệnh
điều kiện và rẽ nhánh)
a. Viết hàm đổi một ký tự hoa sang ký tự thường.
b. Viết thủ tục giải phương trình bậc nhất.
c. Viết thủ tục giải phương trình bậc hai.
d. Viết hàm trả về giá trị nhỏ nhất của 4 số
nguyên.
e. Viết thủ tục hoán vị hai số nguyên.
f. Viết thủ tục sắp xếp 4 số nguyên tăng dần.
&
VC
ự
ậ
Bài t p th c hành
BB
6. Bài tập 3 trang 155 chương 9 (Câu lệnh lặp). Hàm
nhận vào một số nguyên dương n và thực hiện:
a. Trả về số đảo của số đó.
b. Có phải là số đối xứng (Trả về True/False)
c. Có phải là số chính phương.
d. Có phải là số nguyên tố.
e. Tổng các chữ số lẻ.
f. Tổng các chữ số nguyên tố.
g. Tổng các chữ số chính phương.
&
VC
ự
ậ
Bài t p th c hành
BB
7. Bài tập 4 trang 156 chương 9 (Câu lệnh lặp). Hàm
nhận vào một số nguyên dương n và thực hiện:
a. S = 1 + 2 + … + n
b. S = 12 + 22 + … + n2
c. S = 1 + 1/2 + … + 1/n
d. S = 1 * 2 * … * n
e. S = 1! + 2! + … + n!
7. Hàm trả về USCLN của 2 số nguyên.
In ra n phần tử của dãy Fibonacy.
8.

