Tải bản đầy đủ (.doc) (24 trang)

đồ án tìm hiểu về ngôn ngữ lập trình c++

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (146.55 KB, 24 trang )

Phần I. mở đầu
Trong giai đoạn hiện nay, giai đoạn mà nền công nghệ thông tin chiếm một vị trí
hết sức quan trọng. Mọi quốc gia trên thế giới đều cố gắng nỗ lực vào, và phấn đấu
phát triển mạnh lĩnh vực công nghệ thông tin. Một trong những công cụ tiếp cận
nhanh nhất đó là tin học.
Đã qua rồi, thời mà cha ông ta phải làm và ghi nhớ mọi việc bằng những phơng
tiện thô sơ. Để tính toán họ đều phải bắt đầu bằng tay và tính toán một cách chi tiết.
Còn ngày nay - Thời đại của công nghệ thông tin - Bạn không cần phải làm nh vậy
nữa. Bạn chỉ cần lập ra một chơng trình rồi sử dụng nó. Nó tiện ích và thuận lợi hơn
rất nhiều. Nó không hạn chế về khối lợng, con số. Thậm chí trong một giây nó có
thể giải quyết hàng vạn bài toán phức tạp vv Do đó tốc độ làm việc và năng suất
tăng lên rất nhiều. Lợi ích rất lớn.
Để nó có thể làm việc và hoạt động đợc thì chúng ta cần phải lập trình, mà muốn
lập trình thì cần phải có ngôn ngữ lập trình. Có rất nhiều ngôn ngữ lập trình nh
Pascal, Cobol, C
++
vv Mỗi ngôn ngữ lập trình có một chức năng riêng, một thế
mạnh riêng, trong đó ngôn ngữ lập trình C
++
rất hay dùng và nó có thế mạnh về quá
trình can thiệp sâu vào máy tính. Nó là điều mà mọi kỹ s lập trình đều cần phải biết
đến, là vấn đề rất quan trọng trong quá trình tiếp cận với máy tính.
Những vấn đề trong ngôn ngữ lập trình C
++
rất đáng phải quan tâm và có rất
nhiều vấn đề, nhng ở đề án này chúng ta chỉ nghiên cứu 3 vấn đề cơ bản nhất đó là:
Chơng I: Hàm.
Chơng II: Biến toàn cục, biến cục bộ.
Chơng III: Chơng trình có sử dụng hàm, biến toàn cục, biến cục bộ.
Trong mỗi chơng sẽ có những vấn đề nhỏ, cụ thể cần nghiên cứu sẽ đợc thể hiện
trong phần nội dung.


Đề án của em đợc hoàn thành dới sự hớng dẫn giúp đỡ của thầy TS. Đặng Quế
Vinh và những tài liệu về bài giảng của thầy cũng nh một số tài liệu khác. Một lần
nữa em xin cảm ơn thầy.
1
Phần II. Nội dung.
Nội dung chính bao gồm: Hàm, biến toàn cục, biến cục bộ.
Chơng I: Hàm.
Chơng trình con: Chơng trình đợc viết theo những quy tắc đặc biệt để có thể đợc
gọi thực hiện bằng một chơng trình khác. Chơng trình chứa lời gọi thực hiện chơng
trình con đợc gọi là chơng trình chính.
Việc viết và sử dụng những chơng trình con cho phép tiết kiệm công sức của ng-
ời viết chơng trình rất nhiều. Trong hầu hết các ngôn ngữ lập trình bậc cao chơng
trình con đợc chia làm 2 loại là thủ tục( x, thủ tục) và hàm(x, hàm).
I. Định nghĩa hàm.
Hàm là một chơng trình con tính một giá trị và trả lại giá trị ấy thông qua tên
hàm.
Hàm chia thành 2 loại là hàm chuẩn và hàm tự định nghĩa còn gọi là hàm do ng-
ời sử dụng định nghĩa.
- Hàm chuẩn là những hàm có sẵn trong ngôn ngữ lập trình. Lập trình viên có
thể sử dụng các hàm chuẩn mà không phải định nghĩa lại các hàm đó. Hầu hết các
hàm toán học thông dụng đều là các hàm chuẩn trong các ngôn ngữ lập trình. Tập
hợp các hàm chuẩn tạo thành th viện hàm chuẩn của ngôn ngữ lập trình th viện hàm
chuẩn là thành phần rất quan trọng của mỗi ngôn ngữ lập trình. Nó làm cho việc lập
trình đợc dễ dàng hơn và làm cho khả năng của ngôn ngữ lập trình tăng lên rất
nhiều.
- Hàm tự định nghĩa: Là những hàm không có sẵn trong th viện hàm chuẩn của
ngôn ngữ lập trình. Muốn sử dụng những hàm này ngời sử dụng phải tạo ra nó. Vì
vậy những hàm này mới có tên là hàm do ngời dùng định nghĩa. Việc tạo ra và sử
dụng những hàm tự định nghĩa làm cho chơng trình ngắn gọn hơn, sáng sủa hơn và
cho phép tiết kiệm công sức của lập trình viên.

