Hàm

Nguyen Dinh Phuong Bài 15

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 ớ ệ

ộ ươ ng trình th c hi n m t tác v đ ệ ộ ộ ấ c đ nh nghĩa c th . Chúng th c ch t ụ ể ự M t hàm là m t đo n ch 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 ử ụ

ộ ệ ớ ượ ử ụ ố ộ ế ầ ặ ể ự ặ ọ ệ ộ ạ ị ể ặ ạ ộ ề ầ ng trình dùng đ tính t l ệ ầ ộ 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 ữ ự c vi ươ ệ ị ố ả ỉ ệ t ra đ tính t l ể ế ể ự ủ ấ c gi ế ả ẽ ượ ươ ượ ệ ơ ọ Nói chung, các hàm đ 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 ử ụ 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 đ ị ớ ư i v trí b t kỳ trong ch ng trình. Các hàm có th đ th c thi t ươ ấ ự s m t ph n c a mã l nh trong m t ch ử ộ ộ ầ ủ N u sau đó, trong cùng ch ế khác, thay vì ph i vi t l ế ạ trăm c a b t kỳ các con s . Sau đó ch toán (trong hàm) và tr v n i nó đã đ lu n v cách ho t đ ng c a 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 ỗ ế ỉ i m t chu i các ch ặ ỗ c ị ượ ẽ ỉ ỗ ả c g i nhi u l n khi có yêu c u. Gi ầ ể ượ ọ ph n trăm cho m t vài con s . ố ể ỉ ệ ố ả ư ậ ầ ươ ầ ph n i các ch th gi ng nh trên, m t hàm có th đ ộ ỉ ệ ể ượ ư ng trình có th nh y đ n hàm đó, đ th c hi n vi c tính ệ ể ố ả i thích rõ ràng h n khi th o c g i. Đi u này s đ ở ề ơ ả ề ủ ề ậ

ọ ể ễ ể ả ơ ị ệ ỡ ố ễ ả cũng nh không h p l ệ ễ ọ ớ ờ ữ ệ ỗ ư t và d hi u. Các hàm đ n gi n có th đ ươ ứ ủ ợ ệ ử ổ ữ ở ể ượ các v trí bên trong ch ầ ị ươ ng trình khác, vì v y ti ế t c vi ể ượ ươ ng trình cũng d dàng h n khi c u trúc ch ng ấ c ki m tra m t cách ể ộ ứ ng trình ch a . Các ch ươ i h n trong các c gi ớ ạ ng trình, mà các ươ ế t ế c g i t ỉ ượ ọ ừ ượ ử ụ c s d ng b i nhi u ch ở ươ ề ậ ư ệ ng trình. M t đi m quan tr ng khác là các hàm thì d vi ễ ế ộ đ th c hi n các tác v xác đ nh. Vi c g r i ch ơ ụ ể ự 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 l p v i các d li u đ u vào, v i d li u h p l ợ ệ ớ ữ ệ ầ ộ ậ 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 đ hàm c a ch ủ hàm còn có th đ t vào m t th vi n và đ ki m đ ệ ễ ả ng trình. M t hàm không ch đ ể ặ c th i gian vi ờ ơ ộ ộ t ch ươ ượ ế

Hàm

209

15.2 C u trúc hàm ấ

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 }

ị ữ ệ ủ c tr v b i hàm. N u không có ki u đ ế ị ẽ ượ

ấ ằ ặ ỗ ả ề ộ ế ấ ể ẩ ứ ấ ả ố ệ ẫ ả ấ ố ả ề ở ố ố ượ ả c g i là ượ ọ ệ tham s hình ố ộ ề ặ ầ ộ ượ c type_specifier xác đ nh ki u d li u c a giá tr s đ ể c phân cách b i d u ph y. M t đ a ra, hàm cho r ng tr v m t k t qu s nguyên. Các đ i s đ ộ ở ấ ư 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 ố ế ặ th cứ ho c ặ đ i số ố s nào. Các tham s xu t hi n trong c p d u ngo c () đ ặ ệ ố 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 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); }

ng trình trên tính tính bình ph ượ ự ế ệ ằ ươ c truy n t ữ ệ ng các s t ố ừ ề ừ ủ ụ ề ườ ượ squarer. D li u đ c g i 1 đ n 10. Đi u này đ ợ ố ố ượ th t c g i (trong tr ọ ọ ủ ụ t nh là ư ế c g i là các ọ ọ squarer thông qua các đ i s . Trong th t c g i, các đ i s đ ố ố ượ ượ ố ố ệ c th c hi n b ng vi c ế ng h p trên là hàm main()) đ n các c bi đ i số ố ọ ố ữ ứ ố ố ố ố ự và trong đ nh nghĩa c a hàm đ ủ ị ố ố ự ữ ệ ủ ể ớ ơ Ch ươ g i hàm ọ hàm đ ượ c g i (squarer()) các đ i s đ đ i s th c 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 ả c a các tham s th c ph i gi ng nh c a các tham s hình th c. l ượ ể ng và th t ứ ự ủ ố ự ư ủ ứ ả ố ố

ề ọ ể c chuy n đ n cho nó, ở ế c th c thi và khi b t g p câu l nh return, nó s ắ ặ đó các đ i s hình th c ứ ố ố ẽ ự ệ ể ẽ ượ ượ ng trình g i nó. Khi m t hàm đ ề ộ ượ đ ố ố ự ế ở ượ chuy n quy n đi u khi n cho ch ể ề ề c g i, quy n đi u khi n s đ c thay th b i các đ i s th c. Sau đó hàm đ ể ươ ọ

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 Hàm squarer() đ ượ ượ khai báo theo m t trong các cách sau khi đ nh nghĩa hàm. ộ ề ị

Ph ng pháp 1 ươ

ữ ể ệ ặ ấ ặ ớ ị c đ nh nghĩa cùng v i ki u d li u trong c p d u ngo c ()*/ squarer(int x) ượ /* x đ

210

L p trình c b n C

ơ ả

Ph ng pháp 2 ươ

Nguyen Dinh Phuong

ượ ặ ủ ể ấ ặ ượ x đ ặ c đ t trong c p d u ngo c (), và ki u c a nó đ c khai báo squarer(x) int x; /* ngay sau tên hàm */

c đ nh nghĩa ngay sau tên hàm, tr ườ ả ượ ị ướ c truy n. Trong tr ng h p sau, ợ ề ữ ệ ượ ề c kh i l nh. Đi u này ề ố ệ ư ậ ng h p nh v y, ợ ườ Chú ý, trong tr th t ti n l ậ ệ ợ ch ph i ch rõ ki u đ m t l n duy nh t t ỉ ả ỉ x ph i đ i khi có nhi u tham s có cùng ki u d li u đ ố i đi m b t đ u. ắ ầ ề ộ ầ ể ể ấ ạ ể

c đ nh nghĩa riêng l ố ố ượ ỗ ố ố ặ ấ ị c khai báo trong c p d u ngo c (), m i đ i s ph i đ ụ ế ộ ữ ệ ộ ẻ Khi các đ i s đ , ặ 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 ự ả ề ừ

return có hai m c đích: L nh ệ ụ

ậ ứ ả ề ng trình g i ọ  Ngay l p t c tr đi u khi n t  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 hàm v ch ể ừ ấ ặ ề ươ ặ ượ ả ề ư ộ ị ng trình g i. ấ ch ươ ọ

c đ nh nghĩa đ l u giá tr bình ph ể ư ươ ượ ủ ị ề ộ ế ệ ệ ị ủ ụ ề ầ c vi ế j ki u int đ ể ị c tr v cho hàm g i thông qua l nh ọ ả ề ượ ủ ụ ọ ề ể ề ả return có th đ ng h p nh v y, l nh ể ượ ư ậ ợ ị ả ề ấ ố ố ể ả ề return(0) ho cặ ẽ ả t d ng ế ạ ề ị ườ ộ ế ằ ộ ng c a đ i s Trong hàm squarer(), m t bi n truy n vào. Giá tr c a bi n này đ 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 ệ ị ấ 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. ề ợ ị

