計算機很多操作都遵循IPO原則,程式設計亦如此,輸入→處理→輸出。輸入就是函式的入參,輸出就是函式的返回值,處理過程就是函式的實現。可以沒有輸入,但不能沒有輸出,沒有輸出就好似函式幹了一大堆事卻沒有產出,那是沒有意義的。
但輸出並不一定都得用函式的返回值來體現。
或者說函式不一定都要有返回值,所有的函式都是void照樣能寫程式。很多C函式都透過引數來作函式輸出,通常這些引數都是傳遞指標,函式內部透過指標修改內容。
所以微軟還專門搞了個_in_和_out_的宏來標記引數用來做函式的輸入還是輸出。
C語言返回值要麼是基本型別,要麼是指標型別。基本型別很簡單,指標型別的返回值有很多坑了:
1、這個返回的指標首先不能是指向函式執行棧裡的值,因為函式執行完棧記憶體就被回收了,這個指向棧記憶體的指標就成了懸掛指標,使用懸掛指標會出現不確定的現象。
2、這個返回的指標最好不要是指向全域性區的值(比如全域性變數或static),因為你多次呼叫函式返回的是同一塊記憶體的指標,外面的呼叫者並不知道兩次返回的指標指向同一塊記憶體,就會導致A修改了指向的值B不知道這次修改。會增加程式的維護難度。真要使用,介面文件裡必須詳細說明。
3、這個返回的指標是呼叫malloc等函式動態申請的堆記憶體。這種情況下上面說的兩種問題就都沒有了,但函式的註釋或文件裡一定要明確說明怎麼釋放這段記憶體,否則就會記憶體洩漏。像windows API有很多這樣成對的函式CreateXxx和DestroyXxx。這些成對的函式在MSDN都有很很完善的文件說明。
用了C 和cpp就知道這種痛苦,換了Java就再也不想換回去了。
計算機很多操作都遵循IPO原則,程式設計亦如此,輸入→處理→輸出。輸入就是函式的入參,輸出就是函式的返回值,處理過程就是函式的實現。可以沒有輸入,但不能沒有輸出,沒有輸出就好似函式幹了一大堆事卻沒有產出,那是沒有意義的。
但輸出並不一定都得用函式的返回值來體現。
或者說函式不一定都要有返回值,所有的函式都是void照樣能寫程式。很多C函式都透過引數來作函式輸出,通常這些引數都是傳遞指標,函式內部透過指標修改內容。
所以微軟還專門搞了個_in_和_out_的宏來標記引數用來做函式的輸入還是輸出。
C語言返回值要麼是基本型別,要麼是指標型別。基本型別很簡單,指標型別的返回值有很多坑了:
1、這個返回的指標首先不能是指向函式執行棧裡的值,因為函式執行完棧記憶體就被回收了,這個指向棧記憶體的指標就成了懸掛指標,使用懸掛指標會出現不確定的現象。
2、這個返回的指標最好不要是指向全域性區的值(比如全域性變數或static),因為你多次呼叫函式返回的是同一塊記憶體的指標,外面的呼叫者並不知道兩次返回的指標指向同一塊記憶體,就會導致A修改了指向的值B不知道這次修改。會增加程式的維護難度。真要使用,介面文件裡必須詳細說明。
3、這個返回的指標是呼叫malloc等函式動態申請的堆記憶體。這種情況下上面說的兩種問題就都沒有了,但函式的註釋或文件裡一定要明確說明怎麼釋放這段記憶體,否則就會記憶體洩漏。像windows API有很多這樣成對的函式CreateXxx和DestroyXxx。這些成對的函式在MSDN都有很很完善的文件說明。
用了C 和cpp就知道這種痛苦,換了Java就再也不想換回去了。