Có thể coi hàm là một phép toán do ngời dùng xác định. Nói chung hàm đợc
biểu thị bởi một tên gọi chứ không phải là một toán tử. Các toán hạng của hàm, đợc
gọi là các đối của nó, đợc xác định trong danh sách đối phân cách nhau bởi dấu
phẩy và đợc bao trong dấu ngoặc tròn. Kết quả của hàm thờng đợc coi là kiểu cho
lại của nó. Hàm không cho lại giá trị nào có kiểu cho lại là Void. Các hành động
thực tại mà một hàm thực hiện đợc xác định trong thân hàm. Thân hàm đợc bao
trong ngoặc nhọn( "{ }" ) và đôi khi còn đợc coi là một khối.
Trong C
++
có 2 cách định nghĩa hàm:
2
Định nghĩa hàm sau hàm main( ) và định nghĩa hàm trớc hàm main(). Tuy nhiên
cách định nghĩa hàm trớc hàm main( ) ngăn gọn hơn và hay dùng hơn cho nên ở
đây ta nghiên cứu kỹ về chúng.
Việc định nghĩa một hàm theo mẫu sau:
Đầu_đề_hàm
{
Phần khai báo
Thân hàm
}
*Đầu đề hàm có dạng sau đây:
TĐK(từ định kiểu) : int, char;
TĐK tên hàm( TĐK1 tham số 1 [, TĐK2 tham_số 2 ] )
TĐK(*) xác định kiểu của hàm, tức là xác định kiểu của giá trị đợc trả lại thông qua
tên hàm.
Các tham số có trong ngoặc tròn ( ) đi sau tên hàm đợc gọi là các tham số hình
thức. Toàn bộ các tham số trong ngoặc ( ) gọi là danh sách tham số hình thức. Danh
sách này gồm 1 hay nhiều tham số, tham số nọ cách tham số kia dấu phẩy. Danh
sách tham số hình thức kết thúc bởi dấu ngoặc, sau đó không có dấu chấm phẩy.
*Phần khai báo của hàm:

Dùng để khai báo các biến đợc dùng trong hàm này. Các biến đợc khai báo
trong hàm chỉ có ý nghĩa trong hàm này nên đợc gọi là các biến cục bộ( địa phơng).
Việc sử dụng các biến cục bộ trong chơng trình khác hoặc chơng trình chính là
không hợp lệ.
Một hàm đợc tính bất kỳ khi nào toán tử gọi( "( )") đợc áp dụng vào tên của
hàm. Nếu hàm cần có các đối thì các đối này, còn đợc gọi là các đối thực tại, sẽ đợc
đặt vào bên trong toán tử gọi. Mỗi đối đợc phân cách bởi một dấu phẩy. Nó còn đợc
gọi là truyền đối cho hàm.
*Thân hàm:
Giống nh phần thân chơng trình của một chơng trình thông thờng. Tuy nhiên
sau khi tính xong giá trị hàm thì trong thân hàm thờng có câu lệnh return để trả lại
giá trị vừa tính đợc trong thân hàm cho tên hàm.
Nó có dạng:
Return Biểu thức;
hoặc Return( biểu thức).
3
Câu lệnh này có tác dụng trả cho tên hàm giá trị của biểu thức có trong câu lệnh
này. Câu lệnh return kết thúc việc thực hiện các câu lệnh trong thân hàm và trả điều
kiện về chỗ đã gọi hàm trong chơng trình chính. Tuy nhiên câu lệnh return là không
bắt buộc phải có.
Hàm trả lại giá trị qua tên hàm nên hàm có thể đợc dùng là một toán hạng trong
biểu thức.
Trong C
++
chỉ có một loại chơng trình con đó là hàm. Mỗi chơng trình
Trong C
++
phải có ít nhất một hàm main( ). Hàm trong C
++
không nhất thiết phải

có tham số, trả lại giá trị( đó là kiểu void). Trong chơng trình nguồn hàm có thể là
một toán hạng trong biểu thức hoặc có thể đứng một mình nh một câu lệnh đơn độc.
Ví dụ:
#include<iostream.h>
#include<conio.h>
// Dinh nghia ham BINH_PHUONG
int BINH_PHUONG(int n)
{
int ketqua;
ketqua=n*n;
return ketqua;
}
// Chuong trinh chinh
main()
{
int m;
cout<<"m=";
cin>>m;
cout<<'\n'<<m<<"binhphuong=";
cout<<BINH_PHUONG(m); (1);
getch();
}
Trong chơng trình này dòng(1) có chứa lời gọi hàm là BINH_PHUONG(m). ở
đây m đợc gọi là tham số thực sự gặp lời gọi này máy sẽ thực hiện hàm
BINH_PHUONG mà ta đã khai báo ở trên.
II.Sử dụng hàm.

Muốn sử dụng hàm ta phải viết lời gọi hàm. Lời gọi hàm có dạng sau:
Tên hàm( [ Danh sách tham số thực sự] )
Danh sách tham số thực sự bao gồm một hay một số tham số thực sự cách nhau

