Không thể thực hiện ngữ nghĩa gọi hàm mà không sử dụng một số loại ngăn xếp. Bạn chỉ có thể chơi các trò chơi chữ (ví dụ: sử dụng một tên khác cho nó, như "bộ đệm trả về FILO").
Có thể sử dụng một cái gì đó không thực hiện chức năng gọi ngữ nghĩa (ví dụ: kiểu truyền tiếp tục, các tác nhân), và sau đó xây dựng ngữ nghĩa gọi hàm trên đầu trang; nhưng điều này có nghĩa là thêm một số loại cấu trúc dữ liệu để theo dõi nơi điều khiển được truyền khi hàm trả về và cấu trúc dữ liệu đó sẽ là một loại ngăn xếp (hoặc ngăn xếp có tên / mô tả khác).
Hãy tưởng tượng bạn có nhiều chức năng mà tất cả có thể gọi nhau. Trong thời gian chạy, mỗi chức năng phải biết trở về nơi khi chức năng thoát. Nếu first
cuộc gọi second
thì bạn có:
second returns to somewhere in first
Sau đó, nếu bạn second
gọi third
:
third returns to somewhere in second
second returns to somewhere in first
Sau đó, nếu bạn third
gọi fourth
:
fourth returns to somewhere in third
third returns to somewhere in second
second returns to somewhere in first
Khi mỗi chức năng được gọi, nhiều thông tin "nơi trở về" phải được lưu trữ ở đâu đó.
Nếu một hàm trả về, thì thông tin "nơi trả về" của nó được sử dụng và không còn cần thiết nữa. Ví dụ: nếu fourth
quay trở lại một nơi nào third
đó thì lượng thông tin "nơi quay lại" sẽ trở thành:
third returns to somewhere in second
second returns to somewhere in first
Về cơ bản; "ngữ nghĩa gọi hàm" ngụ ý rằng:
- bạn phải có thông tin "nơi để trở về"
- lượng thông tin tăng lên khi các hàm được gọi và giảm đi khi các hàm quay trở lại
- phần đầu tiên của thông tin "nơi trở về" được lưu trữ sẽ là phần cuối cùng của thông tin "nơi trả lại" bị loại bỏ
Điều này mô tả bộ đệm FILO / LIFO hoặc ngăn xếp.
Nếu bạn cố gắng sử dụng một loại cây, thì mỗi nút trong cây sẽ không bao giờ có nhiều hơn một con. Lưu ý: một nút có nhiều con chỉ có thể xảy ra nếu một hàm gọi 2 hoặc nhiều hàm cùng một lúc , yêu cầu một số loại đồng thời (ví dụ: luồng, fork (), v.v.) và nó sẽ không phải là "ngữ nghĩa gọi hàm". Nếu mỗi nút trong cây sẽ không bao giờ có nhiều hơn một con; sau đó "cây" đó sẽ chỉ được sử dụng làm bộ đệm FILO / LIFO hoặc ngăn xếp; và bởi vì nó chỉ được sử dụng làm bộ đệm FILO / LIFO hoặc một ngăn xếp nên công bằng khi cho rằng "cây" là một ngăn xếp (và sự khác biệt duy nhất là trò chơi chữ và / hoặc chi tiết triển khai).
Điều tương tự cũng áp dụng cho bất kỳ cấu trúc dữ liệu nào khác có thể được sử dụng để thực hiện "ngữ nghĩa gọi hàm" - nó sẽ được sử dụng như một ngăn xếp (và sự khác biệt duy nhất là trò chơi chữ và / hoặc chi tiết triển khai); trừ khi nó phá vỡ "chức năng gọi ngữ nghĩa". Lưu ý: Tôi sẽ cung cấp các ví dụ cho các cấu trúc dữ liệu khác nếu tôi có thể, nhưng tôi không thể nghĩ ra bất kỳ cấu trúc nào khác hơi hợp lý.
Tất nhiên làm thế nào một ngăn xếp được thực hiện là một chi tiết thực hiện. Nó có thể là một vùng bộ nhớ (nơi bạn theo dõi "đỉnh ngăn xếp hiện tại"), nó có thể là một loại danh sách được liên kết (nơi bạn theo dõi "mục hiện tại trong danh sách") hoặc có thể được thực hiện trong một số cách khác. Nó cũng không quan trọng nếu phần cứng có hỗ trợ tích hợp hay không.
Lưu ý: Nếu chỉ một lời mời của bất kỳ thủ tục nào có thể được kích hoạt bất cứ lúc nào; sau đó bạn có thể phân bổ tĩnh không gian cho thông tin "nơi quay lại". Đây vẫn là một ngăn xếp (ví dụ: một danh sách được liên kết của các mục được phân bổ tĩnh được sử dụng theo cách FILO / LIFO).
Cũng lưu ý rằng có một số điều không tuân theo "ngữ nghĩa gọi hàm". Những điều này bao gồm "ngữ nghĩa có khả năng rất khác nhau" (ví dụ: tiếp tục vượt qua, mô hình diễn viên); và cũng bao gồm các phần mở rộng phổ biến cho "ngữ nghĩa gọi hàm" như đồng thời (luồng, sợi, bất cứ thứ gì), setjmp
/ longjmp
, xử lý ngoại lệ, v.v.