Project_OKI’s diary

エンジニアの勉強ブログ

C++学習4(Autoについて)

1. 目的

C++ の auto キーワードについて、型推論の仕組みと使い方、注意点を整理する。

2. 目次

3. 概要

auto は変数の型をコンパイラに自動で判断させるキーワード。

型名の記述を省略できる一方、意図しない型になる場合もあるため注意点を合わせて確認する。

4. 内容

4.1 auto キーワード

4.1.1 auto とは

型をコンパイラに自動で判断させる仕組み。

  • auto x = 10; → int と判断される
  • auto y = 3.14; → double と判断される
  • auto z = true; → bool と判断される
#include <iostream>
using namespace std;

int main() {
    auto x = 10;   // int と判断される
    auto y = 3.14; // double と判断される
    auto z = true; // bool と判断される

    cout << x << endl;
    cout << y << endl;
    cout << z << endl;
    return 0;
}

結果:https://paiza.io/projects/vYg_Za21eG2lxF8OOkkgDQ?language=cpp

 

4.1.2 なぜ便利か

型名が長いときに特に役立つ。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> scores = {10, 20, 30};

    // 型を自分で書く(長い)
    std::vector<int>::iterator it1 = scores.begin();

    // auto を使う(短い)
    auto it2 = scores.begin();

    cout << *it1 << endl;
    cout << *it2 << endl;
    return 0;
}

結果:https://paiza.io/projects/zK1wXRu6qFEtDtmObp6aXg?language=cpp

 

4.1.3 auto を使う場合の注意点

(1) 初期値が必ず必要

初期値がないと型を決められないため、コンパイルエラーになる。

int main() {
    // auto x; // エラー:型が決められない(コメントを外すとコンパイルエラーになります)
    auto x = 0; // OK
    return 0;
}

結果:https://paiza.io/projects/EkGeSIQoi7l5H3bzQSXEPg?language=cpp

 

(2) 意図しない型になることがある

整数同士の割り算は int のまま扱われ、小数点以下が切り捨てられる。

#include <iostream>
using namespace std;

int main() {
    auto a = 5;       // int
    auto b = 5.0;     // double
    auto c = 1 / 2;   // 結果は 0(int の割り算)
    auto d = 1.0 / 2; // 結果は 0.5(double の割り算)

    cout << c << endl; // 0
    cout << d << endl; // 0.5
    return 0;
}

結果:https://paiza.io/projects/7JhQAcWe5Nz7tIW55JxGPg?language=cpp

 

(3) 文字列の型に注意

"..."const char* と判断されるため、string 型のメソッドは使えない。

#include <iostream>
#include <string>
using namespace std;

int main() {
    auto s1 = "hello";         // const char*(C言語の文字列)
    auto s2 = string("hello"); // string(C++の文字列)

    // s1 は string のメソッドが使えない
    // cout << s1.length(); // エラーになる

    cout << s2.length() << endl; // OK:5 と表示
    return 0;
}

結果:https://paiza.io/projects/C0UcgENReChhMR8OfehdAw?language=cpp

 

(4) 参照と組み合わせるとき

auto は値のコピーになる。参照にしたい場合は auto& と書く。

#include <iostream>
using namespace std;

int main() {
    int score = 100;
    auto a = score;  // int のコピー(score とは別物)
    auto& b = score; // int& の参照(score の別名)

    a = 200; // score は変わらない
    b = 200; // score も 200 になる

    cout << "a=" << a << " score=" << score << endl;
    return 0;
}

結果:https://paiza.io/projects/Jlne8x0fcbIhcZy04WQXiA?language=cpp

 

 

C++学習3(nullptr(NULL との違い))

1.目的

C++ における nullptr の役割と、C言語由来の NULL との違いを理解する。

2.目次

3.概要

  • NULL はC言語由来の値で、実体は整数の 0
  • C++ ではオーバーロード解決時に NULL が意図しない挙動を招くことがある。
  • nullptr はポインタ専用の値として C++11 で導入され、この問題を解決する。

4.内容

 4.1NULL とは?(C言語の復習)

 C言語で「ポインタが何も指していない」状態を表すために使われる値。

  • int* ptr = NULL; と書くと、ポインタが何も指していない状態を表す。
  • しかし、NULL は、単なる整数の0と定義されている。(#define NULL 0)

 C++言語でも同様であり、NULLは、0(int型)と誤認識されてしまう場合がある。

そのため、C++では、何も指していないポインタを表すものとして、nullptrを使用する。

 4.2 基本的な書き方

ポインタの初期化や比較に使う。

  • int* ptr = nullptr;(初期化)
  • if (ptr == nullptr)(比較)
#include <iostream>
using namespace std;

int main() {
    int* ptr = nullptr; // 何も指していない状態
    if (ptr == nullptr) {
        cout << "ptr は空です" << endl;
    }

    return 0;
}

結果:https://paiza.io/projects/0IAn-wA2aRM_zWDj1J8YYg?language=cpp

 

参考

過去の記事:
 
C++Builder関連
 
C++学習関連

C++学習1(入力と出力:iostream(cin / cout)) - Project_OKI’s diary

 

 

C++学習2(参照(reference, &)の仕組み)

1.目的

C++ における参照(reference, &)の仕組みと使い方を整理する。

2.概要

  • 参照とは、既存の変数に別名をつける仕組み
  • 同じメモリを共有するため、参照を通じた変更は元の変数にも反映される
  • 関数の引数で特によく使われる(参照渡し)
  • ポインタより安全・簡潔に書ける C++ スタイルの機能

3.内容

3.1.参照(reference, &)とは

 既存の変数に別名をつける機能。

  • 宣言時に int& ref = score; のように書く
  • refscore は同じメモリを指す
  • ref を変更すると score も変わる

基本的な書き方

  • 型& 参照名 = 既存の変数;
#include <iostream>
using namespace std;

int main() {
    int score = 100;
    int& ref = score;  // score の参照(別名)を作る

    // 参照を通じて値を変更
    ref = 200;

    // score も変わっているか確認
    cout << "score = " << score << endl; // 200 と表示される
    cout << "ref = " << ref << endl;     // 200 と表示される

    return 0;
}

 

出力結果:https://paiza.io/projects/4ac7B3iRQy56Q0Sn-zxsQw

  • score = 200
  • ref = 200

 

なぜ参照が必要か(参照渡し)

関数の引数として使うことで、元の変数を直接操作できる。

  • 値渡し:引数がコピーされるため、元の変数は変わらない
  • 参照渡し:元の変数を直接操作できる

 

#include <iostream>
using namespace std;

// ❌ 値渡し:コピーされるので元の変数は変わらない
void addTen_value(int n) {
    n += 10;
}

// ✅ 参照渡し:元の変数を直接操作できる
void addTen_ref(int& n) {
    n += 10;
}

int main() {
    int score = 100;

    addTen_value(score);
    cout << "値渡し後:" << score << endl;  // 100 のまま

    addTen_ref(score);
    cout << "参照渡し後:" << score << endl; // 110 になる

    return 0;
}

結果:https://paiza.io/projects/SAqnffW6VJPUKJS1DvLhfg?language=cpp

 

ポインタとの比較

項目 参照(&) ポインタ(*)
初期化 宣言時に必ず初期化が必要。 初期化せずに宣言だけも一応できる(ただし未初期化は危険。初期化推奨)。
参照先の変更 一度どの変数を参照するか決めたら、後から参照先を変えられない。 後から別のアドレスを代入して、指す先を自由に変えられる。
null になれるか 常に「何か有効なオブジェクト」を指す前提で、null 参照は基本的に不可。 nullptr や NULL を代入して「どこも指さない状態(null)」にできる。
アクセスの書き方 普通の変数と同じように ref と書くだけで中身にアクセスできる。 値を触るには *ptr と書く(ptr 単体は「アドレス」)。
型の見た目 int& r = x; のように & が型名側に付く。 int* p = &x; のように * が変数宣言に付く。
主な用途イメージ 関数引数などで「別名として扱いたい」「直感的に元変数をいじりたい」場合。 動的メモリ、配列操作、C との連携、null チェックで存在有無を表現したい場合など。
安全性・わかりやすさ null がなく、書き方も通常変数と同じなので、仕様上シンプルで安全寄り。 null や未初期化ポインタなどバグ要因が多く、アドレス・*・& を意識する必要あり。
初心者向けかどうか 「値の別名」として直感的に使えるので、初心者にはかなり扱いやすい メモリアドレスの概念が必要で難しめなので、初心者にはややハードル高め

 

C言語との違い(ポインタ vs 参照)

並べて比較:

#include <iostream>
using namespace std;

int main() {
    int score = 100;

    // ポインタ(C言語スタイル)
    int* ptr = &score; // score の「アドレス」を持つ
    *ptr = 200;        // * で中身にアクセス(デリファレンス)
    cout << "ポインタ:" << ptr << endl; // 110 になる

    // 参照(C++スタイル)
    int& ref = score;  // score の「別名」になる
    ref = 200;         // そのまま書くだけでアクセスできる
    cout << "参照:" << ref << endl; // 110 になる

    return 0;
}

結果:https://paiza.io/projects/Lzj9bEmwLAVNylPpdnMNgA

 

#include <iostream>
using namespace std;

int main() {
    int score = 100;

    // ポインタ(C言語スタイル)
    int* ptr = &score;   // score の「アドレス」を持つ
    *ptr = 200;           // * で中身にアクセス(デリファレンス)
    cout << "ポインタ経由で変更後: score = " << score << endl;

    // 参照(C++スタイル)
    int& ref = score;     // score の「別名」になる
    ref = 300;             // そのまま書くだけでアクセスできる
    cout << "参照経由で変更後: score = " << score << endl;

    // アドレスも確認してみる
    cout << "scoreのアドレス: " << &score << endl;
    cout << "ptrが指すアドレス: " << ptr << endl;
    cout << "refのアドレス(scoreと同じ): " << &ref << endl;

    return 0;
}

結果:https://paiza.io/projects/ZMwsyJCfRCl_meW_hHmV-A

 

参考

過去の記事:
 
C++Builder関連
 
C++学習関連

C++学習1(入力と出力:iostream(cin / cout)) - Project_OKI’s diary

 

C++学習1(入力と出力:iostream(cin / cout))

1.目的

  • C++ について学習した内容をまとめる。

 

目次


2.概要

 C++の標準ライブラリ iostreamに含まれているcin及びcoutの使い方について記載する。

3.内容

  iostream 
  ・[C++]の標準入出力ライブラリ。        
  ・コンソールへの出力と、キーボードからの入力を扱う。        
  ・C言語の [printf] / [scanf] に相当するもの。


3.1 基本の書き方

(1) cout(出力)

 std::cout << 値; で画面に出力する。

 << を繋げて複数の値を続けて出力できる。

 
・Hellow,World!を出力
 #include <iostream>
  int main() {
      std::cout << "Hello, World!" << std::endl;
      return 0;
  }
 
・数値を出力
 #include <iostream>
  int main() {
  std::cout << "答えは " << 42 << " です" << std::endl;
      return 0;
  }
 
(2)[endl] と \n の違い
 どちらも改行。
 endl は改行 + バッファのフラッシュ(書き出し)をする。
  \n は改行のみで、endl より少し速い。
 普段は \n でよく、確実に出力したい時に endl を使う。
 
(3) cin(入力)
 cin>> 変数;
 でキーボードから入力を受け取る。
 
・数値を入力しそのまま出力する
#include <iostream>
using namespace std;
int main(void){
    // Your code here!
     int x;
    std::cin >> x;        // 数値を入力
    std::cout << "入力= "<<x;
}

参考:https://paiza.io/projects/bI0tkQEZcHvF-fggNqK8qw?language=cpp
 
・cin の注意点 
  >>> は空白や改行で区切られる。
  スペースを含む文字列を1行まるごと読みたい時は cin >> では取れない。
  その場合は [getline] を使う。
 
・stdについて
  stdとは、名前空間を指し、stdの名前空間にあるcinや、coutを呼び出している。
  名前空間については別途記載する。 
 using namespace std; と書けば std:: を省略できるが、
  大規模なコードでは名前の衝突を避けるため省略しない方が無難。 
 
(4) printf / scanf との違い

 ・型を自動で判別してくれる(%d や %s が不要)
 ・<< >> で直感的に書ける
 ・型の指定ミスによるバグが起きにくい

 

関連記事

C++Builder 入門メモ② 環境設定とVCLテストアプリ作成

1.目的

  • C++ Builderを始めるので、そのメモを記載する。
  • 今回はアプリケーション作成する為の設定や実際にテストアプリを作成する。

 

目次

 

参考資料:

C++Builderで始めるビジュアルプログラミング

 

2.環境の設定

参考動画:

www.youtube.com

 

2.1 Windows VCLアプリケーションの作成時の初期表示設定

 (1) ファイル→新規作成→Windows VCL アプリケーションを選択

 

 (2) 初期画面が表示される。 

 

 (3) コンポーネントを表示させる

・右上の空白部分を右クリックし、コンポーネントにチェックを入れる。

 (この画像ではすでにチェックが入っている)

 

3.アプリケーションの作成、実行

 (1) 配置するものを検索する。

 ※ここではボタンを配置する為、butを検索欄に入れる。

 (2) 配置したいコンポーネントをクリックする。

 (3) ボタンを配置したいところ(Form1の中)をクリックする。 

 (4) Caption のButtonxxを変えたいボタンの表示に変える。

 (5)上側の三角マーク(デバッカを使わずに実行)を押下

 (6) アプリが実行され、ボタンが配置されたアプリが表示される。

 (7) 作成したプロジェクトのWin32の中に、アプリが作成される。

 ※デバッグモードで実行している場合はDebugフォルダが作成される。

  ※今回はtest1.exeという名前でアプリが作成されている。 

 これをダブルクリックすると、アプリが起動される。

4.ボタンを押下したときの処理の追加

 (1) 設置したボタンをダブルクリックする。

 →クリックしたボタン用の関数が表示される。

 (2) 関数内に、ボタンが押下された時実行する処理を作成

 (3) 作成したプログラム

 ・保存用メッセージボックスを表示するプログラム

void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (MessageDlg(L"保存しますか?",
			   mtConfirmation,
			   TMsgDlgButtons() << mbYes << mbNo,
			   0) == mrYes)
	{
		// はい のときの処理
	}
	else
	{
		// いいえ のときの処理
	}
}

 ・表示されたメッセージボックス

 

関連記事

 

C++Builder 入門メモ① C++Builderのインストール

1.目的

  • C++ Builderを始めるので、そのメモを記載する。
  • 今回はインストールと、最初のはじめ方に関してのメモを記載

 

目次

 

 

事前準備(Windows 用)

  1. 対応 OS と要件の確認

    • C++Builder は Windows 10/11 を公式にサポートしており、64‑bit Windows が推奨されている

    • メモリ 8 GB 以上、空き容量 数 GB 以上(完全インストールで10 GB前後)を確保しておくと安全。

  2. Embarcadero アカウントの登録

    • 無料トライアルや Community Edition をダウンロードするには、Embarcadero のサイトでアカウント登録が必要。

    • 登録後にメールで「インストール番号(シリアル等)」やダウンロードリンクが届く。

ダウンロード:無料版 - エンバカデロ・テクノロジーズ

 

2.インストール

 (1) C++ Builderのインストールを行う。

 下記動画を参考にインストールした。

 現在は、RAD Studio12。 この動画では10.4であるが、基本同じ。 

www.youtube.com

 

 (2) インストール時のインストーラ内容

・追加するオプションについて

 

項目 概要 いれる目安
日本語 IDE や関連表示を日本語で使うための言語パックです。 日本語で使いたいなら入れる。
Samples サンプルコードや例題です。 学習や確認に便利なので、基本的に入れてよいです。
Help オフラインヘルプです。 調べながら使いたいなら入れる。
Fonts IDE で使うフォント関連の追加要素です。 通常は入れて問題ありません。
Modeling 設計やモデリング関連の機能です。 UML などを使うなら入れる。
TeeChart Standard グラフ描画用のコンポーネントです。 グラフ機能が必要なら入れる。
DUnit Unit Testing Frameworks 単体テスト用の機能です。 テストを行うなら入れる。
InterBase Express (IBX) Components InterBase 用のデータベース接続部品です。 InterBase を使うなら入れる。
InterBase 2020 Developer Edition 開発用の InterBase データベースです。 DB 開発が必要なら入れる。
 

・改善への同意確認

  • Windows 10 Kitsが匿名の使用状況データをMicrosoftに送信することの同意を求めています
  • データは製品改善のために使用され、ユーザーが作成したコードやソフトウェアは収集されません
  • 参加は任意です。

 YesでもNoでもどっちでもよい。

 

・使用する機能のダウンロード

 

コンポーネント 用途
Windows Performance Toolkit パフォーマンス計測・分析ツール ascii
Debugging Tools for Windows WinDBGなどのデバッグツール ascii
Application Verifier アプリのバグ検出ツール
.NET Framework 4.8 SDK .NET開発用
Windows App Certification Kit ストアアプリ申請用の検証ツール
Windows IP Over USB デバイスのUSBデバッグ接続
MSI Tools インストーラー作成ツール
SDK Signing Tools アプリへの署名ツール
SDK for UWP Managed Apps UWPアプリ(C#等)開発用
SDK for UWP C++ Apps UWPアプリ(C++)開発用
SDK for Desktop C++ x86/amd64/arm/arm64 デスクトップアプリ(C++)開発用 image.jpg

 

関連記事

過去の記事:

AIで作った魔王の子育てクソゲー作成

魔王の街づくりと子育て(バトル編)をAIで作ってみた記録

今回の記事では、「街づくりと子育てを同時にやるクソゲーを、AI多めで作ってみた記録」をまとめます。

1. 目的

今回の開発における主な目的は以下の通りです。

  • 街づくりと子育てを同時にやるクソゲーを、AI多めで作ってみた記録を残す
  • AIを活用して、ゲーム本体から音楽まで作成する流れを把握する
  • たとえ「クソゲー」であっても、一つの形として完成させられることを実証する
  • 街づくり要素が実装できなくても、雰囲気だけで押し切れるか試す

2. 概要

今回作ったのは、魔王が街づくりしながら子育てする風のバトルゲームです。

  • ジャンル: カード風バトルゲーム
  • 雰囲気: 異世界・魔王・雑な育成
  • 制作スタイル: 基本全てAIで作成。

3. 使用しているAIツール

🎮 ゲーム作成

  • ChatGPT: 仕様作成に使用。ゲーム設定やルールをそれっぽく膨らませたり、クソ要素を正当化する言い訳作りに活用。
  • Claude Sonnet: ゲーム実装のメインに使用。コード生成能力が高く、勢いで実装を進めるのに貢献。
  • Perplexity: 調べ物やアイデアの補強に使用。
  • Cursor: Claude Sonnetで作ったゲームコードを元に、エラー修正やリファクタリングを実施。
  • Gemini: ゲーム内の画像を生成。
  • Suno: ゲーム用BGMを自動生成。魔王っぽい雰囲気の曲を雑に量産してもらいました。

🎬 動画作成

  • CapCut Free AI Video Maker: YouTube用の紹介動画作成に使用。「Smart One-Click Video Creation in Seconds」機能を使い、動画をAIで自動生成したり編集したりしました。

4. 今回作成したゲーム

ゲームタイトル

魔王の街づくりと子育て(バトル編)

ゲーム内容

  • 魔王が拾った子供にカードを渡し、それを使用して成長しつつ敵を倒すバトルゲーム

5. ゲームテーマ

今回の元ネタとなったゲームテーマと設定です。

  • 異世界転生を阻止した魔王
  • 軍事力拡大のため街づくりを再開
  • 途中で人間の少年を拾い、街づくりの傍ら子育てを開始
  • 子供のために魔力を結晶化し、カードに変換
  • 本来勝てない敵と戦わせ、勝つことで強制的に成長させる

6. 作ってみて学んだこと

良かった点

  • AIで音楽まで作ると一気にゲーム感が出る: Sunoで作ったBGMがあるだけで、クソゲーでもそれっぽくなる。

うまくいかなかった点

  • 街づくり要素を実装する余裕がない。
  • バトルが単調: 戦略性が思ったより上手くゲームに落とし込めなかった。

7. まとめ

今回は、街づくりと子育てをしている気がするクソゲーを作成しました。

  • AIで音楽を入れるだけで完成度が上がる
  • 実際は雑でも、雰囲気は作れる
  • クソゲーでも公開すると不思議な達成感はある

正直まだまだクソですが、「作った」という事実だけは残りました。

8. 次回予告

次回は、「魔王の防衛戦記」というテーマで新しい別のゲームを作る予定です。

また勢いで作ります。お楽しみに!