1. Trang chủ
  2. » Công Nghệ Thông Tin

lap trinh can ban docx

55 290 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 55
Dung lượng 0,9 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Khai báo và định nghĩa hàm tt Hàm nguyên mẫu function prototype :  Đượ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

Trang 1

Môn: PHƯƠNG PHÁP LẬP TRÌNH

Chương 6: Hàm và con trỏ

Trang 2

6.1.4 Các phương pháp truyền tham số

6.1.5 Phạm vi của các đối tượng

6.1.6 Cấp lưu trữ của các đối tượng

6.1.7 Đệ qui

6.1.8 Nạp chồng hàm

6.1.9 Tổ chức chương trình

6.1.10 Các chỉ thị tiền xử lý

Trang 3

Chương 6: Hàm và con trỏ 3

6.1.1 Khái niệm Hàm

 Một hàm là một khối lệnh được đặt tên và có tính chất là nó có thể được

thực thi tại nhiều điểm khác nhau trong chương trình khi được gọi Khối lệnh này còn được gọi là unit hay module

 Hàm có thể được sử dụng trong chương trình này mà cũng có thể được sử

dụng trong chương trình khác, dễ cho việc kiểm tra và bảo trì chương trình

 Hàm có một số đặc trưng:

 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

Trang 4

6.1.1 Khái niệm Hàm (tt)

Trang 5

 Để 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 <tên tập tin>

 Ví dụ: #include <iostream.h>

#include <conio.h>

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

Trang 6

6.1.2 Khai báo và định nghĩa hàm

.//Trị trả về

[Return <Biểu thức trả về>;]

}

Trang 7

Chương 6: Hàm và con trỏ 7

6.1.2 Khai báo và định nghĩa hàm (tt)

Hàm nguyên mẫu (function prototype) :

 Đượ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:

[<kiểu giá trị trả về>] <tên hàm>([<danh sách các tham số>]) ;

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

Trang 8

6.1.2 Khai báo và định nghĩa hàm (tt)

Tổ chức một chương trình “C/C++”

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 VÀ ĐỊNH NGHĨA HÀM

HÀM main()

Cách 2: chương trình gồm 4 phần (nên dùng cách này)

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

Trang 9

Chương 6: Hàm và con trỏ 96.1.2 Khai báo và định nghĩa hàm (tt)

Ví dụ:

Trang 10

6.1.3 Các dạng hàm

1 Hàm không có giá trị trả về

Ví dụ: Hàm xoá màn hình 100 lần

Trang 11

Chương 6: Hàm và con trỏ 11

6.1.3 Các dạng hàm (tt)

1 Hàm không có giá trị trả về

Ví dụ:

Trang 12

6.1.3 Các dạng hàm (tt)

2 Hàm có giá trị trả về (Lệnh return)

Ví dụ: hàm tính luỹ thừa n (với n nguyên) của một số thực bất kỳ

Trang 13

Chương 6: Hàm và con trỏ 13

6.1.3 Các dạng hàm (tt)

2 Hàm có giá trị trả về (tt)

Ví dụ: Tính tổng các phần tử có trong mảng

Trang 14

6.1.3 Các dạng hàm (tt)

3 Hàm gọi đệ qui: một lệnh trong thân hàm gọi đến chính nó

Ví dụ: Chương trình tính giai thừa của n

if(n==0) return 1;

Trang 15

Chương 6: Hàm và con trỏ 15

6.1.3 Các dạng hàm (tt)

4 Hàm không có tham số

Ví dụ: Hàm in dòng chữ “HELLO C”

Trang 16

6.1.3 Các dạng hàm (tt)

5 Hàm có tham số

Ví dụ: hàm in số lớn nhất

Trang 17

Chương 6: Hàm và con trỏ 17

6.1.4 Các phương pháp truyền tham số

Có hai loại tham số:

Tham số thực (actual parameter) là tham số trong lời gọi hàm.

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

Trang 18

6.1.4 Các phương pháp truyền tham số (tt)

Trang 19

Chương 6: Hàm và con trỏ 19

6.1.4 Các phương pháp truyền tham số (tt)

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

Trang 20

6.1.4 Các phương pháp truyền tham số (tt)

Ví dụ: Khảo sát chương trình

Trang 21

Chương 6: Hàm và con trỏ 21

6.1.4 Các phương pháp truyền tham số (tt)

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

Trang 22

6.1.4 Các phương pháp truyền tham số (tt)

Ví dụ: Khảo sát chương trình sau

Trang 23

Chương 6: Hàm và con trỏ 23

6.1.4 Các phương pháp truyền tham số (tt)

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

 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

Trang 24

6.1.4 Các phương pháp truyền tham số (tt)

Truyền mảng vào hàm:

 Truyền mảng vào hàm mặc định là truyền tham chiếu Những thay

đổi đến giá trị của các phần tử mảng trong thân hàm sẽ ảnh hưởng đến mảng gôc

Ví dụ: Viết chương trình thay đổi giá trị các phân tử mảng theo yêu cầu:

