intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Ngôn ngữ C/C++ và kỹ thuật lập trình cơ sở: Phần 2

Chia sẻ: _ _ | Ngày: | Loại File: PDF | Số trang:167

16
lượt xem
10
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tiếp nội dung phần 1, cuốn sách "Kỹ thuật lập trình cơ sở với ngôn ngữ C/C++" phần 2 cung cấp cho người đọc những kiến thức như: phương pháp lập trình có cấu trúc; cấu trúc dữ liệu mảng và con trỏ; dữ liệu cấu trúc và xử lý tệp tin. Mời các bạn cùng tham khảo!

Chủ đề:
Lưu

Nội dung Text: Ngôn ngữ C/C++ và kỹ thuật lập trình cơ sở: Phần 2

  1. Chương 4 PHƯƠNG PHÁP LẬP TRÌNH CỐ CẤU TRÚC 4.1. Giới thiệu phương pháp lập trình có cấu trúc Lập trình có cấu trúc có thể hiểu một cách đom giản như là việc chia một chương trình lớn thành nhiều đơn vị chương trình nhỏ hom, mỗi đom vị chương trình như vậy thường để thực hiện một nhiệm vụ cụ thể, nhằm phục vụ cho chương trình lớn, ta gọi là chương trình con. Cũng như trong thực tiễn người ta thường chia một công việc cần thực hiện thành nhiều phần việc và giao mỗi phần việc cho một người thực hiện, sau đó tổng hợp kết quả cho công việc ban đầu. Có thể minh họa như sau: Theo cách này, để lập một chương trình giải quyết một bài toán lớn chúng ta thường phân rã bài toán đó thành nhiều bài toán con, có thể mỗi bài toán con lại được phân rã tiếp cho đến khi thu được bài toán đơn giản và có thể lập trình dễ dàng. Phương pháp này được gọi là “chia để trị” hoặc gọi là phương pháp phân tích “top-down” để giải quyết một bài toán.
  2. 96 KỸ THUẬT LẬP TRÌNH c ơ SỞ VỞ1 NGÒN NGỮ C/C++ Một Vấn đề quan trọng trong phương pháp này là chúng ta sẽ dừng việc chia một việc thành các việc nhỏ hơn khi nào, quá trình chia phải làm thế nào để việc tổng hợp kết quả dễ dàng và hiệu quả. Đe có được một cách nhìn tổng thể và chi tiết hơn chúng ta tham khảo trong các tài liệu liên quan, trong tài liệu này chúng ta chỉ đề cập ở khía cạnh lập trình là chính. Có thể coi chương trình con như là mô-đun chương trình tương đối độc lập, hoạt động dưới sự điều khiển (gọi thực hiện) của một mô-đun chương trình khác. M ột chương trình con ngoài tính chất độc lập còn phải có tính chất phổ dụng, tức là có thể sử dụng cho nhiều trường hợp của cùng một kiểu công việc. Muốn vậy thường chúng ta phải thiết kế một danh sách các biến hình thức (coi như đầu vào của mô-đun) và các đầu ra để liên kết với mô-đun điều khiển nó.
  3. KỸ THUẬT LẬP TRỈNH c ơ s ở v ớ i ngôn n g ữ C/C++ 97 Chương trình con được dùng để tối ưu hoá việc tổ chức chương trình, chia một chương trình lớn thành nhiều công việc nhỏ độc lập tương đối. Dùng chương trình con để thực hiện các công việc nhỏ, tạo thành một mô-đun. Khi đó nhiệm vụ chương trình chính chỉ là cung cấp dữ liệu đầu vào cho các mô-đun để hoàn thành công việc của mình. M ột chương trình viết theo cách này gọi là chương trình có cẩu trúc. Như vậy một chương trình con sẽ được gắn với công việc mà nó thực hiện, chúng ta cần phải đưa dữ liệu vào cho chương trình con để thực hiện công việc tương ứng và sau đó sẽ trả về kết quả. Có thể hình dung chương trình con dưới dạng hộp đen như sau: Chương trình con thực hiện công việc A Dữ liệu đưa vào Dữ liệu kết để thực quả của việc hiện việc A A Để nhận các dữ liệu đưa vào cho chương trình con và nếu cần có thể chứa dữ liệu kết quả ra, chúng ta phải sử dụng tham số (parameters) của chương trình con. Tham số tồn tại dưới hai hình thức, đó là tham số hình thức và tham số thực. Tham số hình thức là tham số xác định tại thời điểm khai báo và xây dựng chương trình con, còn tham số thực được xác định tại thời điểm đưa dữ liệu vào khi gọi chương trình con.
  4. 98 KỸ THUẬT LẬP TRÌNH c ơ SỜ vở l NGÔN NGỮ CIO** 4.2. Khai báo và xây dựng hàm trong ngôn ngữ C/C++ M ột số ngôn ngữ lập trình cung cấp hai loại chương trình con riêng biệt đó là hàm (function) và thủ tục (procedures) như Pascal. Tuy nhiên, ngôn ngữ C/C++ chỉ cung cấp một dạng thức đó là hàm. Chương trình chính của C/C++ cũng là một hàm và đó là hàm main(), trong đó gồm dãy các lệnh theo thuật toán nào đấy sao cho sau khi máy thực hiện xong dãy các lệnh này ta thu được kết quả mong muốn. Hệ thống thư viện cung cấp trong lập trình C/C++ cũng là hệ thống các hàm được xây dựng sẵn, từ đó trong các chương trình chúng ta đều viết lệnh gọi đến các hàm này để xử lý theo yêu cầu công việc. Điều đó có nghĩa là hệ thống thư viện chuẩn của C/C++ là một chương trình viết theo cấu trúc gồm các chương trình con dạng hàm. Phần tiếp sau đây sẽ cung cấp cho chúng ta cách viết các chương trình con dạng hàm thực hiện các chức năng, cách sử dụng hàm (gọi hàm), cấu trúc một chương trình C/C++ có sử dụng chương trình con dạng hàm. Trước hết, để tạo một hàm chúng ta cần phải xác định: - Hàm được xây dựng sẽ thực hiện công việc gì? - Sau khi thực hiện xong, kết quả của nó được thể hiện dưới dạng là một dữ liệu hay nhiều dữ liệu hay chỉ là một hành động nào đó mà kết quả không thể hiện bằng dữ liệu trên máy tính. - Để thực hiện việc đó chúng ta cần phải cung cấp đầu vào là những dữ liệu gì? - Đe thực hiện công việc của hàm, chúng ta sử dụng thuật toár nào hoặc phương pháp xử lý để ra được kết quả đúng cho hàm. Ví dụ: Lập trình một hàm để tìm số lớn nhất của 3 số nguyên khi đó ta xác định các yếu tố sau: - Chức năng thực hiện: tìm số lớn nhất (max) của 3 số neuyên
  5. KỸ THUẬT LẬP TRÌNH c ơ s ở VỚI NGÔN NGỮ C/C++ 99 - Két quả trả về: một số nguyên (là số max) - D ữ liệu đầu vào: 3 số nguyên - Phương pháp thực hiện: so sánh hai số đầu với nhau để chọn ra số lớn hơn, sau đó so sánh số lớn hơn này với số thứ ba để biết số lớn nhất trong ba số. Hàm tìm max 3 số nguyên số nguyên a nội dung các câu lệnh kết quả max số nguyên b ------------ ------------- ► xử lý theo thuật toán sô nguyên c Sau khi trả lời được các câu hỏi trên thì chúng ta sẽ chuyển sang thực hiện khai báo và xây dựng hàm. 4.2.1. Khai báo hàm Khai báo hàm được thực hiện ở phần đầu chương trình (sau lệnh khai báo nạp thư viện, #include), khai báo hàm như là việc báo cho máy tính biết các thông tin cơ bản về hàm bao gồm: kiểu dữ liệu trả về, tên của hàm, các tham số hình thức bao gồm kiểu dữ liệu và tên của từng tham số. Quy tắc khai báo hàm trong C/C++ như sau: kiểu-trả-về tên-hàm( kiểul t _ s ố l, kiểu2 t_số2, ... ); Trong đó: - kiểu_trả_về: là một tên kiểu dữ liệu quy định cho dữ liệu kết quả trả về sau khi xử lý của hàm. - tên hàm: tự đặt theo quy tắc đặt tên của C/C++. - kiểu l , 2,...: xác định kiểu dữ liệu của tham số thứ nhất, hai,...
  6. 100 KỸ THUẬT LẬP TRÌNH c ơ s ở vở l NGÒN NGỮ C/C++ - t_số 1, 2 ,...: đặt tên cho các tham số hình thức của hàm tương ứng với từng kiểu dữ liệu. Tên các tham số hình thức này có thể bỏ qua tại bước khai báo. Ví dụ: int sum ( in t , in t ); float max ( float X , float y ); Hàm ‘sum ’ trả về kết quả là số nguyên (kiểu của hàm là int) và có hai tham số hình thức đều có kiểu int (số nguyên). Cả hai tham số này chưa quy định tên. Còn hàm ‘max’ cũng có hai tham số kiểu float (số thực) nhưng đã được quy định tên của chúng (là X và y), hàm này trả về kết quả là sổ thực (kiểu hàm là float). Nếu hàm không có dữ liệu được định kiểu trả về thì viết tên kiểu trả về là void, nếu không có tham số thì bỏ trống và phải có cặp dấu mở đóng ngoặc 0 sau tên hàm. Ví dụ: void PrintMe ( ); 4.4.2. Xây dựng hàm Sau khi khai báo xong hàm chúng ta có thể viết lệnh thực hiện công việc đặt ra cho hàm đó, thông thường viết lệnh cho hàm đặt ở sau chương trình chính (cuối chương trình). Cú pháp thực hiện viết lệnh cho hàm đã khai báo: kiểu-trả-về tên-hàm ( kiểu l t-số lf kiểu2 tsố2, ... ) < viết-các-lệnh-thực-hiện-công-việc-dặt-ra-cho-hàm 2 ________________________________________________________________________________ Ở đây chúng ta lặp lại khai báo hàm như trên nhưng các tham số cần phải được xác định tên của chúng để xử lý trong nội dung hàm, nếu trong khai báo đã quy định tên thì ở đây cũng phải viết lại tên đó.
  7. KỸ THUẬT LẬP TRÌNH c ơ SỞ VỚI NGÔN NGỮ C/C++ 101 Các tên tham số khai báo tại thời điểm này được gọi là tham số hình thức, tức chúng chưa có giá trị cụ thể. Khi cần kết thúc thực hiện hàm và trả về dữ liệu kết quả nào đấy, chúng ta viết lệnh sau vào vị trí cần thiết trong hàm. Lệnh để kết thúc thực hiện hàm và trả về giá trị kết quả nếu có như sau: return giá-trị-dữ-liệu-trả-về; trong đó dữ liệu trả về sẽ được bỏ qua nếu hàm có kiểu void, nên lệnh ‘return’ chỉ cần dấu chấm phẩy kết thúc lệnh là được. Cụ thể: return; Ví dụ: int sum ( int a, int b) { return a+b; > hoặc float max ( float X, float y) { if ( x>y ) return x; else return y; > Đối với hàm có kiểu void thì ta có ví dụ: void PrintMe ( ) { printf( "Họ và tên: Nguyễn Thúy Hà" ); printf( "Ngày sinh: 14/02/1976" ); printf( "Quê quán: Nghệ Tĩnh" ); return; >
  8. 102 KỸ THUẬT LẬP TRÌNH c ơ s ở VỚI NGỔN NGỮ C/C++ CÓ thể không cần lệnh return trong hàm kiểu void này, khi đó mặc định dấu ‘} ’ để đóng khối lệnh của nội dung hàm cũng là kết thúc hàm. Chú ý: Thông thường với những chương trình đơn giản có ít chương trình con thì người ta viết lệnh cho hàm ngay tại nơi khai báo. Nhưng các hàm cần phải được khai báo trước khi gọi sử dụng chúng. 4.2.3. Lời gọi hàm Khi bắt đầu thực hiện một chương trình, mặc định máy chỉ vào thực hiện các lệnh trong chương trình chính (hàm main), do đó để yêu cầu máy thực hiện công việc tương ứng với chương trình con (hàm) nào thì ta phải viết lệnh gọi hàm đó như sau: tên-hàm ( các-tham-số-thực-truyền-vào ); Các tham số thực là các giá trị dữ liệu được truyền vào cho các tham số hình thức tương ứng của hàm theo thứ tự trái sang phải. Lời gọi này có thể là một câu lệnh độc lập hoặc đặt ưong các biểu thức, nếu đặt trong biểu thức thì hàm đó phải có giá trị trả về để thực hiện tính toán biểu thức đó. Ví dụ: printf( "%d" , sum (4,23) ); PrintMeO; Là 2 lệnh gọi hàm, ở lệnh đầu ta gọi hàm ‘sum ’ và truyền vào tham số thực là số 4 và số 23, hai số này lần lượt đưa vào thay thế cho tham số hình thức là a và b ở trên để tính toán bên trong hàm. Kết quả của hàm ‘sum ’ (được trả về bởi lệnh return) sẽ dùng để in ra ra bời lệnh ‘p r in tf . Lệnh sau gọi hàm ‘PrintM e’, hàm này không có dữ liệu trả về (kiểu void) nên gọi nó sẽ là một lệnh độc lập. Cách thực hiện kh i gọ i chương trình con (hàm)-. Khi một hàm được gọi (bằng câu lệnh như trên), máy sẽ tạm dừng quá trình chạy của phần chương trình hiện tại và chuyển sang chạy hàm được gọi
  9. KỸ THUẬT LẬP TRÌNH c ơ s ở VỚI NGÔN NGỮ C/C++ 103 tương ứng. Sau khi kết thúc hàm được gọi, máy sẽ quay về tiếp tục chạy phần chương trình đã bị tạm dừng trước đó (minh họa hình vẽ sau). Trong hình vẽ, giả sử máy đang chạy hàm “A ” và đoạn chương trình (1) được thực hiện. Tiếp theo, có lệnh gọi hàm “B” nên máy tạm dừng chạy hàm “A ”, chuyển sang thực hiện nội dung (3) trong hàm “B”. Sau khi xong hàm “B”, máy quay trở lại chạy tiếp hàm “A ” bị tạm dừng trước đó với nội dung thực hiện là (2). Ví dụ: printf ( " Tổng hai số 5 và 19 là: %d " , sum(5; 19) ); sẽ thực hiện gọi hàm sum ở ví dụ trên, truyền tham số thực là giá trị 5 và 19 cho tham số hình thức a và b của hàm. Kết quả trả về của hàm (lệnh returm ) sẽ dùng để in ra bởi lệnh printf. float m = max( a, b ); sẽ gọi hàm max và truyền tham sổ thực là giá trị trong 2 biến nhớ a và b cho tham số hình thức X và y của hàm. PrintMeO; là lời gọi hàm với một câu lệnh độc lập. Thông thường lời gọi hàm được viết trong chương trình chính, tuy nhiên có thể trong một chương trình con khác. Các chương trình con có thể gọi lẫn nhau, nhưng chúng ta phải chú ý đến vấn đề “đệ quy” sẽ được xét ở phần sau nếu không sẽ dẫn đến “treo máy”.
  10. 104 KỸ THUẬT LẬP TRÌNH c ơ SỞ VỞ) NGÒN NGỮ C/C++ Ví dụ:______________________________________________ int max ( int a, int b) if (a>b) return a; else return b; int sum ( int a, int b, int c ) return m ax(a,b)+c; void Printo printf( "Kết quả là: %d" , sum (5,2,29) + m ax(32,12) ); ví dụ trên cho thấy trong hàm Print() gọi đến hàm sum(...) và hàm max(...)> trong hàm sum(...) có gọi đến hàm max(...). Kết quả hiện ra màn hình khi thực hiện hàm Print() sẽ là: Kết quả là: 66 C hú ý: Các hàm gọi lẫn nhau và có thể gọi lại chính nó. Khi các hàm gọi lẫn nhau theo cơ chế vòng (chẳng hạn, hàm A gọi B, B gọi c, c gọi A) hoặc hàm gọi chính nó (hàm A gọi lại chính A) thì được gọi là các hàm đệ quy. Nhưng đệ quy cần phải được thiết kế “neo” hay gọi là điểm dừng, tức là thời điểm mà không có lệnh gọi lại chính nó. Ví dụ: M ột hàm đệ quy như sau: int SUM( int X ) { if( x_______________________________________________________________________________ Trong hàm trên, trường hợp “else” của lệnh if sẽ gọi lại chính nó và “neo” ở đây chính là thời điểm mà tham số X không dương (
  11. KỸ THUẬT LẬP TRÌNH c ơ SỞ VỚI NGỔN NGỮ C/C++ 105 sẽ thực hiện hàm SUM với X = 5, trong đó sẽ trả về 5 + SUM(4) và chạy lại hàm SUM lần 2 với X = 4, trả về là 4 + SƯM(3),.!. cứ tiếp tục cho đến khi X = 0. Kết quả cuối cùng là 5 + 4 + 3 + 2 + 1 + 0 = 1 5 . 4.2.4. Cấu trúc chung của chương trình có chương trình con / * phần khai báo file header */ #include / * phần khai báo các hàm */ kiểu-hàm tên-hàm ( k iế u l, kiểu2 , ...); ■■ ■ / * chương trình chính, hàm main */ int main() / * viết lệnh cho chương trình chính */ ■ ■■ return 0; > / * viết lệnh cho các chướng trình con đã khai báo ở trên*/ kiếu-hàm tên-hàm(kiếul tham -sốl, kiếu2 tham-số2, ...) < ... / * viết lệnh cho hàm này */ ____________ >________________________________________________________ ________ Chú ý: - Các chương trình con có thể viết nội dung trước (phía trên) chương trình chính ngay tại nơi khai báo chúng. - Không được phép viết chương trình con trong thân chương trình chính hoặc trong thân một chương trình con khác.
  12. 106 KỸ THUẬT LẬP TRÌNH c ơ SỞ VỚI NGÒN NGỮ C/C++ 4.3. Trao đổi dữ liệu giữa các hàm Trong một chương trình lớn gồm có nhiều chương trình con khác nhau, mỗi chương trình con thực hiện một phần công việc nào đó phục vụ cho chương trình lớn. Như vậy, các chương trình con luôn luôn có những mối quan hệ với nhau và với chương trình chính (vì chúng cùng tham gia thực hiện một bài toán đã đặt ra cho chương trình lớn). Trong lập trình, chúng ta sẽ xem xét mối quan hệ ràng buộc và tương tác giữa các hàm với nhau ở góc độ dữ liệu, tức là một hàm sẽ thực hiện và kết quả của nó được sử dụng để một hàm khác xử lý tiếp. Chẳng hạn, trong một công ty (như là chương trình), người bảo vệ (như là một hàm) sẽ kiểm tra an ninh các khách hàng đến công ty, nếu khách hàng nào được kiểm tra đạt (kết quả thực hiện của người bảo vệ) thì sẽ đến bộ phận lễ tân (cũng như là một hàm) để tiếp đón và giới thiệu đến các bộ phận khác, cứ như thế tiếp tục cho đến khi đạt được mục tiêu đặt ra ban đầu. Trên cơ sở đó, trong phần này chúng ta sẽ xem xét kỹ vấn đề tương tác, trao đổi dữ liệu giữa các hàm với nhau trong một chương trình. 4.3.1. Biến toàn cục và biến cục bộ Biến toàn cục là biến nhớ được khai báo ở ngoài mọi hàm (thường được khai báo ở phía trên cùng sau khai báo thư viện), có tác dụng đến toàn bộ chương trình cả chương trình chính và các chương trình con. Biến cục bộ là biến nhớ được khai báo bên trong một chương trình con, chỉ có tác dụng ở trong chương trình con đó. Bên ngoài chương trình con thì biến đó không sử dụng được nữa. Ta nói biến toàn cục có phạm vi tác động đến toàn bộ chương trình, biến cục bộ chỉ có phạm vi tác động trong một chương trình con chứa nó mà thôi.
  13. KỸ THUẬT LẬP TRÌNH c ơ SỞ VỚI NGÔN NGỮ C/C++ 107 Có thể minh họa như sau: Toàn bộ chương trình biljj Ịợàiị ẹục ịẹó; phạm;vi 'iỊc độiig đếii tất iẹấ ẹịẫẹ;:; ;chương trình -con! Vẳ;chiroligtnnhchinh ị:ị:ị:ị: Chương trình con A ///////////////////////////////////////////////////////////////////////////////////////////////////////////, f/ / / / / / / iU / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / s / / / / / / / / , . -m f e D / A l w / I M l / A 'I I ểế 'ĨA jA A Ề ầ t/l7 k///////////////////////////////////////////////s//t/////é '// ///// //// //// ? ///// ///} / ///// //// ///// //// //// ///// //// ///// //// //// ///// //// ///// //// ///// //// //// ///// * f/////////////////////S ////////////////////////////////////////////////////////////////////////////////////s '/ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / ế vSNWS\N\N\NNS\W SVSN\\SNV Chương trình con B \\S \\\\\\\\\\\\\\N \S \S S \\\S S \' ^S SSSSSW W SW SSN V SW W N W 'ivV kV ^V V V V V V W V kV V V V kV V W V V V W V V V V V V W V W V V W ^SW W SW W W W W W SSSSW SSSW ' \\NN\NSNSN\S\\\\\SSS\\S\SS\\S\S\SS\\\\\S\\S\\\\\\W\\\\\\\\\S\S\\\\\\\\\\\\S\SSSNS\SNSN\NS\N\S\N\SSN\SN\SNV \S\\S\S\yv\\S\NN\\\\\\S\\NN\\\NSN\N\S\\\SN\\S\\\\\NNN\N\\\\NS\\\\SSN\\N\\NSS\\\\\S\S\N\\\\\\\\N\\\\\\NNVS.\V k\NN\NNW\\N\NN\N\N\\\NNN\\NNNWN\WNW\N\WNWNW\W\W AS\SS\S\\SSSS\S\\\\\\\\SS\\S\\S\S\\\\SSS\\\\\\\\\\S\\SSS\\\\S\SSS\\\\SS\S\SSSSSSS\\S\\\\\SSS\\N\\\\NSS\\\V Ị .
  14. 108 KỸ THUẬT LẬP TRÌNH c ơ s ở vở l NGÒN NGỪ C/C++ Hình vẽ sau minh họa điều này. Ví dụ: một chương trình có sử dụng các biến toàn cục và cục bộ #include #include int a, b; //biến toàn cục int sum (); int m ax(); int main() { clrscr(); printf( "Nhập số a=" ); scanf("%d", &a); printf( "Nhập số b=" ); scanf("%d", &b); printf( " \n Tổng hai số là: %d" , sum () ); printf( " \n Số lớn hơn là: %d" , m ax() ); getch(); return 0; > int sum () { int c = a+b; //biến cục bộ "c" return c; > int m ax() { int c = ((a>b)? a: b); //biến cục bộ "c" return c; >
  15. KỸ THUẬT LẬP TRlNH c ơ s ở v ớ i ngôn n g ữ C/C++ 109 Trong ví dụ trên, hai biến a & b là biến toàn cục được sử dụng trong cả ba hàm sum, max và main. Trong hàm sum và max đều có biến cục bộ là c, tuy nhiên biến c trong hàm sum sẽ độc lập và riêng biệt so với biến c trong hàm max. Biến toàn cục còn gọi là biến chung và biến cục bộ gọi là biến riêng. Chúng ta có thể sử dụng biến chung để chuyển dữ liệu giữa các chương trình con, qua ví dụ trên ta thấy dữ liệu nhập vào a & b thực hiện trong hàm main, hàm sum lấy dữ liệu đó để tính tổng và hàm max tìm số lớn cũng trên a & b chung. Việc này trông có vẻ đom giản nhưng không an toàn dữ liệu và khó kiểm soát giá trị của biến, bởi vì nó có thể bị thay đổi bởi bất kỳ một hàm nào trong chương trình. Vậy giải pháp tốt hơn là chúng ta sẽ sử dụng tham số của chương trình con để chuyển dữ liệu từ hàm này sang hàm khác thay thế cho biến chung. C hú ý: - Khi xử lý máy sẽ ưu tiên sử dụng biến cục bộ, nếu không tìm thấy biến cục bộ thì sẽ tìm và sử dụng biến toàn cục. - Các tham sổ hình thức của hàm cũng đóng vai trò như biến cục bộ, do đó khi xử lý máy cũng ưu tiên các tham sổ hình thức hơn so với biến toàn cục. - Bắt buộc các biên cục bộ phải được đặt tên khác với tên các tham số hình thức. Ngoài ra, trong C/C++ cung cấp cơ chế biến tĩnh “static” . Biến ở dạng này nếu được khai báo trong hàm sẽ được cấp phát một lần đầu khi hàm đó được gọi và giá trị của biến được kế thừa sử dụng ở các lần gọi sau của hàm đó. Chẳng hạn, ta có ví dụ:
  16. 110 KỸ THUẬT LẬP TRÌNH c ơ SỞ vớt NGỔN NGỮ C/Ch #include #include void test() { int c = 5; //biến thường static int d = 10; //biến tĩnh c += 5; d += 5; printf("\n c= %d, d = %d " , c, d); } int main() { te st(); te st(); test(); test(); test(); getch(); return 0; >_______________________________________________________________________________ Với 5 lần gọi hàm test() trong chương trình chính và kết quả in ra sẽ là, c= 10, d = 15 c= 10, d = 20 c= 10, d = 25 c= 10, d = 30 c= 10, d = 35 Ta thấy biến “c” đều có giá 10 nhưng biển “d” có giá trị tăng dần, điều này lý giải cho việc biến tĩnh (static) chỉ được cấp phát một lần đầu gọi hàm và như vậy giá trị của nó cũng chỉ được khởi tạo một lần, còn các lần gọi hàm sau s ẽ kế thừa giá trị của biến tĩnh để sử dụng. Ngược lại, các biến thường sẽ bị xóa khỏi bộ nhớ khi hàm kết thúc và được cấp phát lại sau mỗi lần gọi hàm, như biến “c” ở trên. Có thể thấy biến tĩnh đóng vai trò như biến chung (toàn cục) nhưng chỉ có phạm vi tác động đối với hàm chứa biến đó, các hàm khác không thể sử dụng khai thác.
  17. KỸ THUẬT LẬP TRÌNH c ơ s ở VỚI NGỐN NGỮ C/C++ 111 4.3.2. Tham số hình thức và tham số thực Như đã trình bày ở trên, tham số hình thức là tham số được khai báo khi xây dựng hàm, nó mang ý nghĩa hình thức để nhận các dữ liệu đầu vào cho một hàm. Tham số thực là tham số được xác định khi chúng ta gọi hàm, đó là các dữ liệu được truyền vào cho hàm để thực hiện tính toán. Hình vẽ sau minh họa hai khái niệm này. Ví dụ: Xét hàm sum như sau và chương trình chính sử dụng hàm đó int sum ( int a, int b) { return (a+ b); > void main() { int X = 4 ; printf("Tổng hai số là: ",sum (5, x * 2 - l) ); >
  18. 112 KỸ THUẬT LẠP TRÌNH c ơ SỞ vở l NGÒN NGỮ C/C++ Trong ví dụ trên, tham số a và b trong khai báo hàm sum là tham số hình thức, còn lời gọi hàm sum(5, x*2-l) thì 5 và x*2-l là tham số thực, đó là các hằng số, biểu thứ c,... M ột hàm có thể không có tham số hình thức và khi gọi hàm đó không cần đưa vào tham số thực, ví dụ như hàm PrintMeO ở ví dụ trước. 4.3.3. Tham trị và tham biến Tham số hình thức của chương trình con (hàm) có 2 dạng là tham trị và tham biến. Đây là cách gọi của hai dạng này, về bản chất thì chúng được phân biệt bởi khái niệm con trỏ và địa chỉ của biến nhớ sẽ được xem xét ở những phần sau. a) Tham số dạng tham trị M ột tham số hình thức là tham trị sẽ được khai báo như biến nhớ (các ví dụ từ đầu đến giờ đều sử dụng khai báo dạng tham trị): I kiẩu-dữ-liệu tẻn-tham-số ~ Ví dụ: void myFunction( int X , float y ); thì X và y sẽ là tham trị. Tham trị sẽ nhận dữ liệu đầu vào (tham số thực) là các giá trị dữ liệu vì vậy mọi sự thay đổi dữ liệu trên tham số hình thức của dạng này không ảnh hưởng đến tham số thực truyền vào. Tham số hình thức ở dạng tham trị sẽ luôn nhận được các tham số thực là các hàng, biến, biểu thứ c... và khi đó máy sẽ tính toán ra kết quả dữ liệu rồi mới truyền giá trị kết quả này cho tham số hình thức để hàm tính toán. Ví dụ: . void myFunction( int X , float y) { X = x*2; y = y/2; printf("\n Hai số trong hàm:,%d , % 5.2f", X, y );
  19. KỸ THUẬT LẬP TRỈNH c ơ s ở VỚI NGÔN NGỮ C/C++ 113 > void main() int a = 5; float b=7.5; printf( "\n Hai số trước khi gọi hàm: %d , % 5.2f" , a, b ); myFunction( a, b ); printf( "\n Hai số sau khi gọi hàm: %d , % 5.2f" , a, b ); >___________________________________ lời gọi hàm myFunction(a,b) trong hàm main() sẽ truyền tham số thực là a và b vào thay cho tham số hình thức X và y, trong hàm myFunction() có làm thay đổi giá trị của 2 tham s ố hình thức X và y song sự thay đổi này chỉ có ảnh hưởng trong hàm, còn đối với 2 tham số thực a và b vẫn giữ nguyên giá trị ban đầu. Hay nói một cách khác máy chỉ lấy giá trị của hai biến a và b truyền vào cho tham số hình thức X và y của hàm, còn bản thân hai biến a, b đó không bị ảnh hưởng bởi quá trình thực hiện của hàm. Kết quả khi chạy chương trình trên là: Hai số trước khi gọi hàm: 5 , 7.5 Hai số trong hàm: 1 0 , 3.75 Hai số sau khi gọi hàm: 5 , 7.5 Với kiểu tham số dạng tham trị này chúng ta có thể truyền vào cho tham số hình thức là các tham số thực dưới dạng hằng, biến, biểu thức... Chẳng hạn, với hàm ‘myFunction’ ở trên và lời gọi hàm sau: myFunction( 5, 2+7.0/2 ); thì máy truyền số 5 cho tham trị X và tính toán 2+7.0/2 được 5.5 và truyền cho tham trị y, kết quả là in ra của hàm sẽ là: Hai số trong hàm: 1 0 , 2.75 b) Tham số dạng tham biến Tham số hình thức là tham biến sẽ được khai báo như sau (sử dụng dấu sao đặt trước tên của tham số): tên-kiếu-dữ-liệu * tên-tham-số
  20. 114 KỸ THUẬT LẬP TRÌNH c ơ SỞ VỚI NGỔN NGừ C/C++ Khai báo này được gọi là khai báo con trỏ (sẽ đề cập chi tiết ở chương sau). Ví dụ: void myFunction( int X , float * y ); thì tham số X là tham trị còn tham số y là tham biến. Tham biến sẽ có tác động đến tham số thực tương ứng (của lời gọi hàm) khi có sự thay đổi giá trị tham số hình thức dạng này trong hàm. Tức là mọi sự thay đổi của tham số hình thức cũng sẽ là sự thay đổi tương ứng với tham số thực truyền vào khi gọi hàm. Khi một thấm số ở dạng tham biến (có dấu *) thì việc sử dụng nó trong hàm cũng phải sử dụng dấu * đi kèm để tính toán và xử lý đến giá trị dữ liệu thực truyền vào cho chúng. Tham số thực tương ứng với tham biến phải luôn là một biến nhớ, khi đó ta phải sử dụng dấu và (&) ở trước biến nhớ để truyền cho hàm ứng với tham biến đó. Dấu & sử dụng trước tên biến dùng để lấy địa chỉ của biến (sẽ đề cập chi tiết ở phần sau). Ví dụ: void myFunction( int X , float *y) { X = x*2; *y = *y/2; printf( "\n Hai số trong hàm: %d , % 5.2f" , X, *y ); > void main() { int a = 5; float b=7.5; printf( "\n Hai số trước khi gọi hàm: %d , % 5.2f" , a, b ); myFunction( a, &b ); printf( "\n Hai số sau khi gọi hàm: %d , % 5.2f" , a, b ); >___________________________________ Hàm myFunction() sẽ tăng X lên 2 lần và giảm y đi một nửa, lời gọi hàm này trong hàm mainQ truyền hai tham số thực là a và b (để ý
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
5=>2