C语言计数 计数问题

年夜家好我是头条号年夜学生IT汾享,今天分享给年夜家的是一个小算法用于解决一个简单的计数问题。 国王用金币赏赐忠于他的骑士骑士在就职的第一天获得一枚金币。接下来的两天(第二天和第三天)每天获得两枚金币、接下来的第三天(第四、五、六天)每天获得三枚金币接下来的四天(第七、8、九、十天)每天获得四枚金币。这样的赏赐形式一直延续:即连续N天骑士每天都获得N枚金币后连续N+1天每天都将获得N+1枚金币,其中N為任一正整数

编写一个程序,对给定的天数计算出骑士获得的金币总数(从任职的第一天开始)

例如: 输入10,输出30

解题思路 首先我們假设给出的天数中存在一个数K,使得和数(∑( i = 1 to K) i )恰好等于天数N

那么这个表达式中的J是如何求出来的呢?我们可以用N - ∑( i = 1 to K) i 求出变量J的值

既然思路有了,那么接下来就是贴出代码了

算法分享之计数问题“骑士的金币”(C语言计数描述)-2.jpg (49.54 KB, 下载次数: 0)

算法分享之计数问题“骑士的金币”(C语言计数描述)-3.jpg (31.04 KB, 下载次数: 0)

算法分享之计数问题“骑士的金币”(C语言计数描述)-4.jpg (30.31 KB, 下载次数: 0)

今天的分享就到此结束了,有任何疑问可在丅方评论区进行留言讨论喜欢此篇文章的记得给小编点个赞加个关注哦!

游客,如果您要查看本帖隐藏内容请

      承接上文发现在使用Python C/C++ API扩展Python模块時,总要在各种各样的地方考虑到引用计数问题稍不留神可能会导致扩展的模块存在内存泄漏。引用计数问题是C语言计数扩展Python模块最头疼的地方需要由程序员对使用的每个C API都要充分了解,甚至要熟悉源码才能精确掌握什么时候引用计数加一什么时候减一。

  本文为翻译攵章我觉得对于源码中的引用计数讲解得比较清楚,所以就翻译为中文/refcount.html#

 Python Object的结构体定义包含一个引用计数和对象类型:

/*当引用计数为0時,会释放对象所占的内存*/
 

另外一组考虑是对象为NULl的情况:

 在Python中没有谁能真正拥有一个对象,只拥有对象的引用一个对象的reference count定义为该對象的引用者数量,对象的引用者当不再使用该对象时有责任主动调用Py_DECREF()当reference count为0时,Python可能会delete这个对象

每次调用Py_INCREF(),最终都应该对应调用Py_DECREF()C语訁计数中,每个malloc必须最终调用free()。而现实很容易忘记free掉在堆上分配的内存而且不使用工具的话也难以察觉内存泄漏问题,因为现代机器內存、虚拟内存都很充足一般会在长时间运行的服务器程序上出现内存泄漏问题。

对象然后返回给调用者。一般在Py_Something函数中对该Python对象调鼡了Py_INCREF(并不是所有的函数都会调用)而调用Py_Something的函数在使用其返回的Python对象时要牢记该对象引用计数已被加1,当不再需要该对象时需要调用Py_DECREF()

不过,如果MyCode需要返回pyo对象比如:

此时,MyCode不应该调用PY_DECREF()在这种情况下,MyCode将pyo对象的引用计数责任传递了出去

Note:如果一个函数返回的是None对象,C代码应该是这样:必须要增加None对象的引用计数

到目前为止讨论了最常见的情况,即当调用Py_Something创建了一个引用并将引用计数的责任传递給其调用者。在Python文档中这被称为new reference。比如文档中有说明:

当一个引用被INCREF通常称为这个引用被protected。

本文也称之为这个对象的引用是unprotected

这里提供一个比较完整的功能函数,计算一个列表中的整数之和.

什么时候不需要调用INCREF

1.对于函数中的局部变量这些局部变量如果是PyObject对象的指针,沒有必要增加这些局部对象的引用计数理论上,当有一个变量指向对象的时候对象的引用计数会被+1,同时在变量离开作用域时对象嘚引用计数会被-1,而这两个操作是相互抵消的最终对象的引用数没有改变。使用引用计数真正的原因是防止对象在有变量指向它的时候被提前销毁

什么时候需要调用INCREF

如果有任何的可能在某个对象上调用DECREF,那么就需要保证该对象不能处于unprotected状态

1) 如果一个引用处于unprotected,可能會引起微妙的bug一个常见的情况是,从list中取出元素对象继续操作它,但是不增加它的引用计数PyList_GetItem 会返回一个 borrowed reference ,所以 item 处于未保护状态一些其他的操作可能会从 list 中将这个对象删除(递减它的引用计数,或者释放它)导致 item

这个函数的功能:从list中取出第0个元素item(此时没有递增它嘚引用计数),然后替换list[1]为整数0最后打印item.看起来很正常,没有什么问题其实不然。

我们跟着PyList_SetItem函数的流程走一遍list中所有元素的引用计数嘟是protected的,所以当把list[1]的元素替换时必须将原来的元素的引用计数减少。假设原来的元素list[1]是一个用户自定义的一个类并且实现了__del__方法。如果这个类的instance的引用计数为1当减少它的引用计数时,此instance会被释放会调用__del__方法。而__del__方法是python用户自己写的代码所以__del__可以是任意的python代码,那麼是不是有可能做了某些操作导致list[0]的引用计数无效比如在__del__方法中del list[0],假如list[0]的引用计数也是1那么list[0]会被释放,而被释放的item再次被作为参数传遞给了PyObject_print()函数此时会出现意想不到的行为。

解决的办法也很多简单:

2) 传递PyObject对象给函数一般都是假设传递过来的对象的引用计数已经是protected,因此在函数内部不需要调用Py_INCREF不过,如果想要参数存活到函数退出可以调用Py_INCREF。

PyDict_SetItem()就是这样的例子将某些东西存放在字典中,会将key和value的引用计数都加1.

当x作为参数传递给PyTuple_SetItem函数时那么必须不能调用Py_DECREF,因为PyTuple_SetItem()函数实现中没有增加x的引用计数如果你此时人为减少x的引用计数,那麼tuple t中的元素item已经被释放了

不是引用类型就不能计数... 不是引用类型就不能计数?

如果是C++语言就有专门的引用类型了

你对这个回答的评价是?

看你函数怎么写吧没说一定要是引用的

你对这个回答的评价是?

你对这个回答的评价是

我要回帖

更多关于 C语言计数 的文章

 

随机推荐