nếu giá trị >=0 thì thay bằng 1, ngược lại thay bằng 0

Trang 26

6.1.5 Phạm vi của các đối tượng

 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 cục bộ (local scope)

− Phạm vi khối (Block scope)

− Phạm vi hàm (Function scope)

Phạm vi toàn cục (global scope)

− Phạm vi tập tin (File scope)

− Phạm vi chương trình (Program scope)

Trang 27

Chương 6: Hàm và con trỏ 27

6.1.5 Phạm vi của các đối tượng (tt)

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(){

int i; /* block scope */

return 0;

}

Trang 28

6.1.5 Phạm vi của các đối tượng (tt)

Ví dụ:

Trang 29

Chương 6: Hàm và con trỏ 29

6.1.5 Phạm vi của các đối tượng (tt)

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 */

}

Trang 30

6.1.5 Phạm vi của các đối tượng (tt)

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 x = 0; /* program scope */

float y = 0.0; /* program scope */

Trang 31

Chương 6: Hàm và con trỏ 316.1.5 Phạm vi của các đối tượng (tt)

Ví dụ:

Trang 32

6.1.5 Phạm vi của các đối tượng (tt)

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

int x = 0; /* program scope */

static int y = 0; /* file scope */

static float z = 0.0; /* file scope */

Trang 33

Chương 6: Hàm và con trỏ 336.1.5 Phạm vi của các đối tượng (tt)

Ví dụ:

Trang 34

6.1.5 Phạm vi của các đối tượng (tt)

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

Chỉ có thể được truy xuất bên trong

phạm vi khối hay hàm đó mà thôi Có thể được truy xuất ở mọi nơi trong chương trình

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á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

Trang 35

Chương 6: Hàm và con trỏ 35

6.1.6 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 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

Trang 36

6.1.6 Cấp lưu trữ của các đối tượng (tt)

Biến register (ít dù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()

{ /* block scope with the register specifier */

register int i;

for (i=0; i<MAX_NUM; i++){ /* some statements */}

return 0;

Trang 37

Chương 6: Hàm và con trỏ 37

6.1.6 Cấp lưu trữ của các đối tượng (tt)

Biến static (còn gọi là biến tĩnh)

 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

Trang 38

6.1.6 Cấp lưu trữ của các đối tượng (tt)

Ví dụ: Biến static

Trang 39

Chương 6: Hàm và con trỏ 39

6.1.6 Cấp lưu trữ của các đối tượng (tt)

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 đó

Trang 40

6.1.6 Cấp lưu trữ của các đối tượng (tt)

Ví dụ: Biến extern

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

Trang 41

Chương 6: Hàm và con trỏ 416.1.6 Cấp lưu trữ của các đối tượng (tt)

Cấp lưu trữ biến (Storage class)

Trang 43

Chương 6: Hàm và con trỏ 43

6.1.7 Đệ qui (tt)

Đặ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

 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

Trang 44

6.1.7 Đệ qui (tt)

Cấu trúc chung của hàm đệ qui

if (trường hợp suy biến)

Trang 45

Chương 6: Hàm và con trỏ 45

6.1.7 Đệ qui (tt)

Đệ quy - Các ví dụ

Ví dụ: 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.

Trang 46

6.1.7 Đệ qui (tt)

Ví dụ: Tính số hạng thứ n của dãy Fibonaci là dãy f(n) được định nghĩa:

− f(0) = f(1) = 1

− f(n) = f(n-1) + f(n-2) với n ≥ 2.∀

Trang 47

Chương 6: Hàm và con trỏ 47

6.1.9 Một số gợi ý khi thiết kế hàm

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)

Đặt tên hàm sao cho có tính gợi nhớ (Mnemonic)

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

Trang 48

6.1.9 Một số gợi ý khi thiết kế hàm (tt)

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ố?

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

Trang 49

Chương 6: Hàm và con trỏ 49

6.1.10 Các chỉ thị tiền xử lý

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.

Trang 50

6.1.10 Các chỉ thị tiền xử lý (tt)

b Chỉ thị macro #define

Cú pháp: #define tên_macro xaukitu

 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

 Ví dụ:

#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

if (i < MAX) then begin

Ok = TRUE;

cout << i ; end

if (i < 100 then {

Ok = 1;

Viết

CT dịch

Trang 51

Chương 6: Hàm và con trỏ 51

6.1.10 Các chỉ thị tiền xử lý (tt)

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

#endif }

Trang 52

6.1.10 Các chỉ thị tiền xử lý (tt)

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ử 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

Trang 53

Chương 6: Hàm và con trỏ 53

6.1.10 Các chỉ thị tiền xử lý (tt)

d Chỉ thị #ifdef và #ifndef

 Thư viện 1 tên tệp: MYLIB.H

int max(int a, int b)

Trang 54

6.1.10 Các chỉ thị tiền xử lý (tt)

Khắc phục

// 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

Ngày đăng: 11/07/2014, 09:20