Bài 15: Hàm ppsx

20 147 0
Bài 15: Hàm ppsx

Đ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

Nguyen Dinh Phuong Bài 15 Hàm M c tiêu:ụ K t thúc bài h c này, b n có th :ế ọ ạ ể  Tìm hi u v cách s d ng các hàmể ề ử ụ  Tìm hi u v c u trúc c a m t hàmề ề ấ ủ ộ  Khai báo hàm và các nguyên m u hàmẫ  Th o lu n các ki u khác nhau c a bi nả ậ ể ủ ế  Tìm hi u cách g i các hàm:ể ọ • G i b ng giá trọ ằ ị • G i b ng tham chi uọ ằ ế  Tìm hi u v các qui t c v ph m vi c a hàmể ề ắ ề ạ ủ  Tìm hi u các hàm trong các ch ng trình có nhi u t p tinể ươ ề ậ  Tìm hi u v các l p l u trể ề ớ ư ữ  Tìm hi u v con tr hàm.ể ề ỏ Gi i thi uớ ệ M t hàm là m t đo n ch ng trình th c hi n m t tác v đ c đ nh nghĩa c th . Chúng th c ch tộ ộ ạ ươ ự ệ ộ ụ ượ ị ụ ể ự ấ là nh ng đo n ch ng trình nh giúp gi i quy t m t v n đ l n.ữ ạ ươ ỏ ả ế ộ ấ ề ớ 15.1 S d ng các hàmử ụ Nói chung, các hàm đ c s d ng trong C đ th c thi m t chu i các l nh liên ti p. Tuy nhiên, cáchượ ử ụ ể ự ộ ỗ ệ ế s d ng các hàm thì không gi ng v i các vòng l p. Các vòng l p có th l p l i m t chu i các chử ụ ố ớ ặ ặ ể ặ ạ ộ ỗ ỉ th v i các l n l p liên ti p nhau. Nh ng vi c g i m t hàm s sinh ra m t chu i các ch th đ cị ớ ầ ặ ế ư ệ ọ ộ ẽ ộ ỗ ỉ ị ượ th c thi t i v trí b t kỳ trong ch ng trình. Các hàm có th đ c g i nhi u l n khi có yêu c u. Giự ạ ị ấ ươ ể ượ ọ ề ầ ầ ả s m t ph n c a mã l nh trong m t ch ng trình dùng đ tính t l ph n trăm cho m t vài con s .ử ộ ầ ủ ệ ộ ươ ể ỉ ệ ầ ộ ố N u sau đó, trong cùng ch ng trình, vi c tính toán nh v y c n ph i th c hi n trên nh ng con sế ươ ệ ư ậ ầ ả ự ệ ữ ố khác, thay vì ph i vi t l i các ch th gi ng nh trên, m t hàm có th đ c vi t ra đ tính t l ph nả ế ạ ỉ ị ố ư ộ ể ượ ế ể ỉ ệ ầ trăm c a b t kỳ các con s . Sau đó ch ng trình có th nh y đ n hàm đó, đ th c hi n vi c tínhủ ấ ố ươ ể ả ế ể ự ệ ệ toán (trong hàm) và tr v n i nó đã đ c g i. Đi u này s đ c gi i thích rõ ràng h n khi th oở ề ơ ượ ọ ề ẽ ượ ả ơ ả lu n v cách ho t đ ng c a các hàm.ậ ề ạ ộ ủ M t đi m quan tr ng khác là các hàm thì d vi t và d hi u. Các hàm đ n gi n có th đ c vi tộ ể ọ ễ ế ễ ể ơ ả ể ượ ế đ th c hi n các tác v xác đ nh. Vi c g r i ch ng trình cũng d dàng h n khi c u trúc ch ngể ự ệ ụ ị ệ ỡ ố ươ ễ ơ ấ ươ trình d đ c, nh vào s đ n gi n hóa hình th c c a nó. M i hàm có th đ c ki m tra m t cáchễ ọ ờ ự ơ ả ứ ủ ỗ ể ượ ể ộ đ c l p v i các d li u đ u vào, v i d li u h p l cũng nh không h p l . Các ch ng trình ch aộ ậ ớ ữ ệ ầ ớ ữ ệ ợ ệ ư ợ ệ ươ ứ các hàm cũng d b o trì h n, b i vì nh ng s a đ i, n u yêu c u, có th đ c gi i h n trong cácễ ả ơ ở ữ ử ổ ế ầ ể ượ ớ ạ hàm c a ch ng trình. M t hàm không ch đ c g i t các v trí bên trong ch ng trình, mà cácủ ươ ộ ỉ ượ ọ ừ ị ươ hàm còn có th đ t vào m t th vi n và đ c s d ng b i nhi u ch ng trình khác, vì v y ti tể ặ ộ ư ệ ượ ử ụ ở ề ươ ậ ế ki m đ c th i gian vi t ch ng trình.ệ ượ ờ ế ươ 15.2 C u trúc hàmấ Hàm 209 Cú pháp t ng quát c a m t hàm trong C là:ổ ủ ộ type_specifier function_name (arguments) { body of the function return statement } type_specifier xác đ nh ki u d li u c a giá tr s đ c tr v b i hàm. N u không có ki u đ cị ể ữ ệ ủ ị ẽ ượ ả ề ở ế ể ượ đ a ra, hàm cho r ng tr v m t k t qu s nguyên. Các đ i s đ c phân cách b i d u ph y. M tư ằ ả ề ộ ế ả ố ố ố ượ ở ấ ẩ ộ c p d u ngo c r ng () v n ph i xu t hi n sau tên hàm ngay c khi n u hàm không ch a b t kỳ đ iặ ấ ặ ỗ ẫ ả ấ ệ ả ế ứ ấ ố s nào. Các tham s xu t hi n trong c p d u ngo c () đ c g i là ố ố ấ ệ ặ ấ ặ ượ ọ tham s hình ố th cứ ho c ặ đ i số ố hình th cứ . Ph n thân c a hàm có th ch a m t ho c nhi u câu l nh. M t hàm nên tr v m t giáầ ủ ể ứ ộ ặ ề ệ ộ ả ề ộ tr và vì v y ít nh t m t l nh return ph i có trong hàm.ị ậ ấ ộ ệ ả 15.2.1 Các đ i s c a m t hàmố ố ủ ộ Tr c khi th o lu n chi ti t v các đ i s , xem ví d sau,ướ ả ậ ế ề ố ố ụ #include <stdio.h> main() { int i; for(i =1; i <=10; i++) printf(“\nSquare of %d is %d “, i,squarer (i)); } squarer(int x) /* int x; */ { int j; j = x * x; return(j); } Ch ng trình trên tính tính bình ph ng các s t 1 đ n 10. Đi u này đ c th c hi n b ng vi cươ ươ ố ừ ế ề ượ ự ệ ằ ệ g i hàm ọ squarer. D li u đ c truy n t th t c g i (trong tr ng h p trên là hàm main()) đ nữ ệ ượ ề ừ ủ ụ ọ ườ ợ ế hàm đ c g i ượ ọ squarer thông qua các đ i s . Trong th t c g i, các đ i s đ c bi t nh là ố ố ủ ụ ọ ố ố ượ ế ư các đ i s th c ố ố ự và trong đ nh nghĩa c a hàm đ c g i (squarer()) các đ i s đ c g i là các ị ủ ượ ọ ố ố ượ ọ đ i số ố hình th cứ . Ki u d li u c a các đ i s th c ph i cùng ki u v i các đ i s hình th c. H n n a, sể ữ ệ ủ ố ố ự ả ể ớ ố ố ứ ơ ữ ố l ng và th t c a các tham s th c ph i gi ng nh c a các tham s hình th c.ượ ứ ự ủ ố ự ả ố ư ủ ố ứ Khi m t hàm đ c g i, quy n đi u khi n s đ c chuy n đ n cho nó, đó các đ i s hình th cộ ượ ọ ề ề ể ẽ ượ ể ế ở ố ố ứ đ c thay th b i các đ i s th c. Sau đó hàm đ c th c thi và khi b t g p câu l nh return, nó sượ ế ở ố ố ự ượ ự ắ ặ ệ ẽ chuy n quy n đi u khi n cho ch ng trình g i nó.ể ề ề ể ươ ọ Hàm squarer() đ c g i b ng cách truy n s c n đ c tính bình ph ng. Đ i s ượ ọ ằ ề ố ầ ượ ươ ố ố x có th đ cể ượ khai báo theo m t trong các cách sau khi đ nh nghĩa hàm.ộ ị Ph ng pháp 1ươ squarer(int x) /* x đ c đ nh nghĩa cùng v i ki u d li u trong c p d u ngo c ()*/ượ ị ớ ể ữ ệ ặ ấ ặ Ph ng pháp 2ươ 210 L p trình c b n Cậ ơ ả Nguyen Dinh Phuong squarer(x) int x; /* x đ c đ t trong c p d u ngo c (), và ki u c a nó đ c khai báoượ ặ ặ ấ ặ ể ủ ượ ngay sau tên hàm */ Chú ý, trong tr ng h p sau, ườ ợ x ph i đ c đ nh nghĩa ngay sau tên hàm, tr c kh i l nh. Đi u nàyả ượ ị ướ ố ệ ề th t ti n l i khi có nhi u tham s có cùng ki u d li u đ c truy n. Trong tr ng h p nh v y,ậ ệ ợ ề ố ể ữ ệ ượ ề ườ ợ ư ậ ch ph i ch rõ ki u đ m t l n duy nh t t i đi m b t đ u.ỉ ả ỉ ể ề ộ ầ ấ ạ ể ắ ầ Khi các đ i s đ c khai báo trong c p d u ngo c (), m i đ i s ph i đ c đ nh nghĩa riêng l ,ố ố ượ ặ ấ ặ ỗ ố ố ả ượ ị ẻ cho dù chúng có cùng ki u d li u. Ví d , n u x và y là hai đ i s c a m t hàm abc(), thìể ữ ệ ụ ế ố ố ủ ộ abc(char x, char y) là m t khai báo đúng và ộ abc(char x, y) là sai. 15.2.2 S tr v t hàmự ả ề ừ L nh ệ return có hai m c đích:ụ  Ngay l p t c tr đi u khi n t hàm v ch ng trình g iậ ứ ả ề ể ừ ề ươ ọ  B t kỳ cái gì bên trong c p d u ngo c () theo sau ấ ặ ấ ặ return đ c tr v nh là m t giá tr choượ ả ề ư ộ ị ch ng trình g i.ươ ọ Trong hàm squarer(), m t bi n ộ ế j ki u int đ c đ nh nghĩa đ l u giá tr bình ph ng c a đ i sể ượ ị ể ư ị ươ ủ ố ố truy n vào. Giá tr c a bi n này đ c tr v cho hàm g i thông qua l nh ề ị ủ ế ượ ả ề ọ ệ return. M t hàm có thộ ể th c hi n m t tác v xác đ nh và tr quy n đi u khi n v cho th t c g i nó mà không c n tr vự ệ ộ ụ ị ả ề ề ể ề ủ ụ ọ ầ ả ề b t kỳ giá tr nào. Trong tr ng h p nh v y, l nh ấ ị ườ ợ ư ậ ệ return có th đ c vi t d ng ể ượ ế ạ return(0) ho cặ return. Chú ý r ng, n u m t hàm cung c p m t giá tr tr v và nó không làm đi u đó thì nó s trằ ế ộ ấ ộ ị ả ề ề ẽ ả v giá tr không thích h p.ề ị ợ Trong ch ng trình tính bình ph ng c a các s , ch ng trình truy n d li u t i hàm ươ ươ ủ ố ươ ề ữ ệ ớ squarer thông qua các đ i s . Có th có các hàm đ c g i mà không c n b t kỳ đ i s nào. đây, hàmố ố ể ượ ọ ầ ấ ố ố Ở th c hi n m t chu i các l nh và tr v giá tr , n u đ c yêu c uự ệ ộ ỗ ệ ả ề ị ế ượ ầ Chú ý r ng, hàm ằ squarer() cũng có th đ c vi t nh sauể ượ ế ư squarer(int x) { return(x*x); } đây m t bi u th c h p l đ c xem nh m t đ i s trong câu l nh return. Trong th c t , l nhỞ ộ ể ứ ợ ệ ượ ư ộ ố ố ệ ự ế ệ return có th đ c s d ng theo m t trong các cách sau đây:ể ượ ử ụ ộ return; return(h ng);ằ return(bi n);ế return(bi u th c);ể ứ return(câu l nh đánh giá); ệ ví d : ụ return(a>b?a:b); Tuy nhiên, gi i h n c a l nh ớ ạ ủ ệ return là nó ch có th tr v m t giá tr duy nh t.ỉ ể ả ề ộ ị ấ 15.2.3 Ki u c a m t hàmể ủ ộ type-specifier đ c s d ng đ xác đ nh ki u d li u tr v c a m t hàm. Trong ví d trên, ượ ử ụ ể ị ể ữ ệ ả ề ủ ộ ụ type- specifier không đ c vi t bên c nh hàm ượ ế ạ squarer(), vì squarer() tr v m t giá tr ki u ả ề ộ ị ể int. type- Hàm 211 specifier là không b t bu c n u m t giá tr ki u s nguyên đ c tr v ho c n u không có giá trắ ộ ế ộ ị ể ố ượ ả ề ặ ế ị nào đ c tr v . . Tuy nhiên, t t h n nên ch ra ki u d li u tr v là int n u m t giá tr s nguyênượ ả ề ố ơ ỉ ể ữ ệ ả ề ế ộ ị ố đ c tr v và t ng t dùng void n u hàm không tr v giá tr nào. ượ ả ề ươ ự ế ả ề ị 15.3 G i hàmọ Có th g i m t hàm t ch ng trình chính b ng cách s d ng tên c a hàm, theo sau là c p d uể ọ ộ ừ ươ ằ ử ụ ủ ặ ấ ngo c (). C p d u ngo c là c n thi t đ nói v i trình biên d ch là đây là m t l i g i hàm. Khi m tặ ặ ấ ặ ầ ế ể ớ ị ộ ờ ọ ộ tên hàm đ c s d ng trong ch ng trình g i, tên hàm có th là m t ph n c a m t m t l nh ho cượ ử ụ ươ ọ ể ộ ầ ủ ộ ộ ệ ặ chính nó là m t câu l nh. Mà ta đã bi t m t câu l nh luôn k t thúc v i m t d u ch m ph y (ộ ệ ế ộ ệ ế ớ ộ ấ ấ ẩ ;). Tuy nhiên, khi đ nh nghĩa hàm, không đ c dùng d u ch m ph y cu i ph n đ nh nghĩa. S v ng m tị ượ ấ ấ ầ ở ố ầ ị ự ắ ặ c a d u ch m ph y nói v i trình biên d ch đây là ph n đ nh nghĩa c a hàm và không đ c g i hàm.ủ ấ ấ ẩ ớ ị ầ ị ủ ượ ọ M t s đi m c n nh :ộ ố ể ầ ớ  M t d u ch m ph y đ c dùng cu i câu l nh khi m t hàm đ c g i, nh ng nó không đ cộ ấ ấ ẩ ượ ở ố ệ ộ ượ ọ ư ượ dùng sau m t s đ nh nghĩa hàm.ộ ự ị  C p d u ngo c () là b t bu c theo sau tên hàm, cho dù hàm có đ i s hay không.ặ ấ ặ ắ ộ ố ố  Hàm g i đ n m t hàm khác đ c g i là ọ ế ộ ượ ọ hàm g i ọ hay th t c g iủ ụ ọ . Và hàm đ c g i đ n cònượ ọ ế đ c g i là ượ ọ hàm đ c g i ượ ọ hay th t c đ c g iủ ụ ượ ọ .  Các hàm không tr v m t giá tr s nguyên c n ph i xác đ nh ki u c a giá tr đ c tr v .ả ề ộ ị ố ầ ả ị ể ủ ị ượ ả ề  Ch m t giá tr có th đ c tr v b i m t hàm.ỉ ộ ị ể ượ ả ề ở ộ  M t ch ng trình có th có m t ho c nhi u hàm.ộ ươ ể ộ ặ ề 15.4 Khai báo hàm N u mế M t hàm ộ nên đ c ượ g iọ khai báo trong hàm main() tr c khi nó đ c đ nh nghĩa ướ ượ ị ho c sặ ử d ng. ụ Đi u này ề ph i ả đ c ượ th c hi n ự ệ trong tr ng h p hàm đ c g i tr c khi nó đ c ườ ợ ượ ọ ướ ượ đ nhị nghĩa.thi hàm ph i đ c khai báo trong hàmả ượ main() tr c khi nó đ c s d ng.ướ ượ ử ụ Xem ví d ,ụ #include <stdio.h> main() { . . address(); . . } address() { . . . } Hàm main() g i hàm ọ address() và hàm address() đ c g i tr c khi nó đ c đ nh nghĩa. M c dù,ượ ọ ướ ượ ị ặ nó không đ c khai báo trong hàm ượ main() thì đi u này có th th c hi n đ c trong m t s trìnhề ể ự ệ ượ ộ ố biên d ch C, hàm ị address() đ c g i mà không c n khai báo gì thêm c . Đây là s ượ ọ ầ ả ự khai báo không t ng minh ườ c a m t hàm.ủ ộ 212 L p trình c b n Cậ ơ ả Nguyen Dinh Phuong 15.5 Các nguyên m u hàmẫ M t nguyên m u hàm là m t khai báo hàm trong đó xác đ nh rõ ki u d li u c a các đ i s và trộ ẫ ộ ị ể ữ ệ ủ ố ố ị tr v . Thông th ng, các hàm đ c khai báo b ng cách xác đ nh ki u c a giá tr đ c tr v b iả ề ườ ượ ằ ị ể ủ ị ượ ả ề ở hàm, và tên hàm. Tuy nhiên, chu n ANSI C cho phép s l ng và ki u d li u c a các đ i s hàmẩ ố ượ ể ữ ệ ủ ố ố đ c khai báo. M t hàm abc() có hai đ i s ki u int là x và y, và tr v m t giá tr ki u char, cóượ ộ ố ố ể ả ề ộ ị ể th đ c khai báo nh sau:ể ượ ư char abc(); ho c ặ char abc(int x, nt y); Cách đ nh nghĩa sau đ c g i là ị ượ ọ nguyên m u hàmẫ . Khi các nguyên m u đ c s d ng, C có thẫ ượ ử ụ ể tìm và thông báo b t kỳ ki u d li u không h p l khi chuy n đ i gi a các đ i s đ c dùng đấ ể ữ ệ ợ ệ ể ổ ữ ố ố ượ ể g i m t hàm v i s đ nh nghĩa ki u c a các tham s . M t l i s đ c thông báo ngay khi có sọ ộ ớ ự ị ể ủ ố ộ ỗ ẽ ượ ự khác nhau gi a s l ng các đ i s đ c s d ng đ g i hàm và s l ng các tham s khi đ nhữ ố ượ ố ố ượ ử ụ ể ọ ố ượ ố ị nghĩa hàm. Cú pháp t ng quát c a m t nguyên m u hàm:ổ ủ ộ ẫ type function_name(type parm_namel,type parm_name2, type parm_nameN); Khi hàm đ c khai báo không có các thông tin nguyên m u, trình biên d ch cho r ng không có thôngượ ẫ ị ằ tin v các tham s đ c đ a ra. M t hàm không có đ i s có th gây ra l i khi khai báo không cóề ố ượ ư ộ ố ố ể ỗ thông tin nguyên m u. Đ tránh đi u này, khi m t hàm không có tham s , nguyên m u c a nó sẫ ể ề ộ ố ẫ ủ ử d ng ụ void trong c p d u ngo c (). Nh đã nói trên, ặ ấ ặ ư ở void cũng đ c s d ng đ khai báo t ngượ ử ụ ể ườ minh m t hàm không có giá tr tr v .ộ ị ả ề Ví d , n u m t hàm noparam() tr v ki u d li u char và không có các tham s đ c g i, có thụ ế ộ ả ề ể ữ ệ ố ượ ọ ể đ c khai báo nh sauượ ư char noparam(void); Khai báo trên ch ra r ng hàm không có tham s , và b t kỳ l i g i có truy n tham s đ n hàm đó làỉ ằ ố ấ ờ ọ ề ố ế không đúng. Khi m t hàm không nguyên m u đ c g i t t c các ki u ộ ẫ ượ ọ ấ ả ể char đ c đ i thành ki u ượ ổ ể int và t t cấ ả ki u ể float đ c đ i thành ki u ượ ổ ể double. Tuy nhiên, n u m t ế ộ hànghàm là nguyên m u, thì các ki uẫ ể đã đ a ra trong nguyên m u đ c gi nguyên và không có s tăng c p ki u x y ra.ư ẫ ượ ữ ự ấ ể ả 15.6 Các bi nế Nh đã th o lu n, các bi n là nh ng v trí đ c đ t tên trong b nh , đ c s d ng đ ch a giá trư ả ậ ế ữ ị ượ ặ ộ ớ ượ ử ụ ể ứ ị có th ho c không th đ c s a đ i b i m t ch ng trình ho c m t hàm. Có ba lo i bi n c b n:ể ặ ể ượ ử ổ ở ộ ươ ặ ộ ạ ế ơ ả bi n c c b , tham s hình th c,ế ụ ộ ố ứ và bi n toàn c cế ụ . 1.Bi n c c b ế ụ ộ là nh ng bi n đ c khai báo bên trong m t hàm.ữ ế ượ ộ 2.Tham s hình th c ố ứ đ c khai báo trong m t đ nh nghĩa hàm nh là các tham s . ượ ộ ị ư ố 3.Bi n toàn c c ế ụ đ c khai báo bên ngoài các hàm. ượ 15.6.1 Bi n c c b ế ụ ộ Hàm 213 Bi n c c b còn đ c g i là ế ụ ộ ượ ọ bi n đ ngế ộ , t khoá ừ auto đ c s d ng đ khai báo chúng. Chúng chượ ử ụ ể ỉ đ c tham chi u đ n b i các l nh bên trong c a kh i l nh mà bi n đ c khai báo. Đ rõ h n, m tượ ế ế ở ệ ủ ố ệ ế ượ ể ơ ộ bi n c c b đ c t o ra trong lúc vào m t kh i và b hu trong lúc đi ra kh i kh i đó. Kh i l nhế ụ ộ ượ ạ ộ ố ị ỷ ỏ ố ố ệ thông th ng nh t mà trong đó m t bi n c c b đ c khai báo chính là hàm.ườ ấ ộ ế ụ ộ ượ Xem đo n mã l nh sau:ạ ệ void blkl(void) /* void denotes no value returned*/ { char ch; ch = ‘a’; . . } void blk2(void) { char ch; ch = ‘b’; . . } Bi n ế ch đ c khai báo hai l n, trong ượ ầ blk1() và blk2(). ch trong blk1() không có liên quan đ n ế ch trong blk2() b i vì m i ở ỗ ch ch đ c bi t đ n trong kh i l nh mà nó đ c khai báo.ỉ ượ ế ế ố ệ ượ Vì các bi n c c b đ c t o ra và hu đi trong m t kh i mà chúng đ c khai báo, nên n i dungế ụ ộ ượ ạ ỷ ộ ố ượ ộ c a chúng b m t bên ngoài ph m vi c a kh i. Đi u này có nghĩa là chúng không th duy trì giá trủ ị ấ ạ ủ ố ề ể ị c a chúng gi a các l n g i hàm.ủ ữ ầ ọ T khóa ừ auto có th đ c dùng đ khai báo các bi n c c b , nh ng th ng nó không đ c dùng vìể ượ ể ế ụ ộ ư ườ ượ m c nhiên các bi n không toàn c c đ c xem nh là bi n c c b .ặ ế ụ ượ ư ế ụ ộ Các bi n c c b đ c s d ng b i các hàm th ng đ c khai báo ngay sau d u ngo c m ‘{‘ c aế ụ ộ ượ ử ụ ở ườ ượ ấ ặ ở ủ hàm và tr c t t c các câu l nh. Tuy nhiên, các khai báo có th bên trong m t kh i c a m tướ ấ ả ệ ể ở ộ ố ủ ộ hàm. Ví d , ụ void blk1(void) { int t; t = 1; if(t > 5) { char ch; . . } . } Trong ví d trên bi n ụ ế ch đ c t o ra và ch h p l bên trong kh i mã l nh ượ ạ ỉ ợ ệ ố ệ if’. Nó không th đ cể ượ tham chi u đ n trong m t ph n khác c a hàm ế ế ộ ầ ủ blk1(). M t trong nh ng thu n l i c a s khai báo m t bi n theo cách này đó là b nh s ch đ c c pộ ữ ậ ợ ủ ự ộ ế ộ ớ ẽ ỉ ượ ấ phát cho nó khi n u đi u ki n đ đi vào kh i l nh ế ề ệ ể ố ệ if đ c tho . Đi u này là b i vì các bi n c c bượ ả ề ở ế ụ ộ ch đ c khai báo khi đi vào kh i l nh mà các bi n đ c đ nh nghĩa trong đó. ỉ ượ ố ệ ế ượ ị 214 L p trình c b n Cậ ơ ả Nguyen Dinh Phuong Chú ý: Đi u quan tr ng c n nh là t t c các bi n c c b ph i đ c khai báo t i đi m b t đ uề ọ ầ ớ ấ ả ế ụ ộ ả ượ ạ ể ắ ầ c a kh i mà trong đó chúng đ c đ nh nghĩa, và tr c t t c các câu l nh th c thi.ủ ố ượ ị ướ ấ ả ệ ự Ví d sau có th không làm vi c v i m t s các trình biên d ch.ụ ể ệ ớ ộ ố ị void blk1(void) { int len; len = 1; char ch; /* This will cause an error */ ch = ‘a’; . . } 15.6.2 Tham s hình th cố ứ M t hàm s d ng các đ i s ph i khai báo các bi n đ nh n các giá tr c a các đ i s . Các bi nộ ử ụ ố ố ả ế ể ậ ị ủ ố ố ế này đ c g i là ượ ọ tham s hình th c ố ứ c a hàm và ho t đ ng gi ng nh b t kỳ m t bi n c c b bênủ ạ ộ ố ư ấ ộ ế ụ ộ trong hàm. Các bi n này đ c khai báo bên trong c p d u ngo c () theo sau tên hàm. Xem ví d sau:ế ượ ặ ấ ặ ụ blk1(char ch, int i) { if(i > 5) ch = ‘a’; else i = i +1; return; } Hàm blk1() có hai tham s : ố ch và i. Các tham s hình th c ph i đ c khai báo cùng v i ki u c a chúng. Nh trong ví d trên, ố ứ ả ượ ớ ể ủ ư ụ ch có ki u ề char và i có ki u ể int. Các bi n này có th đ c s d ng bên trong hàm nh các bi n c c bế ể ượ ử ụ ư ế ụ ộ bình th ng. Chúng b hu đi khi ra kh i hàm. C n chú ý là các tham s hình th c đã khai báo cóườ ị ỷ ỏ ầ ố ứ cùng ki u d li u v i các đ i s đ c s d ng khi g i hàm. Trong tr ng h p có sai, C có thể ữ ệ ớ ố ố ượ ử ụ ọ ườ ợ ể không hi n th l i nh ng có th đ a ra m t k t qu không mong mu n. Đi u này là vì, C v n đ aể ị ỗ ư ể ư ộ ế ả ố ề ẫ ư ra m t vài k t qu trong các tình hu ng khác th ng. Ng i l p trình ph i đ m b o r ng không cóộ ế ả ố ườ ườ ậ ả ả ả ằ các l i v sai ki u.ỗ ề ể Cũng gi ng nh v i các bi n c c b , các phép gán cũng có th đ c th c hiên v i tham s hìnhố ư ớ ế ụ ộ ể ượ ự ớ ố th c c a hàm và chúng cũng có th đ c s d ng b t kỳ bi u th c nào mà C cho phép.ứ ủ ể ượ ử ụ ấ ể ứ 15.6.3 Bi n toàn c cế ụ Các bi n toàn c c là bi n đ c th y b i toàn b ch ng trình, và có th đ c s d ng b i ế ụ ế ượ ấ ở ộ ươ ể ượ ử ụ ở m t ộ mã l nh b t kỳ. Chúng đ c khai báo bên ngoài các hàm c a ch ng trình và l u giá tr c a chúngệ ấ ượ ủ ươ ư ị ủ trong su t s th c thi c a ch ng trình. Các bi n này có th đ c khai báo bên ngoài ố ự ự ủ ươ ế ể ượ main() ho cặ khai báo b t kỳ n i đâu tr c l n s d ng đ u tiên. Tuy nhiên, t t nh t đ khai báo các bi n toànấ ơ ướ ầ ử ụ ầ ố ấ ể ế c c là t i đ u ch ng trình, nghĩa là tr c hàm ụ ạ ầ ươ ướ main(). int ctr; /* ctr is global */ Hàm 215 void blk1(void); void blk2(void); void main(void) { ctr = 10; blk1 (); . . } void blk1(void) { int rtc; if (ctr > 8) { rtc = rtc + 1; blk2(); } } void blk2(void) { int ctr; ctr = 0; } Trong đo n mã l nh trên, ạ ệ ctr là m t bi n toàn c c và đ c khai báo bên ngoài hàm ộ ế ụ ượ main() và blk1(), nó có th đ c tham chi u đ n trong các hàm. Bi n ể ượ ế ế ế ctr trong blk2(), là m t bi n c c b vàộ ế ụ ộ không có liên quan v i bi n toàn c c ớ ế ụ ctr. N u m t bi n toàn c c và c c b có cùng tên, t t c cácế ộ ế ụ ụ ộ ấ ả tham chi u đ n tên đó bên trong kh i ch a đ nh nghĩa bi n c c b s đ c k t h p v i bi n c cế ế ố ứ ị ế ụ ộ ẽ ượ ế ợ ớ ế ụ b mà không ph i là bi n toàn c c.ộ ả ế ụ Các bi n toàn c c đ c l u tr trong các vùng c đ nh c a b nh . Các bi n toàn c c h u d ngế ụ ượ ư ữ ố ị ủ ộ ớ ế ụ ữ ụ khi nhi u hàm trong ch ng trình s d ng cùng d li u. Tuy nhiên, nên tránh s d ng bi n toànề ươ ử ụ ữ ệ ử ụ ế c c n u không c n thi t, vì chúng gi b nh trong su t th i gian th c hi n ch ng trình. Vì v yụ ế ầ ế ữ ộ ớ ố ờ ự ệ ươ ậ vi c s d ng m t bi n toàn c c n i mà m t bi n c c b có kh năng đáp ng cho hàm s d ngệ ử ụ ộ ế ụ ở ơ ộ ế ụ ộ ả ứ ử ụ là không hi u qu . Ví d sau s giúp làm rõ h n đi u này:ệ ả ụ ẽ ơ ề void addgen(int i, int j) { return(i + j); } int i, j; void addspe(void) { return(i + j); } C hai hàm ả addgen() và addspe() đ u tr v t ng c a các bi n ề ả ề ổ ủ ế i và j. Tuy nhiên, hàm addgen() đ c s d ng đ tr v t ng c a hai s b t kỳ; trong khi hàm ượ ử ụ ể ả ề ổ ủ ố ấ addspe() ch tr v t ng c a cácỉ ả ề ổ ủ bi n toàn c c ế ụ i và j. 15.7 L p l u trớ ư ữ (Storage Class) M i bi n trong C có m t đ c tr ng đ c g i là ỗ ế ộ ặ ư ượ ọ l p l u tr .ớ ư ữ L p l u tr xác đ nh hai khía c nhớ ư ữ ị ạ c a bi n: ủ ế th i gian s ng ờ ố c a bi n và ủ ế ph m vi ạ c a bi n. ủ ế Th i gian s ngờ ố c a m t bi n là th iủ ộ ế ờ gian mà giá tr c a bi n t n t i. ị ủ ế ồ ạ Ph m viạ S th y đ cự ấ ượ c a m t bi n xác đ nh các ph n c a m tủ ộ ế ị ầ ủ ộ 216 L p trình c b n Cậ ơ ả Nguyen Dinh Phuong ch ng trình s có th nh n ra bi n. ươ ẽ ể ậ ế M t bi n có th có t m nhìn trong m t kh i, m t hàm, m tộ ế ể ầ ộ ố ộ ộ t p tin, m t nhóm các t p tin, ho c toàn b ch ng trình.ậ ộ ậ ặ ộ ươ M t bi n có th xu t hi n trong m tộ ế ể ấ ệ ộ kh i, m t hàm, m t t p tin, m t nhóm các t p tin, ho c toàn b ch ng trìnhố ộ ộ ậ ộ ậ ặ ộ ươ Theo cách nhìn c a trình biên d ch C, m t tên bi n xác đ nh m t vài v trí v t lý bên trong máy tính,ủ ị ộ ế ị ộ ị ậ đó m t chu i các bit bi u di n giá tr đ c l u tr c a bi n. Có hai lo i v trí trong máy tính màở ộ ỗ ể ễ ị ượ ư ữ ủ ế ạ ị đó giá tr c a bi n có th đ c l u tr : b nh ho c thanh ghi CPU. L p l u tr c a bi n xácở ị ủ ế ể ượ ư ữ ộ ớ ặ ớ ư ữ ủ ế đ nh v trí bi n đ c l u tr là trong b nh hay trong m t thanh ghi. C có b n l p l u tr . Đó là:ị ị ế ượ ư ữ ộ ớ ộ ố ớ ư ữ  auto  external  static  register Đó là các t khoá. Cú pháp t ng quát cho khai báo bi n nh sau:ừ ổ ế ư storage_specifier type var_name; 15.7.1 Bi n t đ ngế ự ộ Bi n t đ ng th t ra là bi n c c b mà chúng ta đã nói trên. Ph m vi c a m t bi n t đ ng cóế ự ộ ậ ế ụ ộ ở ạ ủ ộ ế ự ộ th nh h n hàm, n u nó đ c khai báo bên trong m t câu l nh ghép: ph m vi c a nó b gi i h nể ỏ ơ ế ượ ộ ệ ạ ủ ị ớ ạ trong câu l nh ghép đó. Chúng có th đ c khai báo b ng t khóa ệ ể ượ ằ ừ auto, nh ng s khai báo này làư ự không c n thi t. B t kỳ m t bi n đ c khai báo bên trong m t hàm ho c m t kh i l nh thì m cầ ế ấ ộ ế ượ ộ ặ ộ ố ệ ặ nhiên là thu c l p auto và h th ng cung c p vùng b nh đ c yêu c u cho bi n đó.ộ ớ ệ ố ấ ộ ớ ượ ầ ế 15.7.2 Bi n ngo iế ạ Trong C, m t ch ng trình l n có th đ c chia thành các module nh h n, các module này có thộ ươ ớ ể ượ ỏ ơ ể đ c biên d ch riêng l và đ c liên k t l i v i nhau. Đi u này đ c th c hi n nh m tăng t c đượ ị ẻ ượ ế ạ ớ ề ượ ự ệ ằ ố ộ quá trình biên d ch các ch ng trình l n. Tuy nhiên, khi các module đ c liên k t, các t p tin ph iị ươ ớ ượ ế ậ ả đ c ch ng trình thông báo cho bi t v các bi n toàn c c đ c yêu c u. M t bi n toàn c c ch cóượ ươ ế ề ế ụ ượ ầ ộ ế ụ ỉ th đ c khai báo m t l n. N u hai bi n toàn c c có cùng tên đ c khai báo trong cùng m t t pể ượ ộ ầ ế ế ụ ượ ộ ậ tin, m t thông đi p l i ‘ộ ệ ỗ duplicate variable name’ (tên bi n trùng) có th đ c hi n th ho c đ nế ể ượ ể ị ặ ơ gi n trình biên d ch C ch n m t bi n khác. M t l i t ng t x y ra n u t t c các bi n toàn c cả ị ọ ộ ế ộ ỗ ươ ự ả ế ấ ả ế ụ đ cượ yêu c u b i ch ng trình ầ ở ươ đ c ượ ch a trong m i t p tin. M c dù trình biên d ch không đ a raứ ỗ ậ ặ ị ư b t kỳ m t thông báo l i nào trong khi biên d ch, nh ng s th t các b n sao c a cùng m t bi nấ ộ ỗ ị ư ự ậ ả ủ ộ ế đang đ c t o ra. T i th i đi m liên k t các t p tin, b liên k t s hi n th m t thông báo l i nhượ ạ ạ ờ ể ế ậ ộ ế ẽ ể ị ộ ỗ ư sau ‘duplicate label’ (nhãn trùng nhau) vì nó không bi t s d ng bi n nào. L p ế ử ụ ế ớ extern đ c dùngượ trong tr ng h p nàyườ ợ . T t c các bi n toàn c c đ c khai báo trong m t t p tin và các bi n gi ngấ ả ế ụ ượ ộ ậ ế ố nhau đ c khai báo ượ nh ư là bi n ngo iế ạ ngoàiở trong t t c các t p tin. Xem đo n mã l nh sau:ấ ả ậ ạ ệ Filel File2 int i,j; extern int i,j; char a; extern char a; main() xyz() { { . i = j * 5 . . . . } } abc() pqr() { { i = 123; j = 50; Hàm 217 . . . . } } File2 có các bi n toàn c c gi ng nh ế ụ ố ư File1, ngo i tr m t đi m là các bi n này có t khóa ạ ừ ộ ể ế ừ extern đ c thêm vào s khai báo c a chúng. T khóa này nói v i trình biên d ch là tên và ki u c a bi nượ ự ủ ừ ớ ị ể ủ ế toàn c c đ c s d ng mà không c n ph i t o l i s l u tr cho chúng. Khi hai module đ c liênụ ượ ử ụ ầ ả ạ ạ ự ư ữ ượ k t, các tham chi u đ n các bi n ngo i đ c gi i quy t. ế ế ế ế ạ ượ ả ế N u m t bi n không đ c khai báo trong m t hàm, trình biên d ch s ki m tra nó có so kh p v iế ộ ế ượ ộ ị ẽ ể ớ ớ b t kỳ bi n toàn c c nào không. N u kh p v i m t bi n toàn c c, thì trình biên d ch s xem nhấ ế ụ ế ớ ớ ộ ế ụ ị ẽ ư m t bi n toàn c c đang đ c tham chi u đ n. ộ ế ụ ượ ế ế 15.7.3 Bi n tĩnhế Các bi n ế tĩnh là các bi n c đ nh bên trong các hàm và các t p tin. Không gi ng nh các bi n toànế ố ị ậ ố ư ế c c, chúng không đ c bi t đ n bên ngoài hàm ho c t p tin c a chúng, nh ng chúng gi đ c giáụ ượ ế ế ặ ậ ủ ư ữ ượ tr c a chúng gi a các l n g i. Đi u này có nghĩa là, n u m t hàm k t thúc và sau đó đ c g i l i,ị ủ ữ ầ ọ ề ế ộ ế ượ ọ ạ các bi n tĩnh đã đ nh nghĩa trong hàm đó v n gi đ c giá tr c a chúng. S khai báo bi n tĩnhế ị ẫ ữ ượ ị ủ ự ế đ c b t đ u v i t khóa ượ ắ ầ ớ ừ static. Có th đ nh nghĩa các bi n tĩnh có cùng tên nh h ng d n v i các bi n ngo i. Các bi n c c bể ị ế ư ướ ẫ ớ ế ạ ế ụ ộ (bi n tĩnh cũng nh bi n đ ng) có đ u tiên cao h n các bi n ngo i và giá tr c a các bi n ngo iế ư ế ộ ộ ư ơ ế ạ ị ủ ế ạ s không nh h ng b i b t kỳ s thay đ i nào các bi n c c b . Các bi n ngo i có cùng tên v iẽ ả ưở ở ấ ự ổ ế ụ ộ ế ạ ớ các bi n n i trong m t hàm không th đ c truy xu t tr c ti p bên trong hàm đó.ế ộ ộ ể ượ ấ ự ế Các giá tr kh i t o có th đ c gán cho các bi n trong s khai báo các bi n tĩnh, nh ng các giá trị ở ạ ể ượ ế ự ế ư ị này ph i là các h ng ho c các bi u th c. Trình biên d ch t đ ng gán m t giá tr m c nhiên 0 đ nả ằ ặ ể ứ ị ự ộ ộ ị ặ ế các bi n tĩnh không đ c kh i t o. S kh i t o th c hi n đ u ch ng trình.ế ượ ở ạ ự ở ạ ự ệ ở ầ ươ Xem hai ch ng trình sau. S khác nhau gi a bi n c c b : t đ ng và tĩnh s đ c làm rõ. ươ ự ữ ế ụ ộ ự ộ ẽ ượ Ví d v bi n t đ ng:ụ ề ế ự ộ #include <stdio.h> main() { incre(); incre(); incre(); } incre() { char var = 65; /* var is automatic variable*/ printf(“\nThe character stored in var is %c”, var++); } kK t qu ế ả th c thi ự c a ch ng trình trên s là: ủ ươ ẽ The character stored in var is A The character stored in var is A The character stored in var is A 218 L p trình c b n Cậ ơ ả [...]... hàm không th ể t ương tác v ới mã l ệnh hay dữ liệu được định nghĩa trong hàm khác bởi vì hai hàm có phạm vi khác nhau  Một hàm không thể được định nghĩa bên trong một hàm khác  Một nguyên mẫu hàm là một sự khai báo hàm xác địnhđể chỉ ra các kiểu dữ liệu của các đối số  Lời gọi một hàm từ bên trong một hàm khác được gọi là sự làm tổ của lời gọi hàm  Một con trỏ hàm có thể được dùng để gọi một hàm. .. Trong chương trình trên, hàm main() gọi hàm palindrome() Hàm palindrome() gọi đến ba hàm khác getstr(), reverse() và cmp() Hàm getstr() để nhận một chuỗi ký tự từ người dùng, hàm reverse() đảo ngược chuỗi và hàm cmp() so sánh chuỗi được nhập vào và chuỗi đã được đảo Vì main() gọi palindrome(), hàm palindrome() lần lượt gọi các hàm getstr(), reverse() và cmp(), các lời gọi hàm này được gọi là được lồng... Dinh Phuong Tóm tắt bài học  Trong C, các hàm được dùng để thực thi một chuỗi các chỉ thị nhiều hơn m ột lần  type_specifier xác định kiểu dữ liệu của giá trị sẽ được trả về bởi hàm  Các đối số tới hàm có thể là các hằng, biến, biểu thức hay các hàm  Các đối số còn được gọi là các đối số thực trong hàm gọi và đối số hình thức trong hàm được gọi  Một hàm phải được khai báo trong hàm main(), trước... định 15.12 Con trỏ đến hàm Một đặc tính mạnh mẽ của C vẫn chưa được đề cập, chính là con trỏ hàm Dù rằng một hàm không phải là một biến, nhưng nó có địa chỉ vật lý trong bộ nhớ n ơi có thể gán cho m ột con tr ỏ Một địa chỉ hàm là điểm bắt đầuđi vào của hàm và con trỏ hàm có thể được sử dụng để gọi hàm Để hiểu các con trỏ hàm làm việc như thế nào, thật sự cần phải hiểu th ật rõ m ột hàm đ ược biên dịch... ịnh nghĩa bên trong một hàm không thể tương tác với mã lệnh hay d ữ li ệu đ ược đ ịnh nghĩa trong hàm khác bởi vì hai hàm có phạm vi khác nhau Trong C, tất cả các hàm có cùng mức phạm vi Nghĩa là, m ột hàm không th ể đ ược đ ịnh nghĩa bên trong một hàm khác Chính vì lý do này mà C không phải là m ột ngôn ngữ cấu trúc khối về mặt kỹ thuật 15.9 Gọi hàm Một cách tổng quát, các hàm giao tiếp với nhau b... được truyền đến một hàm như là các đối số để cho phép hàm được g ọi c ủa ch ương trình truy xuất các biến mà phạm vi của nó không v ượt ra kh ỏi hàm g ọi Khi m ột con tr ỏ đ ược truyền đến một hàm, địa chỉ của dữ liệu được truyền đến hàm nên hàm có th ể tự do truy xu ất n ội dung của địa chỉ đó Các hàm gọi nhận ra bất kỳ thay đổi trong n ội dung của địa chỉ Theo cách này, đối số hàm cho phép dữ liệu... chúng Sau đó các biến con trỏ được truyền đến hàm swap(), hàm này hoán vị các giá trị lưu trong x và y thông qua các con trỏ 15.10 Sự lồng nhau của lời gọi hàm Lời gọi một hàm từ một hàm khác được gọi là sự lồng nhau của lời gọi hàm Một chương trình kiểm tra một chuỗi có phải là chuỗi đọc xuôi - đọc ngược như nhau hay không, là m ột ví d ụ cho các lời gọi hàm lồng nhau Từ đọc xuôi - ngược giống nhau... nào trong C Khi mỗi hàm được biên dịch, mã nguồn được chuyển thành mã đối tượng và một điểm bắt đầuđi vào của hàm được thiết lập Khi một lời gọi được thực hiện đến một hàm, một lời gọi ngôn ngữ máy được thực hiện để chuyển điều khiển đ ến đi ểm bắt đầuđi vào của hàm Vì vậy, nếu một con trỏ chứa địa chỉ của điểm bắt đầuđi vào của hàm, nó có thể được dùng để gọi hàm đó Địa chỉ của một hàm có thể lấy được... b)) printf(“Equal”); else printf(“Not Equal”); } Hàm check() được gọi bằng cách truyền hai con trỏ ký tự và một con trỏ hàm Trong hàm check(), các đối số được khai báo là các con trỏ ký tự và một hàm con trỏ Chú ý cách khai báo một hàm con trỏ được khai báo Cú pháp tương tự được dùng khi khai báo các hàm con trỏ khác b ất lu ận đó là kiểu trả về của hàm Cặp dấu ngoặc () bao quanh *cmp là cần thiết... luật về phạm vi của một hàm Qui luật về phạm vi là những qui luật quyết định một đoạn mã lệnh có th ể truy xu ất đ ến m ột đoạn mã lệnh khác hayhoặc dữ liệu hay không Trong C, mỗi hàm của chương trình là các khối lệnh riêng lẻ Mã lệnh bên trong một hàm là cục bộ với hàm đó và không th ể đ ược truy xu ất b ởi bất kỳ lệnh nào ở ngoài hàm, ngoại trừ lời gọi hàm Mã lệnh bên trong một hàm là ẩn đ ối v ới ph . Phuong Bài 15 Hàm M c tiêu:ụ K t thúc bài h c này, b n có th :ế ọ ạ ể  Tìm hi u v cách s d ng các hàm ề ử ụ  Tìm hi u v c u trúc c a m t hàm ề ấ ủ ộ  Khai báo hàm và các nguyên m u hàm . ộ ố ố  Hàm g i đ n m t hàm khác đ c g i là ọ ế ộ ượ ọ hàm g i ọ hay th t c g iủ ụ ọ . Và hàm đ c g i đ n cònượ ọ ế đ c g i là ượ ọ hàm đ c g i ượ ọ hay th t c đ c g iủ ụ ượ ọ .  Các hàm không. ch ng trình trên, hàm ươ main() g i hàm ọ palindrome(). Hàm palindrome() g i đ n ba hàm ế khác getstr(), reverse() và cmp(). Hàm getstr() đ nh n m t chu i ký t t ng i dùng, hàm ậ ộ ỗ ự ừ ườ

Ngày đăng: 05/08/2014, 15:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan