毎度です(^^;
ちょっと気になったことがあったので・・・
かなりはしょりますが・・・
kansu(char *moziretsu);
char global[12];
WinMain( ・・・・ )
{
}
WinProc( ・・・・ )
{
char InProc[12];
kansu(InProc);
kansu(Global);
MessageBox(NULL, Global, "グローバル", MB_OK);
MessageBox(NULL, InProc, "プロシージャ内", MB_OK);
}
kansu(char *moziretsu)
{
char buf[12];
[何らかの文字列をbufに格納]
strcpy(moziretsu, buf);
}
といったように、外部関数などで文字列を取得しようとしたときに、グローバルで宣言した変数は正常に表記されるのですが、プロシージャ内で宣言した文字列変数は、半角で「フフフフフフフフフフ・・・・」とでてしまいます。
プロシージャ内で宣言してしまうと、アドレスがずれたり、壊れたりしてしまうのでしょうか?
何やら初心者的な質問かもしれなくてごめんなさい・・・。
プロシージャ内だけで使用すればよい文字列変数を、わざわざグローバルで宣言しなければならないのがむずがゆくて・・・
そんなことはありません。きっと、他にバグがあります。
#include <stdio.h>
void setstring(char *p) {
strcpy(p, "Hello!");
}
int main() {
char str[12];
setstring(str);
printf("%s\n", str);
return 0;
}
まったく正常(=期待通り)です。
tetrapodさん
記入されたソースは、プロシージャはいっさいでてきませんが・・・
私が言っているのは、WinProcやDlgProc内で文字列変数を宣言した時の話をしているのですが・・・。
ちなみに、作成した外部関数内で、strcpyした後の文字列(私が書いた例で言うと「moziretsu」になりますが)をMessageBoxで出力すると、思ったとおりの値がでますが、プロシージャ内で宣言した文字列にその関数を使用し、MessageBoxで出力すると、おかしな表記になるということです。
全く同じ構成で、その文字列だけをグローバルで宣言すると正常に表示されます。
> 記入されたソースは、プロシージャはいっさいでてきませんが
出てきますよ。main プロシージャと setstring プロシージャが。
> 私が言っているのは、WinProcやDlgProc内で文字列変数を宣言した時の話をしているのですが
であれば「ウィンドウプロシージャ」とか「ダイアログプロシージャ」って書かないとわからないと思います。
#ちなみに WndProc では? まぁ、関数名は自由ですが。
WinProc で、kansu() の呼び出しと MessageBox での表示は、ひとつのメッセージの処理内で行っていますか?
でない場合、InProc は WinProc が呼ばれるたびに初期化されますよ。
(;´Д`)y-~~ わからんヤシだな。
もしプロシージャだのコールバックだのが関係あんなら,
tetorapod 氏もそこらへんを指摘しただろうよ。
例外がねーわけじゃねーが,上級者でもない限り気にするもんでもねーし。
以下のコードを試してみること ( ´Д`)y-~~
#include <windows.h>
#include <string.h>
void kansu (char *moziretsu) {
char buf[12];
strcpy (buf, "moziretsu");
strcpy (moziretsu, buf);
}
char Global[12];
LRESULT __stdcall WinProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
char InProc[12];
if (msg == WM_NCCREATE) {
kansu (InProc);
kansu (Global);
::MessageBox (NULL, Global, "グローバル", MB_OK);
::MessageBox (NULL, InProc, "プロシージャ内", MB_OK);
return FALSE;
}
return ::DefWindowProc(hwnd, msg, wparam, lparam);
}
int __stdcall WinMain (HINSTANCE hinst, HINSTANCE, LPSTR, int) {
WNDCLASSEX wx = { sizeof(WNDCLASSEX), 0, WinProc, 0, 0,
hinst, ::LoadIcon(NULL, IDI_WINLOGO), ::LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_BTNFACE + 1), NULL, "MoziretsuTestClass", NULL };
ATOM atom = ::RegisterClassEx(&wx);
if (! atom) return 0;
::CreateWindowEx (0, reinterpret_cast<LPCTSTR>(atom), "", 0,
0, 0, 0, 0,
0, 0, hinst, 0 );
return 0;
}
シャノンさん
> であれば「ウィンドウプロシージャ」とか「ダイアログプロシージャ」って> 書かないとわからないと思います。
・・・ですね。
大変失礼しました。
> #ちなみに WndProc では? まぁ、関数名は自由ですが。
これもおっしゃるとおりですね(^^;
WndProcです。
> WinProc で、kansu() の呼び出しと MessageBox での表示は、ひとつのメッ> セージの処理内で行っていますか?
> でない場合、InProc は WinProc が呼ばれるたびに初期化されますよ。
それだ!!
そう言うことだったんですね〜。
一つのメッセージの処置内で行っていなかったです。
ありがとうございます。
nonameさん
私がよく分かっていないのは自分でもわかっています。
だからこそ掲示板に質問しているのでは?
言い方が少しひどいのでは・・・(T_T)
(;´Д`)y-~~ 悪かったよ。
>> WinProc で、kansu() の呼び出しと MessageBox での表示は、ひとつのメッセージの処理内で行っていますか?
>> でない場合、InProc は WinProc が呼ばれるたびに初期化されますよ。
> 一つのメッセージの処置内で行っていなかったです。
ちなみに、static 変数にしても OK です。
他にも、グローバル以外にも方法はいろいろあります。
参考までに。
デバッガ内で「フフフフ…」と表示されているのは、単にその配列変数が
未初期化であることを示しています。VC++デバッガは、デバッグモード時、
未初期化の変数を0xCC(2進数だと、11001100)で初期化するためです。
ツイート | ![]() |