ươ ươ ủ ươ c g i mà không c n b t kỳ đ i s nào. squarer đây, hàm ng c a các s , ch ượ ể ng trình truy n d li u t ề ấ ữ ệ ớ ố ố i hàm Ở Trong ch ng trình tính bình ph thông qua các đ i s . Có th có các 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 ầ

squarer() cũng có th đ c vi Chú ý r ng, hàm ằ ể ượ ế t nh sau ư

squarer(int x) { return(x*x); }

đ ư ộ ố ố ứ ợ ệ ượ ệ ộ ự ế ệ , l nh đây m t bi u th c h p l ể Ở return có th đ c s d ng theo m t trong các cách sau đây: ể ượ ử ụ c xem nh m t đ i s trong câu l nh return. Trong th c t ộ

ứ ệ 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 ể ủ ộ

Hàm

211

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 đ specifier không đ c vi squarer(), vì squarer() tr v m t giá tr ki u ượ ử ụ ế ượ t bên c nh hàm ạ ộ ả ề ộ type- ị ể int. type-

ị ể ố ả ề ộ ộ ố ơ ặ ế ị ố ỉ dùng void n u hàm không tr v giá tr nào. ng t specifier là không b t bu c n u m t giá tr ki u s nguyên đ ế ắ c tr v . . Tuy nhiên, t nào đ ượ ả ề c tr v và t đ ả ề ượ ị c tr v ho c n u không có giá tr ế ượ 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 ả ề ộ ị ể ữ ệ ả ề ươ ự ế

15.3 G i hàmọ

ch ộ ể ọ ủ ặ ừ ặ ộ ờ ọ ế ể ằ ớ ọ ộ ấ ộ ớ t đ nói v i trình biên d ch là đây là m t l ầ ủ ộ ấ ị ấ ầ 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 ấ Có th g i m t hàm t ươ ử ụ i g i hàm. Khi m t ộ ngo c (). C p d u ngo c là c n thi ầ ị ấ ặ ặ ặ 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 c s d ng trong ch tên hàm đ ộ ệ ộ ượ ử ụ ể ươ ẩ ;). Tuy t m t câu l nh luôn k t thúc v i m t d u ch m ph y ( chính nó là m t câu l nh. Mà ta đã bi ế ệ ộ ệ ế nhiên, khi đ nh nghĩa hàm, không đ cu i ph n đ nh nghĩa. S v ng m t ặ c dùng d u ch m ph y ự ắ ầ ở ố ượ c g i hàm. 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 đ ượ ọ ủ ẩ ủ ấ ấ ầ ị ấ ớ ị ị

M t s đi m c n nh : ớ ộ ố ể ầ

 M t d u ch m ph y đ cu i câu l nh khi m t hàm đ c g i, nh ng nó không đ ộ ấ ượ ở ố ệ ộ ượ ọ ư ượ c c dùng dùng sau m t s đ nh nghĩa hàm. ẩ ấ ộ ự ị ộ ặ ắ ộ ố ố 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 ượ ọ ể ủ ả ị ị ượ c tr v . ả ề ị  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. ặ c g i là  Hàm g i đ n m t hàm khác đ ọ ủ ụ ượ ọ . c g i ượ ọ hay th t c đ  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 đ ị ố ầ  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

c khi nó đ ướ ượ ị ho c sặ ử ượ đ nhị c N u mế M t hàm ộ Đi u này d ng. ề ụ nghĩa.thi hàm ph i đ c ượ g iọ khai báo trong hàm main() tr ệ trong tr c ượ th c hi n ự c khai báo trong hàm ườ main() tr nên đ ph i ả đ ả ượ ng h p hàm đ ợ c khi nó đ ướ c đ nh nghĩa c g i tr c khi nó đ ướ ọ ượ c s d ng. ượ ử ụ

Xem ví d ,ụ

#include main() {

. . address(); . . }

address() {

. . . }

212

L p trình c b n C

ơ ả

c g i tr c khi nó đ ượ ọ ướ ượ ị main() thì đi u này có th th c hi n đ ượ ể ự ượ address() đ c g i mà không c n khai báo gì thêm c . Đây là s ọ c khai báo trong hàm ọ address() và hàm address() đ ề ầ ượ ệ ả c đ nh nghĩa. M c dù, ặ c trong m t s trình ộ ố ự khai báo không Hàm main() g i hàm nó không đ biên d ch C, hàm ị ng minh t ườ c a m t hàm. ộ ủ

Nguyen Dinh Phuong 15.5 Các nguyên m u hàm

ộ ữ ệ ủ ể ị c khai báo b ng cách xác đ nh ki u c a giá tr đ ườ ộ ả ề ị ượ ị ng, các hàm đ ượ ẩ ữ ệ ủ ố ượ ể ủ ể ả ề ộ ố ố ể ị ể ộ c khai báo nh sau: 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 ị ố ố ẫ ả ề ở c tr v b i tr v . Thông th ằ ng và ki u d li u c a các đ i s hàm hàm, và tên hàm. Tuy nhiên, chu n ANSI C cho phép s l ố ố đ 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 đ ể ượ ư

char abc(); ho c ặ char abc(int x, nt y);

ị ượ c g i là ọ ẫ nguyên m u hàm ợ ệ ể ữ ệ ể ộ ể ể ự ng các tham s khi đ nh . Khi các nguyên m u đ ẫ ượ ử ụ khi chuy n đ i gi a các đ i s đ ổ ữ i s đ ố ộ ỗ ẽ ượ c s d ng đ g i hàm và s l ể ọ c s d ng, C có th c dùng đ ố ố ượ c thông báo ngay khi có s ị ủ ố ố ượ ử ụ ấ ớ ự ị ữ ố ượ ố ượ ố Cách đ nh nghĩa sau đ tìm và thông báo b t kỳ ki u d li u không h p l ể g i m t hàm v i s đ nh nghĩa ki u c a các tham s . M t l ọ khác nhau gi a s l ng các đ i s đ 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);

ượ ằ ị ố ượ ư ể ỗ ộ ề ể void trong c p d u ngo c (). Nh đã nói void cũng đ 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 ẫ i khi khai báo không có ố ố ử ẫ ủ ườ ng c s d ng đ khai báo t ể ượ ử ụ ư ấ Khi hàm đ c đ a ra. M t hàm không có đ i s có th gây ra l tin v các tham s đ ề 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 ụ trên, ặ ở ặ minh m t hàm không có giá tr tr v . ị ả ề ộ

c g i, có th ả ề ể ữ ệ ố ượ ọ ể ụ ế ộ c khai báo nh sau 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 đ đ ượ ư

char noparam(void);

i g i có truy n tham s đ n hàm đó là ấ ằ ố ỉ ờ ọ ố ế ề Khai báo trên ch ra r ng hàm không có tham s , và b t kỳ l không đúng.

t c các ki u c g i t ể char đ ượ ượ ổ ể int và t ẫ ượ ế ổ c gi Khi m t hàm không nguyên m u đ ộ ki u ể float đ đã đ a ra trong nguyên m u đ ư ẫ c đ i thành ki u ẫ ượ t cấ ả 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 nguyên và không có s tăng c p ki u x y ra. ự ữ ể ấ ả

15.6 Các bi nế

c đ t tên trong b nh , đ ậ ư ữ ế ể ứ ả ặ ể ị c s d ng đ ch a giá tr ớ ượ ử ụ ế ơ ả ng trình ho c m t hàm. Có ba lo i bi n c b n: ộ ộ ặ ạ Nh đã th o lu n, các bi n là nh ng v trí đ ượ ặ có th ho c không th đ ươ ộ ụ . ứ và bi n toàn c c bi n c c b , tham s hình th c, ế ị c s a đ i b i m t ch ể ượ ử ổ ở ố ế ụ ộ

c khai báo bên trong m t hàm. ế ụ ộ là nh ng bi n đ ộ ượ ế ượ c khai báo trong m t đ nh nghĩa hàm nh là các tham s . ố ộ ị ư c khai báo bên ngoài các hàm. ế

