我對C語言比較熟悉而嵌入式了解不多。今天和一個嵌入式開發討論C語言的時候遇到一個這樣的問題。
void f(){}
對于一個回傳值型別為void的函式
我認為這個函式是沒有回傳值。
而那個嵌入式開發卻認為所有函式都有回傳值,包括void函式。
只是void函式不回傳。
很拗口很難理解,既然不回傳又怎么會有回傳值。
而我不管是查看匯編還是查教科書,都無法找到有回傳值但不回傳的描述。
這個嵌入式開發一直強調嵌入式中這是常識。
無奈之下,來到這個論壇請教各位嵌入式前輩。
請問,void f(){}這樣的函式是沒有回傳值,還是有回傳值而不回傳?
uj5u.com熱心網友回復:
這個問題還蠻有意思的。深入去想的話,應該是涉及到了函式的呼叫機制。
首先要明白的是,計算機的處理器只有一個(早期是這樣,后來多執行緒就另說了),所以程式的運行其實是一條PC指標順序執行命令的程序。
而函式呼叫的實作,實際上是PC指標根據程式的內容跳轉到了被呼叫函式的存盤地址,而函式呼叫完成后,PC指標也需要跳轉回呼叫之前所在的地址,這就是一個函式被呼叫的實作程序。
而函式呼叫的目的是處理業務,所以相應的傳參、回傳值的變化就是呼叫的目的。而傳參、回傳值這些資料是必須有暫存器來進行存盤的,在C語言層面,void不需要去考慮為了回傳值的存盤而開辟一段記憶體來使用,可以認為就不存在回傳值。
而嵌入式這塊,實際上說的太籠統了,是8位MCU,還是16位MCU,或者arm,甚至同位數MCU的不同架構,都會因為其編譯器的差異,而存在很多不同的特性。并不是所有的概念都是通用的。
不過,他的這種想法,放在早期的8位MCU里(比如51系列),也是可以理解的,因為這類MCU,結構比較簡單,回傳值的存放位置是一段固定的暫存器組,所以無回傳值只是不去讀這些暫存器而已。
最后,這個問題貌似也沒什么應用上的實際意義。
uj5u.com熱心網友回復:
的確談不上什么實用意義只是類似辯經的活動
上論壇不就是吹吹牛嘛 哈哈哈
對于回傳值的存放位置是一段固定的暫存器組這種情況
void 函式也不會去設定暫存器組的記錄
那么暫存器組中的記錄應該是上次呼叫函式的回傳值
而不是本函式的回傳值
我這樣理解合理嗎?
感謝回復
uj5u.com熱心網友回復:
是的,無回傳值的函式里,如果存盤回傳值的暫存器是固定的,那里面的資料是無意義的(也不一定就是上次呼叫回傳值,因為暫存器可能會被其他因素更改數值)
uj5u.com熱心網友回復:
沒有回傳值。有回傳值的,會向指定的暫存器保存回傳值。
這個void就不會有這個操作。
uj5u.com熱心網友回復:
在學習程序中,發現疑點去思考、去假設、去討論、去否定才能推動科學進步。牛頓被蘋果砸到,如果只是埋怨自己運氣不好,站錯了位置,萬有引力的發現就會推后N年
uj5u.com熱心網友回復:
我對C語言比較熟悉而嵌入式了解不多。今天和一個嵌入式開發討論C語言的時候遇到一個這樣的問題。
void f(){}
對于一個回傳值型別為void的函式
我認為這個函式是沒有回傳值。
而那個嵌入式開發卻認為所有函式都有回傳值,包括void函式。
只是void函式不回傳。
很拗口很難理解,既然不回傳又怎么會有回傳值。
而我不管是查看匯編還是查教科書,都無法找到有回傳值但不回傳的描述。
這個嵌入式開發一直強調嵌入式中這是常識。
無奈之下,來到這個論壇請教各位嵌入式前輩。
請問,void f(){}這樣的函式是沒有回傳值,還是有回傳值而不回傳?
所有回傳值都應該理解為是邏輯層面的,拋開邏輯談回傳值沒有意義!
先理解一下什么是回傳值:
如果是匯編編程,可能將運行的一個結果值,保存到一個暫存器或存盤器里,函式通過RET指令回傳后,你可以選擇使用暫存器或存盤器里的的值或不使用,這是有回傳的函式;如你函式沒有定義回傳值,那么應該就不會將結果保存到暫存器或存盤器里里,呼叫位置,使用這樣的值就么有意義;
如果是C或pascal語言編程,函式一般引數和回傳值通過堆疊進行傳遞,有回傳的函式,會有回傳值的堆疊空間,對于沒有回傳值的函式,編譯器一般不會分配回傳值空間;
其他語言也是一樣,void的函式,不會有回傳值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/284306.html
標籤:單片機/工控
上一篇:請問上面這個編譯命令用哪個可以把 .asm和.c編譯出來
下一篇:關于運放使用問題