bởi dấu phẩy. Danh sách tham số thực sự có thể là một hàm, một biến hoặc một
biểu thức. Danh sách tham số thực sự là tuỳ chọn. Số tham số thực sự trong danh
4
sách tham số thực sự phải bằng số tham số hình thức trong danh sách tham số hình
thức. Kiểu của tham số thực sự phải phù hợp với kiểu của tham số hình thức tơng
ứng.
Một lời gọi hàm có thể làm cho 1 hay 2 điều xuất hiện. Nếu hàm đã đợc khai
báo là inline thì thân của hàm đợc mở rộng tại điểm gọi nó trong lúc dịch, ngoài ra
hàm sẽ đợc gọi trong lúc chạy. Một lời gọi hàm làm cho điều khiển của chơng trình
đợc chuyển cho hàm đợc gọi, việc thực hiện của hàm đang chạy lúc đó bị tạm
ngừng. Khi tính toán của hàm đợc gọi đã hoàn tất thì hàm bị ngừng sẽ lấy lại hoạt
động tại điểm sau lời gọi. Việc gọi hàm đợc quản lý trong chồng khi chạy của ch-
ơng trình. Nếu một hàm không đợc khai báo trong chơng trình trớc khi dùng nó thì
sẽ có lỗi khi dịch.
Hàm chỉ đợc định nghĩa một lần trong chơng trình. Về cơ bản định nghĩa hàm
trong tệp văn bản riêng của nó hay trong tệp văn bản có chứa nó và các hàm có liên
quan khác. Một hàm thờng đợc dùng trong các tệp khác tệp chứa định nghĩa của nó.
Do đó cần có phơng pháp phụ để khai báo hàm.
Khai báo hàm bao gồm kiểu cho lại của hàm, tên hàm và danh sách đối.
III.Truyền tham số cho hàm.

Khi gặp lời gọi hàm trong chơng trình chính thì quá trình thực hiện hàm bắt
đầu. Quá trình này gồm các công việc sau:
- Máy tạm thời rời khỏi chơng trình chính, cấp phát bộ nhớ cho các tham số hình
thức và các biến cục bộ.
- Gán các giá trị của tham số thực sự cho các tham số hình thức tơng ứng.
- Lần lợt thực hiện các câu lệnh trong thân hàm. Nếu gặp câu lệnh return hoặc
gặp dấu } thì máy sẽ xoá các tham số hình thức hoặc các biến cục bộ quay về ch-
ơng trình chính ở chỗ có lời gọi hàm. Nếu thoát khỏi hàm bằng câu lệnh Return thì
giá trị biểu thức có trong câu lệnh này sẽ đợc gán cho tên hàm.

