如何在保持代碼的遞歸性質的同時使此函數線程安全?在保持遞歸性的同時使此函數保持安全線程
int foo(char *p)
{
static int i = 0;
if (*p == '\0') return i;
i++;
return foo(p+1);
}
如何在保持代碼的遞歸性質的同時使此函數線程安全?在保持遞歸性的同時使此函數保持安全線程
int foo(char *p)
{
static int i = 0;
if (*p == '\0') return i;
i++;
return foo(p+1);
}
#include <iostream>
using namespace std;
int foo(char* p, int start)
{
if (*p == 0) return start;
return foo(p+1, start+1);
}
int main()
{
char test[] = "HI THERE";
cout << foo(test, 0);
return 0;
}
這有額外的優勢,允許尾遞歸優化(即函數調用可以轉換爲循環) – 2013-02-28 20:16:36
這不是等同的,雖然'我'得到重置每個電話。 – Pubby 2013-02-28 20:19:42
@Pubby不等同,但可能是OP真正想要的。 :-) – 2013-02-28 20:38:23
在C++ 11,你可以使用thread_local
:
int foo(char *p)
{
thread_local int i = 0;
if (*p == '\0') return i;
i++;
return foo(p+1);
}
功能是,我希望,只是舉個例子作爲i=0
將只執行一次(在你的例子)並在我的示例中每個線程一次。
舊版編譯器有時支持將static __thread
作爲C++之前的替代版本。
int foo(char *p, int i = 0)
{
if(*p == '\0')
return i;
return foo(p+1, i+1);
}
遞歸是很好,所有,但它可以低於循環,如果創建堆棧幀。這是導致堆棧溢出的最簡單方法。我會建議擺脫它。以下是簡單和容易更快:
int foo(char *p)
{
return strlen(p);
}
或者更好的是,只需撥打strlen
直接擺脫foo
。
請注意,這是非常不安全的。如果'\0'
不來?你只會讀到誰知道什麼......
+1爲'i'的默認值。但'strlen'就像「不安全」一樣(除了它不會在超長字符串中堆棧)...... p參數指向NUL終止的字符串是一個(不可測試的)前提條件。 – 2013-02-28 20:31:32
這將工作在通用庫嗎? – user2115365 2013-03-01 08:43:49
@ user2115365'strlen'是一個通用的庫... C++標準庫。它的工作原理。 – David 2013-03-01 13:18:22
通過'我'作爲第二個參數。但爲什麼??? – 2013-02-28 20:05:09
可能會更精緻一點?謝謝。 – user2115365 2013-02-28 20:06:24
[你稱之爲線程安全的東西是什麼 - Eric Lippert](http://blogs.msdn.com/b/ericlippert/archive/2009/10/19/what-is-this-thing-you-call- thread-safe.aspx) – 2013-02-28 20:16:17