1.Bi n c c b ữ 2.Tham s hình th c ứ đ ố ụ đ 3.Bi n toàn c c ượ

Hàm

213

15.6.1 Bi n c c b ế ụ ộ

c g i là ượ ử ụ ộ , t ừ c tham chi u đ n b i các l nh bên trong c a kh i l nh mà bi n đ bi n đ ng ế ệ ể ế ượ ế khoá ủ ố ộ ỏ ố Bi n c c b còn đ ượ ọ ế ụ ộ đ ượ ở ế bi n c c b đ ế ụ ộ ượ ạ thông th auto đ ố ệ ị c khai báo chính là hàm. ng nh t mà trong đó m t bi n c c b đ ỉ c s d ng đ khai báo chúng. Chúng ch c khai báo. Đ rõ h n, m t ộ ơ ể 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 ố ệ ỷ ấ ế ụ ộ ượ ườ ộ

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 đ ượ trong blk2() b i vì m i c khai báo. c khai báo hai l n, trong ầ c bi ỗ ch ch đ ỉ ượ ở blk1() và blk2(). ch trong blk1() không có liên quan đ n ế ch t đ n trong kh i l nh mà nó đ ượ ế ế ố ệ

c t o ra và hu đi trong m t kh i mà chúng đ ộ ượ ạ ượ ộ ộ ố ỷ ủ ề ể ố c khai báo, nên n i dung Vì các bi n c c b đ ế 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. ủ ụ ị ấ ữ ầ ọ

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ì ể ượ ế ụ ộ ườ ượ T khóa m c nhiên các bi n không toàn c c đ ế ể ụ ượ ừ ặ ư c xem nh là bi n c c b . ế ụ ộ ư

ng đ ế ụ ộ ượ ử ụ c s d ng b i các hàm th ở ườ ượ ặ t c các câu l nh. Tuy nhiên, các khai báo có th c t ệ ủ c khai báo ngay sau d u ngo c m ‘{‘ c a ấ ộ bên trong m t kh i c a m t ộ ở ố ủ ể ở ướ ấ ả Các bi n c c b đ hàm và tr hàm. Ví d , ụ

void blk1(void) {

int t; t = 1; if(t > 5) {

char ch; . .

} . }

bên trong kh i mã l nh if’. Nó không th đ ỉ ợ ệ ệ ố ể ượ c Trong ví d trên bi n ế ch đ ụ tham chi u đ n trong m t ph n khác c a hàm blk1(). c t o ra và ch h p l ượ ạ ủ ầ ế ế ộ

214

L p trình c b n C

ơ ả

ộ ữ ớ ẽ ộ c tho . Đi u này là b i vì các bi n c c b i c a s khai báo m t bi n theo cách này đó là b nh s ch đ ậ ợ ủ ự ệ ề ỉ ượ ấ c c p ế ụ ộ ộ ố ệ ượ ế ề ả ở M t trong nh ng thu n l phát cho nó khi n u đi u ki n đ đi vào kh i l nh ch đ c khai báo khi đi vào kh i l nh mà các bi n đ c đ nh nghĩa trong đó. ế if đ ế ượ ị ể ố ệ ỉ ượ

Nguyen Dinh Phuong

t c các bi n c c b ph i đ ấ ả ả ượ ề ầ ọ ắ ầ i đi m b t đ u ể Chú ý: Đi u quan tr ng c n nh là t ớ c đ nh nghĩa, và tr c a kh i mà trong đó chúng đ ượ ị ủ ế ụ ộ c t ướ ấ ả c khai báo 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 ứ ố

ố ố ị ủ ậ ố ố tham s hình th c ố ử ụ c g i là ọ ế ể ạ ộ ế ụ ộ ư ấ ượ ủ ố ộ ế 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 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 khai báo bên trong c p d u ngo c () theo sau tên hàm. Xem ví d sau: Các bi n này đ ế ượ ụ ặ ấ ặ

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 s d ng bên trong hàm nh các bi n c c b c khai báo cùng v i ki u c a chúng. Nh trong ví d trên, ế ể ượ ử ụ ư ứ ầ ỷ ị ố ườ ợ ữ ệ ị ỗ ớ ư ẫ ố ả ng. Ng ng h p có sai, C có th ề ả ả ườ ậ ả ằ ườ ố Các tham s hình th c ph i đ ki u ề char và i có ki u ể int. Các bi n này có th đ bình th ườ cùng ki u d li u v i các đ i s đ ố ố ượ ử ụ ể không hi n th l ộ ế ể ư ể ra m t vài k t qu trong các tình hu ng khác th các l ch có ế ụ ộ 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 s d ng khi g i hàm. Trong tr ọ ư 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 i l p trình ph i đ m b o r ng không có ả ế i v sai ki u. ộ ỗ ề ể

ố c th c hiên v i tham s hình ớ ự ế ố c s d ng b t kỳ bi u th c nào mà C cho phép. Cũng gi ng nh v i các bi n c c b , các phép gán cũng có th đ ể ượ ộ ụ ư ớ th c c a hàm và chúng cũng có th đ ứ ể ượ ử ụ ứ ủ ể ấ

15.6.3 Bi n toàn c c ụ ế

c th y b i toàn b ch ụ ở ấ ộ ươ ể ượ ử ụ ế ấ ủ ư

ng trình, và có th đ c s d ng b i ở m t ộ mã ng trình và l u giá tr c a chúng c khai báo bên ngoài các hàm c a ch ươ ị ủ main() ho cặ c khai báo bên ngoài ng trình. Các bi n này có th đ ể ượ ế ươ t nh t đ khai báo các bi n toàn c l n s d ng đ u tiên. Tuy nhiên, t ế ố ấ ể ng trình, nghĩa là tr ầ c hàm main(). Các bi n toàn c c là bi n đ ế ượ l nh b t kỳ. Chúng đ ượ ệ trong su t s th c thi c a ch ủ ố ự ự khai báo b t kỳ n i đâu tr c c là t i đ u ch ụ ấ ạ ầ ơ ươ ướ ầ ử ụ ướ

Hàm

215

int ctr; /* ctr is global */

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

ctr là m t bi n toàn c c và đ c khai báo bên ngoài hàm ượ ụ ế ộ ế ụ ộ ấ ả ụ ế ế ộ main() và ế ctr trong blk2(), là m t bi n c c b và t c các ụ ctr. N u m t bi n toàn c c và c c b có cùng tên, t ế ụ c k t h p v i bi n c c ớ ụ ộ ế ụ ộ ẽ ượ ế ứ ị ế ợ ế ế Trong đo n mã l nh trên, ộ ệ ạ ế c tham chi u đ n trong các hàm. Bi n blk1(), nó có th đ ế ể ượ không có liên quan v i bi n toàn c c ớ tham chi u đ n tên đó bên trong kh i ch a đ nh nghĩa bi n c c b s đ ố b mà không ph i là bi n toàn c c. ả ộ ụ ế

ụ ữ ố ị ủ ế ớ ế ề ụ ữ ế b nh trong su t th i gian th c hi n ch ử ụ ữ ộ ử ụ ươ ữ ệ ố ự ệ ầ ờ ụ trong các vùng c đ nh c a b nh . Các bi n toàn c c h u d ng ộ 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 ậ ng trình. Vì v y ử ụ n i mà m t bi n c c b có kh năng đáp ng cho hàm s d ng ả ứ c l u tr Các bi n toàn c c đ ượ ư khi nhi u hàm trong ch ươ t, vì chúng gi c c n u không c n thi ế ụ ế vi c s d ng m t bi n toàn c c ụ ở ơ ế ộ ệ ử ụ 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); }

addgen() và addspe() đ u tr v t ng c a các bi n ủ ề c s d ng đ tr v t ng c a hai s b t kỳ; trong khi hàm ể ả ề ổ ủ ả ề ổ ố ấ ế i và j. Tuy nhiên, hàm addgen() addspe() ch tr v t ng c a các ỉ ả ề ổ ủ C hai hàm ả đ ượ ử ụ bi n toàn c c ế ụ i và j.

