C++ 再入門 その1 最初の一歩から大混乱
書こう書こうと思いつつ、なかなか手を付けられなかったC++ですが、年度も新しくなったことですし、ボチボチのペースで始めてみたいと思います。
とりあえずコンパイルして実行するための環境を作らなければならないのですが、ここが使っている環境やら個人的な趣味でいろいろな組み合わせがあるので、そこはネットを検索したり、最近流行りのAIに尋ねて構築してください。私は手元のWindowsでVisutal StudioとLinux仮想マシンでのg++で確認して進めてみます。
最初の一歩といえば、お馴染みの”Hello World!”なんですが、Visual Studioのウィザードが作ってくれるコードは以下のようなコードです(余分なコメントは削除済み)。
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
}
C言語であれば printf(”Hello World!\n”); となるところが、何やら cout というキーワードや << という演算子がいきなり登場します。よく見ればインクルードするファイルも”stdio.h”ではなく”iostream”となっています。末尾が”.h”で無くなっていますね。もちろんコードを書いているファイルも末尾が”.c”ではなく”.cpp”にしますけどね。
いろいろなWEBサイトを探すと、だいたい同じようなコードが例に出ているのですが、main関数の最後にキチンと return 0; が書いてあるのは置いておくとして、文字列の最後に改行を示す”\n”ではなく、endl というキーワードになっているものも見かけます。
#include <iostream>
using namespace std;
int main(){
cout << "Hello World!" << endl;
return 0;
}
それに、std という名前が違うところに書かれていたり、書かれていなかったりします。
もちろんC++でC言語と同じコードを”.cpp”の拡張子で書いてコンパイルして実行することはできたりします。
#include <stdio.h>
int main() {
printf("Hello World!\n");
}
まず「この違いは何なんだろう」というところが最初の一歩ですかね。
この違いは、サンプルコードのように静的な文字列を出力するのではなく、printfであれば%dなどを使って変数の値を出力するようにすると明らかになります。
まずはC言語のままprintfを使うと、以下のお馴染みのコードになります。
#include <stdio.h>
int main() {
int i = 10;
printf("i=%d\n", i );
}
これをC++らしく書くと
#include <iostream>
int main() {
int i = 10;
std::cout << "i=" << i << std::endl;
}
となります。あれぇ?演算子を使って書くのは良いのだけど”%d”といった書式指定子はどこに行ったの?となるわけです。単に i と書けばちゃんと10と出力されるのは何故?となるわけです。
いや、俺は整数の値を16進で出したいんだと思えば printf だったら”%x”が使えたはずなんだけど、C++でどうするのかと言えば、
#include <iostream>
int main() {
int i = 10;
std::cout << "i=" << std::hex << i << std::endl;
}
と書くのですが、ここで hex というキーワードが登場するわけです。いったいC++はどういう仕組みでこれらを解釈しているのかがさっぱりわからないというところでしょうかね。
ポイントはprintfは引き数の型を理解せず、どんな型の変数であっても、書式指定子で示された型であると解釈して値を表示していたのですが、cout というキーワードに << 演算子で値を送り込む時は、ちゃんと変数の型情報を使って適切な表示を行ってくれるということです。
いったい何が起こっているんでしょう。これをキチンと理解するには演算子であるとか名前空間がどうのこうのをいきなり理解しなければなりません。とりあえず見よう見まねでコードは書けそうですが、この時点でもうハードルが上がっている気がしてしまいますよね。
ということで、この辺から進めたいと思います。いやぁ次はいつになることやら。ちゃんと続くのか自分でも心配。
ヘッダ画像は、以下のものを使わせていただきました。
https://commons.wikimedia.org/wiki/File:ISO_C%2B%2B_Logo.svg
Jeremy Kratz - https://github.com/isocpp/logos, パブリック・ドメイン, https://commons.wikimedia.org/w/index.php?curid=62851110による