Version 6.02
コンパイルエラーをなくす!
「さて、今回はコンパイルエラーについて」
『コンパイルしたときに出るエラーで、これはバグじゃないんだよね』
「そうです。そしてまず一番重要なこと。コンパイルエラーは論外!!」
『論外!?』
「そう。前回言ったように、コンパイルエラーの場合には Exe が作られま
せん」
『つまり商品ってゆーか製品ってゆーか、そういうのすらない状態だもん
ね』
「だから、まず〈プログラマー〉と言える最低ラインが、どんなコンパイル
エラーが出てもクリアできること、って言えるかな」
『……それってすんごく大変じゃない?』
「確かにそうかもしれないけど、実際にアプリが作れなきゃ、お話にならな
いでしょ」
『確かに』
「ま、実際大変だけどね。今日は基本的なことだけ。コンパイルエラーの原
因にはかなり色々とあるから、それは少しずつ」
『はーい』
「じゃ、基本的なコンパイルエラーから。一番多いのが書き間違い、つまり
スペルミス」
iny i = 100;
『 int が iny ね。でも、 int とかは色が変わるでしょ?』
「そう、 int とか for とか、初めから用意されてる単語は【オプション】
の【書式】で色を変えられるから大丈夫なんだけど」
『ってことは、色の変わらない……変数名とか?』
「変数名が多いかな。途中で変数名を変えたりしたときとか。そういう場合
には、関数全体を選択して、選択範囲内で置換した方がいいかな」
『他に見逃しやすいのは?』
「まず似た形状の文字。 1 (いち)と l (小文字のエル)、 0 (ゼロ)
と O (大文字のオー)とか。特に、本に載ってるのを書き写すときに」
『確かに分かりにくい本って多いよね……』
「あと、いわゆる全角文字。 A をAって書いたり、半角スペースを全角ス
ペースで書いたり」
『同じアルファベットなのに、ダメなんだ』
「前にやったでしょ、文字は数字」
『 A とAじゃその数字が違うからダメってことね』
「で、さっきの iny の例だとこれだけエラーが出ます」
error C2065: 'iny' : 定義されていない識別子です。
error C2146: 構文エラー : ';' が、識別子 'i' の前に必要です。
error C2065: 'i' : 定義されていない識別子です。
『うわ、いっぱい』
「 iny のせいで、 i って変数自体が作られないからね。これで分かること
はふたつ。まず〈定義されていない識別子です〉っていう、分かりにくいエ
ラーが出るってこと」
『これじゃなんかよく分かんないね。そのあとの i のとこにも同じエラー
が出てるし』
「コンパイルエラーははっきしいって原因が分かりにくいから。ここではそ
ういう原因の分かりにくいエラーを中心に紹介するからね」
『はーい』
「あと、コンパイルエラーは必ず上から直す、ってことが重要」
『そっか、 iny を直せばあとは全部消えるんだもんね』
「ここでは削除してるけど、エラーが出た行が表示されるし、そこをダブル
クリックすればその行に飛んでくれるから」
『結局は、打ち間違いに気を付けなきゃいけないんだよね』
「そういうわけでもないよ。 VC には〈自動補完機能〉が付いてるから、た
とえば……」
int iUserDataNo = 100;
「この iUserDataNo を入力するときには、 iUser くらいまで入力して、デ
フォルトなら Ctrl + スペースキーで単語全体が入力されるから」
『おお! でも iUser 以前が間違ってたら』
「そのときはうまく補ってくれないから、それで入力が間違ってるって分か
るでしょ」
『あ、そっか』
「あとクラスのメンバ関数とか入力するときも、 . (ピリオド)や -> を
入力すると一覧が出るから」
『それから選べばいいんだ』
「こういった機能を活用すれば、スペルミスはぐっと減るはず」
『なるほど』
「ただ、 ; (セミコロン)と : (コロン)には注意」
『これは分かりにくい!』
「同じ演算子だし、見た目にも似てるし、最悪なのが、キーボードでも隣っ
ていう点」
『打ち間違えたらヤバイね……』
「初めのうちは一番注意した方がいいかも。さて、コンパイルエラーで同じ
く多いのが、型の問題」
『そうそうそう! ポインタとかうまくいかないことが多いんだけど』
「まず、クラスをメンバ変数として持つクラスの例」
// あるクラス。
class CInner
{
public:
int m_i;
};
// そのクラスをメンバ変数として持ってみます。
class COver
{
public:
CInner m_cInner;
}
『さて、ここで COver のポインタを返す関数があったとします』
COver *GetCOver()
{
static COver s_cOver;
return &s_cOver;
}
『 static ってやったっけ』
「あ、やってないね。 static っていうのは〈たった一度しか作られない変
数、作られたらずっと残る変数〉にする指定。普通の変数だと、 GetCOver()
が終了したら」
『なくなっちゃうね。だからこういうふうにポインタを返すのはいけないん
だよね』
「そう。ところが static を付けた変数は、関数が終了してもなくなりませ
ん」
『なくならない?』
「メモリ上にずっと残るってこと。で、次に GetCOver() が呼ばれたときも
その残ってた変数が使われます」
『へー、だからこういうふうにポインタを返せるんだ』
「ま、使い道とか詳しいことはまた今度。で、そのポインタを受け取ってみ
ます」
void CDebugDlg::OnButton1()
{
COver *pcOver = GetCOver();
// さて?
}
「さて問題。 pcOver を使って CInner::m_i にアクセスするにはどうすう
ればいい?」
『えーっと、まず pcOver のメンバ変数 m_cInner にアクセスするんだよ
ね。だから』
pcOver.m_cInner
「違う違う、ポインタの時は . じゃなく -> を使うから」
『あ、そっか』
pcOver->m_cInner
『で、次に m_cInner を通して m_i にアクセスするんだから』
pcOver->m_cInner->m_i
「そうじゃないんだよねー」
『げ、やっぱ? じゃあ』
pcOver->m_cInner.m_i
「そう、そっち」
『そうなんだ……でもどうして?』
「順に考えればいいだけ」
pcOver
「これはポインタだから、 m_cInner には -> を使えばいいでしょ」
pcOver->m_cInner
『ここまではいいんだけど』
「そしたら、 pcOver-> を無視するのがコツ。つまり」
m_cInner
「しか見ない!」
『それっていーの?』
「いいのっていうか、そうなんだから。 pcOver->m_cInner は〈 pcOver の
メンバ変数の m_cInner 〉って意味でしょ。でも〈 pcOver のメンバ変数
の〉って部分に関係なく、 m_cInner は m_cInner でしょ」
『???』
「うーん、たとえば、ある〈哲也君〉がいたとして、それを〈山田さんの家
の哲也君〉と呼ぼうが〈翔君の弟の哲也君〉と呼ぼうが、それが〈哲也君〉
には変わりないでしょ。それと同じ」
『分かったような分かんないような……そうだ、つまり、 m_cInner として
見れば、これはポインタじゃないから』
pcOver->m_cInner.m_i
『ってなるってことなんだよね。じゃーさ』
pcOver->m_cInner->m_i
『ってなるのはどういうとき?』
「そりゃもちろんポインタの時」
class COver2
{
public:
CInner *m_pcInner;
};
『そっか、メンバ変数がポインタって場合もあるんだ』
「これなら」
pcOver2->m_pcInner->m_i;
「って、ポインタとしてアクセスすればいいわけ」
『なるほど』
/*
Preview Next Story!
*/
『どれが正体か、見分けるの難しいね』
「次回もそうだよ?」
『げげ、もしかしてプログラミングってそういうのばっか?』
「いかに頭がこんがらがらないかが鍵かも」
『そんな〜』
「というわけで次回」
< Version 6.03 別名に注意! >
『につづく!』
「別名なんて嫌い! そのまんまの名前賛成!!」
『じゃ、〈水希ちゃん〉ってちゃん付けしないで』
「ヤダ」