15.7 L p l u tr ớ ư ữ (Storage Class)

216

L p trình c b n C

ơ ả

ớ ư ữ ị c g i là ọ ph m vi M i bi n trong C có m t đ c tr ng đ ượ ư ộ ặ ỗ ế ế th i gian s ng c a bi n: c a bi n và ế ủ ờ ủ gian mà giá tr c a bi n t n t ị ủ ố ế ồ ạ Ph m vi i. ạ ữ L p l u tr xác đ nh hai khía c nh l p l u tr . ớ ư ố c a m t bi n là th i c a bi n. ờ ế Th i gian s ng ạ ộ ủ ủ ộ ự ấ ượ c a m t bi n xác đ nh các ph n c a m t c S th y đ ủ ế ầ ủ ờ ộ ạ ế ị

ng trình s có th nh n ra bi n. ể ươ ẽ ể ậ ộ ộ ệ ố ấ ươ ộ

Nguyen Dinh Phuong ch t p tin, m t nhóm các t p tin, ho c toàn b ch ậ ậ 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 có t m nhìn trong m t kh i, m t hàm, m t ầ ng trình. ộ M t bi n có th xu t hi n trong m t ặ ặ ộ ế ộ ươ ế ộ ậ ộ ậ ố ộ ộ

ủ ộ ị ộ ậ ạ ị ể ế ị ữ ủ ặ ỗ ị ủ ớ 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, ế ộ c l u tr c a bi n. Có hai lo i v trí trong máy tính mà đó m t chu i các bit bi u di n giá tr đ ị ượ ư ở đó giá tr c a bi n có th đ c a bi n xác ữ ộ ở ế đ nh v trí bi n đ ớ ị c l u tr : b nh ho c thanh ghi CPU. L p l u tr ế ớ ư 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 ế ự ộ

đ 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 ủ ạ ế ụ ượ ộ c khai báo b ng t ư ằ t. B t kỳ m t bi n đ ố ệ ầ Bi n t ế ự ộ th nh h n hàm, n u nó đ ỏ ơ ế ể trong câu l nh ghép đó. Chúng có th đ ể ượ ệ không c n thi ộ ượ ấ ế nhiên là thu c l p auto và h th ng cung c p vùng b nh đ ệ ố c khai báo bên trong m t câu l nh ghép: ph m vi c a nó b gi ệ khóa ừ ộ ặ c yêu c u cho bi n đó. ớ ượ đ ng có ị ớ ạ i h n ủ auto, nh ng s khai báo này là ự c khai báo bên trong m t hàm ho c m t kh i l nh thì m c ặ ầ ế ộ ớ ộ ế ấ ộ

15.7.2 Bi n ngo i ạ ế

ươ ể ượ c liên k t l ẻ ề ệ ố ị và đ ươ ậ ụ ượ ụ ộ ế ng trình l n có th đ ớ ế ạ ớ ượ ượ ng trình l n. Tuy nhiên, khi các module đ ớ t v các bi n toàn c c đ ế ế ề ươ c khai báo m t l n. N u hai bi n toàn c c có cùng tên đ ụ ế ượ ng trình thông báo cho bi ộ ầ i ‘ ế ng t ể ượ ế ấ ả ế đ ệ ỗ duplicate variable name’ (tên bi n trùng) có th đ x y ra n u t ị ở ứ ư ị ủ ả ế ẽ ể ị ậ ể ế ạ i t ộ ỗ ươ ỗ ậ ư ộ ị ộ t s d ng bi n nào. L p ế ế ử ụ ớ extern đ

ng h p này ợ c khai báo ụ ượ trong t ể c chia thành các module nh h n, các module này có th Trong C, m t ch ỏ ơ ộ ộ c th c hi n nh m tăng t c đ i v i nhau. Đi u này đ đ c biên d ch riêng l ự ằ ị ượ ả c liên k t, các t p tin ph i quá trình biên d ch các ch ế ượ c yêu c u. M t bi n toàn c c ch có đ c ch ỉ ế ầ ượ c khai báo trong cùng m t t p ộ ậ th đ ể ượ c hi n th ho c đ n ơ tin, m t thông đi p l ặ ị ể ộ ụ t c các bi n toàn c c gi n trình biên d ch C ch n m t bi n khác. M t l ự ả ế ọ ộ ả c ượ ch a trong m i t p tin. M c dù trình biên d ch không đ a ra cượ yêu c u b i ch ng trình đ ặ ươ ầ 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 b t kỳ m t thông báo l ế ộ ộ ự ậ ỗ ấ ư 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 đang đ ỗ ờ ượ ạ c dùng sau ‘duplicate label’ (nhãn trùng nhau) vì nó không bi ượ . 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 trong tr ế ế ộ ậ ấ ả t c các t p tin. Xem đo n mã l nh sau: ạ ngoài nh ư là bi n ngo i nhau đ ấ ả ế ườ ượ ệ ậ ạ ở

Filel File2

Hàm

217

int i,j; char a; main() { . . . } abc() { i = 123; extern int i,j; extern char a; xyz() { i = j * 5 . . } pqr() { j = 50;

. . } . . }

ế ụ ư File1, ngo i tr m t đi m là các bi n này có t ừ ể ế ạ ừ ộ ớ ố ủ ự ị 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 c liên khóa ể ủ ượ ụ ượ ử ụ ữ ầ File2 có các bi n toàn c c gi ng nh đ ượ toàn c c đ k t, các tham chi u đ n các bi n ngo i đ ế ừ 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 đ ả ạ ạ ự ư i quy t. c gi ả ế ạ ượ ế ế ế

ộ ẽ ể ượ ớ 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 ớ ư ị ụ ụ ế ế ế ẽ ớ ộ ị ộ ớ c tham chi u đ n. N u m t bi n không đ ế ế 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 đ ộ ượ ụ ế ế ế

15.7.3 Bi n tĩnh ế

ư ậ ố ượ ủ ư ữ ề ế ộ ặ ậ ế đ ữ ượ ị ủ ự ẫ static. khóa 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 ế ế ố ị t đ n bên ngoài hàm ho c t p tin c a chúng, nh ng chúng gi c bi c giá đ c c, chúng không đ ữ ượ ụ ế ế ượ ọ ạ c g i l 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 đó đ 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 ớ ừ

ng d n v i các bi n ngo i. Các bi n c c b ể ị ế ẫ ớ ế ế ụ ế ộ ư ạ ạ ị ủ ạ ộ ở ấ ưở ự ế ộ Có th đ nh nghĩa các bi n tĩnh có cùng tên nh h ư ướ ế (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 ạ ơ ư ế ớ 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 s không nh h ẽ 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 đó. ấ ự ế ể ượ ả ộ ế ộ

ị ế ế ư ị ặ ở ạ ằ ứ ể ị ộ ng trình. Các giá tr kh i t o có th đ ự ể ượ này ph i là các h ng ho c các bi u th c. Trình biên d ch t ặ c kh i t o. S kh i t o th c hi n các bi n tĩnh không đ ự ở ạ ị 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 đ ng gán m t giá tr m c nhiên 0 đ n ế ự ộ đ u ch ệ ở ầ ả ế ở ạ ươ ượ ự

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

incre(); incre(); incre(); }

incre() { /* var is automatic variable*/ char var = 65; printf(“\nThe character stored in var is %c”, var++); }

kK t qu ng trình trên s là: ả th c thi ự ế c a ch ủ ươ ẽ

218

L p trình c b n C

ơ ả

The character stored in var is A The character stored in var is A The character stored in var is A

Nguyen Dinh Phuong Ví d v bi n tĩnh: ụ ề ế

#include main() {

incre(); incre(): incre(): }

incre() {

static char var = 65; /* var is static variable */ printf(“nThe character stored in var is %c”, var++); }

ng trình trên s là: kK t quế ả th c thi ự c a ch ủ ươ ẽ

The character stored in var is A The character stored in var is B The character stored in var is C

