搜索
bottom↓
回复: 22

函数的指针参数所指向的内容不允许修改?

[复制链接]

出0入0汤圆

发表于 2017-3-21 13:40:46 | 显示全部楼层 |阅读模式
如下是嵌入式系统高级C编程书中的内容:

如书中所说,一个潜在的约定是不对输入指针参数所指向的内容进行任何写入操作.这个如何理解?
例如下面我写的部分代码,我想通过按键的键值key来修改ACTIVE类型变量的值,那我设计的这个函数是不是已经违反了这个"潜在的约定",那假如我想遵守这个约定,我该如何修改我的代码,还是说这个约定本身就由漏洞?
恳请大神指教~~~
  1. typedef struct Active
  2. {
  3.         int ActivePage;
  4.         int ActiveItem;
  5. }ACTIVE;
  6. int SysKey;
  7. ACTIVE SysAct;
  8. void MenuSet(ACTIVE *act, const int key)
  9. {
  10.         switch(key)
  11.         {
  12.                 case KEY_SWI_PRES:   
  13.                         act->ActivePage++;
  14.                         act->ActiveItem = 0;
  15.                         if (act->ActivePage >= SYS_PAGE_NUMBER)
  16.                         {
  17.                                 act->ActivePage = 0;
  18.                         }
  19.                         break;
  20.                 case KEY_INC_PRES:
  21.                         act->ActiveItem++;
  22.                         if (act->ActiveItem >= SysPageTable[act->ActivePage]->ItemNumber)
  23.                         {
  24.                                 act->ActiveItem = SysPageTable[act->ActivePage]->ItemNumber - 1;
  25.                         }
  26.                         break;
  27.                 case KEY_DEC_PRES:
  28.                         act->ActiveItem--;
  29.                         if (act->ActiveItem <= 0)
  30.                         {
  31.                                 act->ActiveItem = 0;
  32.                         }
  33.                         break;
  34.                 case KEY_ENT_PRES:
  35.                         /* */
  36.                         break;
  37.                 default:
  38.                         break;
  39.         }
  40. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2017-3-21 13:50:57 | 显示全部楼层
指针是很有威力的,也特别容易出事,所以提倡指针常量。好多C程序,到今天为止,还经常因为指针出事。

这个是作为一个好习惯来的。

当然你可以不遵守,就跟大括号退格一个道理。

出0入0汤圆

 楼主| 发表于 2017-3-21 14:00:25 | 显示全部楼层
TBG3 发表于 2017-3-21 13:50
指针是很有威力的,也特别容易出事,所以提倡指针常量。好多C程序,到今天为止,还经常因为指针出事。

这 ...

那请教大神:这个函数还有啥比较好的改进的办法嘛(小弟还真想不到其它比较好的办法了)?

出0入0汤圆

发表于 2017-3-21 14:01:50 | 显示全部楼层
擦鞋匠 发表于 2017-3-21 14:00
那请教大神:这个函数还有啥比较好的改进的办法嘛(小弟还真想不到其它比较好的办法了)? ...

不用指针就好了。

出0入0汤圆

发表于 2017-3-21 14:05:48 | 显示全部楼层
擦鞋匠 发表于 2017-3-21 14:00
那请教大神:这个函数还有啥比较好的改进的办法嘛(小弟还真想不到其它比较好的办法了)? ...

给你要修改的数据提供一个static的方法,这样可以避免外部没有约束的直接修改

出0入0汤圆

发表于 2017-3-21 14:06:22 | 显示全部楼层
LZ 还是换本书看吧,最好不要看国内作者写的
就这几行看得云里雾里的,什么“输入指针”、“指针函数内部的代码”都不知道说的是啥

举个简单的例子,memcpy() 函数 dest 所指向的位置的内容不让修改的话,这个函数的功能怎么实现?
像 src 这种只用于获取内容的参数,加个 const 修饰符就行了
  1. void *memcpy(void *dest, const void *src, size_t n);
复制代码

出0入0汤圆

发表于 2017-3-21 14:08:27 | 显示全部楼层
并没有这么个狗屁约定。只有你加了const修饰的指针,才是约定不能修改的。

出0入0汤圆

 楼主| 发表于 2017-3-21 14:11:26 | 显示全部楼层
TBG3 发表于 2017-3-21 14:01
不用指针就好了。

不用指针的话,其实就没有真正修改到这个全局变量SysAct(只是修改了函数内部这个局部变量而已).

出0入0汤圆

发表于 2017-3-21 14:13:40 | 显示全部楼层
擦鞋匠 发表于 2017-3-21 14:11
不用指针的话,其实就没有真正修改到这个全局变量SysAct(只是修改了函数内部这个局部变量而已). ...

你可以直接把变量当作输入参数,不用指针。

出0入0汤圆

发表于 2017-3-21 14:15:05 | 显示全部楼层
TBG3 发表于 2017-3-21 14:13
你可以直接把变量当作输入参数,不用指针。

把变量当参数传入,遇到结构体很大的情况,难免会堆栈溢出系统崩溃。

出0入0汤圆

发表于 2017-3-21 14:17:05 | 显示全部楼层
flamma 发表于 2017-3-21 14:15
把变量当参数传入,遇到结构体很大的情况,难免会堆栈溢出系统崩溃。

他这程序要写的才两个变量而已。

出0入0汤圆

发表于 2017-3-21 14:21:27 | 显示全部楼层
TBG3 发表于 2017-3-21 14:17
他这程序要写的才两个变量而已。

我认为,他问的是一个能通用的解决方法。而且当变量不用指针来传入,并不能达到他希望改变变量的值的目的。

出40入42汤圆

发表于 2017-3-21 14:22:37 | 显示全部楼层
指针该怎么用就怎么用,除非楼主直接修改全局变量。

这种“潜在约定”从来都没有约束到我

出0入0汤圆

发表于 2017-3-21 14:24:16 | 显示全部楼层
flamma 发表于 2017-3-21 14:21
我认为,他问的是一个能通用的解决方法。而且当变量不用指针来传入,并不能达到他希望改变变量的值的目的 ...

很抱歉,写程序没有通用的方法。

所有各种方法,都是各有利弊而已。

程序员所能知道的,就是知道这些利弊,然后用到合适的地方。

但是,好的习惯,能非常大的提高编程效率。

最后加一句:指针出的问题,很不容易发现,也很不容易找出来。

出0入0汤圆

 楼主| 发表于 2017-3-21 14:31:34 | 显示全部楼层
TBG3 发表于 2017-3-21 14:24
很抱歉,写程序没有通用的方法。

所有各种方法,都是各有利弊而已。

thanks

出0入0汤圆

发表于 2017-3-21 14:47:38 | 显示全部楼层
这是哪本书   
我要拉入黑名单

出0入93汤圆

发表于 2017-3-21 14:48:28 来自手机 | 显示全部楼层
TBG3 发表于 2017-3-21 14:13
你可以直接把变量当作输入参数,不用指针。

恰恰你的方法是有问题的。将变量直接当输入参数,可是c语言只能按值传递,结果就是发生了复制,你希望修改的值根本就没有改变。要么就用指针,要么用全局变量,要么改成c++。

出0入0汤圆

发表于 2017-3-21 14:53:55 | 显示全部楼层
takashiki 发表于 2017-3-21 14:48
恰恰你的方法是有问题的。将变量直接当输入参数,可是c语言只能按值传递,结果就是发生了复制,你希望修 ...

你说得对,糊涂了。

直接操作全局变量好了。

出0入0汤圆

发表于 2017-3-21 15:09:22 | 显示全部楼层
少年,读这种书不如读读专业的C语言书籍,然后多看看人家的代码。

出0入93汤圆

发表于 2017-3-21 15:15:50 | 显示全部楼层
你这个教科书说的是没有错的,然而并没有卵用。
他说的是输入参数,只能当作输入不要用作输出或输入输出(因为C语言的限制,输出多变量时要么用结构体,要么用指针)。在其他的语言中可能会用in、out、inout、ref、var、retval之类的指明。
简单的讲,其实就是const XXX *,里面的内容不能改变而已。

出0入0汤圆

发表于 2017-3-21 15:20:20 | 显示全部楼层
你可能是看了假书,代码示例很棒,不需要改。

出0入0汤圆

发表于 2017-3-21 15:25:06 | 显示全部楼层
”不对输入指针参数所指向的内容进行任何写入操作“,这句话本来的意思是:除非是输出数据,否则不要对指针参数指向的地址进行写入操作。

出0入0汤圆

发表于 2017-3-21 15:35:56 | 显示全部楼层
总体是这个意思,因为C语言的指针特别方便,也特别强大,所以,应用不当,也特别容易出问题。C的指针是不检查边界的,一旦越界,就会有不可预测的事件发生,而且很难找出来。

对全局数组,其实也一样。

所以,好的习惯能大幅减少这中问题的发生。

好的习惯一:操作数组也罢,变量也罢,在一段代码里,必须严格定义是输入还是输出,尽管其实可以不用。如果用到函数参数里面去,也必须定义是输入还是输出。

定义为输入时,一般用 const修饰。 如果是输出,就不用管。

为什么用const修饰呢? 用const 修饰,如果你改变其中的数值,就会出现警报。

这种严格区分输入输出的方法,其实是增加了编程工作量,但是增加的很少,在形成习惯后,编程时间几乎不增加,但是因此减少的出错概率,几乎是直线上升的,因此带来的效率提升,是惊人的。

这就是为什么有人写的代码问题少,而有人写的代码问题多的原因。

一般来说,程序出BUG,在很多人那里,低级错误很多,效率较低。

类似习惯在西方程序员那里,比比皆是。另一个有名的例子,就是 1==x


回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 15:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表