我最近写了一篇文章名为“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的值进行自加运算,用于指向下一个字符。这样操纵也是可以的,因为参数的传参的值已经没用了,而这里需要的是新值。
总结:函数传参后参数大部分情况是只读的,因为在函数体内如果对参数再写操作,传参值就丢失了,找不到了。如果对参数再次写操作,而且无影响,也是可以写的,不过这种写法的前提就是函数调用的一次传参数值确定是没用了。正规的做法就是定义一个临时变量,然后将参数的值写到这个临时变量中,我们在后面的操作去操作这个栈变量。
最后,充分理解“拷贝”的深层含义,意思是:不同的存储介质,但是存储大小,存储类型,以及存储内容是一致的。