我最近寫了一篇文章名為“C語言關于函數傳參和返回值的一些想法”(C語言關于函數傳參和返回值的一些想法-CSDN博客),里面提到了一種觀點就是傳參的參數在函數體內部是只讀的,不能寫它,因為如果寫了,也就是污染了傳參值,再也找不到了。正確的做法是定義對應棧內存(也是就臨時變量),并完成一份拷貝。(拷貝的意思是不同的內存變量,但是數據內容是一致的),在函數體內部使用這一份拷貝來操作。
我最近在拜讀一些前同事寫的函數,發現也有某些特殊情況,直接使用了參數變量進行寫操作,我想補充的是這樣操作的前提是程序員知道對參數進行寫操作,在函數體內部相關操作不會有影響,才能操作。我還是建議在函數體內部準備一份拷貝,操作這一份拷貝變量。
案例1:ucoss-ii中恢復優先級的操作
該案例中傳參的prio如果是OS_PRTO_SELF,那么需要查詢OSTCBCur指向結構體的成員值,然后對prio進行寫操作,也就是對參數變量進行寫操作了,不過寫了prio的新值后對后面的相關操作無影響。正規寫法是應以一個INT8U prio_temp的棧內存,然后將查詢的OSTCBCur->OSTCBPrio值寫到這里面去,然后操作這個變量。
案例2:LCD1602驅動函數,打印字符串
void write_lcd_s(INT8U y,INT8U x,char *s) reentrant
{INT8U add = x;if(y == 0)add += 0x80;else add += 0xc0;lcd_write_com(add);while(*s){lcd_write_data(*s++); /**這里參數也改變了,不過沒有影響,當然常規的寫法是定義一個臨時變量 */}
}
最后while(*s)循環中lcd_write_data(*s++)對參數s的值進行自加運算,用于指向下一個字符。這樣操縱也是可以的,因為參數的傳參的值已經沒用了,而這里需要的是新值。
總結:函數傳參后參數大部分情況是只讀的,因為在函數體內如果對參數再寫操作,傳參值就丟失了,找不到了。如果對參數再次寫操作,而且無影響,也是可以寫的,不過這種寫法的前提就是函數調用的一次傳參數值確定是沒用了。正規的做法就是定義一個臨時變量,然后將參數的值寫到這個臨時變量中,我們在后面的操作去操作這個棧變量。
最后,充分理解“拷貝”的深層含義,意思是:不同的存儲介質,但是存儲大小,存儲類型,以及存儲內容是一致的。