Bản chất thực sự của Return và cách thức nó hoạt động?
Em biết mọi người sẽ kêu em google hoặc đọc sách tìm hiểu, nhưng em vẫn không thể nào hiểu cặn kẽ về return được.
Mọi người nói Return dùng để trả về một giá trị nào đó khi thực hiện xong một hàm.
Vậy nó trả về như thế nào ? Nó trả về chỗ nào ? Giá trị của nó lưu ở đâu ?
Bình thường em code C có thể không dùng return cũng vẫn được mà nhưng hoc đệ quy thì nhất thiết phải dùng đến return.
Ví dụ đi ạ:
- long giaiThua(int n)
- {
- if(n==0) return 1;
- else return n*giaiThua(n-1);
- }
Như đoạn code trên, thì sau khi return thì cái gì lưu giá trị được return ? Giá trị đó lưu ở đâu ? Tại sao n=0 thì lại return 1 ?
Rất mong mọi người giúp đỡ ạ.
Học assembly phát là hiểu ngay à
Ví dụ mình sẽ chạy đoạn code này với số
n = 3
Vẽ paint hơi xấu
vấn đề chính là em muốn hiểu cách thức hoạt động của return. Giá trị sau khi return là cái gì? nằm ở đâu? Vì em không thấy có biến nào lưu giá trị đấy cả
return trả về như thế nào ? Nó trả về chỗ nào ? Giá trị của nó lưu ở đâu ? Tại sao không có biến để lưu giá trị đó mà nó vẫn có thể thực hiện được ạ ?
Nó trả về giá trị, đơn giản z thôi. Nếu là các kiểu primative thì nó trả về 1 giá trị gán cho biến gọi nó(giá trị trong biến return sẽ được coppy gán cho biến gọi…). Nếu là tham chiếu trả về địa chỉ cho biến gọi nó
còn cái hàm giai thuật đó, thì khi tính giai thừa thì 0! = 1 => nó sẽ return 1, còn không phải nó sẽ gọi đệ qui, cái hàm này muốn đầy đủ thì phải kiểm tra điều kiện vd: n >=0 chẳng hạn
(cách trả về giá trị của hàm đệ qui thì tự search, không nên serch tiếng việt)
còn muốn hiểu sau thì hơi khó, như hàm trên giá trị trả về là 1 kiểu primative, nó sẽ lưu ở stack, giống như bạn gán : int x =10 vậy
À, chủ topic không học ngôn ngữ Pascal mà nhảy vô học C ngay nên mới có sự rối loạn như vậy.
Cần biết qua chút về “hàm”: Trong Pascal thì người ta phân biệt giữa hai loại “hàm”: 1. Hàm có nhận giá trị trả về, tên gọi nó là function; 2. Thủ tục: không nhận giá trị trả về, tên gọi nó là procedure.
Còn trong C, người ta gọi tất là function , tức gồm cả hàm (function) và thủ tục (procedure) bên Pascal.
Vậy, câu hỏi đặt ra là làm sao nhận biết lúc nào hàm thực sự là function, lúc nào hàm là có bản chất procedure bên C?
Cứ thấy cái nào mà có khai báo:
thì cái này đích thị là procedure bên Pascal.
Hiểu một cách rất đơn giản: đây là nơi gom các khai báo, gọi hàm được cung cấp sẵn bởi C, hoặc read/ write/ làm cái gì đó - ngoài việc tính toán biểu thức. Khi có từ void đứng đầu, thì function này không nhận giá trị trả về, và không lưu vào đâu hết, thực hiện xong không có lỗi là im re. Đây đích thị có bản chất là procedure.
Còn nếu thấy khai báo dạng:
hoặc:
thì lúc này ta thấy người tra khai báo có kiểu dữ liệu đứng trước hàm, ở 2 ví dụ trên là int, double , lúc này, từ hàm nó giống y như giải toán, có dữ liệu đầu vào, sau khi tính toán đã đời thì cần phải trả về giá trị (kết quả) để sử dụng trong các biểu thức tính toán khác và/ hoặc xuất ra. Vậy, nếu nó trả về mà cứ hiện lên màn hình thì quá bất tiện, cho nên, lúc này tên-của-hàm đóng vai trò gần như một biến, và giá trị nó nằm trong đó, ta cần thì write/ print nó ra hoặc ta gán cho một biến nào đó để dùng.
Ví dụ về hàm không có giá trị trả về:
Còn hàm có giá trị trả về:
Ở ví dụ đầu (*), ta không thể:
printf("%d", congHaiSo()); được, vì lúc này hàm congHaiSo thực chất là 1 procedure. Nhưng ở ví dụ sau (**) thì ta có thể:
printf("%d", congHaiSo(4,5)); và nó cho giá trị là 9.
Thêm một dấu hiệu nhận biết nữa là function có trả về thường hay có đối số, tức là int tên-hàm(đối số, đối số, đối số) { làm gì đó; return }, còn nếu không có giá trị trả về, nó ít khi có đối số mà void tên-hàm(void nốt) { làm gì đó }
Nếu chủ topic chưa hiểu nữa thì vui lòng kiếm một cuốn sách tốt để đọc, ở đó họ giải thích rất kỹ. Nếu vẫn bó tay, kiếm cuốn lập trình Pascal đọc trước để hiểu sơ qua về lập trình là gì, vì bắt đầu với C là quá khó với một số người.
Mình không học sâu về cách mà máy tính hoạt động nhưng theo mình hiểu gì đệ quy giống như việc bạn gọi một hàm nhiều lần. Khi bạn thực hiện đệ quy thì hàm đầu tiên sẽ đợi giá trị từ hàm tiếp theo, rồi hàm tiếp theo lại đợi kết quả từ hàm kế tiếp nữa, cứ thế cho tới khi nào một hàm thỏa giá trị
if n = 0
như trên ví dụ thì đệ quy coi như kết thúc bằng việcreturn 1
. Ở đây không phải đợi một hàm nào khác nữa.Mình sẽ coi như đệ quy gọi hàm
n
lần. Lần thứn
làreturn 1
. Vậy lần thứn - 1
đang chờ lần thứn
sẽ có được kết quả1
. Sau khi trả về nó sẽ tính toán và trả về giá trị cho lần thứn - 2
. Và tiếp theo hàm thứn - 2
cũng đang đợi kết quả từ hàm thứn - 1
, và cứ thế thằng sau có giá trị, nó sẽ vứt cho thằng trước, thằng trước có giá trị nó lại vứt về cho thằng trước nó nữa. Cho tới mà kết quả được vứt tới thằng đầu tiên.EDIT: Tưởng tượng kiểu thực tế như việc bạn hỏi thông tin vậy. Bạn hỏi thằng A, A kêu là đợi tao đi hỏi B, B lại nói với A đợi tao đi hỏi C, C lại tiếp tục kêu B đợi tao hỏi D. Sau khi D trả lời thì C biết câu trả lời về nói cho B, B lại về nói cho A. Khi A có đáp án về mách cho bạn
Thằng cha này hoạt động nhiệt tình nhỉ
Ý anh là sao ạ.
Tại ở đâu cũng thấy răng
Biết không nhiều, nhưng nghĩ có thể giúp được người khác ở những kiến thức căn bản nên cũng muốn gõ góp vào vài chữ thôi ạ
Ukm, thay mặt ae cám ơn bạn. Thấy bạn cũng hiểu khá sâu về cấu trúc dữ liệu
Cái này chắc phải đề nghị a Đạt cho lên làm Mod
Hàm có return gần như chẳng khác gì một phép toán cả.
int a = b + c;
tức là phép gána = b + c;
Giả sử bạn có hàm Add như sau:
Vậy thì
int a = Add(b, c);
hoàn toàn giống vớiint a = b + c;
return là trả về kết quả của 1 phép toán. Và kết quả của phép toán thì lưu trong thanh ghi của CPU (chém gió vui mồm. Mình cũng chẳng biết kết quả phép toán lưu ở đâu đâu.).
em cảm ơn anh rất nhiều. Em hiểu 90% rồi ^^
Trước đây em có có học qua Pascal trên trường, ở quê nên là thầy cô dạy qua quýt cho xong.
Kết quả của hàm số có thể được lưu trong thanh ghi của CPU, cũng có thể được lưu ngay trên thread stack
và tên của hàm sẽ lưu giá trị được trả về phải không bác ?
Nói thế ông nội em nó cũng không hiểu
thread(luồng) stack: bộ nhớ chính(Ram)
register(thanh ghi), bộ nhớ đệm CPU, nằm bên trong CPU
Mẹ tức đéo cám ơn mn, cám ơn có 1 người. Ghét không rep nữa
em đang đọc nốt mấy cmt bên trên anh ạ -_- nó hơi lằng nhằng nên em phải đọc đi đọc lại…mà em đã thả tim rồi còn gì :’(