c语言函数的副作用 c语言的作用和影响
C语言函数问题
编译器根据对代码进行优化的需要自行规定对实参的求值顺序。有的编译器规定自左至右,有的编译器规定自右至左,这种对求值顺序的不同规定,对一般参数来讲没有影响。但是,如果实参表达式中带有副作用的运算符时,就有可能产生由于求值顺序不同而造成了二义性。你的编译器是自右向左的顺序。
创新互联专注于企业全网整合营销推广、网站重做改版、达日网站定制设计、自适应品牌网站建设、H5页面制作、商城网站开发、集团公司官网建设、成都外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为达日等各大城市提供网站开发制作服务。
c语言为什么有函数危险一说啊? 比如gets()的溢出操作等;
是的,如果这是某书上的做法,那么,我只能说它为你们提供了一个错误的榜样。
这样使用gets()已经发生了溢出!这是gets()不检查数据边界的bug造成的。
另外,“字符串不是总是以'\0'作为串的结束符”,答案是肯定的,不然puts()函数就不能在合适的地方停下来了。这里st[15]被gets()函数赋值为'\0'。这里要说明的是st[15],st[16]是存在而不合法的,因为字符串实际上就等同于指针,类似st[16]是实在的地址但是是不应该被引用的。
为什么这里溢出没有产生错误?可能系统分配内存是以一个最小的大小整段整段的分配(这个我只是猜测)。你可以试着输入的字符串变长一点,就可以看到内存读写出错的提示了,这就是溢出的严重后果!我在dos系统下测试字符串长了直接当机。
验证1:st[15]被赋值为'\0'
#include"stdio.h"
main()
{
charst[15];
printf("inputstring:");
gets(st);
puts(st);
printf("%d",st[15]);
getch();
}
验证2:
#include"stdio.h"
main()
{
charst[15];
printf("inputstring:");
gets(st);
puts(st);
//printf("%d",st[16]);
st[1]='\0';
printf("%s\n",st);
printf("%s",st+2);
getch();
}
同样的建议:拒绝gets(),这本来就是一个有bug的函数!
为什么C语言的子函数不直接用型参参与运算,而是另外声明个局部变量,形参再赋值给这个局部变量?
函数的副作用是最令人头疼的问题
我们都知道形参使得函数可以改变调用者的变量值
所以很容易产生副作用
所以函数设计时应当避免频繁改变形参的值
这就是你所看到的现象:“不直接用型参参与运算”
这样就不会改变调用者的变量值
当然最后还是要改变形参的值,否则形参就没有意义了
还有另一个原因是编译有关的
局部变量是在栈分配空间的
生成的机器代码是近调用的短地址
而形参就很难说了
可能有的编译器,先按值参处理,最后再用结果修改形参
这样做就不用担心“直接用型参参与运算”的会频繁修改形参了
但是却不符合形参的本义
因此编译器会直接引用形参的地址,就会生成远调用的长地址了
把形参编译成长短不同的地址,这在调用系统功能时就有讲究了
你的代码里有“interrupt”字样,我没猜错的话就是中断调用
这时需要长地址还是短地址,那可是一点也不可弄错了
用局部变量就会得到短地址
本文名称:c语言函数的副作用 c语言的作用和影响
分享URL:http://scyanting.com/article/doogcec.html