ả ng trình g i ng trình th nh t, m i l n ứ ấ c kh i t o l ở ạ ạ ầ ớ ư ữ ặ ượ A). Vì v y khi k t thúc hàm, giá tr m i c a ỗ ầ incre() đ ượ i là 65 (là mã ASCII t ớ c g i, ọ ng ươ ự ng c a ký t ủ ị ấ ứ ự ế ọ incre() ba l n. Trong ch C hai ch ươ ươ bi n ế var v i l p l u tr ữ auto (l p l u tr m c đ nh) đ ị ớ ớ ư ị ớ ủ var (66) b m t đi (ASCII ng v i ký t ậ ứ B).

var đ ủ ớ ư ữ static. ượ Ở var là c a l p l u tr ố ầ ươ ở ạ ị ứ ị ọ ỉ ộ c kh i t o là 65 ch m t var có giá tr 66 (ASCII B) và c tăng ượ ọ ị printf(). Giá tr này b m t khi ch ố ng trình k t thúc. thi hành c a l nh ng trình th hai, Trong ch ươ l n duy nh t khi biên d ch ch ng trình. Cu i l n g i hàm đ u tiên, ấ ầ ọ ế ế var có giá tr 67 (ASCII C). Sau l n g i hàm cu i cùng, l n g i k ti p t ự ở ầ ươ ự th c thi giá tr theo s ự đây ầ ầ ị ấ var đ ế ng t ị ủ ệ ươ ị

15.7.4 Bi n thanh ghi ế

c s d ng đ t m th i l u tr d li u đ ờ ư ộ ố ọ ữ ữ ệ c truy xu t th ự ộ ể ạ ượ ư ơ ữ ệ ả ế ữ ệ ư (h p ng ), ng ữ ợ ạ ả ứ ữ ườ ậ ơ ớ ử ụ ươ ể ườ ủ t đ ị ặ ậ ữ ư ữ ậ ị ị ng xuyên (ví d giá tr đi u khi n c a m t vòng l p), i l p trình. N u m t giá tr đ c bi ể ườ ậ ặ ộ ữ ủ ụ ộ ể ủ ấ ủ ế ộ ộ c đ t vào thanh ghi đó. Ng ủ ớ ế ẽ register đ ế ớ ư ố c l ượ ạ ộ ớ ừ ư ữ ế ộ Các máy tính có các thanh ghi trong b s h c logic - Arithmetic Logic Unit (ALU), các thanh ghi ờ ủ ng xuyên. K t qu t c th i c a này đ ườ ấ ượ ượ ử ụ c l u vào các thanh ghi. Các thao tác th c hi n trên d li u l u tr trong các phép tính toán cũng đ ệ thanh ghi thì nhanh h n d li u trong b nh . Trong ngôn ng assembly i l p trình ữ ng trình ch y nhanh h n. Các ph i truy xu t đ n các thanh ghi này và s d ng chúng đ giúp ch ấ ế ngôn ng l p trình b c cao th ng không truy xu t đ n các thanh ghi c a máy tính. Trong C, vi c ệ ấ ế ệ ượ c l a ch n v trí l u tr cho m t giá tr tùy thu c vào ng ộ ọ ự dùng th l p l u tr c a nó có th khai báo ị ề ườ là register. Sau đó n u trình biên d ch tìm th y m t thanh ghi còn tr ng, và các thanh ghi c a máy ị i, trình biên d ch s xem các tính đ l n đ ch a bi n, bi n s đ ị ế ẽ ượ ặ ể ứ cượ bi n thanh ghi nh các bi n đ ng khác, nghĩa là l u tr chúng trong b nh . T khóa ư dùng khi đ nh nghĩa các bi n thanh ghi. ế ế ị

ạ ự ở ạ c a các bi n thanh ghi là gi ng nh các bi n ạ ừ ị ư ế ố ộ ế đ ngộ , ngo i tr v trí l u ư ị c g i và giá tr i l p trình. Ph m vi ủ tr . Các bi n thanh ghi là c c b trong m t hàm. Nghĩa là, chúng t n t ồ ạ ụ ộ ữ b m t đi m t khi thoát kh i hàm. S kh i t o các bi n này đ ự ỏ ị ấ và s kh i t o ế ộ i khi hàm đ c th c hi n b i ng ở ệ ượ ọ ườ ậ ự ở ạ ượ ế

Hàm

219

ng các thanh ghi là có h n, l p trình viên c n xác đ nh các bi n nào trong ch ng trình ế ậ ầ ạ ị ươ ng xuyên đ khai báo chúng là các bi n thanh ghi. Vì s l ố ượ c s d ng th đ ượ ử ụ ườ ế ể

ế ủ ụ máy này đ n m t máy khác và t ộ ổ ừ ế ừ ộ c h tr b i t t c ế ế ộ ị ấ ượ ố ế ậ ẫ ế ượ c th c thi nhanh h n g p đôi. m t trình biên S h u d ng c a các bi n thanh ghi thay đ i t ự ữ ượ ỗ ợ ở ấ ả – d ch C này đ n m t trình biên d ch khác. Đôi khi các bi n thanh ghi không đ ị auto. Trong các register v n đ khóa t khóa c xem gi ng nh là t c ch p nh n nh ng đ ừ ư ậ ừ ư tr c h tr và n u l p trình viên s d ng chúng m t cách ng h p khác, n u bi n thanh ghi đ ợ ộ ử ụ ườ h p lý, ch ươ ợ ượ ế ng trình s đ ẽ ượ ỗ ợ ấ ơ ự

c khai báo nh bên d i: Các bi n ế thanh ghi đ ượ ư ướ

register int x; register char c;

ự ể ắ ứ ế ố ộ ỉ ườ ợ ng h p S khai báo thanh ghi ch có th g n vào các bi n đ ng và tham s hình th c. Trong tr sau, s khai báo s gi ng nh sau: ẽ ố ư ự

f(c,n) register int c, n; {

register int i; . . . }

ươ ể ậ ươ ộ ố ằ ng các s thành ph n c a m t s b ng ầ ủ ố Xét m t ví d , ị ổ ộ chính s đó. Ví d 370 là m t s nh v y, vì: ố ng trình hi n th t ng l p ph ộ ố ư ậ đó ch ụ ở ụ

33 + 73 + 03 = 27 + 343 + 0 = 370

Ch ươ ng trình sau in ra các con s nh v y trong kho ng 1 đ n 999. ố ư ậ ế ả

#include main() {

register int i; int no, digit, sum; printf(“\nThe numbers whose Sum of Cubes of Digits is Equal to the number itself are:\n\n”);

for(i = 1; i < 999; i++) {

sum = 0; no = i; while(no) {

digit = no%10; no = no/10; sum = sum + digit * digit * digit; }

if (sum == i) printf(“t%d\n”, i); } }

220

L p trình c b n C

ơ ả

K t qu ng trình trên nh sau: ả th c thi ự ế c a ch ủ ươ ư

Nguyen Dinh Phuong

The numbers whose Sum of Cubes of Digits is Equal to the number itself are:

1 153 370 371 407

ổ ừ ươ ậ ớ ị ế ượ ầ Trong ch ng trình trên, giá tr c a ươ t ng con s riêng l ố ừ nahunhau, i đ nó đ ượ 1 đ n 999. V i m i giá tr này, l p ph ị ủ i , thay đ i t ỗ ế c so sánh v i c c ng và k t qu t ng đ ị ượ ả ổ ế c s d ng đ đi u khi n s l p, (ph n chính c a ch ể ề ể ự ặ ượ ử ụ c khai báo là c a l p l u tr thanh ghi. S khai báo này làm tăng hi u qu c a ch ự ủ ng c a ằ ớ i. N u hai giá tr này là b ng ng trình), ủ ng trình. ả ủ đ ộ ẻ ượ c hi n th . Vì i đ ị ể ủ ớ ư ươ ươ ữ ệ

15.8 Các qui lu t v ph m vi c a m t hàm ậ ề ủ ộ ạ

