Bài giảng Ngôn ngữ lập trình - Chương 6: Hàm và cấu trúc chương trình
Quy tắc xây dựng một hàm:
Hàm có thể xem là một đơn vị độc lập của chương trình. Các hàm có vai trò ngang nhau, vì vậy không cho phép xây dựng một hàm bên trong một hàm khác.
Dòng đầu tiên (của một hàm) chứa các thông tin về hàm:
Kiểu giá trị của hàm (nếu hàm có giá trị)
Tên hàm
Danh sách các đối số (nếu có) Các dòng tiếp theo dùng để khai báo kiểu giá trị của đối số.Và bắt buộc phải khai báo kiểu giá trị cho tất cả các đối số.
Tiép theo là thân hàm. Thân hàm là nội dung chính của hàm nó bắt đầu bằng dấu { và kết thúc }
Trong thân hàm có thể dùng 1 hoặc nhiều lệnh return hoặc có thể không dùng. Và có thể đặt chúng ở bất kỳ chỗ nào nếu thấy thích hợp.
Cú pháp chung của lệnh return
return ([Biểu thức]);
Giá trị của biểu thức trong ngoặc sẽ được gán cho hàm.
Trang 1
Trang 2
Trang 3
Trang 4
Trang 5
Trang 6
Trang 7
Trang 8
Trang 9
Trang 10
Tải về để xem bản đầy đủ
Tóm tắt nội dung tài liệu: Bài giảng Ngôn ngữ lập trình - Chương 6: Hàm và cấu trúc chương trình
CH ƯƠ NG VIHÀM VÀ CẤU TRÚC CH ƯƠ NG TRÌNH Hàm Quy tắc xây dựng một hàm: Hàm có thể xem là một đơ n vị đ ộc lập của ch ươ ng trình. Các hàm có vai trò ngang nhau, vì vậy không cho phép xây dựng một hàm bên trong một hàm khác. Dòng đ ầu tiên (của một hàm) chứa các thông tin về hàm: Kiểu giá trị của hàm (nếu hàm có giá trị) Tên hàm Danh sách các đ ối số (nếu có) Các dòng tiếp theo dùng đ ể khai báo kiểu giá trị của đ ối số.Và bắt buộc phải khai báo kiểu giá trị cho tất cả các đ ối số. Tiép theo là thân hàm. Thân hàm là nội dung chính của hàm nó bắt đ ầu bằng dấu { và kết thúc } Trong thân hàm có thể dùng 1 hoặc nhiều lệnh return hoặc có thể không dùng. Và có thể đ ặt chúng ở bất kỳ chỗ nào nếu thấy thích hợp. Cú pháp chung của lệnh return return ([Biểu thức]); Giá trị của biểu thức trong ngoặc sẽ đư ợc gán cho hàm. Quy tắc hoạt đ ộng của hàm Cách gọi hàm: tên_hàm([Danh sách tham số thực]); Chú ý: - Số tham số thực phải bằng với số tham số hình thức ( đ ối) và mỗi tham số thực phải có cùng kiểu với giá trị nh ư kiểu giá trị của đ ối t ươ ng ứng của nó. - Về nguyên tắc mọi hàm cần đư ợc khái báo tr ư ớc khi sử dụng nó. Nó hoàn toàn giống với việc khai báo một biến. Ví dụ: Viết ch ươ ng trình tìm số lớn nhất và nhỏ nhất của từng cột trong ma trận, có sử dụng hàm tìm max, tìm min. #include "stdio.h" int max(a,b) int a,b; { int m; m=a>b?a:b; return (m); } int min(a,b) int a,b; { int m; m=a<b?a:b; return (m); } main() { int s,k,i,j,ma,mi,max(),min(),temp; int a[3][3]; clrscr(); for (i=0;i<3;++i) for (j=0;j<3;++j) { printf("a[%d,%d] ",i,j); scanf("%d",&temp); a[i][j]=temp; } for (i=0;i<3;++i) { for (j=0; j<3;++j) printf(" %10d",a[i][j]); printf("\n"); } for (j=0;j<3;++j) { ma=mi=a[0][j]; for (i=0; i<3;++i) { mi=min(a[i][j],mi); ma=max(a[i][j],ma); } printf("\n Cot %d Max = %d \Min = %d",i,ma,mi); } getch(); return 0; } 3. Các khái niệm liên quan đ ến hàm: Tên hàm Kiểu giá trị của hàm Đối hay tham số hình thức Thân hàm Khái báo hàm Lời gọi hàm Tham số thực Cách xây dựng hàm [type] tên_hàm([Danh sách đ ối số]) [Khai báo kiểu giá trị cho tất cả các đ ối] { [Các khai báo kiểu giá trị cho các biến cục bộ và các hàm nó sử dụng] [return ([Biểu thức]);] } Chú ý: Khi xây dựng hàm cần nắm vững những qui đ ịnh về mối quan hệ giữa: tham số thực và tham số hình thức ( đ ối) cũng nh ư các đ ối trong thân của hàm Đối với hàm không cho giá trị thì chúng ta không cần khai báo kiểu giá trị của nó. Đối với các hàm có giá trị mà ta quên không khai báo kiểu giá trị của nó, thì máy sẽ coi hàm đ ó có giá trị nguyên. Nh ư vậy đ ối với hàm có gái trị kiểu nguyên thì không cần khai báo kiểu giá trị cho chúng. Khi gặp lệnh return có chứa biểu thức, thì giá trị của biểu thức bao giờ cũng đư ợc chuyển về theo kiểu giá trị của hàm tr ư ớc khi nó đư ợc gán cho hàm. Nguyên tắc hoạt đ ộng của tham số thực, các đ ối và các biến cục bộ Do đ ối và biến cục bộ đ ều có phạm vi hoạt đ ộng trong cùng một hàm nên đ ối và biến cục bộ cần có tên khác nhau. Đối và biến cục bộ đ ều là biến tự đ ộng. Chúng đư ợc cung cấp bộ nhớ khi hàm đư ợc khởi đ ộng và chúng sẽ lập tức biến mất khi máy ra khỏi hàm. Nh ư vậy, không thể mang giá trị của đ ối ra khỏi hàm. Điều này có nghĩa là không thể sử dụng đ ối đ ể làm thay đ ổi giá trị của bất kỳ một đ ại l ư ợng nào ở ngoài hàm. Khi một hàm đư ợc gọi tới, việc đ ầu tiên là gái trị của các tham số thực đư ợc gán cho các đ ối. Nh ư vậy, các đ ối chính là bản sao của các tham số thực. Hàm chỉ làm vcệc trên các đ ối, tức là chỉ làm việc trên các bản sao này. Các đ ối có tể bị biến đ ổi nh ư ng các tham số thực (các bản chính) không hề bị thay đ ổi Con trỏ và đ ịa chỉ Đia chỉ Liên quan đ ến một biến ta đ ã có các khái niệm: Tên biến Kiểu giá trị của biến Giá trị của biến Khi khai báo một biến thì máy sẽ cấp phát cho biến một vùng nhớ có số byte bằng với đ ộ lớn của kiểu đ ó. Ví dụ: Kiểu int là 2 byte Kiểu float là 4 byte Chúng ta cũng có thể hiểu: Địa chỉ của biến là số thứ tự của byte đ ầu tiên trong một dãy các byte liên tiếp nhau mà máy dành cho biến. Cần chú ý rằng: Địa chỉ của biến là mộ số nguyên nh ư ng không đư ợc đ ánh đ ồng nó với các số nguyên thông th ư ờng trong các phép tính Phép toán &x cho ta đ ịa chỉ của biến x Con trỏ Con trỏ là một biến dùng đ ể chứa đ ịa chỉ. Vì có nhiều loại đ ịa chỉ nên cũng có bấy nhiêu kiểu con trỏ t ươ ng ứng. Ví dụ: Con trỏ kiểu int dùng đ ể chứa đ ịa chỉ các biến kiểu int. Cũng nh ư biến thì con trỏ cũng cần phải đ ựoc khai báo tr ư ớc khi sử dụng. Cú pháp khai báo: type *tên_con_trỏ Ví dụ: int x,y,*px,*py Toán tử: & và * là các toán tử một ngôi, nó chỉ tác đ ộng lên biến, phần tử của mảng hoặc chuỗi. &: Toán tử lấy đ ại chỉ của biến *: Toán tử lấy giá trị tại đ ịa chỉ nào đ ó. Các toán tử này có đ ộ ư u tiên h ơ n các toán tử số học và có đ ộ ư u tiên t ươ ng đươ ng với toán tử một ngôi. Các biểu thức con trỏ: Phép gán con trỏ: Con trỏ cũng là một biến nên ta cũng có thể áp dụng phép gán lên nó. Ví dụ: int *p1, *p2,x; Lúc đ ó các phép toán sau là hợp lệ: p1=&x; p2=p1; b. Phép toán số học trên con trỏ: Các phép toán số học đư ợc áp dụng trên biến con trỏ cũng nh ư giá trị của nó là 2 phép toán cộng và trừ. Ví dụ: int *p; Thì ta có thể dùng: p++: đ ể trỏ đ ến phần tử kế tiếp; p--: trỏ đ ến phần tử tr ư ớc đ ó p= p+3: Nhảy đ ến đ ịa chỉ cách p là 3*Sizeof(p) Trong biểu thức ta có thể dùng các dạng sau của một biến con trỏ p: (*p)++,++(*p):T ă ng giá trị tại p lên 1 *(p++): lấy gía trị phần tử kế tiếp trỏ bởi p,... So sánh con trỏ Các phép toán so sánh đ ịa chỉ của các biến con trỏ là: >,<, = = Kiểu giá trị trong khai báo: Mọi thành phần của cùng một khai báo (biến, phần tử mảng, hàm, con trỏ) khi xuất hiện trong biểu thức đ ều có cùng một kiểu giá trị. Ví dụ: int a, b[5], f(), *p; Thì a, b[i], f(x) hoặ *p xuất hiện trong một biểu thức thì chúng luôn luôn cho một gia trị kiểu float. 5. Hàm có đ ối con trỏ: Nếu đ ối là con trỏ thì tham số thực t ươ ng ứng phải là đ ịa chỉ của biến hoặc đ ịa chỉ của phần tử mảng có kiểu t ươ ng ứng. Khi đ ó đ ịa chỉ của biến đư ợc truyền cho đ ối con trỏ t ươ ng ứng. Ví dụ: #include "stdio.h" int swap(x,y) int x,y; { int tem; tem=x; x=y; y=tem; return (x,y); } main() { int x,y,swap(); printf("Nhap x = \n y = "); scanf("%d %d",&x,&y); printf("x = %d y = %d",x,y); swap(x,y); printf("x = %d y = %d",x,y); getch(); return 0; } #include "stdio.h" swap(x,y) int *x,*y; { int tem; tem=*x; *x=*y; *y=tem; } main() { int x,y; clrscr(); printf("Nhap x = "); scanf("%d",&x); printf("\nNhap y = "); scanf("%d",&y); printf("x = %d y = %d",x,y); swap(&x,&y); printf("\nx = %d y = %d",x,y); getch(); return 0; } Sử dụng biến con trỏ: Trong các đ ối của hàm, ta có thể chia thành 2 loại: Gồm các đ ối dùng đ ể chứa các giá trị đ ã biết.(Tham trị) Gồm các đ ối dùng đ ể chứa các kết quả mới nhận đư ợc (Tham biến) Ví dụ: Viết ch ươ ng trình giải phu ơ ng trình bậc hai có sử dụng con trỏ đ ể xây dựng hàm giải ph ươ ng trình #include "stdio.h" #include "math.h" int ptb2(a,b,c,x1,x2) float a,b,c,*x1,*x2; { float delta; if (a==0) return (0); delta=pow(b,2)-4*a*c; if (delta<0) return (-1); *x1=(-b+sqrt(delta))/(2*a); *x2=(-b-sqrt(delta))/(2*a); return (1); } main() { int s; float a,b,c,x1,x2; clrscr(); printf("Nhap cac gia tri cho he so"); scanf("%f%f%f",&a,&b,&c); printf("\na = %6.2f b = %6.2f c = %6.2f",a,b,c); s=ptb2(a,b,c,&x1,&x2); if (s==0) printf("\nKhong phai la phuong trinh bac 2 vi a=0"); else if (s==-1) printf("\nPhuong trinh vo nghiem"); else printf("\n x1 = %6.2f x2 = %6.2f",x1,x2); getch(); return 0; } Con trỏ và mảng Ví dụ: int a[10]; int *p; p =a; Từ ví dụ trên thì lúc này con trỏ p trỏ đ ến đ ầu mảng a, đ iều này có nghĩa p = &a[0] Khi đ ó các biểu thức sau là t ươ ng đươ ng nhau: *p a[0] *(p+i) a[i] p+i &a[i] p=p+1 *pa=a[4] Việc khai báo mảng là đ ịa chỉ của mảng đư ợc cấp rõ ràng và đ ủ kích th ư ớc, đ ịa chỉ này không thay đ ổi. Tên mảng đư ợc xem nh ư một hằng đ ịa chỉ Việc khai báo con trỏ thì vị trí đư ợc cấp là chổ của con trỏ ở, còn vị trí con trỏ trỏ đ ến là tuỳ ý, và nó chỉ trao đ ổi đ ịa chỉ, giá trị khi nó đ ã có đ ịa chỉ. Ví dụ: Viết ch ươ ng trình nhập vào mảng một chiều d ư ới dạng con trỏ. #include main() { int a[5],tam, *pa; int i; pa=a; for (i =0; i<5;++i) {printf("\na[%d] = ",i); scanf("%d",pa+i); } tam=0; for (i=0;i<5;++i) if (*(pa+i)<0) {tam+=1; continue; } for (i=0;i<5;++i) printf("%6d ",*(pa+i)); printf("\nTong so cac so am %d ",tam); getch(); return 0; } Con trỏ và mảng nhiều chiều Việc xử lý mảng nhiều chiều phức tạp h ơ n so với mảng một chiều. Vì không phải mọi quy tắc của mảng một chiều có thể áp dụng đư ợc với mảng nhiều chiều. Bởi những lý do sau: Phép toán lấy đ ịa chỉ không dùng đư ợc đ ối với các phần tử của mảng nhiều chiều. Mảng nhiều chiều thì các phần tử đư ợc bố trí liên tiếp nhau trong bộ nhớ hết hàng này đ ến hàng khác. Nh ư ng không thể sử dung phép toán a+i đ ể nhập số liệu cho phần tử của mảng nhiều chiều. Tuy nhiêu chúng ta có thể dùng con trỏ đ ể truy cập đ ến từng phần tử của mảng nhiều chiều, với số đ ịa chỉ bằng với số phần tử trong mảng nhiều chiều. Ví dụ: Viết ch ươ ng trình nhập vào một ma trân 3 dòng 3 cột và xác đ ịnh phần phần tử lớn nhất trong ma trân chỉ sử dụng con trỏ, không dùng mảng. #include "stdio.h" main() { int i,max; int *pa; clrscr(); for (i=0;i<9;++i) scanf("%d",pa+i); for (i=1;i<10;++i) {printf(" %10d",*(pa+i-1)); if (i % 3 ==0) printf("\n"); } max=*pa; for (i=0;i<9;++i) if (*(pa+i)>max) max=*(pa+i); printf("\n Max = %d ",max); getch(); return 0; }
File đính kèm:
- bai_giang_ngon_ngu_lap_trinh_chuong_6_ham_va_cau_truc_chuong.ppt