dポイントプレゼントキャンペーン実施中!

CやC++についてまだよくわかっていないのですが、関数内に関数を書くと
「コンパイラ エラー C2601 ローカル関数の定義が正しくありません。」となります。
そこで以下の子スレッドのように関数を関数外に定義して、利用する変数も関数外に定義しました。
変数を外部に定義すると、メモリアクセスになるので、できるだけ避けたかったために
関数内に子スレッドを最初書いていたのですが、何か良い方法はありますか?

子スレッドの引数や戻り値を利用できればいいのですが、そんなことできるのかもわかりません。

あと、関数を配列のように定義できるのでしょうか?
test_thread_0, test_thread_1と逐一書くのが面倒です。

int sum1 = 0, sum2 = 0;

unsigned __stdcall test_thread_0(void *lpx) // lpxはおまじない?
{
// 全て足す
for (int i = ST1; i <= EN1; i++){
sum1 += Data1[i] * Data2[i];
}
return 0; // 正常という意味?
}

unsigned __stdcall test_thread_1(void *lpx)
{
// 全て引く
for (int i = ST2; i <= EN2; i++){
sum2 -= Data1[i] * Data2[i];
}
return 0;
}

A 回答 (2件)

そもそも関数内の子関数では、スタックを親の関数と共用する前提がありますので、スレッド化することは不可能です。

スレッドは専用のスタックを持つことを覚えておいてください。

スレッドは親関数である必要があり、基本的にグローバル領域のメモリかmallocやnewしたヒープ領域のメモリしか参照出来ません。
ローカル変数を受け渡すことは不可能ではないですが、スレッドが動いている間は、そのローカル変数を宣言した関数を抜けることが出来ません。関数を抜けるとローカル変数が保障されなくなるからです。これ理解できますか?

値を返す場合は、CreateThreadの第4パラメータに_biginThreadなら第3パラメータで指定されたポインタ値をスレッドに渡していますので、これを使います。
>unsigned __stdcall test_thread_0(void *lpx) // lpxはおまじない?
このlpxです。
パラメータを渡して、かつ戻り値を受け取りたいなら、lpxに渡すポインタを構造体にすれば複数のポインタを渡すことが出来るので解決できます。理解できますか?

>あと、関数を配列のように定義できるのでしょうか?
>test_thread_0, test_thread_1と逐一書くのが面倒です。
関数参照配列は作れますが、そんなに呼び出すんでしょうか?
配列にするメリットは、添え字で呼び出し関数を切り替えるプログラムを書けるアルゴリズムだった場合だけです。

あと、sum1をグローバル参照にしたくなったとのことですが、ローカル変数にlsumとかを作って計算はそこで行い。最後にsum1=lsum;とすれば解決します。
それとスレッドで参照や変更する変数は、volatile宣言を必ずしてください。
http://proger.blog10.fc2.com/blog-entry-20.html

前に紹介した「APIで学ぶWindows徹底理解」は読みましたか?中途半端な知識でスレッドをやるより、理解が早まるのでぜひ読んでくださいね。
スレッドは覚えること理解することが沢山ありますのでがんばってください!
    • good
    • 0

GCCでは、関数内に関数を書くこともできますが、それは置いておいて...



C++であれば、次のようにすれば、関数内に関数を書くことができます。

void func1()
{
 struct A
 {
  static void func2()
  {
   ...
  }
 };

 A::func2();
}

この回答への補足

VC6やVC2005では、無理なのでしょうか?
コンパイラによって、こんな大きな違いがあるとは驚きました。

補足日時:2007/10/19 14:58
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!