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

Các cấu trúc điều khiển và hàm

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

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

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 19
Dung lượng 189,71 KB

Nội dung

Updatesofts.com Ebooks Team Trang 22 Các cấu trúc ñiều khiển. Một chương trình thường không chỉ bao gồm các lệnh tuần tự nối tiếp nhau. Trong quá trình chạy nó có thể rẽ nhánh hay lặp lại một ñoạn mã nào ñó. ðể làm ñiều này chúng ta sử dụng các cấu trúc ñiều khiển. Cùng với việc giới thiệu các cấu trúc ñiều khiển chúng ta cũng sẽ phải biết tới một khái niệm mới: khối lệnh, ñó là một nhóm các lệnh ñược ngăn cách bởi dấu chấm phẩy (;) nhưng ñược gộp trong một khối giới hạn bởi một cặp ngoặc nhọn: { } . Hầu hết các cấu trúc ñiều khiển mà chúng ta sẽ xem xét trong chương này cho phép sử dụng một lệnh ñơn hay một khối lệnh làm tham số, tuỳ thuộc vào chúng ta có ñặt nó trong cặp ngoặc nhọn hay không. Cấu trúc ñiều kiện: if else Cấu trúc này ñược dùng khi một lệnh hay một khối lệnh chỉ ñược thực hiện khi một ñiều kiện nào ñó thoả mãn. Dạng của nó như sau: if (condition) statement trong ñó condition là biểu thức sẽ ñược tính toán. Nếu ñiều kiện ñó là true , statement ñược thực hiện. Nếu không statement bị bỏ qua (không thực hiện) chương trình tiếp tục thực hiện lệnh tiếp sau cấu trúc ñiều kiện. Ví dụ, ñoạn mã sau ñây sẽ viết x is 100 chỉ khi biến x chứa giá trị 100: if (x == 100) cout << "x is 100"; Nếu chúng ta muốn có hơn một lệnh ñược thực hiện trong trường hợp condition là true chúng ta có thể chỉ ñịnh một khối lệnh bằng cách sử dụng một cặp ngoặc nhọn { } : if (x == 100) { cout << "x is "; cout << x; } Chúng ta cũng có thể chỉ ñịnh ñiều gì sẽ xảy ra nếu ñiều kiện không ñược thoả mãn bằng cách sửu dụng từ khoá else. Nó ñược sử dụng cùng với if như sau: if (condition) statement1 else statement2 Ví dụ: Updatesofts.com Ebooks Team Trang 23 if (x == 100) cout << "x is 100"; else cout << "x is not 100"; Cấu trúc if + else có thể ñược móc nối ñể kiểm tra nhiều giá trị. Ví dụ sau ñây sẽ kiểm tra xem giá trị chứa trong biến x là dương, âm hay bằng không. if (x > 0) cout << "x is positive"; else if (x < 0) cout << "x is negative"; else cout << "x is 0"; Các cấu trúc lặp Mục ñích của các vòng lặp là lặp lại một thao tác với một số lần nhất ñịnh hoặc trong khi một ñiều kiện nào ñó còn thoả mãn. Vòng lặp while . Dạng của nó như sau: while (expression) statement chức năng của nó ñơn giản chỉ là lặp lại statement khi ñiều kiện expression còn thoả mãn. Ví dụ, chúng ta sẽ viết một chương trình ñếm ngược sử dụng vào lặp while: // custom countdown using while #include <iostream.h> int main () { int n; cout << "Enter the starting number > "; cin >> n; while (n>0) { cout << n << ", "; --n; } cout << "FIRE!"; return 0; } Enter the starting number > 8 8, 7, 6, 5, 4, 3, 2, 1, FIRE! Khi chương trình chạy người sử dụng ñược yêu cầu nhập vào một số ñể ñếm ngược. Sau ñó, khi vòng lặp while bắt ñầu nếu số mà người dùng nhập vào thoả mãn ñiều kiện ñiều kiện n>0 khối lệnh sẽ ñược thực hiện một số lần không xác ñịnh chừng nào ñiều kiện (n>0) còn ñược thoả mãn. Updatesofts.com Ebooks Team Trang 24 Chúng ta cần phải nhớ rằng vòng lặp phải kết thúc ở một ñiểm nào ñó, vì vậy bên trong vòng lặp chúng ta phải cung cấp một phương thức nào ñó ñể buộc condition trở thành sai nếu không thì nó sẽ lặp lại mãi mãi. Trong ví dụ trên vòng lặp phải có lệnh --n; ñể làm cho condition trở thành sai sau một số lần lặp. Vòng lặp do-while Dạng thức: do statement while (condition); Chức năng của nó là hoàn toàn giống vòng lặp while chỉ trừ có một ñiều là ñiều kiện ñiều khiển vòng lặp ñược tính toán sau khi statement ñược thực hiện, vì vậy statement sẽ ñược thực hiện ít nhất một lần ngay cả khi condition không bao giờ ñược thoả mãn. Ví dụ, chương trình dưới ñây sẽ viết ra bất kì số nào mà bạn nhập vào cho ñến khi bạn nhập số 0. // number echoer #include <iostream.h> int main () { unsigned long n; do { cout << "Enter number (0 to end): "; cin >> n; cout << "You entered: " << n << "\n"; } while (n != 0); return 0; } Enter number (0 to end): 12345 You entered: 12345 Enter number (0 to end): 160277 You entered: 160277 Enter number (0 to end): 0 You entered: 0 Vòng lặp do-while thường ñược dùng khi ñiều kiện ñể kết thúc vòng lặp nằm trong vòng lặp, như trong ví dụ trên, số mà người dùng nhập vào là ñiều kiện kiểm tra ñể kết thúc vòng lặp. Nếu bạn không nhập số 0 trong ví dụ trên thì vòng lặp sẽ không bao giờ chấm dứt. Vòng lặp for . Dạng thức: for (initialization; condition; increase) statement; chức năng chính của nó là lặp lại statement chừng nào condition còn mang giá trị ñúng, như trong vòng lặp while. Nhưng thêm vào ñó, for cung cấp chỗ dành cho lệnh khởi tạo lệnh tăng. Vì vậy vòng lặp này ñược thiết kế ñặc biệt lặp lại một hành ñộng với một số lần xác ñịnh. Cách thức hoạt ñộng của nó như sau: Updatesofts.com Ebooks Team Trang 25 1, initialization ñược thực hiện. Nói chung nó ñặt một giá khí ban ñầu cho biến ñiều khiển. Lệnh này ñược thực hiện chỉ một lần. 2, condition ñược kiểm tra, nếu nó là ñúng vòng lặp tiếp tục còn nếu không vòng lặp kết thúc statement ñược bỏ qua. 3, statement ñược thực hiện. Nó có thể là một lệnh ñơn hoặc là một khối lệnh ñược bao trong một cặp ngoặc nhọn. 4, Cuối cùng, increase ñược thực hiện ñể tăng biến ñiều khiển vòng lặp quay trở lại bước 2. Sau ñây là một ví dụ ñếm ngược sử dụng vòng for. // countdown using a for loop #include <iostream.h> int main () { for (int n=10; n>0; n--) { cout << n << ", "; } cout << "FIRE!"; return 0; } 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! Phần khởi tạo lệnh tăng không bắt buộc phải có. Chúng có thể ñược bỏ qua nhưng vẫn phải có dấu chấm phẩy ngăn cách giữa các phần. Vì vậy, chúng ta có thể viết for (;n<10;) hoặc for (;n<10;n++) . Bằng cách sử dụng dấu phẩy, chúng ta có thể dùng nhiều lệnh trong bất kì trường nào trong vòng for, như là trong phần khởi tạo. Ví dụ chúng ta có thể khởi tạo một lúc nhiều biến trong vòng lặp: for ( n=0, i=100 ; n!=i ; n++, i-- ) { // cái gì ở ñây cũng ñược . } Vòng lặp này sẽ thực hiện 50 lần nếu như n i không bị thay ñổi trong thân vòng lặp: Các lệnh rẽ nhánh lệnh nhảy Lệnh break. Sử dụng break chúng ta có thể thoát khỏi vòng lặp ngay cả khi ñiều kiện ñể nó kết thúc chưa ñược thoả mãn. Lệnh này có thể ñược dùng ñể kết thúc một vòng lặp Updatesofts.com Ebooks Team Trang 26 không xác ñịnh hay buộc nó phải kết thúc giữa chừng thay vì kết thúc một cách bình thường. Ví dụ, chúng ta sẽ dừng việc ñếm ngược trước khi nó kết thúc: // break loop example #include <iostream.h> int main () { int n; for (n=10; n>0; n--) { cout << n << ", "; if (n==3) { cout << "countdown aborted!"; break; } } return 0; } 10, 9, 8, 7, 6, 5, 4, countdown aborted! Lệnh continue. Lệnh continue làm cho chương trình bỏ qua phần còn lại của vòng lặp nhảy sang lần lặp tiếp theo. Ví dụ chúng ta sẽ bỏ qua số 5 trong phần ñếm ngược: // break loop example #include <iostream.h> int main () { for (int n=10; n>0; n--) { if (n==5) continue; cout << n << ", "; } cout << "FIRE!"; return 0; } 10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE! Lệnh goto. Lệnh này cho phép nhảy vô ñiều kiện tới bất kì ñiểm nào trong chương trình. Nói chung bạn nên tránh dùng nó trong chương trình C++. Tuy nhiên chúng ta vẫn có một ví dụ dùng lệnh goto ñể ñếm ngược: // goto loop example #include <iostream.h> int main () { int n=10; loop: ; cout << n << ", "; n--; if (n>0) goto loop; cout << "FIRE!"; return 0; } 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! Hàm exit. Updatesofts.com Ebooks Team Trang 27 Mục ñích của exit là kết thúc chương trình trả về một mã xác ñịnh. Dạng thức của nó như sau void exit (int exit code); exit code ñược dùng bởi một số hệ ñiều hành hoặc có thể ñược dùng bởi các chương trình gọi. Theo quy ước, mã trả về 0 có nghĩa là chương trình kết thúc bình thường còn các giá trị khác 0 có nghĩa là có lỗi. Cấu trúc lựa chọn: switch. Cú pháp của lệnh switch hơi ñặc biệt một chút. Mục ñích của nó là kiểm tra một vài giá trị hằng cho một biểu thức, tương tự với những gì chúng ta làm ở ñầu bài này khi liên kết một vài lệnh if else if với nhau. Dạng thức của nó như sau: switch (expression) { case constant1: block of instructions 1 break; case constant2: block of instructions 2 break; . . . default: default block of instructions } Nó hoạt ñộng theo cách sau: switch tính biểu thức kiểm tra xem nó có bằng constant1 hay không, nếu ñúng thì nó thực hiện block of instructions 1 cho ñến khi tìm thấy từ khoá break, sau ñó nhảy ñến phần cuối của cấu trúc lựa chọn switch. Còn nếu không, switch sẽ kiểm tra xem biểu thức có bằng constant2 hay không. Nếu ñúng nó sẽ thực hiện block of instructions 2 cho ñến khi tìm thấy từ khoá break. Cuối cùng, nếu giá trị biểu thức không bằng bất kì hằng nào ñược chỉ ñịnh ở trên (bạn có thể chỉ ñịnh bao nhiêu câu lệnh case tuỳ thích), chương trình sẽ thực hiện các lệnh trong phần default: nếu nó tồn tại vì phần này không bắt buộc phải có. Hai ñoạn mã sau là tương ñương: ví dụ switch if-else tương ñương switch (x) { case 1: cout << "x is 1"; break; case 2: cout << "x is 2"; break; if (x == 1) { cout << "x is 1"; } else if (x == 2) { cout << "x is 2"; } else { Updatesofts.com Ebooks Team Trang 28 default: cout << "value of x unknown"; } cout << "value of x unknown"; } Tôi ñã nói ở trên rằng cấu trúc của lệnh switch hơi ñặc biệt. Chú ý sự tồn tại của lệnh break ở cuối mỗi khối lệnh. ðiều này là cần thiết vì nếu không thì sau khi thực hiện block of instructions 1 chương trình sẽ không nhảy ñến cuối của lệnh switch mà sẽ thực hiện các khối lệnh tiếp theo cho ñến khi nó tìm thấy lệnh break ñầu tiên. ðiều này khiến cho việc ñặt cặp ngoặc nhọn { } trong mỗi trường hợp là không cần thiết có thể ñược dùng khi bạn muốn thực hiện một khối lệnh cho nhiều trường hợp khác nhau, ví dụ: switch (x) { case 1: case 2: case 3: cout << "x is 1, 2 or 3"; break; default: cout << "x is not 1, 2 nor 3"; } Chú ý rằng lệnh switch chỉ có thể ñược dùng ñể so sánh một biểu thức với các hằng. Vì vậy chúng ta không thể ñặt các biến ( case (n*2): ) hay các khoảng ( case (1 3): ) vì chúng không phải là các hằng hợp lệ. Nếu bạn cần kiểm tra các khoảng hay nhiều giá trị không phải là hằng số hãy kết hợp các lệnh if else if. Updatesofts.com Ebooks Team Trang 29 Hàm (I) Hàm là một khối lệnh ñược thực hiện khi nó ñược gọi từ một ñiểm khác của chương trình. Dạng thức của nó như sau: type name ( argument1, argument2, .) statement trong ñó: type là kiểu dữ liệu ñược trả về của hàm name là tên gọi của hàm. arguments là các tham số (có nhiều bao nhiêu cũng ñược tuỳ theo nhu cầu). Một tham số bao gồm tên kiểu dữ liệu sau ñó là tên của tham số giống như khi khai báo biến (ví dụ int x ) ñóng vai trò bên trong hàm như bất kì biến nào khác. Chúng dùng ñể truyền tham số cho hàm khi nó ñược gọi. Các tham số khác nhau ñược ngăn cách bởi các dấu phẩy. statement là thân của hàm. Nó có thể là một lệnh ñơn hay một khối lệnh. Dưới ñây là ví dụ ñầu tiên về hàm: // function example #include <iostream.h> int addition (int a, int b) { int r; r=a+b; return (r); } int main () { int z; z = addition (5,3); cout << "The result is " << z; return 0; } The result is 8 ðể có thể hiểu ñược ñoạn mã này, trước hết hãy nhớ lại những ñiều ñã nói ở bài ñầu tiên: một chương trình C++ luôn bắt ñầu thực hiện từ hàm main . Vì vậy chúng ta bắt ñầu từ ñây. Chúng ta có thể thấy hàm main bắt ñầu bằng việc khai báo biến z kiểu int . Ngay sau ñó là một lời gọi tới hàm addition . Nếu ñể ý chúng ta sẽ thấy sự tương tự giữa cấu trúc của lời gọi hàm với khai báo của hàm: Updatesofts.com Ebooks Team Trang 30 Các tham số có vai trò thật rõ ràng. Bên trong hàm main chúng ta gọi hàm addition truyền hai giá trị: 5 3 tương ứng với hai tham số int a int b ñược khai báo cho hàm addition . Vào thời ñiểm hàm ñược gọi từ main , quyền ñiều khiển ñược chuyển sang cho hàm addition . Giá trị của c hai tham số ( 5 3 ) ñược copy sang hai biến cục bộ int a int b bên trong hàm. Dòng lệnh sau: return (r); kết thúc hàm addition , trả lại quyền ñiều khiển cho hàm nào ñã gọi nó ( main ) tiếp tục chương trình ở cái ñiểm mà nó bị ngắt bởi lời gọi ñến addition . Nhưng thêm vào ñó, giá trị ñược dùng với lệnh return ( r ) chính là giá trị ñược trả về của hàm.\ Giá trị trả về bởi một hàm chính là giá trị của hàm khi nó ñược tính toán. Vì vậy biến z sẽ có có giá trị ñược trả về bởi addition (5, 3) , ñó là 8 . Phạm vi hoạt ñộng của các biến [nhắc lại] Bạn cần nhớ rằng phạm vi hoạt ñộng của các biến khai báo trong một hàm hay bất kì một khối lệnh nào khác chỉ là hàm ñó hay khối lệnh ñó không thể sử dụng bên ngoài chúng. Ví dụ, trong chương trình ví dụ trên, bạn không thể sử dụng trực tiếp các biến a , b hay r trong hàm main vì chúng là các biến cục bộ của hàm addition . Thêm vào ñó bạn cũng không thể sử dụng biến z trực tiếp bên trong hàm addition vì nó làm biến cục bộ của hàm main . Tuy nhiên bạn có thể khai báo các biến toàn cục ñể có thể sử dụng chúng ở bất kì ñâu, bên trong hay bên ngoài bất kì hàm nào. ðể làm việc này bạn cần khai báo chúng bên ngoài mọi hàm hay các khối lệnh, có nghĩa là ngay trong thân chương trình. ðây là một ví dụ khác về hàm: // function example #include <iostream.h> The first result is 5 The second result is 5 Updatesofts.com Ebooks Team Trang 31 int subtraction (int a, int b) { int r; r=a-b; return (r); } int main () { int x=5, y=3, z; z = subtraction (7,2); cout << "The first result is " << z << '\n'; cout << "The second result is " << subtraction (7,2) << '\n'; cout << "The third result is " << subtraction (x,y) << '\n'; z= 4 + subtraction (x,y); cout << "The fourth result is " << z << '\n'; return 0; } The third result is 2 The fourth result is 6 Trong trường hợp này chúng ta tạo ra hàm subtraction . Chức năng của hàm này là lấy hiệu của hai tham số rồi trả về kết quả. Tuy nhiên, nếu phân tích hàm main các bạn sẽ thấy chương trình ñã vài lần gọi ñến hàm subtraction . Tôi ñã sử dụng vài cách gọi khác nhau ñể các bạn thấy các cách khác nhau mà một hàm có thể ñược gọi. ðể có hiểu cặn kẽ ví dụ này bạn cần nhớ rằng một lời gọi ñến một hàm có thể hoàn toàn ñược thay thế bởi giá trị của nó. Ví dụ trong lệnh gọi hàm ñầu tiên : z = subtraction (7,2); cout << "The first result is " << z; Nếu chúng ta thay lời gọi hàm bằng giá trị của nó (ñó là 5 ), chúng ta sẽ có: z = 5; cout << "The first result is " << z; Tương tự như vậy cout << "The second result is " << subtraction (7,2); cũng cho kết quả giống như hai dòng lệnh trên nhưng trong trường hợp này chúng ta gọi hàm subtraction trực tiếp như là một tham số của cout . Chúng ta cũng có thể viết: cout << "The second result is " << 5; [...]... m t hàm nào khác ðó chính là khai báo m u cho hàm Cách này bao g m vi c khai báo hàm m t cách ng n g n nhưng ñ ñ cho trình d ch có th bi t các tham s ki u d li u tr v c a hàm D ng c a nó như sau: type name ( argument_type1, argument_type2, ); ðây chính là ph n ñ u c a ñ nh nghĩa hàm, ngo i tr : • • Nó không có b t kì l nh nào cho hàm ði u này có nghĩa là nó không bao g m thân hàm v i t t c các l... , y ); Trong trư ng h p này khi chúng ta g i hàm addition thì các giá tr 5 and 3 ñư c truy n cho hàm, không ph i là b n thân các bi n ð n ñây các b n có th h i tôi: Như v y thì sao, có nh hư ng gì ñâu ? ði u ñáng nói ñây là khi các b n thay ñ i giá tr c a các bi n a hay b bên trong hàm thì các bi n x y v n không thay ñ i vì chúng ñâu có ñư c truy n cho hàm ch có giá tr c a chúng ñư c truy n mà thôi... d này chúng ta ñ nh nghĩa hai hàm có cùng tên nhưng m t hàm dùng hai tham s ki u int hàm còn l i dùng ki u float Trình biên d ch s bi t c n ph i g i hàm nào b ng cách phân tích ki u tham s khi hàm ñư c g i ð ñơn gi n tôi vi t c hai hàm ñ u có mã l nh như nhau nhưng ñi u này không b t bu c B n có th xây d ng hai hàm có cùng tên nhưng ho t ñ ng hoàn toàn khác nhau Các hàm inline Ch th inline có th... Trang 33 Updatesofts.com Ebooks Team Hàm (II) Truy n tham s theo tham s giá tr hay tham s bi n Cho ñ n nay, trong t t c các hàm chúng ta ñã bi t, t t c các tham s truy n cho hàm ñ u ñư c truy n theo giá tr ði u này có nghĩa là khi chúng ta g i hàm v i các tham s , nh ng gì chúng ta truy n cho hàmcác giá tr ch không ph i b n thân các bi n Ví d , gi s chúng ta g i hàm addition như sau: int x=5, y=3,... tham s ñ u là d u (&), ñ báo hi u r ng các tham s này ñư c truy n theo tham s bi n ch không ph i tham s giá tr Khi truy n tham s dư i d ng tham s bi n chúng ta ñang truy n b n thân bi n ñó b t kì s thay ñ i nào mà chúng ta th c hi n v i tham s ñó bên trong hàm s nh hư ng tr c ti p ñ n bi n ñó Trong ví d trên, chúng ta ñã liên k t a, b c v i các tham s khi g i hàm (x, y z) m i s thay ñ... khao báo c a m t hàm ñ ch rõ r ng l i g i hàm s ñư c thay th b ng mã l nh c a hàm khi chương trình ñư c d ch Vi c này tương ñương v i vi c khai báo m t macro, l i ích c a nó ch th hi n v i các hàm r t ng n, t c ñ ch y chương trình s ñư c c i thi n vì nó không ph i g i m t th t c con C u trúc c a nó như sau: inline type name ( arguments ) { instructions } l i g i hàm cũng như b t kì m t hàm nào khác Không... n nó, mà thư ng là trong main, vì v y hàm main luôn ph i n m cu i chương trình N u b n th l p l i m t vài ví d v hàm trư c ñây nhưng th ñ t hàm main trư c b t kì m t hàm ñư c g i t nó, b n g n như ch c ch n s nh n ñư c thông báo l i Nguyên nhân là m t hàm ph i ñư c khai báo trư c khi nó ñư c g i như nhưnggx gì chúng ta ñã làm trng t t c các ví d Nhưng có m t cách khác ñ tránh ph i vi t t t c mã chương... m i s thay ñ i v i a bên trong hàm s nh hư ng ñ n giá tr c a x hoàn toàn tương t v i b y, c z Ki u khai báo tham s theo d ng tham s bi n s d ng d u (&) ch có trong C++ Trong ngôn ng C chúng ta ph i s d ng con tr ñ làm vi c tương t như th Truy n tham s dư i d ng tham s bi n cho phép m t hàm tr v nhi u hơn m t giá tr Ví d , ñây là m t hàm tr v s li n trư c li n sau c a tham s ñ u tiên... t ph i ñ t ngay sau l i g i hàm cu i Các hàm không ki u Cách s d ng void N u b n còn nh cú pháp c a m t l i khai báo hàm: type name ( argument1, argument2 ) statement b n s th y rõ ràng r ng nó b t ñ u v i m t tên ki u, ñó là ki u d li u s ñư c hàm tr v b i l nh return Nhưng n u chúng ta không mu n tr v giá tr nào thì sao ? Hãy tư ng tư ng r ng chúng ta mu n t o ra m t hàm ch ñ hi n th m t thông báo... hàm divide Trong l nh ñ u tiên: divide (12) chúng ta ch dùng m t tham s nhưng hàm divide cho phép ñ n hai B i v y hàm s t cho tham s th hai giá tr b ng 2 vì ñó là giá tr m c ñ nh c a nó (chú ý ph n khai báo hàm ñư c k t thúc b i int b=2) Vì v y k t qu s là 6 (12/2) divide Trong l nh th hai: divide (20,4) có hai tham s , b i v y giá tr m c ñ nh s ñư c b qua K t qu c a hàm s là 5 (20/4) Quá t i các hàm . các cấu trúc ñiều khiển. Cùng với việc giới thiệu các cấu trúc ñiều khiển chúng ta cũng sẽ phải biết tới một khái niệm mới: khối lệnh, ñó là một nhóm các. thấy chương trình ñã vài lần gọi ñến hàm subtraction . Tôi ñã sử dụng vài cách gọi khác nhau ñể các bạn thấy các cách khác nhau mà một hàm có thể ñược gọi.

Ngày đăng: 05/10/2013, 07:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w