ộ ạ ậ ữ ế ị ệ ạ ạ ể ươ ủ ỗ . Mã l nh bên trong m t hàm là c c b v i hàm đó và không th đ ẻ ữ ệ ộ ụ ộ ớ ệ ộ ngoài hàm, ngo i tr l ng trình, và tr ở ươ ụ ừ ế ữ ệ ặ ể ượ ầ ệ ng tác v i mã l nh hay d li u đ ượ ệ ủ ể ươ ị 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 ộ ấ ế ố ng trình là các kh i hayho cặ d li u hay không. Trong C, m i hàm c a ch đo n mã l nh khác ệ c truy xu t b i l nh riêng l ấ ở ể ượ ệ ệ i g i hàm. Mã l nh bên trong m t hàm là n đ i v i ph n b t kỳ l nh nào ầ ố ớ ạ ừ ờ ọ ẩ ệ ấ ộ khi nó s d ng bi n ho c d li u toàn c c, nó có th tác đ ng i c a ch còn l ể ử ụ ữ ệ ạ ủ ng trình. Đ rõ h n, mã l nh và d li u đ c đ nh ho c b tác đ ng b i các ph n khác c a ch ị ơ ươ ộ ị ặ ở nghĩa bên trong m t hàm không th t c đ nh nghĩa trong hàm ữ ệ ớ ộ khác b i vì hai hàm có ph m vi khác nhau. ạ ở

t c các hàm có cùng m c ph m vi. Nghĩa là, m t hàm không th đ ấ ả ể ượ ứ ạ ộ ữ ấ ả ộ Trong C, t 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ọ

ộ ế ề ằ ớ ố ổ ố ượ c M t cách t ng quát, các hàm giao ti p v i nhau b ng cách truy n tham s . Các tham s đ truy n theo m t trong hai cách sau: ề ộ

 Truy n b ng giá tr ằ ị  Truy n b ng tham chi u. ằ ề ề ế

15.9.1 Truy n b ng giá tr ề ằ ị

ặ ượ ằ ị c g i, các giá tr đ ề ế ạ ổ ế ạ ượ ọ M c nhiên trong C, t ấ ả c truy n đ n hàm đ các đ i s đ ế ề ố ố ượ thao tác ch đ ệ ự chúng. Xem ví d sau, c truy n b ng giá tr . Đi u này có nghĩa là, khi t c các đ i s c a hàm đ ề ề ố ố ủ ọ ự c truy n thông qua các bi n t m. M i s ị ượ ượ ọ c th c hi n trên các bi n t m này. Hàm đ ị ủ c g i không th thay đ i giá tr c a ể ỉ ượ ụ

#include main() {

Hàm

221

int a, b, c; a = b = c = 0; printf(“\nEnter 1st integer: “); scanf(“%d”, &a); printf(“\nEnter 2nd integer: “); scanf(“%d”, &b); c = adder(a, b); printf(“\n\na & b in main() are: %d, % d”, a, b); printf(“\n\nc in main() is: %d”, c);

/* c gives the addition of a and b */ }

adder(int a, int b) {

int c; c = a + b; a *= a; b += 5; printf(“\n\na & b within adder function are: %d, %d “, a, b); printf(“\nc within adder function is : %d”,c); return(c); }

Ví d v k t qu th c thi khi nh p vào 2 và 4: ụ ề ế ả ự ậ

a & b in main() are: 2, 4 c in main() is: 6 a & b within adder function are: 4, 9 c within adder function is : 6

c truy n đ n hàm ố ế ề ư ạ ố ng trình trên nh n hai s nguyên, hai s này đ ố ố ộ ượ ố ố ủ ứ ả ề ổ ộ ả ế ự ư ố c s d ng trong hàm ượ ư ị ề c thay đ i t c l u tr trong các v trí b nh khác nhau. Đi u này đ ộ ổ ừ ượ ớ adder() đ ng đ n các giá tr c a a và b trong hàm ị ủ ưở ế adder(). Hàm adder() th cự ng i, tính bình ph ươ ố ố ủ main() và adder() có cùng tên. Tuy nhiên, không có gì là ừ c th y rõ t ấ ượ 2 và 4 thành 4 main(). Các ế c trong ữ ng trình trên. Các bi n a và b trong hàm ế ươ ự ả nh ng v trí b nh khác nhau. Bi n ớ ế c trong main() thì khác v i bi n c l u ượ ư ở ổ ị ộ ớ Ch ươ ậ hi n nh sau: nó nh n hai s nguyên nh là các đ i s c a nó, c ng chúng l ệ ậ cho s nguyên th nh t, và c ng 5 vào s nguyên th hai, in k t qu và tr v t ng c a các đ i s ứ ấ th c. Các bi n đ ượ ử ụ ế chung gi a chúng. Chúng đ ữ k t qu c a ch ả ủ ế và 9. Tuy nhiên, s thay đ i này không nh h bi n đ ữ ế adder().

ề ượ ề ế c g i là ọ ị khi giá tr c a các bi n đ ị ủ ổ eên giá tr này cũng không nh h truy n b ng giá tr ằ ị c truy n đ n hàm ng đ n giá tr g c c a bi n đã ị ố ủ ế ế ưở ế ả Vì v y, các đ i s đ ố ố ượ ậ c g i và b t kỳ s thay đ i tr đ ự ấ ượ ọ truy n.ề

15.9.2 Truy n b ng tham chi u ằ ề ế

ị ủ ố ố ủ ị ổ ế , hàm đ ế đ ề ợ ị đó giá tr c a các đ i s ph i đ ả ượ ợ ở c dùng. ằ ậ ằ ng h p, ư ậ truy n b ng tham chi u ằ ớ ự ủ ọ là không b thay c thay đ i. Trong nh ng ữ cượ ố ố ố ố Truy n b ng tham chi u ị ủ ấ ế ể ổ c truy n b ng giá tr , các giá tr c a đ i s c a hàm đang g i Khi các đ i s đ ề ố ố ượ đ i. Tuy nhiên, có th có tr ị ủ ổ ườ ể tr ng h p nh v y, ượ ề ườ phép truy xu t đ n vùng b nh th c c a các đ i s và vì v y có th thay đ i giá tr c a các đ i s ố ố ộ ọ c a hàm g i. ủ

ụ ả ề ị ng trình d ị ủ i đây đ c vi t đ gi ế ể ả ộ ộ ượ ướ ụ ế ố ố ư ươ c. th c hi n đ ị ủ Ví d , xét m t hàm, hàm này nh n hai đ i s , hoán v giá tr c a chúng và tr v các giá tr c a i quy t m c đích chúng. N u m t ch ế ươ này, thì s không bao gi ẽ ậ ng trình gi ng nh ch ố ệ ượ ờ ự

#include main() {

222

L p trình c b n C

ơ ả

int x, y; x = 15; y = 20; printf(“x = %d, y = %d\n”, x, y); swap(x, y); printf(“\nAfter interchanging x = %d, y = %d\n”, x, y);

Nguyen Dinh Phuong

}

swap(int u, int v) {

int temp; temp = u; u = v; v = temp; return; }

K t qu ng trình trên nh sau: ả th c thi ự ế c a ch ủ ươ ư

x = 15, y = 20 After interchanging x = 15, y = 20

