C++でmain関数が空のまま「Hello World」を出力する2つの方法
この記事では、C++でmain関数の中に何も書かずにコンソールへ「Hello World」を出力する方法を解説します。一見不可能に思えますが、C++の言語仕様を活かしたテクニックを使えば簡単に実現できます。
主なアプローチは2つあります。1つ目はグローバル変数を利用する方法、2つ目はクラスのコンストラクタを利用する方法です。それぞれ順番に見ていきましょう。
方法1:グローバル変数とprintf()を使う
printf()関数は、グローバル変数の初期化式として呼び出すことができます。プログラム起動時には、main関数が実行される前にグローバル変数の初期化が行われるため、そのタイミングでprintf()が実行され、「Hello World」が出力されます。
コード例
#include<iostream>
using namespace std;
int a = printf("Hello World");
int main() {
}
出力結果
Hello World
ここでは、printf()の戻り値(出力した文字数)をグローバル変数aに格納しています。グローバル変数の初期化はmain関数よりも先に実行されるため、main関数が空でも文字列が出力されるという仕組みです。
方法2:クラスのコンストラクタを使う
2つ目の方法では、コンストラクタ内で文字列を出力するクラスを定義し、そのオブジェクトをグローバル領域で生成します。オブジェクトが生成されると自動的にコンストラクタが呼び出されるため、main関数が実行される前に「Hello World」が出力されます。
コード例
#include<iostream>
using namespace std;
class my_class {
public:
my_class() {
cout << "Hello World";
}
};
my_class my_obj;
int main() {
}
出力結果
Hello World
どちらの方法も「グローバル変数やオブジェクトの初期化はmain関数の実行前に行われる」というC++の仕様を利用したものです。静的初期化の順序に依存するため、実際の開発現場では扱いに注意が必要ですが、C++の初期化の仕組みを理解するうえで非常に良い学習題材と言えるでしょう。
-
C++で解く「3nスライスのピザ」問題 ― 動的計画法でスライスの合計を最大化する方法
問題の概要 大きさがまちまちの 3n 個のスライスからなるピザがあるとします。私と友人2人は、次のルールに従ってピザを取っていきます。 私が任意のスライスを1枚選びます。 友人のAmalは、私が選んだスライスの反時計回り方向に隣接するスライスを取ります。 友人のBimalは、私が選んだスライスの時計回り方向に隣接するスライスを取ります。 ピザのスライスがなくなるまで、この手順を繰り返します。 各スライスの大きさは、時計回りの順に並べた環状配列 slices として与えられます。求めるのは、私が手にできるスライスの大きさの合計の最大値です。 入出力例 入力が [9, 8, 6, 1, 1,
-
C++で二分木を見やすい形式で2次元配列に出力する方法
本記事では、二分木(バイナリツリー)を m×n の2次元文字列配列として整形して出力する方法を解説します。出力には以下のルールが適用されます。行数 m は、与えられた二分木の高さと一致すること。列数 n は、必ず奇数になること。ルートノードの値は、最初の行のちょうど中央に配置する。ルートノードが存在する行と列によって、残りの領域は「左下」と「右下」の2つの部分に分割される。左側の部分木は左下の領域へ、右側の部分木は右下の領域へそれぞれ出力する。左右の領域は同じサイズとする。片方の部分木が存在しない場合でも、何も出力はしないものの、もう一方の部分木と同じサイズの領域は確保しておく必要がある。ただ