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

Hàm lập trình căn bản pptx

77 434 1
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 77
Dung lượng 1,75 MB

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

Nội dung

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..  K

Trang 2

 Viết chương trình tính S = a! + b! + c! với a, b, c

Nhập

Nhập NhậpNhập NhậpNhập TínhTính TínhTính TínhTính

Trang 3

do {

cout<<“Nhap mot so nguyen duong: ”;

cin>> b ; } while ( b <= 0);

Trang 5

 Giải pháp => Viết 1 lần và sử dụng nhiều lần

do {

cout<<“Nhap mot so nguyen duong: ”;

cin>> n ; } while ( n <= 0);

{ Tính s = n! = 1 * 2 * … * n }

Trang 6

 Khái niệm

đầu ra.

chuyên biệt cho chương trình chính.

nhau.

• Tái sử dụng.

Trang 7

 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)

Trang 9

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 <tên tập tin>.

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

#include <conio.h>

Trang 10

 Cú pháp

• <kiểu trả về> : kiểu bất kỳ của C ( char , int , long ,

float ,…) Nếu không trả về thì là void

• <tên hàm>: theo quy tắc đặt tên định danh.

• <danh sách tham số> : tham số hình thức đầu vào

giống khai báo biến, cách nhau bằng dấu ,

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

{

<các câu lệnh>

[ return <giá trị>;]

}

Trang 11

 Cần xác định các thông tin sau đây:

Trang 12

 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;

cout<<x<<“+”<<y<<“=“<<s;

Trang 13

 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;

Trang 14

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

Trang 15

 Khái niệm

• Toàn cục: khai báo trong 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

Trang 16

int a;

int Ham1() {

int a1;

}

int Ham2() {

int a2;

{

int a21;

} }

void main() {

Trang 17

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:

[<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ị

Trang 18

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 19

int min1 = min(a,b);

cout << “Min = “ << min1;}

int min(int a, int b){ if (a<b) return a;

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

Trang 20

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 21

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

Trang 22

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 23

 Truyền Giá trị (Call by Value)

hàm chỉ sẽ nhận giá trị

giá trị của tham số sau khi thực hiện hàm.

void TruyenGiaTri(int x)

{

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

Trang 24

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

cout << “Inside main function:” << endl;

cout << “a = “ << a << endl;

Trang 25

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

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 26

 Truyền Địa chỉ (Call by Address)

trỏ).

 Không được truyền giá trị cho tham số này.

của tham số sau khi thực hiện hàm.

void TruyenDiaChi(int *x)

{

*x++;

Trang 27

 Truyền Tham chiếu (Call by Reference) ( C++ )

 Không được truyền giá trị cho tham số này.

của tham số sau khi thực hiện hàm.

void TruyenThamChieu(int &x)

{

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

Trang 28

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

cout << “Inside main function:” << endl;

cout << “a = “ << a << endl;

Trang 29

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

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 30

}

Trang 32

 Cách thực hiện

(hằng, biến, biểu thức) cho các tham số theo đúng thứ tự đã được khai báo trong hàm.

<tên hàm> ( <đối số 1> , … , <đối số n> ) ;

Trang 33

 Ví dụ

Trang 34

 Ví dụ

Trang 35

int gt;

if(n==1) return(1);

// goi de qui

gt = giaiThua(n-1)*n; return gt;

}

Trang 37

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

Đệ quy

Trang 38

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

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

Trang 39

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

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

Trang 40

 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);

}

Trang 42

 Ví dụ 2 : Tháp Hà Nội

void chuyen(int n, int di, int den) // n: số tầng, di, den: vị trí đi,

đến{ if (n==1) cout << di << " → " << den << endl;

else { cout << di << "→" << 6-di-den << endl; // 1 tầng từ di qua trung gian

chuyen(n-1, di, den) ; // n-1 tầng từ di qua dencout << 6-di-den << "→" den << endl; // 1 tầng từ tg

về lại den }

Trang 43

BB Nạp chồng hàm

 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

 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ị

double x = 20.0;

int y = 10;

F(x, y); // mơ hồ! chương trình

Trang 44

 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ớ (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,

Trang 45

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

 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 46

 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 47

 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;

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

Trang 48

Ví dụ: 1: /* Scopes in nested block */

10: { /* the beginning of the inner block */

11: int i, j; /* block scope 2, int i hides the outer int i*/

12:

13: cout<<"Within the inner block:\n";

14: for (i=0, j=10; i<=10; i++, j )

15: cout<<"i=“<<i<<“ j= “<<j<<“\n”;

16: } /* the end of the inner block */

17: cout<<"Within the outer block: i=<< i<<endl;

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:

Trang 49

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

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

Trang 50

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

int main(){ int i; /* block scope */

Trang 51

 Ví dụ:

1: /* Program scope vs block scope */

2: #include <stdio.h>

4: int x = 1234; /* program scope */

5: double y = 1.234567; /* program scope */

7: void function_1() 8: {

9: cout<<"From function_1: x=,”<<x<<“ y= “<< y<<endl;

10: } 12: main() 13: {

14: int x = 4321; /* block scope 1*/

16: function_1();

17: cout<<"Within the main block: x= “<<x<<“ y= “<<y;

18: /* a nested block */

19: { 20: double y = 7.654321; /* block scope 2 */

21: function_1();

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

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

Trang 52

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

int main(){ int i; /* block scope */

return 0;

}

Trang 53

Ví dụ:

#include <iostream.h>

int x=3; // biến x toàn cục

const int MAX = 10;

cout<<”Y = “<<y; // Sai vì biến y đã

bị hủy, không thể truy xuất

cout<<”X của hàm main() = “<<x; cout<<”X toàn cục = “<<::x;

} void fct(int x){

Trang 54

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 55

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

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 57

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.

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

Trang 58

{ 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

Trang 59

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

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

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

Ngày đăng: 09/07/2014, 13:21

TỪ KHÓA LIÊN QUAN