ị ở ề ượ ư ị ề ế u và v đ ề ượ ng h p này đ đ t đ ể ạ ượ ớ ườ ế ề ợ c truy n tr v hàm c dùng trong ả c k t qu ế ự c dùng khi th c ố ố ự ỏ ượ ẽ ổ Hàm swap() hoán v các giá tr c a u và v, nh ng các giá tr này không đ ị ủ main(). Đi u này là b i vì các bi n ế u và v trong swap() là khác v i các bi n ở c s d ng trong tr main(). Truy n b ng tham chi u có th đ ể ượ ử ụ ằ mong mu n, b i vì nó s thay đ i các giá tr c a các đ i s th c. Các con tr đ ị ủ ở hi n truy n b ng tham chi u. ằ ố ề ệ ế

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 ọ ủ ố ố ể ượ t ra kh i hàm g i. Khi m t con tr đ ộ ạ ủ ọ ỏ c truy n đ n hàm nên hàm có th t ộ ề ỉ ủ ữ ệ ượ ế ể ự ề ị ế ủ ị ậ ộ ổ ủ ị ề ề ọ ữ ệ ọ ề ặ ả ằ ng ươ Các con tr đ ề ế ỏ ượ c ỏ ượ trình truy xu t các bi n mà ph m vi c a nó không v ộ ế ấ ấ ộ do truy xu t n i truy n đ n m t hàm, đ a ch c a d li u đ 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, ỉ ỉ ữ c thay đ i trong hàm g i, cho phép truy n d li u hai chi u gi a đ i s hàm cho phép d li u đ ố ố ữ ệ hàm g i và hàm đ ố ố c a ủ hàm là các con tr ho c m ng, truy n b ng tham ỏ ọ chi u đ ế ượ ạ ượ ấ ọ ổ ượ c g i. Khi các đ i s ề ớ c t o ra đ i ngh ch v i cách truy n b ng giá tr . ị ượ ố ằ ị

c, gi ng nh s ố ố ướ ả ỏ ố ộ ộ ấ ố ố ự ứ ủ ỏ ể ỏ ư ự ờ ọ i g i c khai báo là m t bi n con tr ho c m t bi n đ c tham chi u đ n (&var). Các đ i s hình th c c a m t hàm là các con tr thì ph i có m t d u * phía tr khai báo bi n con tr , đ xác đ nh chúng là các con tr . Các đ i s th c ki u con tr trong l ế hàm có th đ ể ượ ế ượ ỏ ộ ể ế ị ộ ế ế ặ ỏ

Ví d , đ nh nghĩa hàm ụ ị

getstr(char *ptr_str, int *ptr_int)

c g i b ng câu l nh, ố ố ptr_str tr đ n ki u đ i s ỏ ế ể char và ptr_int tr đ n ki u ỏ ế ể int. Hàm có th đ ể ượ ọ ằ ệ

getstr(pstr, &var)

đó pstr đ c khai báo là m t con tr và đ a ch c a bi n c truy n. Gán giá tr thông qua, ở ượ ỉ ủ ế var đ ỏ ộ ị ượ ề ị

*ptr_int = var;

có th gán các giá tr đ n bi n ờ ị ế ế var trong hàm g i, cho phép truy n ọ ề theo hai chi uề đ nế ể Hàm bây gi hàm. và t ừ

char *pstr;

swap(). Bài toán này s gi i quy t đ c khi con tr đ ủ ẽ ả ế ượ ỏ ượ c truy n thay ề ng t nh sau: Quan sát ví d sau c a hàm ụ vì dùng bi n. Mã l nh t ế ươ ệ ự ư

Hàm

223

#include

void main() { int x, y, *px, *py;

/* Storing address of x in px */ px = &x;

/* Storing address of y in py */ py = &y;

x = 15; y = 20; printf(“x = %d, y = %d \n”, x, y); swap (px, py);

/* Passing addresses of x and y */ printf(“\n After interchanging x = %d, y = %d\n”, x, y); }