Khi gặp lời gọi hàm thì giá trị tham số thực sự sẽ đợc gán cho tham số hình
thức tơng ứng, mọi tính toán trong thân hàm sẽ đợc thực hiện trên các tham số hình
thức. Khi thoát khỏi hàm máy sẽ xoá các tham số hình thức và các biến cục bộ, nh
vậy những thay đổi đối với các tham số hình thức không thể đợc truyền về chơng
trình chính thông qua tham số thực sự tơng ứng.
Vậy làm thế nào để trong chơng trình con có thể thay đổi giá trị các biến có
trong chơng trình chính?
Ngời ta dùng con trỏ làm tham số hình thức để giải quyết vấn đề này. Khi đó
ngời ta truyền cho chơng trình con địa chỉ của biến trớc và sau lời gọi hàm( tức là
trớc và sau khi thực hiện hàm địa chỉ này không thay đổi, hoàn toàn phù hợp với các
giả định của C
++
. Tuy nhiên trong quá trình thực hiện hàm thì giá trị chứa trong địa
chỉ đó có thể bị thay đổi, giá trị này đợc giữ nguyên khi thoát khỏi hàm. Đây là ph-
ơng pháp truyền giá trị từ chơng trình con về chơng trình chính.
5
VD: Truyền giá trị từ chơng trình con về chơng trình chính.
// Chuong trinh co ham tinh tong n so.
#include<iostream.h>
#include<conio.h>
float TONG(float *vecto, int n)
{
int i;
float s=0;
for(i=0; i<n;i++)
s=s+ *(vecto+i);
return (s);
}
main()
{

int i;
float a[4]={1,2,3,4};
float b[6]={5,1,2,3,1,4};
clrscr();
cout<<"\n tong vecto a="<<TONG(a,4);//in so 10
cout<<"\n tong vecto b="<<TONG(&b[0],6); //in ra so 10
getch();
}
IV. Sử dụng hàm trong nhiều ch ơng trình khác.
Giả sử có một tệp gọi là: DVVECTERE.CPP
Chứa các hàm sau:
Float TONG VTF( float * vecter, int n);
Float TICH VTF ( float * vecter, int n);
Void NHAP VTF ( float * vecter, int n);
Void IN VTF ( float * vecter, int n);
// Chơng trình hàm định nghĩa trong chơng trình khác
#include<iostream.h>
#include<conio.h>
#include "C:\ baitap TC \ dvvecter.CPP"
main( )
{
int n=2;
float a[10];
NHAP VTF (a,n);
IN VTF(a,n);
TONG VTF(a,n);
6
TICH VTF (a,n);
Getch( );
}

V. Danh sách đối của hàm.
Các hàm khác nhau của một chơng trình có thể thâm nhập chung vào các giá trị
với nhau theo 2 phơng pháp. Một phơng pháp là dùng biến toàn cục trong chơng
trìnhl; Phơng pháp thứ hai là dùng danh sách đối hình thức.
Danh sách đối đa ra một phơng pháp khác để thâm nhập chung vào các giá trị
giữa một hàm và chơng trình chung. Danh sách đối cùng với kiểu cho lại của hàm
xác định ra giao diện chung của hàm. Một hàm khép kín có thể đợc dùng qua nhiều
chơng trình, nó không nhất thiết bị giới hạn vào một ứng dụng riêng. Nếu bỏ bớt đi
một đối hay truyền cho một đối kiểu sai sẽ gây ra lỗi. Khả năng lỗi trong truyền đối
tăng lên theo kích cỡ của danh sách đối, dùng tối đa là 8 đối.
*Cú pháp danh sách.
Không đợc phép bỏ thiếu danh sách đối của hàm. Một hàm không có đối có thể
đợc biểu thị hoặc bằng danh sách đối rỗng hoặc bằng danh sách đối chỉ chứa một từ
khoá void.
//Khai báo tơng đơng
int fork();
int fork( void);
Danh sách đối còn đợc gọi là dấu hiệu của hàm bởi vì nó thờng đợc dùng để
phân biệt một thể nghiệm của hàm này với hàm khác. Tên và dấu hiệu một hàm xác
định duy nhất nó.
Dấu hiệu bao gồm một danh sách các kiểu đối phân cách nhau bởi dấu phẩy.
Không có hai tên đối nào xuất hiện trong dấu hiệu đợc phép trùng nhau. Tên đối
cho phép đối đó đợc thâm nhập từ trong thân của hàm. Do đó tên đối không cần viết
trong khai báo hàm.
*Truyền đối.
Danh sách đối của hàm mô tả cho các đối hình thức. Mỗi đối hình thức đợc cấp
bộ nhớ bên trong vùng nhớ của hàm. Các biểu thức nằm giữa 2 dâu ngoặc tròn của
lời gọi hàm đợc gọi là các đối thực tại của lời gọi. Việc truyền đối vậy là một tiến
trình khởi đầu cho vùng nhớ của các đối hình thức theo các đối thực tại.
Với truyền theo giá trị, hàm không bao giờ thâm nhập vào các đối thực tại của

lời gọi, nội dung của đối thực tại không bị thay đổi. Có 2 phơng án truyền theo giá
trị.
Thứ nhất là đối hình thức đợc khai báo là con trỏ.
Void pswap( int * x, int * y)
{
int tg=* y;
*y=* x;
7
*x=tg;
}
Thứ 2 để truyền theo giá trị là khai báo đối hình thức có kiểu tham khảo
Void rswap( int &x, int &y)
{
int tg= y;
y= x;
x=tg;
}
VI. Các hàm trong C
++
.
1. Tham chiếu.

Tham chiếu là một bí danh của một vùng nhớ đợc cấp phát cho một biến nào đó.
Một tham biến có thể là một biến tham số hình thức của hàm hay dùng làm một giá
trị trả về của hàm.
*Tham chiếu tới một biến.
VD: int n;
int &p=n;
Dấu & xác định p là một biến tham chiếu, còn dấu "=" và tên biến n để xác định
vùng nhớ mà p tham chiếu tới.

Về bản chất tham chiêu và tham trỏ giống nhau vì cùng chỉ đến đối tợng có địa
chỉ, cùng đợc cấp phát địa chỉ khi khai báo, nhng cách sử dụng chúng thì khác
nhau. Khi nói đến tham chiếu "&p" ta phải gắn nó với một biến nào đó đã khai báo
qua "&p=n", trong khi đó khai báo con trỏ "*p" không nhất thiết phải khởi tạo giá
trị cho nó. Sau khi khởi tạo cho tham chiếu gắn với một biến nào đó rồi thì ta không
thể thay đổi để gắn tham chiếu với một biến khác, do vậy để truy nhập đến vùng
nhớ tơng ứng với một biến chúng ta có thể sử dụng hoặc là tên biến hoặc là tên
tham chiếu tơng ứng.
VD: #include<iostream.h>
Void main( )
{
int x=3, &y=x; // y lúc này là " bí danh" của x
cout<<"x="<<x<<"\n";
cout<<"y="<<y<<"\n";
y=7;
cout<<"x="<<x<<"\n";
<<"y="<<y<<"\n";
}
8
Không thể gắn một tham chiếu với một hằng số trừ trờng hợp có từ khoá const
đứng trớc khai báo tham chiếu.
Const int &p=3;
*Hằng tham chiếu.
Hằng tham chiếu đợc khai báo nh sau:
Int n=5;
Const int &x=n;
Cũng giống nh biến, hằng tham chiếu đến một biến hoặc một hằng.
Int n=5;
Const int &x=n;
Const int &y=100;

Hằng tham chiếu không đợc phép thay đổi giá trị của vùng nhớ mà nó tham
chiếu. Hằng tham chiếu thờng đợc sử dụng làm đối của hàm để cho phép hàm sử
dụng giá trị của các tham số trong lời gọi hàm.
*Truyền tham số cho hàm bằng tham chiếu.
Nếu đối là biến hoặc hằng tham chiếu kiểu K thì tham số ( trong lời gọi hàm) phải
là biến hoặc phần tử mảng kiểu K.
VD:
/*swap.cpp*/
#include<iostream.h>
#include<conio.h>
/*Ham swap1 duoc goi voi cac tham so duoc truyen theo tham tri*/
void swap1(int x, int y)
{
int temp=x;
x=y;
y=temp;
}
/*Ham swap2 thuc hien viec truyen tham so bang tham tro*/
void swap2(int *x, int *y)
{
int temp=*x;
*x=*y;
*y=temp;
}
/*Ham swap3 thuc hien viec truyen tham so bang tham chieu*/
void swap3(int &x, int &y)
{
int temp=x;
x=y;
9

y=temp;
}
void main()
{
int a=2, b=3;
clrscr();
cout<<"Truoc khi goi swap1:\n";
cout<<"a = "<<a<<"b = "<<b<<"\n";
swap1(a,b);
cout<<"Sau khi goi ham swap1:\n";
cout<<"a = "<<a<<"b = "<<b<<"\n";
a=2;b=3;
cout<<"Truoc khi goi swap2:\n";
cout<<"a = "<<a<<"b = "<<b<<"\n";
swap2(&a,&b);
cout<<"Sau khi goi ham swap2:\n";
cout<<"a = "<<a<<"b = "<<b<<"\n";
a=2;b=3;
cout<<"Truoc khi goi swap3:\n";
cout<<"a = "<<a<<"b = "<<b<<"\n";
swap3(a,b);
cout<<"Sau khi goi ham swap3:\n";
cout<<"a = "<<a<<"b = "<<b<<"\n";
getch();
}
ket qua se la:
Truoc khi goi swap1:
a=2 b=3
Sau khi goi swap1:
a=2 b=3

Truoc khi goi swap2:
a=2 b=3
Sau khi goi swap2:
a=3 b=2
Truoc khi goi swap3:
a=2 b=3
Sau khi goi swap3:
a=3 b=2
Trong chơng trình trên ta truyền tham số a,b cho hàm swap1() theo tham trị nên
giá trị của chúng trớc và sau khi gọi hàm là không thay đổi. Hàm swap2( ) thay vì
truyền trực tiếp giá trị 2 biến a,b ngời ta truyền địa chỉ của chúng rồi thông qua các
địa chỉ này để xác định giá trị biến, bằng cách đó giá trị của 2 biến a,b sẽ hoán đổi
cho nhau sau lời gọi hàm. Hàm swap3( )đa ra giải pháp sử dụng tham chiếu, các
tham số hình thức của hàm swap3( ) bây giờ là các tham chiếu đến các tham số thực
10
đợc truyền cho hàm. Nhờ vậy mà giá trị của 2 tham số thực a và b có thể hoán đổi
đợc cho nhau.
*Giá trị trả về của hàm là tham chiếu.
Định nghĩa của hàm có dạng:
<type> & fct( )
{
return< biến có phạm vi toàn cục>;
}
Biểu thức đợc trả lại trong câu lệnh return phải là tên của một biến xác định từ
bên ngoài hàm. Vì nếu là biến cục bộ thì nó sẽ bị mất đi khi kết thúc thực hiện hàm.
Khi trả về của hàm là tham chiếu ta có thể gặp vế trái là một lời gọi hàm chứ
không phải là tên một biến.
VD:
#include<iostream.h>
#include<conio.h>

struct TS
{
char ht[25];
float dt,dl, dh,td;
};
TS ts;
TS &f()
{
return ts;
}
void main()
{
TS &h=f(); // h tham chieu den bien ts
cout<<"\n Ho ten:";
cin.get(h.ht,25);
cout<<" Cac diem toan, diem ly, diem hoa:";
cin>>h.dt>>h.dl>>h.dh;
h.td=h.dt+h.dl+h.dh;
cout<<"\n Ho ten:"<<ts.ht;
cout<<"\n Tong diem:"<<ts.td;
getch();
}
2. Đối có giá trị mặc định.
Thông thờng số tham số trong lời gọi hàm sẽ bằng số đối của hàm. Mỗi đối sẽ đ-
ợc khởi gán giá trị theo tham số tơng ứng của nó. C
++
cho phép tạo giá trị mặc định
11
cho các đối. Các đối này có thể có hoặc không có tham số trong lời gọi hàm. Khi
không có tham số tơng ứng đối đợc khởi gán bởi giá trị mặc định.

Sử dụng hàm có đối mặc định: Lời gọi hàm cần viết theo quy định sau:
Các tham số thiếu vắng trong lời gọi hàm phải tơng ứng với các đối mặc định
cuối cùng, nghĩa là đã dùng giá trị mặc định cho một đối thì cũng phải sử dụng giá
trị mặc định cho các đối còn lại.
VD:
Hàm có 3 đối mặc định.
Void h( int d1, float d2, char *d3="VIET NAM", int d4=10, double
d5=3.14);
//lời gọi hàm
h( 3, 3.4, "ABC", 10, 10);
h( 3, 3.4, "ABC");
h( 3, 3.4);
3. Hàm trực tuyến( inline).
Để khắc phục nhợc điểm của hàm là làm chậm tốc độ chơng trình do phải thực
hiện một số thao tác có tính thủ tục mỗi khi gọi hàm. Ngời ta dùng hàm trực tuyến.
Để biến một hàm thành trực tuyến ta viết thêm từ khoá inline vào trớc nguyên
mẫu hàm. Nếu không dùng nguyên mẫu thì viết từ khoá này trớc dòng đầu tiên của
định nghĩa hàm.
VD:
Inline float f( int n, float x);
Float f(int n, float x)
{
// Các câu lệnh trong thân hàm
}
hoặc
inline float f(int n, float x)
{
// Các câu lệnh trong thân hàm
}
Không đợc đặt inline trớc định nghĩa hàm. Nếu không bị quẩn không thoát đ-

ợc.
VD: Sử dụng hàm trực tuyến.
Chơng trình tính chu vi, diện tích của hình chữ nhật( Không khai báo nguyên
mẫu khi đó hàm tính phải đặt trên hàm main).
#include<conio.h>
12
#include<iostream.h
inline void dtcvhcn(int x, int y, int& dt,int& cv)
{
dt=x*y;
cv=2*(x+y);
}
void main()
{
int x[10],y[10],dt[10],cv[10],;
cout<<"\n So hinh chu nhat:";
cin>>n;
for(int i=1;i<=n;++i)
{
cout<<"\n Nhap 2 canh cua hinh chu nhat thu"<<i<<":";
cin>>x[i]>>y[i];
dtcvhcn(x[i],y[i],dt[i],cv[i]);
}
clrscr();
for(i=1;i<=n;++i)
{
cout<<"\n Hinh chu nhat thu"<<i<<":";
cout<<"\n do dai 2 canh="<<x[i]<<"va"<<y[i];
cout<<"\n Dien tich="<<dt[i];
cout<<"\n Chu vi="<<cv[i];

}
getch();
}
4. Đệ quy.
Một đối tợng đợc gọi là có tính đệ quy nếu trong định nghĩa đối tợng này lại
dùng chính bản thân nó tức là dùng chính đối tợng để định nghĩa đối tợng.
Hàm đệ quy là hàm trong định nghĩa hàm có sử dụng lời gọi hàm. Một định
nghĩa đệ quy có ít nhất 2 điều kiện:
- Điều kiện dừng: Nó không chứa đối tợng đang định nghĩa.
- Thành phần đệ quy: Nó có chứa đối tợng đang định nghĩa.
Nếu không có điều kiện dừng thì hàm sẽ đệ quy mãi mãi. Sử dụng kỹ thuật
đệ quy cho phép biến một quá trình gồm vô hạn các thao tác thành một quá trình
gồm một số hữu hạn. Sau đó giao cho máy thực hiện với tốc độ rất cao.
Chơng trình con đệ quy là chơng trình con có chứa lời gọi đến chính nó. Khi gặp
một lời gọi đến chơng trình con máy sẽ tạo ra một tập hợp các biến cục bộ mới, có
bao nhiêu lời gọi đến chơng trình con thì có bấy nhiêu lần thoát khỏi nó. Mỗi khi
thoát khỏi chơng trình con thì một tập hợp các biến cục bộ đợc giải phóng, quá trình
giải phóng các biến cục bộ ngợc với quá trình tạo ra nó, nghĩa là tập hợp biến cục
bộ nào tạo ra sau thì sẽ đợc giải phóng trớc.
13
Viết và sử dụng các hàm đệ quy làm cho chơng trình ngắn gọn nhng tốn thời
gian tính toán và tốn bộ nhớ. Bằng phơng pháp lập trình thông thờng có thể không
cần đến kỹ thuật đệ quy.
VD:
// định nghĩa hàm GIAI_THUA theo kiểu đệ quy.
Int GIAI_THUA( int n)
{
int gt;
if( n==0)
gt=1; // điều kiện dừng

else
gt=*n GIAI_THUA( n-1); //thành phần đệ quy
return( gt);
}
Chơng II. Biến toàn cục, biến cục bộ.
I. Biến toàn cục.
14
Biến toàn cục là một biến đợc khai báo trong chơng trình và có ý nghĩa( nghĩa là
có thể sử dụng) trong chơng trình này cũng nh tất cả các khối chơng trình thuộc về
chơng trình này. Nh vậy biến toàn cục có thể đợc sử dụng trong nhiều khối chơng
trình khác nhau.
Biến toàn cục có thể đợc thâm nhập tới từ trong thân của hàm, chỉ cần nó đợc
khai báo đúng chỗ. Ngời lập trình có thể gán một giá trị cho lại thứ hai cho một
biến toàn cục.
Biến toàn cục có u điểm là đơn giản, tiện lợi tiện dùng.
Nhợc điểm của nó là không trực giác. Tức là từ lời gọi hàm ta không biết đợc
biến này đã đợc đặt giá trị. Nó gây khó khăn cho ngời lập trình khác khi muốn hiểu
hay muốn thay đổi chơng trình. Khả năng thâm nhập chung vào biến toàn cục từ bất
kỳ đâu bên trong chơng trình vừa là lợi ích chính của nó vừa là độ tin cậy có ý nghĩa
nhất. Tính thấy đợc của biến toàn cục làm cho nó trở thành phơng pháp thuận tiện
cho liên lạc giữa các phần khác nhau của chơng trình. Nhợc điểm của việc dùng
biến toàn cục cho việc liên lạc giữa các hàm là nh sau:
+ Các hàm có dùng tới biến toàn cục phụ thuộc vào sự tồn tại và kiểu của biến
toàn cục đó, làm cho việc dùng lại hàm này trong ngữ cảnh khác trở lên khó khăn
hơn nhiều.
+ Nếu cần sửa đổi chơng trình thì những sự phụ thuộc toàn cục sẽ làm tăng khả
năng sinh lỗi. Hơn nữa việc đa vào những thay đổi cục bộ đòi hỏi việc hiểu biết toàn
bộ chơng trình.
+ Nếu một biến toàn cục nhận một giá trị không đúng thì phải tìm kiếm trong
toàn bộ chơng trình để xem lỗi xuất hiện ở đâu; không có việc cục bộ hoá.

+ Việc đệ quy lại còn khó khăn đi đến đúng chỗ hơn khi hàm dùng một biến
toàn cục.
Một biến cục bộ có thể dùng lại tên của một biến toàn cục. Khi đó biến cục bộ
che lấp biến toàn bộ cùng tên. Chẳng hạn:

include<iostream.h>
int x;
main( )
{
int x=10; //biến cục bộ
cout<< x <<"\n"; //biến toàn cục
}
Trong trờng hợp đó, khi muốn truy xuất tới biến toàn cục phải sử dụng toán tử
phạm vi "::" trớc tên biến:

include<iostream.h>
int x;
main( )
15
{
int x=10; //biến cục bộ
::x=10;// biến toàn cục
cout<< x <<"\n"; //x cục bộ
cout<< ::x <<"\n"; //x toàn cục
}
Một biến toàn cục đợc định nghĩa trong một tệp nhng đợc dùng ở tệp thứ hai hay
trong nhiều tệp khác. Từ khoá extert đa ra giải pháp.
Hai biến toàn cục đợc định nghĩa trong các tệp chơng trình tách biệt cùng dùng
chung một tên nhng đợc dự định nói tới các thực thể chơng trình khác nhau, mỗi
biến rõ ràng đợc dịch riêng rẽ. Nhng khi gắn lại với nhau, biến bị báo là có nhiều

định nghĩa và trình biên dịch dừng lại. Việc dùng từ khoá static đa ra một giải pháp.
II. Biến cục bộ.
Biến cục bộ là biến đợc khai báo trong chơng trình và nó chỉ có ý nghĩa ở phạm
vi nó khai báo. Khi ra khỏi phần nó khai báo thì nó không còn dùng đợc nữa.
Các nguyên lý của biến cục bộ:
+ Các biến cục bộ ( dù trùng tên với biến toàn cục) cũng không làm thay đổi
giá trị của biến toàn cục.
+ Mọi tham biến hình thức loại truyền theo trị trong các chơng trình con( thủ
tục và hàm) đều là các biến cục bộ.
+ Các biến khai báo trong các chơng trình con đều là các biến cục bộ.
+Khi phải sử dụng biến phụ thì nên dùng biến cục bộ.
Phạm vi cục bộ có thể lồng nhau. Mỗi khối có chứa một câu lệnh khai báo đều
duy trì phạm vi cục bộ riêng của nó.
Chơng III.
Chơng trình có sử dụng định nghĩa hàm, biến toàn
cục, biến cục bộ.
16
#include<conio.h>
#include<iostream.h>
#include<iomanip.h>
#include<math.h>
struct MT
{
double a[20][20];
int n;
};
struct VT
{
double b[20];
int n;

};
ostream & operator<<(ostream & os, const MT & x);
ostream & operator<<(ostream & os, const VT & y);
istream & operator>>(istream & is, MT & x);
istream & operator>>(istream & is, VT & y);
MT operator+(const MT & x1,const MT & x2);
MT operator-(const MT & x1,const MT & x2);
MT operator*( const MT & x1,const MT & x2);
VT operator*(const MT & x, const VT & y);
MT operator!(MT x);
ostream & operator<<(ostream & os, const MT & x)
{
os<<setprecision(2)<<setiosflags(ios::showpoint);
for(int i=1;i<=x.n;++i)
{
os<<"\n";
for(int j=1;j<=x.n;++j)
os<<setw(6)<<x.a[i][j];
}
os<<"\n";
return os;
}
ostream & operator<<(ostream & os, const VT & y)
{
os<<setprecision(2)<<setiosflags(ios::showpoint);
for(int i=1;i<=y.n;++i)
os<<setw(6)<<y.b[i];
os<<"\n";
return os;
}

istream & operator>>(istream & is, MT & x);
{
cout<<"- cap ma tran:";
is>>x.n;
17
cout<<"Nhap cac phan tu:\n";
for(int i=1;i<=x.n;++i)
for(int j=1;j<=x.n;++j)
{
cout<<"PT hang"<<i<<"cot"<<j<<"=";
is>>x.a[i][j];
}
return is;
}
istream & operator>>(istream & is, VT & y)
{
cout<<"- cap vector:";
is>>y.n;
cout<<"Nhap cac phan tu:\n";
for(int i=1;i<=y.n;++i)
{
cout<<"Phan tu thu"<<i<<"=";
is>>y.b[i];
}
return is;
}
MT operator+(const MT & x1,const MT & x2)
{
if(x1.n!=x2.n)
{

cout<<"\n Khong thuc hien duoc phep cong vi 2 ma tran khong
cung cap";
getch();
return x1;
}
else
{
MT x;
int i,j,n;
n=x.n=x1.n;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
x.a[i][j]=x1.a[i][j]+x2.a[i][j];
return x;
}
}
MT operator-(const MT & x1,const MT & x2)
{
if(x1.n!=x2.n)
{
cout<<"\n Khong thuc hien duoc phep tru vi 2 ma tran khong
cung cap";
18
getch();
return x1;
}
else
{
MT x;
int i,j,n;

n=x.n=x1.n;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
x.a[i][j]=x1.a[i][j]-x2.a[i][j];
return x;
}
}
MT operator*(const MT & x1,const MT & x2)
{
if(x1.n!=x2.n)
{
cout<<"\n Khong thuc hien duoc phep nhan vi 2 ma tran khong
cung cap";
getch();
return x1;
}
else
{
MT x;
int i,j,n,k;
n=x.n=x1.n;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
{
x.a[i][j]=0.0;
for(k=1;k<=n;++k)
x.a[i][j]+=x1.a[i][j]*x2.a[i][j];
}
return x;
}

}
VT operator*(const MT & x,const VT & y)
{
if(x.n!=y.n)
{
cout<<"\n cap ma tran khac cap vector, phep nhan vo nghia";
getch();
return y;
}
else
19
{
VT z;
int n;
n=z.n=y.n;
for(int i=1;i<=n;++i)
{
z.b[i]=0;
for(int j=1;j<=n;++j
z.b[i]+=x.a[i][j]*y.b[j];
}
return z;
}
}
MT operator!(MT x)
{
MT v;
int i,j,k,r,n;
double tg;
n=v.n=x.n;

for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
if(i==j) v.a[i][j]=1;
else
v.a[i][j]=0;
for(k=1;k<=n;++k)
{
r=k;
for(i=k+1;i<=n;++i)
if(abs(x.a[i][k]>abs(x.a[r][k]))r=i;
if(abs(x.a[r][k])<1.0E-8)
{
cout<<"\n Ma tran suy bien, khong co nghich dao";
getch();
return x;
}
/* Hoan vi hang r va hang k */
for(j=1;j<=n;++j)
{
tg=x.a[k][j];
x.a[k][j]=x.a[r][j];
x.a[r][j]=tg;
tg=v.a[k][j];
v.a[k][j]=v.a[r][j];
v.a[r][j]=tg;
}
/* chia hang k cho a[k,k] */
tg=x.a[k,k];
20
for(j=1;j<=n;++j)

{
x.a[k][j]/=tg;
v.a[k][j]/=tg;
}
/* khu cot k: lam cho a[i,k]=0 voi i!=k */
for(int i=1;i<=n;++i)
if(i!=k)
{
tg=x.a[i][k];
for(j=1;j<=n;++j)
{
x.a[i][j]-=tg*x.a[k][j];
v.a[i][j]-=tg*v.a[k][j];
}
}
}
return v;
}
void main()
{
MT x,v.r.s;
VT z,y;
clrscr();
cout<<"\n Nhap ma tran X";
cin>>x;
cout<<"\n Nhap ma tran V";
cin>>v;
cout<<"\n Nhap ma tran R";
cin>>r;
cout<<"\n Nhap ma tran S";

cin>>s;
cout<<"\n Nhap vector z";
cin>>z;
y=!(x+v)*(r-s)*z;
cout<<"\n Vector y=xz"<<y;
getch();
}
21
Phần III: Kết luận.
Việc sử dụng định nghĩa hàm, biến toàn cục, biến cục bộ là rất quan trọng trong
C
++
. Nó giúp cho những nhà lập trình, những ngời sử dụng thuận tiện hơn trong quá
trình nghiên cứu và sử dụng.
Nói đến hàm không ai không nghĩ tới định nghĩa hàm và cách sử dụng hàm.
Cũng nh cách sử dụng các biến toàn cục, biến cục bộ trong chơng trình. Để viết một
chơng trình lớn và phức tạp ngời ta phải sử dụng chơng trình con, vì nhờ có chơng
trình con mà giải quyết đợc vấn đề hết sức nhanh gọn và hiệu quả. Một phần của
chơng trình con đó là hàm. Việc dùng hàm cho hiệu quả rõ ràng và nhanh hơn rất
nhiều, ngời ta biết tận dụng cách sử dụng các biên. Khi nào thì dùng biến toàn cục.
Khi nào thì dùng biến cục bộ. Mỗi biến có những u, nhợc điểm khác nhau nhng nó
làm nên một chơng trình hoàn hảo và hiệu quả.
Không một ai có thể phủ nhận vai trò quan trọng của hàm, biến toàn cục, biến
cục bộ. Nhng việc sử dụng nó nh thế nào lại tuỳ thuộc vào trình độ của mỗi ngời.
Có ngời cho hiệu quả rất cao nhng ngợc lại có ngời lại thất bại thảm hại. Một vấn đề
đặt ra là phải dùng thời gian thật nhiều để nghiên cứu chúng thì mới có thể đạt đợc
những gì mà mình mong muốn.
Một lần nữa em xin cám ơn TS.Đặng Quế Vinh đã giúp em hoàn thành đề án
này một cách tốt đẹp, và những tài liệu tham khảo trong bài giảng của thầy.
22

Mục lục
Phần I: Mở đầu 1
Phần II: Phần nội dung 2
Chơng I: Hàm 2
I. Định nghĩa hàm 2
II. Sử dụng hàm 4
III. Truyền tham số cho hàm 5
IV.Sử dụng hàm trong nhiều chơng trình khác 6
V. Danh sách đối của hàm 7
VI.Các hàm trong C
++
8
1. Tham chiếu 8
2. Đối có giá trị mặc định 11
3. Hàm trực tuyến 12
4. Đệ quy 13
Chơng II: Biến toàn cục, biến cục bộ 15
I. Biến toàn cục 15
II. Biến cục bộ 16
Chơng III: Chơng trình có sử dụng định nghĩa hàm,
biến toàn cục, biến cục bộ trong C
++
17

Phần III: Phần kết luận 22
Tài liệu tham khảo 24
23
Tài liệu tham khảo
1. C
++

& lập trình hớng đối tợng
G.S- Phạm Văn ất, nhà xuất bản khoa học và kỹ thuật.
2. Ngôn ngữ lập trình
Trung tâm t vấn xuất bản, nhà xuất bản giao thông vận tải.
3. Lập trình hớng đối tợng với C
++
Lê Đăng Hng, Tạ Tuấn Anh, Nguyễn Hữu Đức,
Nguyễn Thanh Thuỷ, nhà xuất bản khoa học và kỹ thuật,1999.
4. Bài giảng của thầy-T.S-Đặng Quế Vinh.

24

×