Accept the values of px and py into u and v */ swap(int *u, int *v) /* {

int temp; temp = *u; *u = *v; *v = temp; return; }

K t qu ng trình trên nh sau: ả th c thi ự ế c a ch ủ ươ ư

x = 15, y = 20 After interchanging x = 20, y = 15

ế ỏ px và py đ ế x và y đ ỉ ủ ế c truy n đ n hàm c gán đ n chúng. Sau swap(), hàm này hoán v các giá tr l u trong x và y thông ỏ ượ ề ượ ế c khai báo, và đ a ch c a bi n ị ị ượ ị ư Hai bi n ki u con tr ể đó các bi n con tr đ ế qua các con tr .ỏ

15.10 S l ng nhau c a l i g i hàm ự ồ ủ ờ ọ

i g i hàm c g i là ọ ờ ọ ươ ộ ộ ượ ỗ ọ ả ượ i g i hàm l ng nhau. T đ c xuôi - ng c a ủ l ư c gi ng nhau là m t chu i các ký t ng trình c nh nhau hay không, là m t ví d cho ụ đ i x ng. Xem ờ ọ ừ ọ ượ s l ng nhau ự ồ ọ ố . M t ch ộ ộ ự ố ứ ộ ỗ L i g i m t hàm t m t hàm khác đ ừ ộ ờ ọ ki m tra m t chu i có ph i là chu i đ c xuôi - đ c ng ỗ ể các l ồ đo n mã l nh theo sau đây: ạ ệ

main() {

. . palindrome(); . .

224

L p trình c b n C

ơ ả

} palindrome() { .

Nguyen Dinh Phuong

. getstr(); reverse(); cmp(); . . }

ng trình trên, hàm ươ main() g i hàm ọ ể ộ ỗ Trong ch khác getstr(), reverse() và cmp(). Hàm getstr() đ nh n m t chu i ký t reverse() đ o ng palindrome(). Hàm palindrome() g i đ n ba hàm i dùng, hàm c đ o. ng c nh p vào và chu i đã đ c chu i và hàm ậ cmp() so sánh chu i đ ỗ ượ ọ ế ườ ượ ả t ự ừ ỗ ượ ậ ả ỗ

t g i các hàm getstr(), reverse() và cmp(), ầ ượ ọ Vì main() g i ọ palindrome(), hàm palindrome() l n l c l ng bên trong các l i g i hàm này đ c g i là đ palindrome(). ượ ọ ượ ồ ờ ọ

c phép, trong khi đ nh nghĩa m t hàm bên trong ủ ượ ộ ị S l ng nhau c a các l m t hàm khác là không đ ự ồ ộ i g i hàm nh trên là đ ư ờ ọ c ch p nh n trong C. ậ ượ ấ

15.11 Hàm trong ch ng trình nhi u t p tin ươ ề ậ

ng trình nh v y đ ở ươ ể ượ ạ ề ậ ư ậ ữ đó m i hàm có th chi m m t t p tin. Cũng nh các bi n trong các ch ỗ ng trình có th đ ớ ở ượ ạ ươ ươ ư ế ế ể c t o b i nhi u t p tin. Nh ng ch ộ ậ ị ạ c s d ng trong t ể ượ ấ ả ươ ế ậ t kh i t p tin ch ng trình. Ph n Các ch các hàm l n, nhi u t p tin, các hàm cũng có th đ ề ậ external có th đ ể ượ ử ụ đ nh cho các t p tin. Các hàm static ch đ ậ ị c a nó không v ủ c đ nh nghĩa là t c các t p tin c a ch ủ ậ t bên trong t p tin ch c nh n bi ậ ỉ ượ ầ tiêu đ (ề header) c a hàm nh sau, ở c t o b i ng trình static ho c ặ external. Ph m vi c a hàm ủ ữ ặ ng trình, và đó là cách l u tr m c ư ng trình và ph m vi ạ ươ ư ỏ ậ ượ ươ ủ

static fn _type fn_name (argument list) ho cặ extern fn_type fn_name (argument list)

T khóa extern là m t tuỳ ch n (không b t bu c) vì nó là l p l u tr m c đ nh. ừ ữ ặ ị ớ ư ắ ộ ọ ộ

15.12 Con tr đ n hàm ỏ ế

c đ c p, chính là ộ ặ con tr hàmỏ ẽ ủ ề ậ ằ ẫ ộ ượ ỉ ậ ớ ơ ạ ộ ư ể ả c s d ng đ g i hàm. M t đ c tính m nh m c a C v n ch a đ không ph i là m t bi n M t đ a ch hàm là đi m ỉ . Dù r ng m t hàm ế , nh ng nó có đ a ch v t lý trong b nh n i có th gán cho m t con tr . ỏ ộ ộ ể b t đ u ể ọ ắ ầ đi vào c a hàm và con tr hàm có th đ ể ượ ử ụ ư ị ủ ộ ị ỏ

ỏ ư ế ậ ọ ậ ự ầ ượ ả ị ể b t đ u ượ ể c biên d ch, mã ngu n đ ồ t l p. Khi m t l ế ậ c th c hi n đ chuy n đi u khi n đ n đi m ề ể ể ể b t đ u ắ ầ đi vào c a hàm đ ượ ự ỏ ứ ị c thi ệ ỉ ủ ữ ộ ủ ế ể ượ ể ấ ỉ ủ ằ ộ c biên ượ ộ c chuy n thành ể ượ c th c hi n ệ i g i đ ự ộ ờ ọ ượ ể b tắ ế ể ắ ầ đi vào c a hàm, nó có ủ c b ng cách s d ng tên hàm ử ụ ỏ ệ c dùng đ g i hàm đó. Đ a ch c a m t hàm có th l y đ ẽ ố ố ng trình sau s minh h a khái ni m c a con tr ọ ể ọ ặ ươ ủ ấ ấ Đ 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 g i nh th nào trong C. Khi m i hàm đ d ch và đ ư ế ượ ỗ ị ng và m t đi m mã đ i t ủ ộ ố ượ i g i ngôn ng máy đ đ n m t hàm, m t l ộ ờ ọ ộ ế đ 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 ậ th đ ượ ị không có d u ngo c () hay b t kỳ đ i s nào. Ch hàm.

#include #include

void check(char *a, char *b, int (*cmp)());

Hàm

225

main()

{

char s1[80], s2[80]; int (*p)(); p = strcmp; gets(s1); gets(s2); check(s1, s2, p); }

void check(char *a, char *b, int (*cmp)()) { printf(“Testing for equality \n”); if(!(*cmp)(a, b)) printf(“Equal”); else printf(“Not Equal”); }

226

L p trình c b n C

ơ ả

và m t con tr hàm. Trong hàm ọ ằ ự ỏ và m t hàm con tr . Chú ý cách ỏ ộ ộ ỏ . Cú pháp t ng t ấ *cmp là c n thi ng c g i b ng cách truy n hai con tr ký t ề ượ c khai báo là các con tr ký t ỏ đ ự ượ ặ check(), khai báo m t hàm con ự ộ c dùng khi khai báo các hàm con tr khác b t lu n đó là ậ ỏ trình biên d chị ế ể ch t đ ươ ươ ấ ầ ặ Hàm check() đ các đ i s đ ố ố ượ trỏ đ ượ ki u tr v c a hàm. C p d u ngo c () bao quanh ể hi u câu l nh này m t cách rõ ràng. ể c khai báo ả ề ủ ệ ộ

Nguyen Dinh Phuong Tóm t

t bài h c ọ ắ

 type_specifier xác đ nh ki u d li u c a giá tr s đ

 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. ượ ể ự ộ ầ ề ộ ỗ ơ ỉ ị

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.

 M t hàm ph i đ

các đ i s th c đ i s hình th c ố ố ượ c g i là ọ ố ố ự trong hàm g i và ọ ố ố ứ trong hàm đ ượ ọ

 Trong C, m c đ nh, t

c khai báo trong hàm main(), tr c khi nó đ c đ nh nghĩa hay s d ng. ả ượ ộ ướ ượ ị ử ụ

t c các đ i s ặ ị ấ ả ố ố c a ủ hàm đ ượ c truy n b ng giá tr . ị ằ ề

 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. ế ụ ộ ế ơ ả ứ ụ ế ạ ố

 L p l u tr đ nh nghĩa hai đ c tính c a bi n;

c khai báo bên trong m t hàm. c khai báo trong đ nh nghĩa c a tham s hàm. ứ ượ ố ủ • Bi n c c b đ ế ụ ộ ượ • Tham s hình th c đ ố • Bi n toàn c c đ c khai báo bên ngoài t ụ ượ ế ộ ị t c các hàm. ấ ả

ớ ư ữ ị ế th i gian s ng ố c a bi n và ờ ủ ủ ế ặ t m nhìn ầ hay ph mạ vi.

 T t c các bi n toàn c c đ

 Các bi n t ế ự ộ đ ng gi ng nh các bi n c c b . ế ụ ộ ư ố

 Các bi n ế static là các bi n c đ nh bên trong các hàm ho c t p tin c a chúng.

c khai báo trong m t t p tin và gi ng v i các bi n đ c khai báo ấ ả ộ ậ ế ố ớ ượ extern trong t ụ ượ t c các t p tin. ế ấ ả ậ

ế ố ị ặ ậ ủ

 N u m t giá tr đ c bi

 Không gi ng các bi n toàn c c, các bi n tĩnh không đ t bên ngoài hàm ho c t p tin ế ế ố ượ ặ ậ c các giá tr c a chúng gi a các l n g i. ụ c a nó, nh ng chúng duy trì đ ượ ủ ư ị ủ ọ c nh n bi ế ậ ầ ữ

 Cũng gi ng nh các bi n trong các ch

c s d ng th t đ ng xuyên, có th dùng l p l u tr ị ặ ế ộ ệ ượ ử ụ ườ ớ ư ữ register cho nó. ể

ng trình có nhi u t p tin, các hàm cũng có th đ ố ươ ề ậ ể ượ c ư ế static hay external. đ nh nghĩa là ị

c đ nh nghĩa bên trong m t hàm không th t ng tác v i mã l nh hay ữ ệ ượ ể ươ ộ ị ệ ớ c đ nh nghĩa trong hàm khác b i vì hai hàm có ph m vi khác nhau.  Mã l nh và d li u đ ệ d li u đ ữ ệ ượ ị ạ ở

 M t nguyên m u hàm là m t s khai báo hàm

 M t hàm không th đ c đ nh nghĩa bên trong m t hàm khác. ể ượ ị ộ ộ

 L i g i m t hàm t

ộ ự ẫ xác đ nhị đ ch ra ể ỉ ố các ki u d li u c a các đ i ữ ệ ủ ể ộ s .ố

c g i là s i g i hàm. ờ ọ ộ ừ bên trong m t hàm khác đ ộ ượ ọ ự làm tổ c a l ủ ờ ọ

Hàm

227

 M t con tr hàm có th đ ỏ ể ượ ộ c dùng đ g i m t hàm. ể ọ ộ

1. M t_________ là m t đo n ch

Ki m tra ti n đ h c t p ế ộ ọ ậ ể

ng trình ch a chính nó và th c hi n m t tác v ạ ộ ươ ụ xác đ nhị ứ ự ệ ộ cụ ộ thể.

2. Các đ i s xu t hi n trong c p d u ngo c () còn đ c g i là _____________. ố ố ệ ấ ặ ấ ặ ượ ọ

3. N u không có l nh return, đi u khi n chuy n đ n ch ng trình g i khi g p d u ngo c đóng } ệ ế ặ ấ ặ ọ ươ ể c g i là ____________. ề ế ể c a kh i mã l nh. Đi u này đ ượ ọ ệ ủ ề ố

5. M t __________ là m t s khai báo hàm

4. Hàm g i đ n m t hàm khác có tên là ________ và hàm đang đ c g i đ n có tên là ________. ọ ế ộ ượ ọ ế

ộ ự ộ đ ể xác đ nhị ch raỉ ki u d li u c a các đ i s . ố ố ể ữ ệ ủ

6. _________ ch có th đ c tham chi u đ n b i các l nh bên trong kh i đã khai báo chúng. ể ượ ỉ ố l nh ệ ệ ế ế ở

ng trình, và có th đ ượ c nhìn th y b i toàn b ch ở ộ ươ ấ c s d ng ể ượ ử ụ ở ấ ệ b t kỳ mã l nh 7. ________ đ nào.

ấ ế ế ị ể ệ ệ ạ ạ ộ ộ hayho cặ 8. _________ 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 d li u hay không. ữ ệ

9. Các đ i s đ c g i là truy n ________ khi giá tr c a các bi n đ c truy n đ n hàm đ ố ố ượ ọ ế ượ ị ủ ề ế ề c g i ượ ọ

228

L p trình c b n C

ơ ả

10. Trong_________, hàm đ ượ c phép truy xu t v trí b nh th t c a các đ i s . ố ố ộ ớ ậ ủ ấ ị