プログラミング言語(プログラミング言語)は人とコンピュータの架け橋です。命令を書いたり、コンピュータの動作を制御したり、さまざまなアプリケーションを実装したりするために使用されます。
最新のプログラミング言語ランキングによると、2024 年のトップ 20 プログラミング言語は次のとおりです。
ラムダ式は、特に小さな関数やコールバックを渡す必要がある場合に、コードを簡略化するためによく使用される匿名関数です。ラムダ式の構文は簡潔で、関数ロジックは 1 行で定義できます。ラムダ式は最も一般的に見られます。 C++、JavaScript、Python、C# などの言語。
ラムダ式の基本構文には通常、パラメータ、矢印記号が含まれます。=>および関数本体、たとえば:
(パラメータ) => 関数本体
正確な構文は言語によって異なります。次に例を示します。
[capture](parameters) { function body }lambda parameters: expression(parameters) => expression
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector数値 = {1、2、3、4、5};
// ラムダ式を使用して偶数の合計を計算します
int 合計 = 0;
std::for_each(numbers.begin(),numbers.end(),[&sum](int n) {
if (n % 2 == 0) 合計 += n;
});
std::cout << 「偶数の合計:」 <<合計 << std::endl;
0を返します。
}
# ラムダ式を使用して 2 つの数値の合計を計算します
add = ラムダ x, y: x + y
print(add(5, 10)) # 出力: 15
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
static void Main() {
List numbers = new List{ 1、2、3、4、5 };
// ラムダ式を使用して偶数を除外し、合計を計算します
int sum = 数値.Where(n => n % 2 == 0).Sum();
Console.WriteLine($"偶数の合計: {sum}");
}
}
map、filterそしてreduce高階関数がコレクションに対して動作するまで待ちます。# Python: オブジェクトのプロパティをリストして読み取る
クラス ユーザー:
def __init__(self): self.id = 0; self.name = "アン"
u = ユーザー()
vars(u).items() の k、v の場合:
print(k, v) # id 0 / 名前アン
// C#: フィールド/プロパティを取得し、値を読み取ります
システムを使用する;
System.Reflection を使用します。
var t = typeof(MyType);
foreach (var p in t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
Console.WriteLine($"{p.Name}={p.GetValue(obj)}");
// JavaScript: 動的な列挙と呼び出し
const obj = { x: 1, y: 2, add(){ return this.x + this.y; } };
for (const [k,v] of Object.entries(obj)) console.log(k, v);
console.log(obj["add"]()); // 3
// Java: リフレクションを使用したフィールドの読み取り/書き込み
インポート java.lang.reflect.*;
クラス U {プライベート int ID = 42; }
U u = 新しい U();
フィールド f = U.class.getDeclaredField("id");
f.setAccessible(true);
System.out.println(f.getInt(u)); // 42
// Go: 訪問構造を反映します
インポート「反映」
func Dump(v any) {
val := 反映.ValueOf(v)
私にとって:= 0;私は< val.NumField(); i++ {
名前 := val.Type().Field(i).Name
fmt.Println(名前, val.Field(i).Interface())
}
}
| 言語 | サポート | 説明する |
|---|---|---|
| Python | ✅ | 動的、完全反射、簡単な再帰的オブジェクト/コンテナ検査。 |
| JavaScript / TypeScript | ✅ | オブジェクトはキーと値であり、使用可能ですObject.values再帰。 |
| Ruby | ✅ | instance_variables反射部材。 |
| PHP | ✅ | get_object_vars()あるいは反省。 |
| C# (.NET) | ✅ | リフレクションはフィールド/プロパティを取得し、良好な型安全性を備えています。 |
| Java | ✅ | java.lang.reflectスキャン可能なフィールド。 |
| Kotlin | ✅ | Java と同様に、JVM リフレクションは完了しています。 |
| Go | ✅ | reflect構造体フィールドにアクセス可能。 |
| Swift | ◑ | Mirror訪問は可能ですが、シーンが限定されており、追加の処理が必要です。 |
| C++ (C++23 まで) | ❌ | 実行時の反映がないため、型のチェックを手動で記述する必要があります。 |
| Rust | ❌ | 実行時リフレクションはありません。多くの場合、derive/trait によって実装されます。 |
def is_all_zero(obj, eps=1e-6):
if isinstance(obj, (int, float)): # 基本数値
戻り値 abs(obj) <; eps
elif isinstance(obj, (リスト, タプル, セット)): # シーケンス/セット
return all(is_all_zero(x, eps) for x in obj)
elif isinstance(obj, dict): # 辞書
return all(is_all_zero(v, eps) for v in obj.values())
elif hasattr(obj, "__dict__"): # 一般オブジェクト
vars(obj).values() の v に対して all(is_all_zero(v, eps)) を返します)
それ以外の場合:
Falseを返す
# テスト
クラスポイント:
def __init__(self, x=0, y=0): self.x, self.y = x, y
クラス行:
def __init__(self, p1=なし, p2=なし):
self.p1 = p1 または Point()
self.p2 = p2 または Point()
print(is_all_zero([[0,0],[0,0]])) # True
print(is_all_zero(Line(Point(0,0),Point(0,0)))) # True
print(is_all_zero(Line(Point(1,0),Point(0,0)))) # False
関数 isAllZero(obj, eps = 1e-6) {
const isNumZero = n => Math.abs(n) <; eps;
if (typeof obj === "number") return isNumZero(obj);
if (Array.isArray(obj)) return obj.every(v => isAllZero(v, eps));
if (obj && typeof obj === "オブジェクト")
return Object.values(obj).every(v => isAllZero(v, eps));
false を返します。
}
console.log(isAllZero([[0,0],[0,0]])); //本当
console.log(isAllZero({x:0, y:{z:0}})); //本当
console.log(isAllZero({x:0.000001, y:0})); // eps に依存します
システムを使用する;
System.Linq を使用します。
System.Reflection を使用します。
パブリック静的クラス ZeroCheck {
public static bool IsAllZero(object obj, double eps = 1e-6) {
if (obj == null) は true を返します。
スイッチ (オブジェクト) {
case int i: 戻り値 i == 0;
長さ l の場合: l == 0 を返します。
case float f: return Math.Abs (f) <; eps;
case double d: return Math.Abs (d) <; eps;
}
var t = obj.GetType();
if (t.IsArray)
return ((Array)obj).Cast<object>().All(x => IsAllZero(x, eps));
//フィールドと属性をスキャンします
foreach (var f in t.GetFields(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
if (!IsAllZero(f.GetValue(obj), eps)) は false を返します。
foreach (var p in t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
if (p.CanRead && !IsAllZero(p.GetValue(obj, null), eps)) は false を返します。
true を返します。
}
}
package main
import (
"math"
"reflect"
)
func IsAllZero(v interface{}, eps float64) bool {
val := reflect.ValueOf(v)
switch val.Kind() {
case reflect.Float32, reflect.Float64:
return math.Abs(val.Float()) < eps
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return val.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return val.Uint() == 0
case reflect.Slice, reflect.Array:
for i := 0; i < val.Len(); i++ {
if !IsAllZero(val.Index(i).Interface(), eps) { return false }
}
return true
case reflect.Map:
for _, k := range val.MapKeys() {
if !IsAllZero(val.MapIndex(k).Interface(), eps) { return false }
}
return true
case reflect.Struct:
for i := 0; i < val.NumField(); i++ {
if !IsAllZero(val.Field(i).Interface(), eps) { return false }
}
return true
case reflect.Pointer, reflect.Interface:
if val.IsNil() { return true }
return IsAllZero(val.Elem().Interface(), eps)
default:
return false
}
}
isAllZero、またはテンプレート/マクロを使用してメンバーを拡張します。deriveマクロは型の実装 (カスタム特性など) を自動的に生成します。IsAllZero)。eps、誤った判断につながる精度の問題を避けるため。isAllZero()コストのかかる反射スキャンを回避する方法。メッセージ キュー (MQ) は、ソフトウェア システム間の非同期通信のためのアーキテクチャ パターンです。これにより、独立したアプリケーションやサービスが、相互に直接呼び出したり、相互のリアルタイム ステータスに依存したりすることなく、メッセージを送受信することで情報を交換できるようになります。 MQ の中核的な役割は、対象の受信者がメッセージを処理する準備ができるまでメッセージを一時的に保存する中間層として機能することです。
| スキーマ名 | 説明する | 典型的なアプリケーションシナリオ |
|---|---|---|
| ポイントツーポイント (P2P) | メッセージはキューに送信され、**1 人だけ**の受信者がメッセージをキューから取り出して消費します。消費されると、メッセージは削除されます。 | 注文処理、タスクのディスパッチ、ワークロードバランシング。 |
| パブリッシュ/サブスクライブ、パブリッシュ/サブスクライブ | メッセージがトピックに公開され、トピックに登録している**すべて**の受信者 (サブスクライバー) がメッセージのコピーを受け取ります。 | システムイベントブロードキャスト、ログ収集、データ変更通知。 |
メッセージ キューは、最新の分散システム、マイクロサービス アーキテクチャ、および高可用性アプリケーションの基礎です。時間と空間の間接化を導入することで、システムの回復力、拡張性、堅牢性が大幅に向上します。
| 特性 | メッセージキュー (MQ) | HTTP API (REST/RPC) |
|---|---|---|
| 通信タイプ | 非同期 | 同期 |
| カップリング | 低結合 (送信者と受信者は直接対話しません) | 高結合 (クライアントはサーバーのアドレスを知っていて、応答を待つ必要があります) |
| データフロー | 一方向、中間ブローカーを通過 | 双方向、リクエストとレスポンス (リクエスト-レスポンス) |
| 耐障害性 | 高の場合、ブローカーはメッセージを保存するため、受信者がオフラインであってもメッセージは失われません。 | 低い場合、サーバーがオフラインまたはタイムアウトになり、リクエストが失敗します。 |
| スケーラビリティ | 負荷を処理するために、複数の高負荷コンシューマーを簡単に追加できます。 | 比較的低い、リクエストを分散するためにロードバランサーに依存する |
MQ と HTTP API は代替テクノロジーではありませんが、さまざまな問題に対応するように設計されています。
最新の分散システムでは、さまざまなビジネス ニーズを満たすために 2 つのモードが共存し、相互に連携することがよくあります。
多くのネットワーク アプリケーションでは、一部の操作には時間がかかり、ユーザーが同時に待たされると、ユーザー エクスペリエンスが低下します。 MQ を使用すると、これらのタスクを非同期で実行できます。
MQ は一時的な高トラフィックのシナリオを処理する上で重要であり、バックエンド サービスをクラッシュから保護できます。
複雑な分散システムやマイクロサービス アーキテクチャでは、MQ を使用してサービスを分離し、相互依存を軽減します。
フロントエンド アプリケーションまたはサーバーから大量のログ データを集中処理システムに収集します。
特に、Apache Kafka のような高スループットの MQ/ストリーミング プラットフォームは、リアルタイム データの連続ストリームを処理するのに最適です。
HTTP API を使用して画像やビデオなどの大規模なバイナリ データ (バイナリ データ) を転送する場合の主な課題は次のとおりです。
これは、ブラウザまたはクライアント アプリケーションがファイルをアップロードするための最も標準的で一般的な方法です。
multipart/form-data; boundary=YourBoundaryString
単一のファイルのみをアップロードする必要がある場合は、ファイルのバイナリ コンテンツをリクエストの件名として直接使用できます。
image/jpegまたはimage/png;ビデオ:video/mp4。
バイナリ データを ASCII 文字列に変換し、JSON や XML などのテキスト形式に埋め込んで送信します。
Content-Type, 単純なテキスト形式を処理するための API もサポートされています。バイナリ データのダウンロードは比較的簡単です。サーバーは、ファイルの元のバイナリ コンテンツを HTTP 応答の本文 (応答本文) として直接返します。
image/jpegまたはvideo/mp4。
attachment; filename="example.mp4"、コンテンツを直接表示するのではなく、ファイルとしてダウンロードするようにブラウザーに指示します。特に大きなファイル (特にビデオ) の場合、信頼性と効率を向上させるために次のテクニックをお勧めします。
Rangeアーカイブの特定のフラグメントをリクエストします (例:Range: bytes=100-200)。これはビデオ ストリーミング (ストリーミング) にとって非常に重要で、プレーヤーは再生する必要がある部分のみをダウンロードでき、早送り/巻き戻しをサポートします。ストリーミング送信の核心は、オーディオおよびビデオ コンテンツをサーバーからクライアントに効率的かつ安定して低遅延で送信する方法にあります。
これが現代のストリーミング サービスの基礎です。サーバーは、同じビデオ コンテンツを異なる品質 (ビット レート、解像度) の複数のバージョンにエンコードします。
グローバルユーザーを対象としたストリーミングサービスにはCDNが不可欠です。
オーディオおよびビデオ データを圧縮および解凍してファイル サイズを削減するために使用されます。
Bash では、$?最後に実行されたコマンドの終了ステータス コード (Exit Status) を表します。これは通常、前のコマンドが正常に実行されたかどうかを判断するために使用される整数値です。
#!/bin/bash
ls
echo "前のコマンドの終了ステータス コードは次のとおりでした: $?"
この例では、lsこのコマンドはディレクトリの内容を一覧表示します。実行が成功した後、$?値は0になります。
#!/bin/bash
ls /存在しないディレクトリ
echo "前のコマンドの終了ステータス コードは次のとおりでした: $?"
この例では、ls存在しないディレクトリをリストしようとすると、コマンドは失敗します。$?の値はゼロ以外の数値になります。
#!/bin/bash
cp file1.txt /some/ディレクトリ/
もし[$? -eq 0 ];それから
echo "ファイルは正常にコピーされました。"
それ以外の場合
echo "ファイルのコピーに失敗しました。"
フィ
この例では、コマンドの終了ステータスに基づいて、どのメッセージを表示するかを決定します。
if [条件];それから
指示
フィ
if で複数の条件を同時に満たすには、次を使用します。
-a(古いですが入手可能です)if [ "$a" -gt 0 -a "$b" -gt 0 ];それから
echo 「a と b は両方とも 0 より大きい」
フィ
[[ ]] &&(推薦する)if [[ "$a" -gt 0 && "$b" -gt 0 ]];それから
echo 「a と b は両方とも 0 より大きい」
フィ
&&if [ "$a" -gt 0 ] && [ "$b" -gt 0 ];それから
echo 「a と b は両方とも 0 より大きい」
フィ
次の条件のいずれかが true である限り、実行できます。
-o(古いですが入手可能です)if [ "$a" -eq 0 -o "$b" -eq 0 ];それから
エコー「a または b は 0」
フィ
[[ ]] ||(推薦する)if [[ "$a" -eq 0 || "$b" -eq 0 ]];それから
エコー「a または b は 0」
フィ
||if [ "$a" -eq 0 ] || [ "$b" -eq 0 ];それから
エコー「a または b は 0」
フィ
かっこと一緒に使用して優先順位を制御できます。
if [[ ( "$a" -gt 0 && "$b" -gt 0 ) || "$c" -eq 1 ]];それから
echo 「a と b は両方とも 0 より大きい、または c は 1 に等しい」
フィ
バッシュでは、if命令は通常、次のものとペアになります。[ ](テストコマンド) または[[ ]](拡張テストコマンド)を使用します。 NOT を表現するには、感嘆符を使用します!。
もし [ !状態 ];それから
# 条件が false の場合に実行されるコード
フィ
これは最も一般的な使用法です。たとえば、ファイルが「存在しない」場合はファイルを作成します。
# config.txt という名前のファイルが存在しない場合
もし[! -f "config.txt" ];それから
echo "ファイルが存在しません、作成しています..."
タッチconfig.txt
フィ
# ディレクトリが存在しない場合
もし[! -d "/var/log/myapp" ];それから
mkdir -p "/var/log/myapp"
フィ
文字列が「等しくない」または「空ではない」かどうかを確認します。
STR="こんにちは"
# 変数が「world」と等しくないことを確認します
if [ "$STR" != "ワールド" ];それから
エコー「文字列が一致しません」
フィ
# 文字列が空でないことを確認します (! -z は -n と同等です)
もし[! -z "$STR" ];それから
echo "変数にデータがあります"
フィ
数値的には比較的ですが、-ne(等しくありません)、ただし一致させることもできます!使用。
NUM=10
もし[! "$NUM" -eq 20 ];それから
echo "その数値は 20 に等しくありません"
フィ
| オペレーター | 説明する | 例 |
|---|---|---|
! -f |
ファイルが存在しません | [ ! -f file ] |
! -d |
ディレクトリが存在しません | [ ! -d dir ] |
!= |
文字列が次と等しくない | [ "$a" != "$b" ] |
! -z |
文字列が空ではありません | [ ! -z "$str" ] |
-ne |
値が次と等しくない | [ "$n" -ne 5 ] |
より最新の Bash スクリプトでは、次の使用をお勧めします。[[ ]]、処理中です!ロジックと組み合わせると、より強力になり、エラーが発生しにくくなります。
# 複数の条件を組み合わせる: ディレクトリではなく読み取れない場合
もし[[! -d $パス && ! -r $パス ]];それから
echo 「パスが無効か、権限が不十分です」
フィ
[[ ]]タイムリーなサポート&&そして||[ ]複数の条件文を一緒に使用することをお勧めします&& / ||caseステートメントは変数の値を複数のパターン(パターン)と比較するために使用され、その機能は他の言語と同様です。switch。その文法構造は次のとおりです。
ケース変数
モード1)
# 命令を実行する
;;
モード2)
# 命令を実行する
;;
*)
# デフォルトの実行コマンド(デフォルトと同様)
;;
イーサック
これは最も一般的な使用法であり、ユーザー入力に基づいてさまざまなアクションを実行します。
read -p "(はい/いいえ)を入力してください: " input
「$input」の場合
「はい」)
エコー「はいを選択しました」
;;
「いいえ」)
エコー「いいえを選択しましたか?」
;;
*)
エコー「入力エラー」
;;
イーサック
使用|シンボルを使用すると、複数のモードで同じ命令ブロックを実行できます。
read -p "月の省略形を入力してください: " month
ケース「$month」
1月|2月|3月)
エコー「シーズン1」
;;
4月|5月|6月)
エコー「シーズン2」
;;
*)
「他の月」をエコーする
;;
イーサック
パターン マッチングは、ファイル パスなどの拡張記号をサポートします (例:*, ?, [a-z])。
read -p "文字を入力してください: " char
「$char」の場合
[a-z])
エコー「これは小文字です」
;;
[A-Z])
エコー「これは大文字です」
;;
[0-9])
エコー「これは数字です」
;;
*)
echo "これは特殊記号または複数の文字です"
;;
イーサック
| シンボル | 機能説明 |
|---|---|
) |
パターンの終了タグ。 |
;; |
命令ブロックの終了マーカー (break)。 |
* |
任意の文字列を比較します。通常はデフォルトのオプションとして最後に配置されます。 |
| |
複数の一致パターン (「または」を表す) を区切るために使用されます。 |
esac |
case逆から綴ると、文法ブロックの終わりを表します。 |
"$var") 変数に null 値がある場合の構文エラーを回避します。case上から順に比較していきます。試合が成功して遭遇すると;;停止してしまいますので、特定モードを一般モードにしてください(例:*)前に。デフォルトの動作: 大文字と小文字が区別されます。標準的な Bash 環境では、caseその声明は、大文字と小文字を区別の。これは、「A」と「a」が別のパターンとして扱われることを意味します。
read -p "文字を入力してください: " char
「$char」の場合
a) echo "これは小文字の a" ;;
A) 「これは大文字の A です」をエコーします ;;
イーサック
---
全部欲しい場合はcaseこのステートメントは大文字と小文字を区別せずに使用できます。shoptコマンドが有効になっているnocasematch設定。これは、後続のすべての文字列比較に影響します。case裁判官。
# 大文字と小文字の区別を有効にする
shopt -s nocasematch
read -p "yes または YES: と入力してください。" input
「$input」の場合
はい) echo "一致が成功しました (大文字と小文字を無視します)" ;;
イーサック
# 大文字小文字の無視をオフにする (デフォルトに戻す)
shopt -u nocasematch
---
グローバル設定を変更したくない場合は、スキーマ内で直接ケース範囲を定義するのが最も標準的で一貫性のあるアプローチです。
read -p "文字を入力してください: " char
「$char」の場合
[aA])
echo 「a または A を入力しました」
;;
[b-zB-Z])
echo "追加の文字を入力しました"
;;
イーサック
---
特定の単語については、次のように使用できます。|考えられるすべてのスペルをリストします。
「$input」の場合
停止|停止|停止)
エコー「実行を停止」
;;
イーサック
---
| 方法 | アドバンテージ | 欠点がある |
|---|---|---|
shopt -s nocasematch |
プログラム コードは簡潔で、大規模な比較に適しています。 | スクリプト全体の動作に影響するため、必ず手動でオフにしてください。 |
[a-zA-Z]範囲 |
他の部分に影響を与えることなく正確な制御を実現します。 | 単語が非常に長い場合、書くのが非常に面倒になります。 |
パイプ文字| |
可読性が高く、特定の数語に適しています。 | ランダムな大文字と小文字の組み合わせ (YesS など) を処理できません。 |
Bash の算術拡張機能(( ))内部的には括弧のみを使用できます( )C またはほとんどのプログラミング言語のロジックと一致して、操作の優先順位を明示的に指定します。これは、複雑なロジック (AND、OR、加算、減算、乗算、除算の組み合わせ) を扱う場合に非常に重要です。
# 例: (A と B) または C
if (( (MIN > 91 && MIN< 110) || FORCE_MODE == 1 )); then
echo "條件成立"
fi
存在する(( ))内部では、演算の優先順位は標準の数学的および論理的規則に従います。
( )最高の優先度。*, /, %。+, -。<, >, <=, >=。&&(AND) が優先されます|| (OR)。次のことを決定する必要があるとします。値は範囲内である必要があり、(特定の倍数であるか強制モードである必要がある):
if (( MIN > 91 && (MIN % 5 == 0 || FORCE_MODE == 1) ));それから
{
echo 「複雑な条件判定をトリガーする」
IS_SHUTDOWN=true
} |& tee -a "$LOGFILE"
フィ
| 構文タイプ | グループ化記号 | 注意事項 |
|---|---|---|
(( ... )) |
( ) |
最も直感的なシンボルはエスケープする必要がなく、純粋な数値演算に推奨されます。 |
[[ ... ]] |
( ) |
存在する[[ ]]論理的なグループ化のために括弧を使用することも合法です。 |
[ ... ] |
\( ... \) |
伝統test構文では、括弧はバックスラッシュでエスケープする必要がありますが、これはお勧めできません。 |
Bash スクリプトでは、exitスクリプトの実行を終了し、ステータス コード (Exit Status) を親プログラムに返すために使用されます。
if [ -f "config.txt" ];それから
エコー「ファイルが存在します」
0番出口
それ以外の場合
echo "エラー: プロファイルが見つかりません"
出口1
フィ
スクリプトまたは命令の実行後、特殊変数を使用できます。$?前のプログラムを取得するにはexitステータスコード。
./script.sh
echo "スクリプト終了ステータス: $?"
電話するとき.shファイルを作成し、その「内容を出力」したい(すなわち、echo変数の内容を保存するときは、バッククォートまたは$()。これをコマンド置換と呼びます。
#!/bin/bash
# これは出力コンテンツであり、キャプチャされます
エコー「Ubuntu_User」
# これは最終状態であり、バッククォートによってキャプチャされません。
0番出口
# バッククォートを使用する
RESULT=`./get_name.sh`
# $() を使用します (現代文を推奨)
RESULT=$(./get_name.sh)
echo "取得された結果は次のとおりです: $RESULT"
| ターゲット | 入手方法 | 使用 |
|---|---|---|
| 終了ステータス (ステータスコード) | $? |
命令の実行が成功したかどうか (0 または 1) を判断します。 |
| 標準出力(出力内容) | ` `または$( ) |
スクリプト実行後に生成される文字列データを取得します。 |
両方を同時に取得したい場合は、次の例を参照してください。
OUTPUT=$(./script.sh)
ステータス=$?
echo "内容は: $OUTPUT"
echo "ステータス コードは次のとおりです: $STATUS"
バッシュでは、return指示は特に次の目的で使用されます関数または経由してsource実行するスクリプト。現在の関数またはスクリプトの実行を停止し、指定されたステータス コードを呼び出し元に返しますが、現在のシェル プログラムは閉じません。
これが最も一般的な使用法です。return返されるのは文字列データではなく、ステータス コード (0 ~ 255) です。
#!/bin/bash
# 関数を定義する
check_file() {
if [ -f "$1" ];それから
0 を返す # 成功
それ以外の場合
1 を返す # 失敗しました
フィ
}
# 関数の呼び出し
チェックファイル「test.txt」
結果=$?
if [ $RESULT -eq 0 ];それから
エコー「ファイルが存在します」
それ以外の場合
エコー「ファイルが存在しません」
フィ
スクリプトの実行後に変数と環境を現在のターミナルに残しておきたい場合は、通常、次のように使用します。source。この時点で使用する必要がありますreturnそれよりもexit。
# 論理的判断をシミュレートする
if [ "$USER" != "root" ];それから
echo "権限が不十分です。root でのみ使用できます。"
# exit を使用すると、ターミナルを直接閉じます。 return を使用すると、このスクリプトの実行のみが停止されます。
1を返す
フィ
エクスポート APP_STATUS="準備完了"
0を返す
ソース ./sub_script.sh
echo "スクリプトはステータスを返します: $?"
echo "環境変数を取得: $APP_STATUS"
なぜならreturn数値(ステータスコード)のみを返すことができます。文字列や大量のデータを取得するには、以下を組み合わせることが推奨されます。echoそしてコマンド置換。
#!/bin/bash
計算() {
ローカル val=$(( $1 + $2 ))
# 結果を標準出力に出力
「$val」をエコーする
# 実行ステータスコードを返す
0を返す
}
10 20 を計算します
# 出力内容を取得する
DATA=$(./get_data.sh)
# リターンのステータスコードを取得
ステータス=$?
echo "計算結果は $DATA です"
echo "実行ステータス: $STATUS"
| キーワード | 適用範囲 | メインプログラムへの影響 |
|---|---|---|
exit 0/1 |
独立したスクリプトとサブルーチン | 現在のシェル全体を終了します (ソースで実行した場合)。 |
return 0/1 |
関数、ソーススクリプトがロードされました | 現在のスコープを終了するだけで、メイン プログラムのシェルには影響しません。 |
echo "..." |
どこでも | 実際の「データコンテンツ」を呼び出し元に渡すために使用されます。 |
Bash では、条件判断を使用して変数が空かどうかを確認できます。一般的な方法をいくつか示します。
-z変数が空かどうかを確認する#!/bin/bash
var=""
if [ -z "$var" ];それから
echo "変数が空です"
それ以外の場合
echo "変数が空ではありません"
フィ
-z変数が空かどうかを確認するために使用されます。変数が空の場合、条件は true です。
-n変数が空でないかどうかを確認する#!/bin/bash
var="何らかの値"
if [ -n "$var" ];それから
echo "変数が空ではありません"
それ以外の場合
echo "変数が空です"
フィ
-n変数が空でないかどうかを確認するために使用されます。変数に値がある場合、条件は true になります。
#!/bin/bash
var=""
if [ "$var" == "" ];それから
echo "変数が空です"
それ以外の場合
echo "変数が空ではありません"
フィ
このメソッドは、変数と空の文字列を直接比較して、変数が空かどうかを確認します。
Bash は 2 種類の配列をサポートしています。
fruits=("apple" "banana" "cherry")
echo "${fruits[0]}" # apple
echo "${fruits[1]}" # banana
echo "${fruits[@]}"
echo "${#fruits[@]}"
fruits+=("date")
for fruit in "${fruits[@]}"; do
echo "$fruit"
done
declare -A capital
capital["Taiwan"]="Taipei"
capital["Japan"]="Tokyo"
echo "${capital["Japan"]}" # 東京
"${!capital[@]}" のキーの場合;する
echo "$key の首都は ${capital[$key]} です"
完了しました
declare -A宣言するBash 配列は、複数のデータを格納するための重要な構造であり、パラメーター リスト、ディレクトリ セット、キーと値のペアなどのデータ処理に適しています。
combined=("${array1[@]}" "${array2[@]}")
これにより、両方の配列のすべての要素が新しい配列にマージされます。combined。
array1=("リンゴ" "バナナ")
array2=("チェリー" "日付")
結合=("${配列1[@]}" "${配列2[@]}")
echo "結合された配列:"
"${combined[@]}" 内のアイテムの場合;する
「$item」をエコーする
完了しました
array1+=("${array2[@]}")
これにより、array2コンテンツは直接追加されますarray1後方。
"${array[@]}"要素が誤って展開されるのを防ぐためのフォームstr="ハローワールド"
if [[ "$str" == hello* ]];それから
echo "こんにちはで始まる文字列"
フィ
例証します:使用[[ ]]シェルパターン比較をサポート、*任意の文字を表します。
if [[ "$str" =~ ^hello ]];それから
echo "こんにちはで始まる文字列"
フィ
例証します: ^始まりを示し、[[ ]]で=~は定期的な運用です。
caseナレーション「$str」の場合
hello*) echo "hello で始まる文字列" ;;
*) echo 「hello で始まらない」 ;;
イーサック
例証します: caseこれは、文字列パターンを処理するための優れたツールであり、簡潔で可読性が高くなります。
expr(古い書き方です)if expr "$str" : '^hello' &> /dev/null;それから
echo "こんにちはで始まる文字列"
フィ
例証します:使用expr通常のマッチング関数。古いバージョンのシェルに適しています。
[[ ]]比較する[ ]より充実した機能を使用することをお勧めします=~正規表現を使用できますが、引用符を追加しないように注意してください-e-eファイルまたはディレクトリが存在するかどうか (種類に関係なく) を確認するために使用されます。
ファイル="/etc/passwd"
if [ -e "$FILE" ];それから
エコー「$FILE が存在します」
それ以外の場合
エコー「$FILE が存在しません」
フィ
! -d-dディレクトリであるかどうかを確認するために使用されます。!マイナスの操作です。
DIR="/tmp/myfolder"
もし[! -d "$DIR" ];それから
echo "$DIR が存在しません。作成しています..."
mkdir -p "$DIR"
それ以外の場合
エコー「$DIRはすでに存在します」
フィ
-e: ファイルまたはディレクトリが存在するかどうか (種類は関係ありません)-f:「一般ファイル」かどうか-d:「ディレクトリ」かどうか-L:「シンボリックリンク」かどうかPATH_TO_CHECK="/home/user/config"
if [ -e "$PATH_TO_CHECK" ];それから
エコー「$PATH_TO_CHECKはすでに存在します」
それ以外の場合
echo "$PATH_TO_CHECK が存在しないため、作成中です..."
mkdir -p "$PATH_TO_CHECK"
フィ
-e-dまたは-ftarget_dir="/path/to/your/dir"
subdirs=()
while IFS= read -r -d $'\0' dir; do
subdirs+=("$dir")
done < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)
find: サブディレクトリをリストします (再帰なし)-mindepth 1:自分のディレクトリを除外します-maxdepth 1:最初のレベルのみをリストします-type d:ディレクトリのみをリストします-print0マッチread -d $'\0': スペースを含むパスを処理しますfor dir in "${subdirs[@]}"; do
echo "$dir"
done
subdirs=( "$target_dir"/*/ )
この記述方法では、ワイルドカードを使用してサブディレクトリを照合しますが、ファイルを除外したり、スペースや特殊文字を処理したりすることはできません。
path="~/myfolder/file.txt"
realpath "$(eval echo "$path")"
path="~/myfolder/file.txt"
realpath "$(echo "$path" | sed "s|^~|$HOME|")"
path="~/myfolder/file.txt"
readlink -f "$(eval echo "$path")"
realpath "$(eval echo "$path")"
grep "キーワード" ファイル名
grep -i "キーワード" ファイル名
grep -n "キーワード" ファイル名
grep -r "キーワード" ディレクトリ パス
grep -o "キーワード" ファイル名
grep -H "キーワード" ファイル名
grep "キーワード 1" ファイル名 | grep「キーワード2」
#方法 1: 正規表現
grep -E "キーワード 1 | キーワード 2" ファイル名
#方法 2: 複数の -e パラメータ
grep -e "キーワード 1" -e "キーワード 2" ファイル名
#方法 1: ファイルを強制的にテキストとして扱う
grep -「キーワード」ファイル名
#方法 2: ファイルのエンコードを UTF-8 に変換して検索する
iconv -f 元のエンコーディング -t UTF-8 ファイル名 | grep「キーワード」
# 例(BIG5からUTF-8に変換)
iconv -f BIG5 -t UTF-8 ファイル名 | grep「キーワード」
grep -rin "キーワード" ディレクトリ パス
スペースまたは特殊記号 (空白、引用符、改行など) を含むファイル名またはパスを処理する場合、従来のfind配電線xargsまたはread誤った判断が起こる可能性があります。
-print0許容できるfindnull(\0) 文字を出力区切り文字として使用します。read -d $'\0'Null で区切られたコンテンツを正確に読み取り、各ファイル/パスを正確に分離できます。
subdirs=()
while IFS= read -r -d $'\0' dir; do
subdirs+=("$dir")
done < <(find . -type d -print0)
-print0: 各結果は改行せずに null 文字で終了します。-d $'\0':read一度に 1 つの null で終了する項目を読み取りますIFS=: スペースがフィールド区切り文字として扱われないようにします-r: 処理中の文字のスキップを回避します。txt_files=()
while IFS= read -r -d $'\0' file; do
txt_files+=("$file")
done < <(find "$(pwd)" -type f -name "*.txt" -print0)
探す 。 -type f -print0 | while IFS= 読み取り -r -d $'\0' ファイル;する
echo "処理中: $file"
# your_command "$file"
完了しました
探す 。 -タイプ d -print0 | while IFS= 読み取り -r -d $'\0' ディレクトリ;する
if [[ "$dir" == *" "* ]];それから
echo "スペースを含むディレクトリ: $dir"
フィ
完了しました
従来の使用法は次のとおりです。
find . -type f | while read file; do ...
ただし、ファイル名に改行が含まれていると、read解析が間違っていて、複数行でも複数のファイルと誤って判断されてしまいます。
-print0そしてread -d $'\0'あらゆるファイル名を処理する最も安全な方法-0待機シーン一部の Bash または Cygwin 環境では、次の記述方法が使用されます。最初の項目のみを読み取ります:
while IFS= read -r -d $'\0' dir; do
subdirs+=("$dir")
done < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)
これは通常、「<(find ...)` 在某些系統(如 Cygwin)不是「真正的檔案描述符」,造成 `read` 無法持續讀取。
-print0subdirs=()
find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0 | while IFS= read -r -d $'\0' dir; do
subdirs+=("$dir")
done
**注意**: `subdirs` をメイン プログラムで利用できるようにしたい場合、この方法は適切ではありません (`while ... |` サブシェルは配列を返せないため)。
mapfile -d '' -t subdirs < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)
mapfile(またはreadarray) は、null で区切られた文字列を配列に正しく読み取ることができます。
これは、メイン シェルに保持する最も信頼できる方法です。
"${subdirs[@]}" のディレクトリの場合;する
echo "見つかったディレクトリ: $dir"
完了しました
mapfile -d '' -t処理中です-print0最も安全で最も Bash ネイティブな方法var="line1
line2
line3"
while IFS= 読み取り -r 行;する
echo "読み取り: $line"
完了 <<< "$var"
IFS=空白のトリミングを避ける-rエスケープ文字が解析されないようにする<<<は here-string であり、変数の内容を while への入力として扱います。read -r first_line <<< "$var"
echo "最初の行: $first_line"
readarray -t lines <<< "$var"
for line in "${lines[@]}"; do
echo "$line"
done
find . -mindepth 1 -maxdepth 1 -type d -name "abc*" -printf "%T@ %p\n" | sort -nr | cut -d' ' -f2-
-mindepth 1 -maxdepth 1: 現在のディレクトリの下にあるサブディレクトリのみをリストします。-name "abc*": 名前はabcで始まります-printf "%T@ %p\n": 変更時刻(タイムスタンプ)とディレクトリ名を出力します。sort -nr: 時間値で新しいものから古いものに並べ替えます。cut -d' ' -f2-: タイムスタンプを削除し、パスのみを表示します。./abc_latest
./abc_old
./abc_2020
readarray -t abc_dirs << <(
見つけます。 -min Depth 1 -max Depth 1 -type d -name "abc*" -printf "%T@ %p\n" |
並べ替え -nr |カット -d' ' -f2-
)
"${abc_dirs[@]}" のディレクトリの場合;する
エコー「見つかった:$dir」
完了しました
-printfGNU find 専用関数、macOS のデフォルトfindサポートされていませんが、利用可能ですgfind代わりの%T@「最終更新時刻(秒)」を表します。時間を作成する必要がある場合は、追加のツールが必要です。DIR="/mnt/usb"
if [ -w "$DIR" ];それから
echo "$DIR は書き込み可能です"
それ以外の場合
echo "$DIR は書き込み可能ではありません"
フィ
-wディレクトリに「書き込み権限」があるかどうかを確認します。ただし、ディレクトリ自体は書き込み可能でも、実際のデバイスが読み取り専用である場合 (たとえば、マウントが読み取り専用である場合)、この方法は機能しない可能性があります。
DIR="/mnt/usb"
TESTFILE="$DIR/.write_test"
"$TESTFILE" 2>/dev/null をタッチした場合;それから
echo "$DIR は書き込み可能です"
rm "$TESTFILE"
それ以外の場合
echo "$DIR は書き込み可能ではありません"
フィ
この方法は最も信頼性が高く、マウント ステータスや物理デバイスが実際に書き込み可能かどうかを検出できます。
mountマウントが読み取り専用かどうかを確認する手順MNT="/mnt/usb"
マウントの場合 | grep "$MNT" | grep -q "(ro,"; then
echo "$MNT は読み取り専用でマウントされています"
それ以外の場合
echo "$MNT は書き込み可能なマウントです"
フィ
このメソッドは、デバイスが読み取り専用かどうかを確認する必要があります (ro) 方法。
シェルで「>」を使用して、コマンドの標準出力 (stdout) をファイルまたはデバイスにリダイレクトします。ファイルがすでに存在する場合、内容は上書きされます。
echo "Hello" > output.txt
この一連の指導は、"Hello"書くoutput.txtファイル。
「>>」を使用すると、元の内容を上書きせずに、指定したファイルの末尾に標準出力が追加されます。
echo "Hello again" >> output.txt
このコマンドラインは、"Hello again"に追加するoutput.txtの終わり。
シェルでは、「2>」を使用して標準エラー (stderr) を指定された場所にリダイレクトします。例えば:
ls non_existent_file 2> error.log
このコマンド行はエラー メッセージを次の場所に書き込みます。error.logファイル。
エラー メッセージ ファイルを上書きしたくない場合は、「2>>」を使用してエラー メッセージをファイルの末尾に追加できます。
ls non_existent_file 2>> error.log
このコマンド行では、エラー メッセージが追加されます。error.log。
標準出力と標準エラーの両方を同じファイルまたはデバイスにリダイレクトするには、「&>」を使用します。
command &> all_output.log
このコマンドラインは、commandすべての出力 (標準出力とエラー) は次の場所に書き込まれます。all_output.log。
`2>&1` は、標準エラーを標準出力にマージして、統合管理を容易にします。例えば:
command > output.log 2>&1
この命令行は標準出力とエラーの両方に書き込みます。output.log。
出力を表示したくない場合は、すべての出力を次のように指定できます。/dev/null、のように:
command >/dev/null 2>&1
このコマンドラインは、commandすべての出力は破棄されます。
使用中teeコマンドが出力をファイルに追加するときに、次のように渡すことができます。iconv出力を UTF-8 エンコードに変換し、ファイルの内容が UTF-8 で保存されるようにします。以下に具体的な手順と例を示します。
以下は出力を UTF-8 エンコードとして保存しますtee命令形式:
command | iconv -t utf-8 | tee -a output.txt
-t「ターゲットエンコーディング」を表します。output.txt書類。次の例は、次の方法を示しています。lsコマンドの出力は UTF-8 エンコーディングで書き込まれます。output.txt:
ls | iconv -t utf-8 | tee -a output.txt
この命令を実行すると、output.txtエンコードエラーを避けるために、コンテンツは UTF-8 エンコードで保存されます。
Win + R入力cmdそしてEnterを押してくださいcmdこのパスから直接開くことができますdir:カレントディレクトリ内のファイルやフォルダを表示します。cd: ディレクトリを切り替えます。たとえば、cd C:\Userscls:画面の内容をクリアcopy: ファイルのコピーなどcopy a.txt b.txtdel:ファイルの削除mkdir:新しいフォルダーを作成しますrmdir:フォルダの削除echo: 出力テキストなどecho Helloexit: コマンドプロンプト文字を閉じますdir > file.txt結果をファイルに出力するdir | find "txt"フィルタに含まれるものtxt結果.batファイルは複数のコマンドを一度に実行しますset変数の表示と設定ipconfig /flushdnsまたはsfc /scannowシステムメンテナンスの指示を待っています使用できます&、&&または||手順を続けるには:
cmd /k "最初のコマンドと 2 番目のコマンド"
&: 最初の処理が成功したか失敗したかに関係なく、次の処理が実行されます。&&: 最初の処理が成功した場合にのみ次の処理を実行します。||: 最初の実行が失敗した場合にのみ次の実行を実行します。最初の命令の後に追加call、別のバッチ ファイルの実行を続行できます。
cmd /k "最初のコマンドと 2 番目の.bat の呼び出し"
ウィンドウを開いたままにする必要がない場合は、次のようにすることができます/c:
cmd /c "最初のコマンドと 2 番目のコマンド"
/cすべてのコマンドを実行した後、ウィンドウが自動的に閉じられます。/kウィンドウは保持されます。
Windows コマンド プロンプト (CMD) では、変数はデータまたは設定を保存するために使用される名前空間です。これらは環境に保存することも (環境変数)、バッチ ファイルで定義して使用することもできます (地域変数)。
システムまたはユーザーによって設定された変数は、オペレーティング システム セッション全体で使用できます。例えば:%PATH%、%TEMP%。
環境変数を表示します。使用set注文。
set
環境変数を設定/変更します (現在の CMD セッションのみ):
set MY_VAR=Hello
バッチファイル内(.batまたは.cmdファイル)setコマンドで定義した変数は、このバッチ ファイルの実行中にのみ有効です。
使用中forループ時に定義された変数。ファイル、フォルダー、または数値シーケンスを反復するために使用されます。通常、名前の前に 2 つのパーセント記号を付けた 1 つの文字が付けられます。次に例を示します。%%A(バッチ ファイル内) または単一のパーセント記号。例:%A(コマンドラインから直接実行した場合)。
バッチ ファイルの実行時にバッチ ファイルに渡されるパラメーター。例えば:%1は最初のパラメータです。%2は 2 番目のパラメータです。%0バッチ ファイル自体のパスと名前です。
変数の値を取得するには、通常、変数名の前後にパーセント記号を追加する必要があります。%。
set NAME=CMD ユーザー
エコー 私の名前は%NAME%です
出力:私の名前はCMDユーザーです
@エコーオフ
set MESSAGE=これはバッチメッセージです
エコー%メッセージ%
一時停止する
使用できますIF DEFINEDまたはIF NOT DEFINEDステートメントを使用して、変数がすでに存在するか、定義されているか(空ではないか)を確認します。
@エコーオフ
rem は、変数 MY_DEFAULT_VALUE が定義されているかどうか (空ではないか) を確認します。
定義されていない場合は、MY_DEFAULT_VALUE (
set MY_DEFAULT_VALUE=Default_Setting
エコー変数 MY_DEFAULT_VALUE は未定義で、デフォルト値に設定されています。
) それ以外 (
エコー変数 MY_DEFAULT_VALUE はすでに存在します。値は %MY_DEFAULT_VALUE% です。
)
rem が 1 回実行されると、変数は Default_Setting に設定されます
rem を再度実行すると、すでに存在していることが表示されます。
set MY_DEFAULT_VALUE=既存の設定
レムはもう一度チェックしてください
定義されていない場合は、MY_DEFAULT_VALUE (
set MY_DEFAULT_VALUE=Another_Default
エコー変数 MY_DEFAULT_VALUE は未定義で、Another_Default に設定されています。
) それ以外 (
エコー変数 MY_DEFAULT_VALUE はすでに存在します。値は %MY_DEFAULT_VALUE% です。
)
一時停止する
もう 1 つの巧妙なトリックは、変数拡張のデフォルト値機能を利用することです (ただし、これは主にループとパラメーター処理に使用され、標準ではset「設定されていない場合は設定する」というロジックはコマンドに直接適用されません。したがって、IF NOT DEFINEDこれは最も標準的なアプローチです。 )
ループまたは条件ステートメントでは、標準のパーセント記号変数の展開がステートメントの解析中に 1 回発生します。ループの各反復で変数の新しい値を読み取ることができるようにするには、遅延拡張を有効にし、感嘆符を使用する必要があります。!変数を参照します。
@エコーオフ
setlocal 有効遅延拡張
setCOUNTER=0
:ループ
if %COUNTER% LSS 5 (
/A カウンター +=1 を設定します
現在のエコー数: !COUNTER!
ループに移動
)
エンドローカル
| 変数 | 説明する |
|---|---|
%DATE% |
現在の日付。 |
%TIME% |
現在の時刻。 |
%CD% |
現在のディレクトリのパス。 |
%ERRORLEVEL% |
前のコマンドの終了コード (通常は成功の場合は 0)。 |
%RANDOM% |
0 ~ 32767 のランダムな 10 進数。 |
%~dp0 |
バッチ ファイルが実行されているドライブとパス。 |
パラメーター変数の場合 (例:%1) またはループ変数 (例:%%A)、修飾子を使用してパスのさまざまな部分を抽出できます。
エコーのフルパス: %~1
エコードライブ: %~d1
エコーパス: %~p1
エコーファイル名: %~n1
エコーファイル拡張子: %~x1
これは、アーカイブ パスを操作する場合に便利です。
grep、ただし、組み込みのfindコマンドでも同様の効果が得られます。コマンド | 「キーワード」を見つけるディレクトリ | find "txt" :: "txt" を含むファイルのみを表示
ipconfig | find "IPv4" :: IPv4 を含む行のみを表示
タスクリスト | find "chrome" :: chromeを含む実行可能プログラムをフィルタリングして除外します
/I: たとえば、大文字と小文字を区別します。find /I "error"/V:キーワードを含まない行を表示します/C: 一致した行数のみを表示します。findAND 条件が満たされている場合:type log.txt | find "Error" | find "2025"
findstr:type log.txt | findstr /I "error warning fail"
findstrこれは、複数のキーワードと正規表現をサポートする高度な検索ツールの CMD バージョンです。ディレクトリ | findstr /R ".*\.txt$" :: 正規表現を使用して .txt ファイルを検索します
「log.txt」と入力します。 findstr /I "タイムアウト エラーが失敗しました"
~/.bash_profileまたは~/.bashrc。AutoRunコンテンツがあれば自動で設定が実行されます。HKEY_CURRENT_USER\Software\Microsoft\Command Processor
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor
AutoRun、コンテンツを実行するバッチ ファイルのパスに設定できます。AutoRun = "C:\Users\YourName\cmd_startup.bat"
%SystemRoot%\System32\cmd.exe /k "C:\Users\YourName\cmd_startup.bat"
/k起動後にバッチファイルを実行し、ウィンドウを開いたままにしてください。%AppData%\Microsoft\Windows\Start Menu\Programs\Startup
| Linux bash | Windows CMD対応方法 |
|---|---|
| ~/.bash_profile または ~/.bashrc | ログインフォーム AutoRun または CMD /k でバッチファイルが開始されます |
| カスタム命令を自動的に実行する | カスタマイズされた環境変数とパス設定をバッチ ファイルに配置できます。 |
HKEY_CURRENT_USER\Software\Microsoft\Command Processor存在します。AutoRun値を指定すると、自動的に作成され、指定したバッチ ファイルのパスとして設定されます。@エコーオフ
セットローカル
:: AutoRunで実行するバッチファイルのパスを設定します
「AUTORUN_PATH=C:\Users\%USERNAME%\cmd_startup.bat」を設定します。
「REG_PATH=HKCU\Software\Microsoft\Command Processor」を設定します
echo CMD AutoRun 設定を確認してください...
:: ログインコードが存在するかどうかを確認します
正規クエリ "%REG_PATH%" >nul 2>&1
エラーレベル 1 の場合 (
echo [情報] コマンド プロセッサ コードが見つかりません。作成しています...
reg add "%REG_PATH%" /f >nul
)
:: 自動実行が設定されているかどうかを確認します
reg query "%REG_PATH%" /v AutoRun >nul 2>&1
エラーレベル 1 の場合 (
echo [情報] AutoRun が見つかりません。新しい値を作成しています...
reg add "%REG_PATH%" /v AutoRun /d "%AUTORUN_PATH%" /f >nul
echo [完了] AutoRun が次のように設定されました: %AUTORUN_PATH%
) それ以外 (
echo [OK] AutoRun はすでに存在しており、変更されていません。
)
エンドローカル
一時停止する
reg query: ログインキーまたは値が存在するかどうかを確認するために使用されます。errorlevel: クエリ結果が成功したかどうかを判断するために使用できます (0 は存在することを意味し、1 は存在しないことを意味します)。reg add: ログインキーまたは値を作成します。/f: 強制カバレッジのプロンプトは表示されません。%AUTORUN_PATH%CMD 起動時に自動実行したいバッチファイルのパスに変更します。@エコーオフ
:: PowerShell を検出する
PSModulePath が定義されている場合 (
echo は現在 PowerShell で実行されています
ジャンプ:eof
)
:: Cygwin の検出
CYGWIN が定義されている場合 (
echo は現在 Cygwin で実行されています
ジャンプ:eof
)
SHELL が定義されている場合 (
echo は現在 Cygwin で実行されています (SHELL=%SHELL%)
ジャンプ:eof
)
::デフォルトはCMDです
echo は現在 CMD で実行されています
PSModulePath存在するだろうCYGWIN変数、またはSHELL=/bin/bashWin + X「Windows PowerShell」または「Windows ターミナル」を選択します。powershellこのパスから直接開くことができますGet-ChildItem: 現在のディレクトリ内のファイルとフォルダーを一覧表示します (dir)Set-Location:ディレクトリ切り替え(略称)cd)Clear-Host:画面内容をクリア(略称)cls)Copy-Item:ファイルまたはフォルダーをコピーしますRemove-Item:ファイルまたはフォルダーを削除しますNew-Item:新しいファイルまたはフォルダーを作成しますWrite-Output:出力テキスト(略称)echo)Exit:PowerShellを閉じるGet-Process | Where-Object {$_.CPU -gt 100}Get-ChildItem > file.txtls、cp、rm直接使用可能$var = "Hello"、出力$var.ps1ファイル実行複数コマンドGet-EventLog、Set-ExecutionPolicyシステムメンテナンスの指示を待っていますGet-Variable: 現在の PowerShell セッション内のすべての変数を表示しますGet-ChildItem variable:: 変数ドライバーを介してすべての変数を表示します# すべての変数をリストする
変数の取得
# 変数名のみを表示
変数の取得 |オブジェクト名を選択
# 特定の変数の値を表示する
変数 PATH を取得 |フォーマットリスト *
#変数ドライバーメソッドを使用する
Get-ChildItem 変数:
variable:変数を操作するためのパスとして使用できます。たとえば、Get-Content variable:PATHWhere-Object、例えば:Get-Variable | Where-Object { $_.Name -like "P*" }P で始まる変数のみを表示しますプリプロセッサ ディレクティブは、C または C++ プログラム コードがコンパイラによって正式に処理 (コンパイル) される前に、「プリプロセッサ」と呼ばれるプログラム モジュールによって実行されるコマンドです。これらの指示の前にはシャープ記号 (#) の前にセミコロン (;) 最後に。
プリプロセッサの役割は、テキストの置換、ファイルのインクルード、条件付きコンパイルなどの操作を実行して、コンパイラが使用する最終的な「翻訳単位」を生成することです。
他のファイルの内容を現在のファイルに挿入するために使用されます。
#include <filename>: 標準ライブラリのヘッダー ファイルをインクルードするために使用されます。プリプロセッサは、コンパイラのデフォルトのシステム ヘッダー ファイル パスでファイルを検索します。#include "filename": ユーザー定義のヘッダー ファイルを含めるために使用されます。プリプロセッサは、まず現在のソース コード ファイルのディレクトリを検索し、次にシステム パスを検索します。#include // 標準 I/O ライブラリをインクルードする
#include "my_utility.h" // カスタムヘッダーファイルをインクルードします
記号定数またはコードフラグメントを定義するために使用されるリテラル置換マクロ。
#define: マクロを定義します。#undef: マクロの定義を解除します。#define MAX_SIZE 100 //シンボリック定数を定義
#define SUM(a, b) ((a) + (b)) // パラメータを使用してマクロを定義します
int main() {
int サイズ = MAX_SIZE; // 前処理後は int size = 100;
int 合計 = SUM(5, 3); // 前処理後は int total = ((5) + (3));
0を返します。
}
プリプロセッサ マクロの値に基づいて、コードの特定のブロックをコンパイルする必要があるかどうかを決定できます。
#ifdef: マクロが定義されている場合は、後続のブロックをコンパイルします。#ifndef: マクロが定義されていない場合は、後続のブロックをコンパイルします。 (インクルード ガードでよく使用されます)#if: 指定された定数整数式の値に基づいてコンパイルするかどうかを決定します。#else / #elif: 条件付きコンパイルの置換またはその後の判定。#endif: 条件付きコンパイルブロックを終了します。#define DEBUG_MODE 1
#if デバッグモード
std::cout << "デバッグモードが有効です" << std::endl;
#else
std::cout << "本番モード実行中" << std::endl;
#endif
#ifndef MY_HEADER_H
#defineMY_HEADER_H
// ... ヘッダー ファイルの内容 (インクルード ガードの例)
#endif
#error: このディレクティブが見つかったときにプリプロセッサにコンパイルを強制的に停止させ、指定されたエラー メッセージを表示します。#warning: コンパイルを停止せずに、指定された警告メッセージを出力します (非標準ディレクティブですが、多くのコンパイラでサポートされています)。#ifndef VERSION_DEFINED
#error "バージョン番号マクロ VERSION_DEFINED を定義する必要があります!"
#endif
#pragma: 特別な命令をコンパイラに送信するために使用され、動作はコンパイラに大きく依存します (例:#pragma onceそして#pragma warning)。#line: コンパイラがエラーまたは警告を報告したときに表示される現在の行番号とファイル名を変更するために使用されます。#pragma onceC および C++ 言語の 1 つですプリプロセッサディレクティブ。その中心的な機能は、このディレクティブを含むヘッダー ファイルが 1 回のコンパイル プロセス中にのみコンパイラによって処理されるようにすることです。一度。
このディレクティブの目的は、ヘッダー ファイルが繰り返しインクルードされる問題を解決し、複数のソース コード ファイルまたはマルチレベルのヘッダー ファイルのインクルード関係により、同じコード部分 (クラス定義、関数プロトタイプ、定数宣言など) がコンパイラーによって何度も認識されることを防ぐことです。再定義コンパイルエラー。
C/C++ 標準では、伝統的に次を使用します。ガードを含む繰り返し混入を防止するという目的を達成するため。#pragma onceよりクリーンな代替手段を提供します。
これは、条件付きコンパイル ディレクティブを使用する、標準的で移植可能なアプローチです。
#ifndef MY_HEADER_H
#defineMY_HEADER_H
// ヘッダーファイルの内容
#endif // MY_HEADER_H
これは一意のマクロ名に依存します (例:MY_HEADER_H) コンテンツを含めるかどうかを制御します。
単一行ディレクティブを使用します。
#プラグマワンス
// ヘッダーファイルの内容
コンパイラは、現在のコンパイル セッションでこのファイルがすでに処理されているかどうかを自動的に追跡し、処理されている場合は、ファイルの残りの内容をスキップします。
最新の開発環境、特に Visual Studio または主流のコンパイラを使用する場合、#pragma onceシンプルで便利なため、ヘッダー ファイルが繰り返しインクルードされるのを防ぎます。一般的で推奨される実践。
#pragma warningは、コードの特定のブロック内で使用される C および C++ 言語のプリプロセッサ ディレクティブです。コンパイラ警告の重大度を選択的に抑制、復元、または変更します。。
このディレクティブの主な目的は、プロジェクト レベルの設定よりも細かい制御を提供することです。たとえば、大量の警告を生成する古いバージョンのライブラリを含める必要があるが、警告を全体的にオフにしたくない場合に、このコマンドを使用します。
それでも#pragma warning特定の実装はコンパイラによって若干異なる場合があります (特に MSVC が最も広く使用されています) が、その中心となるアクションは次のタイプに分類されます。
この時点から、コンパイラは指定された警告コードを無視します。
#pragma warning( disable : 4996 ) // C4996 を無効にする (例: 安全でない関数の使用に関する警告)
// C4996 を生成するコードを含めるか、記述する
指定された警告を、プロジェクトまたはコマンド ラインによって設定されたデフォルトの動作に戻します。
#pragma warning(default: 4996) //C4996 をデフォルトの状態に戻す
これは最も安全であり、最も推奨されるモードです。これにより、特定のコード ブロックの処理中に警告設定を変更でき、ブロック終了直後に元の警告状態が確実に復元されて副作用が回避されます。
#pragma warning( push ):現在の警告設定のスタック状態を保存します。#pragma warning( pop ):最新の状態に戻すpush保管状態。#pragma warning( Push ) // 1. 現在の警告設定を保存します。
#pragma warning( disable : 4996 4244 ) // 2. 複数の特定の警告を無効にします
// サードパーティのヘッダー ファイルまたはレガシー コードが含まれています
#pragma warning( Pop ) // 3. 元の設定に戻す
// 後続のコードは復元された設定を使用します
Promote a specific warning code to a compilation error.警告が発生した場合、コンパイルは失敗します。
#pragma warning( error : 4005 ) // 警告 4005 をエラーとして扱います
4996)はいコンパイラ固有の。使用しているコンパイラ (MSVC など) の正しい番号を検索する必要があります。#pragma warning関数を使用しますが、通常は使用することを好みます。-W...コマンドラインフラグまたは特別な#pragma GCC diagnostic警告を制御する構造。C++プログラミングでは、std::標準名前空間を指します。これは、関数、クラス、テンプレート、マクロ、オブジェクトなど、C++ 言語コアとその標準ライブラリ (標準ライブラリ) のすべての標準エンティティを含むコンテナです。
使用std::主な目的は避けることです名前の衝突。標準関数 (例:coutまたはvector) は別の名前空間に配置されません。ユーザーが同じ名前のエンティティを定義すると、コンパイラはどれを使用すればよいのかわかりません。
C++ 標準ライブラリのほとんどの機能は、次の場所にあります。std::名前空間内で。主なカテゴリと機能は次のとおりです。
std::cout: 標準出力ストリーミング オブジェクト。データをコンソールに出力するために使用されます。std::cin: コンソールからデータを読み取るために使用される標準入力ストリーム オブジェクト。std::endl: 改行を出力し、バッファをフラッシュします。std::ifstream / std::ofstream:ファイル入出力ストリーミング。データの保存に使用されるコレクション カテゴリ:
std::vector:動的にサイズ変更される配列。std::list:双方向接続シーケンス。std::map: ソートされたキーと値のペアのコレクション (赤黒ツリー実装)。std::unordered_map: キーと値のペアの順序付けされていないコレクション (ハッシュ テーブルの実装)。std::set: ソートされた一意のキー値のコレクション。std::string: 文字列の処理に使用されるカテゴリ。コンテナーおよび範囲操作の一般的な関数のセット:
std::sort: 範囲内の要素を並べ替えます。std::find:指定した値を範囲内で検索します。std::copy: 要素をある範囲から別の範囲にコピーします。std::shared_ptr / std::unique_ptr: 自動メモリ管理のためのインテリジェントなインジケーター。std::thread: マルチスレッドプログラミングに使用されます。std::function: ユニバーサル関数ラッパー。std::pair / std::tuple: さまざまな型の固定数の値を保存するために使用されるテンプレート。アクセスするstd::ネームスペース内のエンティティには主に 2 つのメソッドがあります。
使用するたびに明確に記入してくださいstd::接頭辞。これは、グローバル名前空間の汚染を避けるために、特にヘッダー ファイルにおいて、最も安全で推奨されるアプローチです。
int main() {
std::cout << "Hello World" << std::endl;
std::vector<int> numbers;
return 0;
}
使用using namespace std;全体std::名前空間の内容は現在のスコープに導入され、名前は何もせずに直接使用できます。std::接頭辞。
#include
名前空間 std を使用します。 // std:: 名前空間を導入します
int main() {
コート << 「ハローワールド」<<終わり; // std:: プレフィックスは必要ありません
ベクトル数字。
0を返します。
}
それでもusing namespace std;便利ですが、名前が競合するリスクが高まるため、大規模なプロジェクトやヘッダー ファイルでは使用しないでください。
C++では、std::stringカテゴリ(クラス)です。を宣言すると、std::string変数に初期値が与えられていない場合、デフォルト コンストラクターが呼び出されます。
"")。0。NULLインジケーターですが、有効なオブジェクトです。#include <文字列>
#include
void 初期化_example() {
std::string ; // 宣言されているが値が与えられていない
std::cout << "長さ: " << s.length() << std::endl; // 出力: 0
std::cout << "コンテンツ: '" << << "" << std::endl; // 出力: ''
}
文字列に文字が含まれていないことを確認するには、最も推奨される方法は次のとおりです。empty()メンバー関数、チェックよりも優れていますlength() == 0一部のコンテナーでは、よりセマンティックで効率的です。
void check_empty(std::string s) {
if (s.empty()) {
std::cout << 「これは空の文字列です。」 << std::endl;
}
}
これはよくある誤解です。std::string オブジェクト自体が null になることはありません。
C++ では「ポインタ」のみを指定できます。nullptr。文字列に値が割り当てられていないかどうかをチェックすることについて言及している場合、通常は、値が割り当てられているかどうかをチェックします。empty()。 C スタイルの文字列ポインターを扱っている場合 (char*)、null をチェックする必要があります。
| タイプ | 確認方法 | 述べる |
|---|---|---|
| std::string s; | s.empty() | コンテンツの長さが 0 かどうかを確認する |
| std::string* ptr; | ptr == nullptr | 「インジケーター」自体がギャップを指しているかどうかを確認する |
| char* c_str; | c_str == nullptr | C スタイルの文字列ポインタが空かどうかを確認する |
既存の文字列を元の空の状態に復元する場合は、次の方法を使用できます。
void clear_example() {
std::string s = "こんにちは";
s.clear(); // 方法 1: 最も一般的に使用される
s = ""; // 方法 2: 再割り当て
s = std::string(); // 方法 3: デフォルトのオブジェクトを割り当てる
}
これは、C++11 で導入された最も簡単なメソッドであり、数値を文字列に変換します。デフォルトでは、小数点以下 6 桁が保持されます。
#include <文字列>
#include
void simple_convert() {
浮動小数点値 = 3.14159f;
std::string s = std::to_string(val);
std::cout << << std::endl; // 出力例:「3.141590」
}
小数点以下の桁数や特定の形式を制御する必要がある場合は、stringstreamこれは最も柔軟なオプションです。それは結合します<iomanip>ライブラリを使用して出力を正確に制御します。
#include
#include
void precision_convert() {
浮動小数点値 = 3.1415926f;
std::stringstream ss;
// 固定小数点のカウント方法 (固定) を設定し、小数点以下 2 桁を保持します
ss << std::fixed << std::setprecision(2) <<ヴァル;
std::string s = ss.str();
std::cout << << std::endl; // 出力: "3.14"
}
C++20 では、フォーマット文字列を使用して、最も簡潔な構文で型変換と精度制御を同時に処理できます。
#include <フォーマット>
void modern_format() {
フロート値 = 123.456f;
// {:.2f} は float 型を表し、小数点以下 2 桁を保持します
std::string s = std::format("{:.2f}", val);
std::cout << << std::endl; // 出力: "123.46" (自動的に四捨五入されます)
}
std::to_string多くの場合、「3.140000」のような余分なゼロが含まれます。組み合わせることができますfind_last_not_ofそしてerase文字列をクリーンアップします。
std::string delete_trailing_zeros(float val) {
std::string s = std::to_string(val);
// ゼロ以外の文字が出現するまで末尾の「0」を削除します
s.erase(s.find_last_not_of('0') + 1, std::string::npos);
// 最後の文字が小数点の場合はそれも削除します
if (s.back() == '.') {
s.pop_back();
}
を返します。
}
| 方法 | 特徴 | 推奨されるシナリオ |
|---|---|---|
| std::to_string | 構文は最短であり、パフォーマンスは許容範囲内です | 小数点以下の桁数に関する要件がない場合の迅速なデバッグ |
| std::stringstream | 高度にカスタマイズ可能 (ゼロパディング、幅、キャリー) | 出力形式を厳密に制御する必要がある場合 |
| std::format | 型安全性、パフォーマンス、最新の構文 | C++20 環境での推奨ソリューション |
| sprintf (C スタイル) | 非常に高速だが安全性は低い | パフォーマンスを極限まで追求した古いコードの保守 |
これは、外部ライブラリに依存しない C++ の最も標準的なアプローチです。を通してfind区切り文字の位置を見つけて使用しますsubstr部分文字列を取得します。
#include
#include <ベクトル>
#include <文字列>
void split_by_three_chars() {
std::string text = "リンゴ---バナナ---チェリー---日付";
std::string 区切り文字 = "---";
std::vectorトークン。
サイズ_t pos = 0;
size_t last_pos = 0;
//ループして区切り文字を検索します
while ((pos = text.find(delimiter, last_pos)) != std::string::npos) {
tokens.push_back(text.substr(last_pos, pos - last_pos));
last_pos = pos + delimiter.length();
}
//最後のフラグメントを挿入します
tokens.push_back(text.substr(last_pos));
//結果を出力する
for (const auto& t : トークン) std::cout << "[" << t <<; "]" << std::endl;
}
文字列が非常に大きい場合は、使用しますstd::string_view分割プロセス中に大量の文字列コピーが生成されるのを回避できるため、パフォーマンスが大幅に向上します。
#include <string_view>
#include <vector>
std::vector<std::string_view> split_sv(std::string_view str, std::string_view del) {
std::vector<std::string_view> output;
size_t first = 0;
while (first < str.size()) {
const auto second = str.find(del, first);
if (second == std::string_view::npos) {
output.emplace_back(str.substr(first));
break;
}
output.emplace_back(str.substr(first, second - first));
first = second + del.size();
}
return output;
}
コードをより簡潔に見せたい場合、または区切り文字が変更される可能性がある場合は、次のように使用できます。std::regex。ただし、正規表現の実行パフォーマンスは通常、手動よりも優れていることに注意してください。find遅い。
#include <正規表現>
void regex_split() {
std::string text = "One###Two###Three";
std::regex ws_re("###"); // 3 文字の区切り文字を定義します
std::copy(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),
std::sregex_token_iterator()、
std::ostream_iterator(std::cout, "\n"));
}
| 方法 | アドバンテージ | 欠点がある |
|---|---|---|
| std::find + substr | 最高の互換性 (C++98+) と安定したパフォーマンス。 | コードは長いため、最後のフラグメントを手動で処理する必要があります。 |
| string_view | 最も効果的な、追加のメモリコピーは生成されません。 | C++17 のサポートが必要であり、元の文字列のライフサイクルに注意を払う必要があります。 |
| std::regex | 構文は最も簡潔で拡張可能です。 | 実行速度は最も遅く、コンパイル時間は長くなります。 |
C++ で確認するにはstd::vectorコンテナーに要素が含まれていない場合 (つまり、サイズがゼロの場合)、最も標準的で推奨される方法は、そのメンバー関数を使用することです。empty()。これは、empty()通常、関数は直接チェックよりも優れていますsize()ゼロに等しいと、特に一部のコンテナ実装では効率的になります。
これは、ベクトルが空かどうかを確認するための推奨される方法です。ブール値を返します。vector に要素がない場合は、値を返します。true;それ以外の場合は戻るfalse。
#include <ベクトル>
#include
#include <文字列>
void check_empty(const std::vector& vec)
{
if (vec.empty()) {
std::cout << 「ベクトルは空です (empty() == true)。」 << std::endl;
} それ以外の場合は {
std::cout << "ベクトルは空ではありません (empty() == false)。要素の数: " << vec.size() << std::endl;
}
}
int main()
{
std::vector空の_vec;
std::vector non_empty_vec = {"リンゴ", "バナナ"};
check_empty(empty_vec);
check_empty(non_empty_vec);
0を返します。
}
これは有効ではありますが、空のステータスを確認する最も慣用的な方法ではなく、最も効率的な方法である可能性もあります。ベクトル内の要素の数がゼロかどうかを直接チェックします。
void check_size(const std::vector& vec)
{
if (vec.size() == 0) {
std::cout << 「ベクトルは空です (size() == 0)。」 << std::endl;
} それ以外の場合は {
std::cout << 「ベクトルは空ではありません (size() != 0)。」 << std::endl;
}
}
のためにstd::vectorに関してはempty()そしてsize() == 0ベクトルはそのサイズをメンバー変数として保存するため、時間計算量は $O(1)$ です。ただし、他の一部の C++ 標準コンテナ (例:std::listまたはstd::forward_list)、標準的な推奨事項は常に使用することです。empty()これは、一般に、空のステータスをチェックするための C++ 標準コンテナ ライブラリの中で最も一般的かつ最速のイディオムであるためです。
C++ では、スペースまたはタブ文字を含む文字 (\t) 分離された文字列は個々の単語またはトークンに解析され、次の場所に保存されます。std::vector<std::string>、最も一般的な方法は ** を使用することですstd::stringstream**。ファイルストリーミングカテゴリstd::stringstreamインメモリ ストリームと同様に、デフォルトでは、読み取り操作の区切り文字として空白文字 (スペース、タブ、改行を含む) が使用されます。
以下が使用されますstd::stringstreamこのタスクを実行する C++ コードの例:
#include
#include // 文字列ストリームを含める
#include <文字列>
#include <ベクトル>
名前空間 std を使用します。
/**
* 入力文字列を空白文字 (スペースまたはタブ) で区切ってベクトルに格納します。
* @param input_str 解析する文字列。
* @return 分離されたすべての単語を含むベクトル。
*/
ベクトル<文字列> split_string_by_whitespace(const string& input_str)
{
ベクトル<文字列>トークン;
// 1. stringstream オブジェクトを作成し、入力文字列で初期化します。
文字列ストリーム ss(input_str);
文字列トークン。
// 2. ループ読み取り
// ストリーム抽出演算子 (>>) は、空白文字 (スペース、タブなど) を区切り文字として使用して、次のトークンを自動的に読み取ります。
// 演算子は、トークンが正常に読み取られた場合は true を返し、それ以外の場合 (文字列の終わりに達した場合) は false を返します。
while (ss >> トークン)
{
tokens.push_back(トークン);
}
トークンを返す。
}
int main()
{
//入力文字列には複数のスペースとタブ記号 (\t) が含まれています
string test_string = "こんにちは\tWorld、これは\taテスト文字列です";
コート << "元の文字列: " <<テスト文字列 <<終わり;
ベクトル<文字列>結果 = split_string_by_whitespace(test_string);
コート << "--- 別の結果 ---" <<終わり;
for (size_t i = 0; i
std::stringstream ss(input_str): このカテゴリは入力文字列を入力ストリーム (Input Stream) として扱い、その機能はファイルから読み取るときに使用されるものと似ています。std::ifstream。>>):
while (ss >> token): これは慣用的な C++ ストリーム読み取りループです。ストリームがデータを正常に抽出して保存している限り、token変数を指定すると、ループは実行を継続します。C++ では、次のように使用できます。std::array多次元配列を 0 に初期化します。
#include
#include <配列>
名前空間 std を使用します。
int main() {
配列<配列, 3> arr = {0}; // すべての要素を 0 に初期化します
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
コート << arr[i][j] << " ";
}
コート <<終わり;
}
0を返します。
}
std::arrayC++ 標準ライブラリのコンテナ クラスであり、コンパイル時にサイズが固定される状況に適しています。std::arrayより多くの機能とセキュリティを提供します。C++ では、ループは、コンテナーまたは配列内のすべての要素を反復する基本操作です。std::vector(動的サイズのコンテナー) およびstd::array(固定サイズ コンテナー) は、さまざまな標準的かつ安全な方法で要素を反復できる C++ 標準ライブラリ (STL) 内のコンテナーです。
これは、C++11 で導入された最も最新で、最も安全で、最も簡潔なトラバーサル方法です。すべての標準コンテナー (以下を含む) で動作します。std::vectorそしてstd::array)。
std::vector: **優先**std::array: **優先**#include
#include <ベクトル>
#include <配列>
void range_based_loop_example()
{
std::vector<int> vec = {10, 20, 30};
std::array arr = {1, 2, 3, 4};
// 自動を使用する(&)参照によって走査するため、効率的で要素の変更が可能になります。
std::cout << "--- ベクトル (変更可能) ---" << std::endl;
for (auto& 要素 : vec) {
要素 += 1; // 要素を変更する
std::cout <<要素 << " ";
}
std::cout << std::endl;
// const auto& を使用します。定数参照によるトラバース。安全で要素の変更は許可されません。
std::cout << "--- 配列 (読み取り専用) ---" << std::endl;
for (const auto& 要素 : arr) {
std::cout <<要素 << " ";
}
std::cout << std::endl;
}
これは伝統的かつ普遍的な方法です。要素インデックスにアクセスする必要がある状況に適しています (たとえば、2 つのコンテナーまたは配列を同時に操作する必要がある、または特定のインデックスで終了する必要がある)。
std::vector:該当、使用size()境界線を取得します。std::array:該当、使用size()境界線を取得します。#include
#include <ベクトル>
#include <配列>
void Index_loop_example()
{
std::vector名前 = {"アリス"、"ボブ"、"チャーリー"};
std::array価格 = {10.5, 20.99, 5.0};
// size() で size_t または auto を使用して、インデックス タイプが正しく、境界が安全であることを確認します
for (size_t i = 0; i < names.size(); ++i) {
// 要素にアクセスするには、operator[] を使用します
std::cout << 「名前:」 <<名前[i] << "、価格: " <<価格[i] << std::endl;
}
}
注: 使用する[]C++ は、演算子が要素にアクセスするときに境界チェックを実行しません。境界チェックが必要な場合は、次を使用します。at()関数 (範囲外の場合にスローされます)std::out_of_range異常な)。
これは C++ で最も柔軟なトラバーサル方法であり、すべての標準コンテナで動作します。イテレータは、C++ 標準ライブラリ (STL) アルゴリズムを操作するときに必要です。
std::vector: **推奨** (STL アルゴリズムまたは特定の制御が必要な場合)std::array: **推奨** (STL アルゴリズムが必要な場合)#include
#include <ベクトル>
void iterator_loop_example()
{
std::vector<double>値 = {100.0, 50.0, 10.0};
// auto を使用して反復子の型を簡略化し、begin() と end() を使用して範囲を取得します
for (auto it = value.begin();
それ != 値.end();
++それ)
{
*it /= 10.0; // *イテレータを逆参照し、要素にアクセスします
std::cout << *それ << " ";
}
std::cout << std::endl;
// cbegin() と cend() を使用して、読み取り専用のトラバーサルに対してイテレータが const であることを確認します。
for (auto cit = value.cbegin(); cit != value.cend(); ++cit)
{
// *cit = 5 を試します;コンパイルエラーが発生します
std::cout << *引用<< " ";
}
std::cout << std::endl;
}
| ループ方式 | 適用容器 | アドバンテージ | 適用時間 |
|---|---|---|---|
| 範囲ベース | std::vector、std::array、すべての標準コンテナ | 最もクリーンで安全な最新の C++ イディオム。 | インデックスは必要なく、各要素を走査するだけで済みます。 |
| インデックスベース | std::vector, std::array | インデックスへのアクセスが可能で汎用性が高い。 | 要素のインデックスを把握または操作する必要がある場合。 |
| イテレーター | すべての標準コンテナ | 非常に柔軟で、次のような STL アルゴリズムで使用できます。std::find) 完璧にフィットします。 |
STL アルゴリズムを使用する必要がある場合、またはコンテナーに対して複雑な操作を実行する必要がある場合。 |
std::array<std::array<std::array<float, 2>, 2>, 2> twoLines;
std::array<std::array<std::array<float, 2>, 2>, 2> twoLinesCopy;
std::array浅いレベルから深いレベルまでの完全なコピーをサポートしているため、そのまま使用できます=:
twoLinesCopy = twoLines;
std::copy(twoLines.begin(), twoLines.end(), twoLinesCopy.begin());
std::memcpy(&twoLinesCopy, &twoLines, sizeof(twoLines));
twoLinesCopy = twoLines;std::copySTL 汎用メソッドを必要とするアプリケーションに適しています。memcpyPOD (Plain Old Data) にのみ適用され、コンストラクター/デコンストラクター ロジックには適用されません。C++ では、ポインタを操作するか、インデックスを使用して配列/メモリにアクセスするときに、無効または範囲外のメモリ位置にアクセスすると、この問題が発生します。未定義の動作。通常、この動作はプログラムとして現れます。クラッシュセグメンテーション違反やアクセス違反エラーなど。
C++標準try-catchこのメカニズムは主に、プログラム コードで明示的にスローされる C++ 例外 (例外) をキャッチするために使用されますが、オペレーティング システムによって発行されるハードウェア エラーやメモリ アクセス エラーを直接キャッチすることはできません。
C++ プログラムが無効なメモリにアクセスしようとすると、たとえば次のようになります。
nullptr記憶の。deleteまたはfreeメモリを解放しました。これらの操作により、基礎となるオペレーティング システムの保護メカニズム (Windows のアクセス違反や Unix/Linux の SIGSEGV シグナルなど) がトリガーされ、プログラムはオペレーティング システムによって終了されます。これらのエラーは、C++ 言語レベルの例外オブジェクト (たとえば、std::exception)、標準try-catch彼らを捕まえる方法はありません。
#include
#include <ベクトル>
名前空間 std を使用します。
void crash_function()
{
// 配列の境界外アクセスの例
ベクトル vec = {10, 20};
コート << "範囲外のインデックスにアクセスしようとしています..." <<終わり;
// これは未定義の動作であり、アクセス違反によるクラッシュを引き起こす可能性があります。
int 値 = vec[100]; // エラー: 無効なインデックスにアクセスしています
コート << "値: " <<値 <<終わり;
}
int main()
{
試してみる
{
クラッシュ関数();
//プログラムは上記の vec[100] でクラッシュするため、ここでは実行されません。
// そして、catch ブロックは実行されません。
}
catch (const 例外& e)
{
// オペレーティング システム レベルのエラーはここではキャプチャできません
エラー <<; "C++ 例外をキャッチしました: " << e.what() <<終わり;
}
キャッチ(...)
{
// まだメモリアクセスエラーを捕捉できません
エラー <<; "不明な例外をキャッチしました" <<終わり;
}
0を返します。
}
最善のアプローチは、このようなエラーを検出しようとするのではなく、コードの設計段階でそのようなエラーが発生しないようにすることです。
std::vectorそしてstd::string、使用at()代わりにメンバー関数[]オペレーター。いつat()範囲外の場合、C++ 例外がスローされます。std::out_of_range、標準化できるtry-catch捕獲。std::unique_ptr, std::shared_ptr) メモリのライフサイクルを自動化します。逆参照しないでくださいnullptr、ポインタを逆参照する前に、ポインタが有効かどうかをチェックします。void セーフ関数()
{
ベクトル vec = {10, 20};
試してみる
{
int 値 = vec.at(100); // 抛出 std::out_of_range 异常
コート << "値: " <<値 <<終わり;
}
catch (const std::out_of_range& e)
{
// C++ 例外を正常にキャッチしました
エラー <<; "安全捕获: " << e.what() <<終わり;
}
}
Windows 環境では、Microsoft の拡張構造化例外処理 (SEH) を使用して、アクセス違反などのオペレーティング システム レベルのエラーを捕捉できます。これは通常、次を使用して行われます__tryそして__exceptキーワード。
注: SEH は非標準であるため、移植可能な C++ コードでの使用は推奨されません。 C++/CLI プロジェクトでは、.NET のtry/catchいくつかの SEH 例外をキャッチしますが、これには特定のコンパイラ設定が必要です (例:/EHa)。
C++ では、インデックス操作に生の配列 (C スタイルの配列) またはポインターを使用するときに、配列の範囲外または無効なメモリ位置にアクセスすると、この問題が発生します。未定義の動作。この動作により、プログラムがオペレーティング システム レベルで実行されることがよくあります。クラッシュアクセス違反やセグメンテーション違反など。
重要なポイントは次のとおりです。C++標準try-catchこのメカニズムは、プログラム コードで明示的にスローされる C++ 例外 (Exceptions) をキャッチするように設計されています。オペレーティング システムによって発行されるハードウェアまたはメモリ保護エラーを捕捉できません。
C++ プログラムが無効なメモリにアクセスしようとしたとき (静的配列へのアクセスなど)arr[100]ただし、配列には要素が 10 個しかありません)、これはオペレーティング システムのメモリ保護ルールに違反します。オペレーティング システムが介入してプログラムを終了する信号または例外を送信し、システムや他のプログラムが損傷するのを防ぎます。これらのエラーは C++ 言語レベルではありませんstd::exceptionオブジェクトであるため、標準では使用できませんtry-catchブロックキャプチャ。
#include
#include // 標準例外を含める
名前空間 std を使用します。
void crash_function()
{
// C スタイルのプリミティブ配列
int raw_array[5] = {1, 2, 3, 4, 5};
コート << "範囲外のインデックスにアクセスしようとしています..." <<終わり;
// 配列の境界外アクセス: これは典型的な未定義の動作です
// プログラムがアクセス許可を持たないメモリにアクセスすると、すぐにアクセス違反が発生し、プログラムがクラッシュします。
int 値 = raw_array[100]; // エラー: 無効なインデックスにアクセスしています
コート << "値 (到達可能な場合): " <<値 <<終わり;
}
int main()
{
試してみる
{
クラッシュ関数();
// プログラムは raw_array[100] で終了し、ここでは実行されません。
}
catch (const 例外& e)
{
// オペレーティング システム レベルのメモリ アクセス エラーはここではキャプチャできません
エラー <<; "C++ 例外をキャッチしました: " << e.what() <<終わり;
}
0を返します。
}
ベスト プラクティスは、範囲外のアクセスを完全に回避するか、C++ が提供する安全なコンテナーとメソッドを使用することです。これらは、エラーが発生したときにキャッチ可能な C++ 例外をスローします。
のためにstd::vector容器、使用at()オリジナルのメンバー関数の代わりに[]オペレーター。アクセスが範囲外になると、at()**を投げますstd::out_of_range**例外。これは標準の C++ 例外であり、次のことが考えられます。try-catch捕獲されて安全に処分されました。
#include <ベクトル>
// ... (その他のインクルード)
voidsafe_vector_access()
{
std::vector<int> vec = {10, 20};
試してみる
{
// 境界チェックには at() を使用します
int 値 = vec.at(100);
std::cout << "値: " <<値 << std::endl;
}
catch (const std::out_of_range& e)
{
// C++ 例外を正常にキャッチしました
std::cerr << "範囲外の例外を安全にキャッチしました: " << e.what() << std::endl;
}
}
C++11を使用して導入std::arrayC スタイルの配列を置き換えます。それでもstd::arrayの[]演算子はチェックされませんが、at()この関数はまたスローしますstd::out_of_range異常な。
#include <配列>
// ...
voidsafe_array_access()
{
std::array arr = {1、2、3、4、5};
試してみる
{
int 値 = arr.at(5); // 範囲外にアクセスすると例外がスローされます
}
catch (const std::out_of_range& e)
{
std::cerr << "std::array 境界外キャプチャ: " << e.what() << std::endl;
}
}
Windows などの特定のプラットフォームでは、**構造化例外処理 (SEH)** を使用して、オペレーティング システムによって発行されたハードウェア例外 (アクセス違反など) を捕捉できます。これには通常、Microsoft 拡張機能の使用が含まれます__tryそして__exceptキーワード。この方法はプラットフォームの非標準であり、コードの移植性が犠牲になるため、通常のエラー処理メカニズムとしては推奨されません。
C++/CLI でSystem::Collections::Generic::List<T>、存在しないインデックスにアクセスしようとした場合 (例:size1ですがアクセスindex1)、プログラムしませんデフォルト値 (0 または null など) を指定すると、すぐに例外がスローされます。
System::ArgumentOutOfRangeExceptionインデックスにアクセスする前に、必ず次のことを確認してください。Count属性、または使用try-catchブロックは潜在的なエラーを捕捉します。
//方法 A: 事前検査 (最も推奨され、最高のパフォーマンス)
if (数値->カウント > 1) {
int 値 = nums[1];
// 処理ロジック
} それ以外の場合は {
// インデックスが不足している状況を処理します
}
//方法 B: 例外をキャッチする
{を試してください
int 値 = nums[1];
catch (System::ArgumentOutOfRangeException^ ex) {
System::Diagnostics::Debug::WriteLine("インデックスが範囲外です!");
}
| コンテクスト | 結果 | 述べる |
|---|---|---|
| インデックスが存在します (e.g., Count=5, index=1) | 正しい値を返す | 通常の動作。 |
| インデックスが存在しません (e.g., Count=1, index=1) | ArgumentOutOfRangeException をスローします | プログラムは実行を中断します。 |
| ネイティブ C++ 配列/std::vector [ ] | 未定義の動作 | コードが文字化けしたりクラッシュしたりする可能性がありますが、.NET 例外が積極的にスローされることはありません。 |
nums[i]事前に確認してくださいi < nums->Count。int value = (nums->Count > 1) ? nums[1] : 0;
System::Linq)、使用できますElementAtOrDefault(1)インデックスが存在しない場合は、型のデフォルト値 (int の場合は 0) を返します。C++ では、最も一般的に使用されるツールは次のように定義されています。<algorithm>でstd::minそしてstd::max。これらは、基本的な型、オブジェクト、さらには初期化リストをサポートします。
#include <アルゴリズム>
#include
#include <ベクトル>
void Basic_usage() {
int a = 10、b = 20;
// 1. 2 つの数値を比較します
int small = std::min(a, b);
intlarge = std::max(a, b);
// 2. 初期化リストの比較 (C++11)
int 最低値 = std::min({5, 1, 9, 3}); // 1を返す
// 3. std::minmax (C++11) - 最大値と最小値を同時に取得します
自動結果 = std::minmax({10, 20, 30, 40});
std::cout << "分: " << result.first << "、マックス: " <<結果.秒;
}
「最小」変数を初期化する必要がある場合は、通常、その変数をその型が表現できる最大の正の数値に設定して、最初の比較時に変数が更新されるようにします。
float最大値 (約 $3.4 \times 10^{38}$)。double最大値。int最大値。std::numeric_limits数値プロパティを取得するための一貫したテンプレート化された方法を提供します。これは、汎用コードを作成するときに非常に役立ちます。
#include <制限>
voidlimits_example() {
// 最大値を取得する
float max_f = std::numeric_limits<float>::max();
int max_i = std::numeric_limits::max();
// 「正の最小数」を取得します (注: 浮動小数点数の場合、min() は負の最大数ではなく正の最小数を返します)
float min_positive_f = std::numeric_limits<float>::min();
// 「最小値」(実際の最小の負の数) を取得します。
float lower_f = std::numeric_limits<float>::lowest();
}
扱っている場合std::vectorまたは配列を使用する必要がありますstd::min_elementまたはstd::max_element、彼らが返すものはイテレーター。
#include <ベクトル>
#include <アルゴリズム>
void collection_example() {
std::vectorスコア = {88.5f, 92.0f, 79.5f, 100.0f};
// 最大値のイテレータを取得する
auto it = std::max_element(scores.begin(),scores.end());
if (it != スコア.end()) {
std::cout << "最高スコア: " << *それ;
}
}
| 名前 | 使用 | 注意事項 |
|---|---|---|
| FLT_MAX | 最小値検索の初期化 | で定義されています<cfloat>、C のレガシー マクロです。 |
| std::min | 2 つの数値またはリストを比較する | パラメーターの型が一貫していない場合 (int とlong など)、テンプレートを明示的に指定する必要があります。std::min<long>(a, b)。 |
| lowest() | 最小の負の数を取得する | 浮動小数点数では、min()は 0 に近い最小の正の数です。lowest()は負の最大値です。 |
| min_element | 検索コンテナ | 返されるのはイテレータであり、使用する前にコンテナが空かどうかを確認する必要があります。 |
C++ 標準数学ライブラリでは、$\pi$ の定数定義は C++20 まで正式に標準化されていませんでしたが、さまざまな C++ バージョンやコンパイラ環境で pi の近似値を取得するために一般的に使用される方法がいくつかあります。
コードの移植性と正確性を確保するために、最も推奨されるアプローチは、std::numbers::pi。
C++20 以降の標準ライブラリは次のとおりです。<numbers>正確でタイプセーフな数学定数がヘッダー ファイルで提供されます。
#include <numbers>#include
#include <数値> // C++20で導入
void use_cpp20_pi()
{
// std::numbers::pi_v;型 T に基づいて正確な値を提供するテンプレート変数です
// std::numbers::pi (<T> なし) は std::numbers::pi_v<double> と同等です。
double pi_double = std::numbers::pi;
float pi_float = std::numbers::pi_v<float>;
long double pi_long_double = std::numbers::pi_v<long double>;
std::cout.precision(16); // 出力精度を設定する
std::cout << "C++20 (ダブル): " << pi_double << std::endl;
std::cout << "C++20 (浮動小数点数): " << pi_float << std::endl;
}
C++20 が登場する前は、多くの開発者が C 数学ライブラリ (<cmath>または<math.h>) は非標準マクロを提供します。これらのマクロはほとんどの最新のシステムに存在しますが、C++ 標準の一部ではないため、すべての環境で動作することが保証されません。
#include <cmath>(または<math.h>)#include
#include // 従来の C 数学ライブラリ
void use_c_macro_pi()
{
// M_PI は最も一般的な PI マクロで、通常は double 型として定義されます。
// 注: このマクロを有効にするには、一部のシステムで _USE_MATH_DEFINES マクロを定義する必要がある場合があります。
#ifdef M_PI
ダブル pi_value = M_PI;
std::cout.precision(16);
std::cout << "C マクロ (M_PI): " << pi_value << std::endl;
#else
std::cout << 「M_PI マクロは未定義です。_USE_MATH_DEFINES を定義する必要があるかもしれません。」 << std::endl;
#endif
}
C++20 または C マクロを使用できない場合は、$\pi$ を定数として自分で定義するか、数学関数を使用して計算することができます (例: $\arccos(-1)$)。
#include
#include
void define_or_calculate_pi()
{
// 数学的演算を通じて定義します。
const double PI_CUSTOM_CALC = std::acos(-1.0);
// 定数として直接定義します。
const double PI_CUSTOM_DEFINE = 3.14159265358979323846;
std::cout.precision(16);
std::cout << 「カスタム計算:」 << PI_CUSTOM_CALC << std::endl;
std::cout << "カスタム定義: " << PI_CUSTOM_DEFINE << std::endl;
}
std::numbers::pi。const double PI = 3.14159...;M_PIマクロですが、その非標準的な性質に注意してください。#include
#include
名前空間システムを使用します。
名前空間 System::Collections::Generic を使用します。
int main()
{
//テストデータを作成する
Dictionary<int, List<float>^>^ data = gcnew Dictionary<int, List<float>^>();
data->Add(1, gcnew List<float>({ 1.2f, 2.3f, 3.4f }));
data->Add(2, gcnew List<float>({ 4.5f, 5.5f, 6.5f, 7.5f }));
data->Add(3, gcnew List<float>()); // 空のリストをテストする
// 各キーの標準偏差を計算します
それぞれ (データ内の KeyValuePair^> エントリ)
{
int キー = エントリ.キー;
リスト<float>gt;^値=entry.Value;
if (値 == nullptr || 値->カウント == 0)
{
Console::WriteLine("キー {0}: データなし", key);
続く;
}
// 平均を計算します
二重和 = 0.0;
それぞれ (浮動小数点 v の値)
{
合計 += v;
}
二重平均 = 合計 / 値 -> カウント;
// 突然変異の数(母性突然変異の数)を計算します
二重分散 = 0.0;
それぞれ (浮動小数点 v の値)
{
二重差分 = v - 平均;
分散 += 差分 * 差分;
}
分散 /= 値->数; // サンプルのバリエーションが必要な場合は、(values->Count - 1) に変更します。
// 標準偏差
double stddev = Math::Sqrt(分散);
Console::WriteLine("キー {0}: 標準偏差 = {1:F4}", key, stddev);
}
0を返します。
}
values->Count - 1。キー 1: 標準偏差 = 0.8981 キー 2: 標準偏差 = 1.1180 キー 3: 情報がない
std::sortC++ 標準テンプレート ライブラリ (STL) で最も一般的に使用される並べ替えアルゴリズムです。それは位置しています<algorithm>ヘッダー ファイルでは、デフォルトで範囲内の要素は次のようになります。上昇並べ替える。
#include <アルゴリズム>
#include <ベクトル>
#include
void Basic_sort() {
std::vector<int>数値 = {5、2、9、1、5、6};
// ソート範囲: 開始イテレータから終了イテレータまで
std::sort(nums.begin(), nums.end());
// 結果: 1、2、5、5、6、9
}
3 番目のパラメーター (比較関数またはラムダ式) を渡すことで、並べ替えロジックを変更できます。
// 1. 累乗には事前定義された std::greater を使用します
std::sort(nums.begin(), nums.end(), std::greater<int>());
// 2. ラムダ式を使用してロジックをカスタマイズする
std::sort(nums.begin(), nums.end(), [](int a, int b) {
a > b を返します。 // true が返された場合、a は b よりも前にランク付けされます
});
カスタム型の場合は、比較ロジックを提供する必要があります。提供しない場合、コンパイラはサイズを比較する方法がわからないため、エラーを報告します。
構造体学生 {
std::文字列名;
int スコア;
};
void sort_students() {
std::vector<学生>学生 = {{"アリス", 90}, {"ボブ", 85}, {"チャーリー", 95}};
// スコアの高い順に並べ替えます
std::sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
a.score > b.score を返します。
});
}
std::sort単一の並べ替えアルゴリズムではなく、各アルゴリズムの利点を組み合わせて最悪のシナリオを回避するように設計されたハイブリッド アルゴリズムです。その動作ロジックは次のとおりです。
| 特性 | 説明する |
|---|---|
| 平均時間計算量 | $O(n \log n)$ |
| 最悪の時間複雑さ | $O(n \log n)$ (イントロソート メカニズムの利点) |
| 空間の複雑さ | $O(\log n)$ (再帰呼び出しスタッキング) |
| 安定性 | 不安定な(等しい要素の相対位置は変更される場合があります)。安定したソートが必要な場合に使用してくださいstd::stable_sort。 |
直線 $ax + by + c = 0$ と点 $P(x_0, y_0)$ の方程式が与えられた場合、点と直線の間の関係を決定する最も速い方法は、次の計算を行うことです。距離係数 $d$:
$$d = a \cdot x_0 + b \cdot y_0 + c$$
$d$ の符号に基づいて、点が線のどちら側にあるかがわかります。しかし、注意しなければならないのは、「上」または「右」の定義は、$a$ と $b$ の符号の影響を受けます。。
ほとんどのコンピューター グラフィックスの座標系では、y 軸は下向きの正の方向になります (y が小さいほど、画面の上に遠くなります)。点 $P$ がライン上にあるかどうかを判断するには、点がライン上の同じ $x_0$ である場合に、点の $y_0$ を $y_{line}$ と比較します。
// 直線の方程式: ax + by + c = 0 => y = (-ax - c) / b
bool isAbove(std::array line, float x0, float y0) {
float a = line[0];
float b = 行[1];
float c = 行[2];
// bが0の場合は縦線を表し、上下を定義できません
if (std::abs(b) < 1e-6) は false を返します。
float y_on_line = (-a * x0 - c) / b;
// y が小さいほど上を表します
戻り値 y0 <; y_オンライン;
}
同様に、ある点の $x_0$ と、線上の同じ $y_0$ の $x_{line}$ を比較します。
// 直線の方程式: ax + by + c = 0 => x = (-by - c) / a
bool isRight(std::array line, float x0, float y0) {
float a = line[0];
float b = 行[1];
float c = 行[2];
// aが0の場合は水平線を表し、左右は定義できません
if (std::abs(a) < 1e-6) は false を返します。
float x_on_line = (-b * y0 - c) / a;
// 大きい x は右辺を表します
x0 > x_on_line を返します。
}
$bを確保できれば< 0$ (透過將整個方程式乘上 -1),那麼 $ax + by + c >0$ は、点が線の上にあることを直接意味します。一般的なロジックは次のとおりです。
| ターゲット | 判定ロジック | 制限 |
|---|---|---|
| 上 (y より小さい) | $y_0 < \frac{-ax_0 - c}{b}$ | $b \neq 0$ (非垂直線) |
| 右(×の方が大きい) | $x_0 > \frac{-by_0 - c}{a}$ | $a \neq 0$ (非水平線) |
aまたはb0 の場合は、最小値を使用することをお勧めします (例:1e-6) 精度の問題を避けるための比較用。直線 $ax + by + c = 0$ の方程式が与えられた場合、直線が「水平線」に偏っているのか、「直線」に偏っているのかを判断する最も直観的な方法は、直線と座標軸との間の角度を見ることです。による45度は分割線であり、$|a|$ と $|b|$ のサイズを比較することに相当します。
使用std::abs比較するline[0]($a$) とline[1]($b$) の絶対値。
#include
#include <配列>
#include
enum クラス LineOrientation {
水平、// 水平線 (< 45 度)
垂直、// 直線 (> 45 度)
対角線 // ちょうど 45 度
};
LineOrientation checkOrientation(std::array line) {
float a = std::abs(line[0]);
float b = std::abs(line[1]);
if (a < b) {
LineOrientation::horizontal を返します。
} else if (a > b) {
LineOrientation::Vertical を返します。
} それ以外の場合は {
LineOrientation::Diagonal を返します。
}
}
傾きの公式 $m = -\frac{a}{b}$ から:
| 状態 | 分類 | 特徴 |
|---|---|---|
| |a| < |b| | 水平 | X軸との角度が小さく、「線の上・下の点」の判定に適しています。 |
| |a| > |b| | 垂直 | Y軸との角度が小さく、「線の左右の点」を判断するのに適しています。 |
| a = 0 | 絶対的な水平線 | X 軸と正確に平行です。 |
| b = 0 | 絶対的な垂直線 | Y 軸と正確に平行です。 |
ポイントとラインの位置を判断するときは、最初に次のチェックを実行することをお勧めします。
C++ では、テンプレートは汎用プログラミング ツールであり、これを使用すると、特定のデータ型を指定せずに関数やカテゴリを作成できるため、コードがより再利用可能になります。テンプレートは、単一のコードでさまざまなタイプのデータを処理するのに役立ち、関数やクラスの定義の重複を回避します。
関数テンプレートを使用すると、さまざまな型を処理できる関数を作成できます。関数テンプレートの構文は次のとおりです。
template <typename T>
T add(T a, T b) {
return a + b;
}
この例では、addこの関数は、加算演算をサポートする任意の型を処理できます。int、floatまたはdouble。
使用する場合は、次のように呼び出すことができます。
int 結果 = add(3, 4); // int型を使用する
double result2 = add(3.5, 2.7); // double 型を使用する
カテゴリ テンプレートを使用すると、複数のタイプに適用できるカテゴリを作成できます。 The syntax of a category template is as follows:
template <typename T>
class MyClass {
private:
T data;
public:
MyClass(T data) : data(data) {}
T getData() { return data; }
};
この例ではMyClassカテゴリでは任意のタイプのデータを使用できます。data。
次のように使用できます。
MyClass<int> obj1(5); // int型
MyClass<double> obj2(3.14); // double型
テンプレートは複数のパラメータを受け入れることができます。次に例を示します。
template <typename T, typename U>
class Pair {
private:
T first;
U second;
public:
Pair(T first, U second) : first(first), second(second) {}
T getFirst() { return first; }
U getSecond() { return second; }
};
このようなテンプレート クラスは、次の 2 つの異なるタイプのデータを保存できます。
Pair<int, double> pair1(1, 3.14);
テンプレートの特殊化により、特定のタイプのテンプレートを明確に定義できます。例えば:
テンプレート<>
クラス MyClass<int> {
パブリック:
MyClass(int data) { /* 特殊な動作 */ }
};
このコードは特殊ですMyClass右int他のタイプと異なるタイプの動作。
テンプレートは、定数値などの非型パラメータも受け入れることができます。
template <typename T, int Size>
class Array {
private:
T data[Size];
public:
int getSize() const { return Size; }
};
ここ、Size配列のサイズを示す非型パラメータです。
使用例:
配列ああ、 // サイズ10のint型配列を作成
C++ テンプレートは強力なので、コードの汎用性が高まり、重複が減ります。関数テンプレート、カテゴリ テンプレート、テンプレートの特化などのテクノロジの使用方法を理解すると、プログラミングの柔軟性とパフォーマンスが大幅に向上します。
C++ で、2 つのクラスが相互に依存しており、それぞれのクラスで直接、同時に互いのメンバーを参照する必要がある場合。.hファイル内#include相手の定義では循環参照の問題が発生し、コンパイルに失敗します。解決策は、「前方宣言」を使用して循環参照を回避することです。
.hこのファイルは相手のカテゴリの存在を宣言するだけであり、相手のヘッダファイルを直接インクルードするものではありません。.cppこのファイルには互いのヘッダー ファイルが含まれているため、コンパイラは完全なクラス定義を取得できます。// クラスA.h
#ifndef CLASSA_H
#CLASSA_H を定義
// ClassB の前方宣言
クラスクラスB;
クラスクラスA {
パブリック:
クラスA();
void setB(ClassB* b); // ポインタを ClassB に設定します
void showBData(); // ClassBデータを表示する
プライベート:
クラスB* b; // ClassB へのポインタ
};
#endif
// クラスB.h
#ifndef CLASSB_H
#define CLASSB_H
// 前方宣言 ClassA
クラスClassA;
クラスクラスB {
パブリック:
クラスB(intデータ);
int getData(); // データを取得する
void setA(ClassA* a); // ポインタを ClassA に設定します
void showAInfo(); // ClassA情報を表示する
プライベート:
int データ;
クラスA* a; // ClassA へのポインタ
};
#endif
#include "ClassA.h"
#include "ClassB.h"
#include <iostream>
ClassA::ClassA() : b(nullptr) {}
void ClassA::setB(ClassB* b) {
this->b = b;
}
void ClassA::showBData() {
if (b != nullptr) {
std::cout << "ClassB data: " << b->getData() << std::endl;
}
}
#include "ClassB.h"
#include "ClassA.h"
#include <iostream>
ClassB::ClassB(int data) : data(data), a(nullptr) {}
int ClassB::getData() {
return data;
}
void ClassB::setA(ClassA* a) {
this->a = a;
}
void ClassB::showAInfo() {
if (a != nullptr) {
a->showBData();
}
}
ClassA.hそしてClassB.h、循環参照を避けるために、他のカテゴリの存在を示すために前方宣言のみを使用します。.cppアーカイブには相手のヘッダー ファイルが含まれており、インジケーターを使用するときに相手の完全なカテゴリ定義が確実に取得されます。C++では、friend関数またはクラスでキーワードを使用すると、他の関数またはクラスがクラスのプライベート メンバーや保護されたメンバーにアクセスできるようになります。このような設計により、カプセル化の原則に違反することなく、外部関数またはクラスが動作できるようになります。
Friend 関数は、別のクラスのプライベートおよび保護されたメンバーへのアクセスが許可される外部関数です。カテゴリ内で宣言される場合は、次で終わりますfriendキーワードを変更するだけです。
例は次のとおりです。
#include名前空間 std を使用します。 クラスボックス{ プライベート: 倍幅。 パブリック: ボックス(ダブル w) : 幅(w) {} //フレンド宣言関数 友人 void showWidth(Box &b); }; //フレンド関数定義、Box クラスのプライベート メンバーにアクセス可能 void showWidth(ボックス&b) { コート << "ボックスの幅: " << b.幅 <<終わり; } int main() { ボックスボックス(10.5); showWidth(ボックス); // Access private member width 0を返します。 }
この例では、showWidthこの関数は Box カテゴリ外の通常の関数ですが、フレンド関数として宣言されているため、Box カテゴリのプライベート メンバーにアクセスできます。width。
Friend クラスを使用すると、あるクラスが別のクラスのすべてのメンバーにアクセスできるようになります。このような設定は、カテゴリを緊密に連携させる必要がある場合に便利ですが、内部の詳細があまりにも公開されないよう注意して使用する必要があります。
例は次のとおりです。
#include名前空間 std を使用します。 クラススクエア; // 前方宣言 クラス長方形{ プライベート: 幅、高さを倍増します。 パブリック: 長方形(double w, double h) : 幅(w), 高さ(h) {} // Square カテゴリをフレンドとして宣言します フレンドクラススクエア。 }; クラス スクエア { パブリック: double areaOfRectangle(長方形&rect) { 長方形の幅 * 長方形の高さを返します。 } }; int main() { 長方形rect(5.0, 3.0); 正方形の正方形。 コート << "長方形の面積: " << square.areaOfRectangle(rect) <<終わり; 0を返します。 }
この例では、Square クラスが Rectangle クラスのフレンド クラスとして宣言されているため、Square クラスのメンバー関数は Rectangle クラスのプライベート メンバーに直接アクセスできます。widthそしてheight。
C++ でフレンド関数とフレンド クラスを使用する場合は注意してください。過度に使用すると、クラスのカプセル化が破壊されます。したがって、friend キーワードは通常、密接な連携が必要なクラスまたは関数を設計する場合にのみ使用されます。
C++ では、テキスト ファイルを 1 行ずつ読み取る最も標準的で推奨される方法は、標準ライブラリのファイル ストリーミング クラスを使用することです。std::ifstream協力するstd::getline関数。
std::ifstreamファイルのストリーミングを開いて管理する責任を負います。std::getlineストリームからテキストの行全体を (改行文字が検出されるまで) 読み取る責任があります。\n) に保存しますstd::stringオブジェクトの中で。
以下は、という名前のファイルを 1 行ずつ読み取る方法を示す完全な C++ の例です。example.txtファイルの内容。
#include
#include // ファイルストリーミングライブラリをインクルードします
#include <文字列> // 文字列カテゴリを含める
名前空間 std を使用します。
void read_file_line_by_line(const string& ファイル名)
{
// 1. std::ifstream オブジェクトを作成する
//指定されたファイルを開いてみます。
ifstream 入力ファイル(ファイル名);
// 2. ファイルが正常に開かれたかどうかを確認します
if (!input_file.is_open())
{
エラー <<; 「エラー: ファイルを開けません」 <<ファイル名 <<終わり;
戻る;
}
文字列行;
int 行番号 = 1;
// 3. std::getline 関数を使用して 1 行ずつ読み取ります
// ループ条件 (getline(stream, string)) は、読み取りが成功するたびに true を返します。
// ファイルの終わり (EOF) に達するか、エラーが発生した場合は false を返し、ループが終了します。
while (getline(入力ファイル, 行))
{
コート << 「行」 <<行番号 << ": " <<行 <<終わり;
行番号++;
}
// 4. ファイルストリーミングを閉じる
// input_file オブジェクトがそのスコープを超えると、デストラクターは自動的にファイルを閉じます。
// ただし、close() を明示的に呼び出すこともできます。
input_file.close();
コート << 「ファイルの読み込みが完了しました。」 <<終わり;
}
int main()
{
read_file_line_by_line("example.txt");
0を返します。
}
std::ifstream: から継承std::istream、特にファイル入力ストリームを処理するために使用されます。ビルド時(または使用時)open()関数) はファイルを開こうとします。input_file.is_open(): これは標準的なエラー チェックです。ファイルが存在しない場合、またはプログラムに読み取り権限がない場合、この関数は戻り値を返します。false。std::getline(stream, string):
input_file) データを読み取ります。std::stringオブジェクトなどline)真ん中。\n、したがってline変数には改行文字が含まれません。true。std::ifstream物体 (input_file) が破棄されると、そのデストラクターが自動的に呼び出され、基礎となるファイル制御コードが閉じられます。これは信頼性の高いリソース管理方法 (RAII、リソース取得は初期化) です。C++ では、データ構造を変換します (例:std::vector<std::string>ファイルを行ごとに書き込み (トークンが読み取られます)、各列 (トークン) が行内で固定幅の配置を維持するようにするには、 ** を使用する必要があります。std::ofstream** **I/O ストリーム マニピュレータ**を使用して出力形式を制御します。
主なフォーマット制御ツールは次のとおりです。
std::setw(width): 次の出力フィールドの最小幅を設定します。std::left / std::right: 列内のテキストの配置(左または右)を設定します。以下は、複数のフィールドを含む 2 次元データ構造を変換する方法を示す C++ の例です (std::vector<std::vector<std::string>>Simulate) を実行してファイルを書き込み、各トークン フィールドが 15 文字の固定幅で左揃えになっていることを確認します。
#include
#include // ファイル出力ストリームを含める
#include <文字列>
#include <ベクトル>
#include // I/O ストリーム マニピュレータを含めます (setw、左/右)
名前空間 std を使用します。
// 2 次元のデータ構造をシミュレートします。各行には複数のフィールド (トークン) が含まれます。
TableData を使用 = ベクトル<ベクトル<文字列>;
void write_aligned_data(const string& ファイル名, const TableData& データ, int column_width)
{
// 1. std::ofstream オブジェクトを作成し、ファイルを開きます
ofstream 出力ファイル(ファイル名);
// 2. ファイルが正常に開かれたかどうかを確認します
if (!output_file.is_open())
{
エラー <<; 「エラー: ファイルを開けません」 <<ファイル名 <<書くためです。 <<終わり;
戻る;
}
//グローバル配置を設定: 左詰め (L 詰め)
出力ファイル <<左;
// 3. データを 1 行ずつ書き込みます
for (const auto& row : data)
{
// 4. トークンごとに書き込み、幅を設定する
for (const auto& トークン : 行)
{
// setw(width) はその直後の次の出力項目にのみ影響します
出力ファイル << setw(列幅) <<トークン;
}
// 5. 行末の後に改行文字を挿入して新しい行を開始します
出力ファイル << "\n";
}
// 6. ファイルストリーミングを閉じる
出力ファイル.close();
コート << "资料すでに成功書入档案: " <<ファイル名 <<終わり;
}
int main()
{
//サンプル データ: 4 つの行が含まれており、各行には 3 つのフィールドがあります。
TableData データ = {
{"名前"、"アイテム"、"価格"}、
{"アリス"、"本"、"19.99"}、
{"ボブジョンソン"、"ペンセット"、"4.50"}、
{"チャーリー"、"ノートブック"、"800.75"}
};
const int COLUMN_WIDTH = 15; // 各列の幅を定義します
write_aligned_data("output_aligned.txt", データ, COLUMN_WIDTH);
0を返します。
}
std::ofstream:ファイル出力ストリーミングカテゴリ。データをファイルに書き込むために使用されます。#include <iomanip>: I/O ストリーム マニピュレータを使用するには、このヘッダー ファイルを含める必要があります。output_file << left;:
rightまたはinternalカバー。output_file << setw(column_width) << token;:
setw(width):次に出力するデータの最小幅を設定します。出力文字列の長さが設定された幅より短い場合は、空白文字が埋め込まれます。setw直後の次の出力操作に対してのみ有効であるため、各出力トークンの前に 1 回呼び出す必要があります。vcpkg はインストール ファイルを介してインストールされるのではなく、ソース コードを GitHub からローカルに直接コピーします。ディスクのルート ディレクトリ (例:C:\vcpkg) パスが長すぎたり、スペースが含まれたりしないようにします。ターミナル (CMD または PowerShell) を開いて次を実行してください。
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
ダウンロード後、スクリプトを実行して vcpkg の実行可能ファイルをコンパイルする必要があります。vcpkg.exe:
.\bootstrap-vcpkg.bat./bootstrap-vcpkg.shこの手順により、開発ツール (Visual Studio など) が vcpkg によってインストールされたパッケージを自動的に認識できるようになります。
埋め込む.\vcpkg integrate install。完了後、VS で作成した新しいプロジェクトを直接実行できます。#includeキットでは、パスを手動で設定する必要はありません。
CMake 構成を実行するときに、vcpkg ツールチェーン ファイルにリンクする次のパラメーターを追加します。
-DCMAKE_TOOLCHAIN_FILE=[vcpkg パス]/scripts/buildsystems/vcpkg.cmake
| 命令 | 説明する | 例 |
|---|---|---|
search |
利用可能なパッケージを検索する | vcpkg search libuv |
install |
指定したパッケージをインストールする | vcpkg install libuv:x64-windows |
list |
インストールされているパッケージを一覧表示する | vcpkg list |
update |
パッケージのバージョン更新を確認する | vcpkg update |
任意のパスで vcpkg を使用しやすくするために、vcpkg フォルダー パスをシステムに追加することをお勧めします。PATHさらに、64 ビットのユニットパッケージをインストールすることを希望する場合は、環境変数を新しく増やすことができます。VCPKG_DEFAULT_TRIPLETその値を次のように設定しますx64-windows。
Windows で vcpkg を使用する前に、vcpkg がインストールされていることを確認してくださいVisual Studio 2015 以降を確認し、「C++ を使用したデスクトップ開発」ワークロード (英語の言語パックを含む) を確認してください。そうでないと、パッケージのコンパイル時にエラーが発生する可能性があります。
周辺機器制御プログラムは、コンピューターまたはホストに接続されている外部ハードウェア デバイス (プリンター、スキャナー、モーター、PLC、センサーなど) と通信し、操作するために使用されるアプリケーションです。
| 言語 | 該当する状況 | 述べる |
|---|---|---|
| Python | 迅速な開発、テストの自動化 | シリアル、USB HIDに適用可能 |
| C/C++ | 組み込み制御とドライバーの開発 | 低レベルのメモリとハードウェアへのアクセス |
| C# | Windows UI + コントロールデバイス | COMポートおよびUSB通信に最適 |
| Java | クロスプラットフォーム制御 | ローエンドデバイスではあまり一般的ではありません |
インポートシリアル
ser = シリアル.Serial('COM3', 9600, タイムアウト=1)
ser.write(b'ON\n') # 制御コマンドを送信する
応答 = ser.readline()
print("デバイス応答:", response.decode())
ser.close()
SerialPort ポート = new SerialPort("COM4", 9600);
port.Open();
port.WriteLine("MOVE 100");
文字列応答 = port.ReadLine();
Console.WriteLine("応答: " + 応答);
port.Close();
libusb(C)、pyusb(Python)、HidSharp(C#) およびその他の関数ライブラリインポートソケット
s = ソケット.ソケット()
s.connect(('192.168.1.100', 5000))
s.sendall(b'START\n')
データ = s.recv(1024)
print("応答:", data.decode())
s.close()
周辺制御プログラムの開発では、デバイスのインターフェースやプロトコルに基づいて適切な言語や関数ライブラリを選択し、シリアル、USB、ネットワークなどの通信方式を組み合わせる必要があり、これらはさまざまなオートメーションおよび産業制御分野で広く使用できます。
// ビルド.gradle
実装「com.journeyapps:zxing-android-embedded:4.3.0」
//Javaコールスキャン画面
IntentIntegrator インテグレータ = 新しい IntentIntegrator(this);
integrator.setPrompt("バーコードをスキャンしてください");
integrator.setBeepEnabled(true);
integrator.setOrientationLocked(false);
integrator.initiateScan();
//onActivityResult は結果を受け取ります
@オーバーライド
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult 結果 = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(結果 != null) {
if(result.getContents() != null) {
文字列バーコード = result.getContents();
Log.d("バーコードの内容", バーコード);
}
}
}
<script src="https://unpkg.com/[email protected]/dist/quagga.min.js"></script>
<スクリプト>
クアッガ.init({
入力ストリーム: {
名前:「ライブ」、
タイプ:「ライブストリーム」、
ターゲット: document.querySelector('#scanner')
}、
デコーダ: {
リーダー: ["code_128_reader"、"ean_reader"、"upc_reader"]
}
}、関数(エラー) {
if (!err) {
クアッガ.start();
}
});
Quagga.onDetected(関数(結果) {
console.log("バーコードの内容: ", result.codeResult.code);
});
</スクリプト>
| プラットフォーム | 推奨キット | 無料ですか? |
|---|---|---|
| Android | ZXing / ML Kit | はい |
| Web | QuaggaJS / jsQR | はい |
| Windows | Dynamsoft / ZXing.NET | 商用利用可能なダイナムソフト |
| Python | ZBar / pyzbar | はい |
バーコード リーダーを開発するには、プラットフォームに応じて適切なオープン ソース パッケージを選択できます。 ZXing は最も広くサポートされている選択肢です。 QuaggaJS は Web で利用できます。商用レベルのサポートが必要な場合は、Dynamsoft Barcode SDK を検討してください。
バーコード リーダーは、基本的にキーボード入力をシミュレートするデバイスです。バーコードがスキャンされると、キーボード入力と同様に、バーコード内のコンテンツが文字ストリームに「出力」されます。
したがって、バーコードは、制御コードを含めることができます (制御コード)、しかしバーコード リーダーとバーコード形式のサポートが必要大丈夫です。
たとえば、次の形式では制御コードをエンコードできます。
一部のバーコード ジェネレーターでは、次のような特殊文字を埋め込むことができます。
\x0DEnter を意味します\x03Ctrl+C を意味します^C、[CTRL+C]特別な構文はツールによって異なりますほとんどのプロ用バーコード プリンタ (Zebra、Honeywell など) は工場でプリセットされています。制御コード出力を無効にする、スキャナーによって提供される「設定バーコード」を通じて有効にする必要があります。
たとえば、Windows アプリケーションでは次のようになります。
keydownそしてCtrlショートカットキーの対応処理。Code128 による ASCII 3 のエンコード:
入力:\x03Hello World
バーコードがスキャンされた後、Ctrl+C がトリガーされ、「Hello World」が出力されます。
sudo apt update && sudo apt upgrade -y
sudo apt install -y wget curl unzip zip git ca-certificates
sudo apt install -y openjdk-17-jdk
sudo dpkg -i ~/Downloads/android-studio-*.deb || sudo apt -f install -y
android-studioまたは解凍する.tar.gz:
tar -xzf ~/Downloads/android-studio-*.tar.gz -C ~
~/android-studio/bin/studio.sh
sudo apt install -y android-sdk-platform-tools
adb kill-server
adb start-server
adb devices
sudo dpkg -i ~/Downloads/code_*.deb || sudo apt -f install -y
sudo apt update && sudo apt install -y openjdk-17-jdk unzip git
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
unzip commandlinetools-linux-*_latest.zip -d ~/android-sdk
~/.bashrcまたは~/.zshrc):
export ANDROID_SDK_ROOT=$HOME/android-sdk
export PATH=$ANDROID_SDK_ROOT/cmdline-tools/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH
sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0"
adb devices見るdeviceテストを展開する準備ができました。adb installまたはフレームワーク CLI (例:flutter run) アプリを携帯電話に展開します。Android Studioで新しいプロジェクトを作成し、「Empty Activity」テンプレートを選択し、プロジェクト名やその他の基本情報を設定します。
存在するres/layout/activity_main.xmlファイル内で設計された単純なユーザー インターフェイス (たとえば、ボタンとテキスト表示領域が含まれます):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="垂直"
android:gravity="センター">
<ボタン
android:id="@+id/ボタン"
android:layout_width="ラップコンテンツ"
android:layout_height="ラップコンテンツ"
android:text="クリックしてください" />
<テキストビュー
android:id="@+id/textView"
android:layout_width="ラップコンテンツ"
android:layout_height="ラップコンテンツ"
android:text="ハロー、ワールド!"
android:layout_marginTop="20dp" />
</LinearLayout>
存在するMainActivity.java、ボタンのクリック イベントを設定して、テキスト表示領域の内容を変更します。
パッケージ com.example.simpleapp;
android.os.Bundle をインポートします。
android.view.Viewをインポートします。
android.widget.Button をインポートします。
android.widget.TextViewをインポートします。
androidx.appcompat.app.AppCompatActivityをインポートします。
public class MainActivity extends AppCompatActivity {
@オーバーライド
protected void onCreate(バンドル保存インスタンス状態) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ボタン button = findViewById(R.id.button);
TextView textView = findViewById(R.id.textView);
button.setOnClickListener(new View.OnClickListener() {
@オーバーライド
public void onClick(View v) {
textView.setText("ボタンをクリックしました!");
}
});
}
}
Android Studio で [実行] ボタンをクリックして、エミュレーターまたは接続された物理デバイスでアプリをテストします。ボタンをクリックすると、テキストが「ボタンをクリックしました!」に変わります。
存在するAndroidManifest.xml次の権限を追加します。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
@オーバーライド
public void onLocationChanged(@NonNull 場所 location) {
二重緯度 = location.getLatitude();
二重経度 = location.getLongitude();
Log.d("GPS", "緯度: " + 緯度 + ", 経度: " + 経度);
}
};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
1000, // ミリ秒間隔
1, // 最小距離 (メートル)
locationListener);
}
FusedLocationProviderClient fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
fusedLocationClient.getLastLocation()
.addOnSuccessListener(this, location -> {
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
Log.d("GPS", "Lat: " + lat + ", Lng: " + lng);
}
});
}
Siri や Hey Google などの音声アシスタント機能を実装するには、次のコンポーネントを組み合わせる必要があります。
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET"/>
SpeechRecognizer レコグナイザー = SpeechRecognizer.createSpeechRecognizer(this);
インテントの意図 = 新しいインテント(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
tent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
tent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
レコグナイザー.setRecognitionListener(new RecognitionListener() {
@オーバーライド
public void onResults(バンドル結果) {
ArrayList<String>一致 = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
if (マッチ != null && !matches.isEmpty()) {
文字列コマンド =matches.get(0).toLowerCase();
if (command.contains("カメラを開く")) {
// 操作を実行します
}
}
}
//その他必要な上書きメソッドは省略
});
レコグナイザー.startListening(意図);
TextToSpeech tts = new TextToSpeech(this, status -> {
if (ステータス == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.TAIWAN);
tts.speak("こんにちは、ここにいます。", TextToSpeech.QUEUE_FLUSH, null, null);
}
});
バックグラウンドを保持し、音声で起動したい場合は、以下を使用する必要があります。
RECORD_AUDIO権限。永続的なバックグラウンド監視の目的は、アプリが音声ウェイクアップ ワード (「Hey Assistant」など) を検出し、画面が開いていないときでも対応する機能をアクティブにできるようにすることです。
SpeechRecognizer長いバックグラウンド実行。SpeechRecognizer完全な音声コマンドを認識します。public class VoiceService extends Service {
@オーバーライド
public int onStartCommand(インテント意図、int フラグ、int startId) {
通知 notification = new NoticeCompat.Builder(this, "voice_channel")
.setContentTitle("音声アシスタントが動作しています")
.setSmallIcon(R.drawable.ic_mic)
.build();
startForeground(1, 通知);
//ホットワード検出を初期化します
startHotwordDetection();
START_STICKY を返します。
}
@オーバーライド
public IBinder onBind(Intent インテント) {
null を返します。
}
}
NotificationChannel channel = new NotificationChannel("voice_channel",
"Voice Assistant", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
Porcupine は、カスタム キーワードを認識し、完全にオフラインで動作する Android SDK を提供します。
PorcupineManager porcupineManager = new PorcupineManager.Builder()
.setAccessKey("あなたのキー")
.setKeywordPath("hey_assistant.ppn")
.setSensitivity(0.7f)
.build((keywordIndex) -> {
//目覚めたときに音声認識のために SpeechRecognizer を呼び出します
startSpeechRecognition();
});
porcupineManager.start();
Intent serviceIntent = new Intent(this, VoiceService.class);
ContextCompat.startForegroundService(this, serviceIntent);
RECORD_AUDIO権限。1. 最新バージョンをダウンロードしてインストールします。Xcode。
2. Xcode を開いて、次の場所に移動します。Preferences > Accounts, Apple ID でサインインして、開発者機能を有効にします。
3.Xcode経由でインストールするCommand Line ToolsSwift コマンドライン ツールを使用します。
1. Xcode を開き、「新しい Xcode プロジェクトの作成」を選択します。
2. 適切なアプリケーション テンプレートを選択します。App (iOS/macOS)。
3. プロジェクト名、バンドル識別子、および言語 (Swift または Objective-C) を設定します。
4. UI フレームワーク (SwiftUI または UIKit) を選択します。
1. 登録するApple Developer Program(年会費99ドルが必要です)。
2.Xcode経由で設定するApp Store Connectそしてアプリを送信します。
3. Apple に従うApp Store Review Guidelinesアプリがリスティング仕様を満たしていることを確認してください。
iOS開発では主に以下を使用します。Xcode, Apple が提供する公式の統合開発環境 (IDE) です。
iOS 開発を学習するには、次の基本を習得する必要があります。
ここでは、役立つ学習および開発リソースをいくつか紹介します。
Xcode は、macOS、iOS、watchOS、tvOS アプリケーションの開発のために Apple が提供する統合開発環境 (IDE) です。
Xcode の最新バージョンは、Mac App Store または Apple の公式開発者 Web サイトからダウンロードできます。
開発効率を向上させるための実践的なヒント:
関連する学習および参考リソース:
Swift は、iOS、macOS、watchOS、tvOS アプリを開発するための Apple の最新プログラミング言語です。
varそしてlet?そして!値の有無を処理しますif、switch、for、whilefunc定義、パラメータラベルと複数の戻り値をサポートclassそしてstructSwift は Apple エコシステムだけでなく、サーバーサイド開発やクロスプラットフォーム ツールにも使用できます。
関連する学習および参考リソース:
Objective-C は、もともと NeXT Corporation によって開発された C ベースのオブジェクト指向プログラミング言語で、その後 Apple によって macOS および iOS アプリケーション開発に広く使用されました。
Objective-C の構文は C と Smalltalk の機能を組み合わせたもので、@ 記号を使用して言語拡張を示します。
@interfaceそして@implementation[object method]@propertyそして@synthesizeObjective-C の開発は主に Apple の Xcode を使用して行われます。
学習および参照用のリソースをいくつか紹介します。
GNews は Google が開発したニュース集約プラットフォームで、ユーザーが最新のグローバル ニュースを入手できるように設計されています。さまざまなニュースソースのコンテンツを統合し、人工知能テクノロジーを使用して、ユーザーに興味のあるニュースの推奨をパーソナライズします。
ユーザーは、GNews の Web サイトにアクセスするか、アプリをダウンロードすることでこのプラットフォームを使用できます。このプラットフォームでは、ユーザーは興味のあるトピックを選択し、特定のニュース ソースをフォローし、ニーズに合わせてニュース フィードをカスタマイズできます。
GNews は、人工知能テクノロジーを使用してユーザーにパーソナライズされたニュース体験を提供する強力なニュース集約ツールです。ニュース情報が急速に変化する中、GNews はユーザーが世界の動向を素早く把握し、必要な情報を入手できるように支援します。
| ツール名 | 主な特長 | 該当するシナリオ | 価格 |
|---|---|---|---|
| n8n | 高度にカスタマイズ可能なプロセス設計を提供し、自己構築ノードをサポートするオープンソースの自動ワークフロー ツール。 | 内部プロセスの自動化、大規模な自動化システム、API統合などに適しています。 | 無料のオープンソースで、有料のクラウド版も利用可能です。 |
| Make | 視覚的なワークフロー構築を提供し、複数のサードパーティ アプリケーションとサービスの統合をサポートし、シンプルさと使いやすさを重視します。 | 中小企業のワークフロー自動化や各種サービスの迅速な統合に適しています。 | 無料プランが利用可能であり、有料プランはユーザーのニーズに基づいてより高度な機能を提供します。 |
| Zapier | ほとんどのアプリケーションとの統合をサポートし、シンプルで使いやすく、トリガーと自動化されたワークフローを作成できます。 | さまざまなビジネス分野、特に中小企業や新興企業の自動化に適しています。 | 無料プランが利用可能で、有料プランではより多くの機能が提供され、ユーザーのニーズに基づいて実行されます。 |
Bolt は、アプリケーションを構築するためのシンプルで効率的なツールを開発者に提供することに重点を置いた、高速で軽量な AI 開発フレームワークです。特徴は次のとおりです。
Cursor は、AI プログラム開発専用に設計されたエディタ ツールで、インテリジェントな補助コード作成機能とデバッグ機能を提供します。特徴は次のとおりです。
v0 は、ユーザーがドラッグ アンド ドロップ インターフェイスを通じてモデルやアプリケーションを構築できるビジュアル開発に基づく AI プラットフォームです。特徴は次のとおりです。
Codeium は、プログラム開発の効率と精度の向上に重点を置いた、AI インテリジェント支援と組み合わせたプログラム エディターです。特徴は次のとおりです。
ソフトウェア エンジニアリングは、ソフトウェアを体系的かつ計画的に開発、運用、保守するエンジニアリング分野です。目標は、高品質で保守可能、信頼性が高く、要求の厳しいソフトウェア システムを構築することです。
このプロジェクトの正式名称を入力してください。
このプロジェクトの理由、背景問題、解決すべき中核問題を説明し、プロジェクトの明確な目標を定義します。
システム機能と全体的なアーキテクチャの概要を示し、システム アーキテクチャ図と組み合わせることができます。
メイン画面のスケッチまたはワイヤーフレームを添付して、各画面の要素とインタラクティブなプロセスを説明できます。
主要なデータ テーブルの構造、フィールド、相関関係などをリストします。
統合する必要がある外部システム、API、またはその他のソフトウェア コンポーネントをリストします。
潜在的なリスク、制約(予算、人材、テクノロジーなど)をリストします。
関連文書リンク、参考資料、用語定義など。
デザイン パターンは、特定の状況で繰り返し発生する設計上の問題を解決するために主にオブジェクト指向プログラミングで使用される、実証済みのソフトウェア設計ソリューションのセットです。
バージョン管理は、ファイルの変更履歴を管理するシステムです。ソフトウェア開発で広く使用されており、複数の開発者が同時に共同作業でき、各変更の完全な記録を保持できます。
git init:バージョンライブラリの初期化git clone [url]:リモートプロジェクトをコピーgit add [ファイル]:ステージング領域に変更を追加しますgit commit -m "メッセージ": 変更を送信しますgit push: 変更をリモート リポジトリにプッシュしますgit pull: リモートの変更を取得してマージしますgit branch: ブランチの表示または作成git merge: ブランチをマージしますGit は、コード変更の追跡、共同開発、およびバージョン管理のために 2005 年に Linus Torvalds (Linux の父) によって開発された分散型バージョン管理システムです。これは現在最も広く使用されているバージョン管理ツールであり、個人開発、チーム プロジェクト、オープン ソース コミュニティで使用されています。
git --versionインストールが成功したことを確認します。初めて Git を使用する場合は、開発者情報を設定する必要があります。
git config --global user.name "あなたの名前" git config --global user.email "あなたのメールアドレス@example.com"
git init # ローカルリポジトリを初期化する git clone URL # リモート リポジトリをコピーします git add 。 # ステージング領域に変更を追加する git commit -m "description" # コミットを作成する git status # 現在のステータスを表示する git log # コミットレコードを表示する git Branch # ブランチリストの表示 git checkout ブランチ名 # ブランチの切り替え git merge ブランチ名 # 指定されたブランチをマージします git Push # 変更をリモート エンドにプッシュします git pull # リモートエンドから更新をプルします
git initまたはgit clone)git add)git commit)git push / git pull)コミットされていない (Uncommitted) およびコミットされているがまだプッシュされていない (ローカル コミット) すべてのローカル変更を完全に破棄し、リモート エンドと完全に一致するようにブランチをリセットする場合は、以下の手順に従ってください。
まず、ローカル インデックスがリモート エンドの最新の進行状況で更新されていることを確認します。
git fetch --all
使用--hardパラメーターは、現在のブランチが対応するリモート ブランチをポイントします (ブランチが main であると仮定します)。
git reset --hard origin/main
git reset --hardGit によってすでに追跡されているファイルのみが処理されます。ローカルに新しく作成したファイルまたはフォルダーがまだ git 追加されていない場合、それらは残ります。それらをすべて削除するには、次を使用しますclean命令:
# 最初にテストを実行して、どのファイルが削除されるかを確認します
git clean -n
# ファイル (-f) とディレクトリ (-d) を正式に削除します
git clean -fd
| ターゲット | 適用可能な指令 |
|---|---|
| ローカルの変更をすべて破棄します | git reset --hard origin/<branch_name> |
| 単一ファイルの変更のみを破棄する | git checkout HEAD -- <file_path> |
| 現在の変更を一時的に保存します(後で復元できます) | git stash |
| gitignore の外側にある不要なものをすべて削除する | git clean -fdx |
git reset --hard危険な操作です。実行後、ローカルのコミットされていないすべてのコードは、取得できません。origin/main現在使用している実際のリモート ブランチ名に置き換えます (例:origin/masterまたはorigin/dev)。Git マージ ブランチが競合すると、ファイルは「マージされていない」としてマークされます。この時点で、Git はファイルに競合マークを挿入するため、比較コマンドを使用して問題を特定し、手動で修正する必要があります。
競合を解決する前に、まず競合しているファイルを特定します。
git status
競合するファイルは次の場所にリストされます。Unmerged pathsセクションの下。
ファイルに競合するタグが含まれている場合、次の方法を使用して相違点を表示できます。
git diff<<<<<<<、=======そして>>>>>>>マーク。git diff --ours <file>git diff --theirs <file>
git diff -p <file>
Git は競合ファイルを直接変更します。形式は次のとおりです。
<<<<<<<<< HEAD (またはブランチ名) これは現在のブランチ (当社) のコンテンツです ======= これは相手方(彼ら)のブランチの内容です >>>>>>>支店名
複雑な競合の場合、テキスト インターフェイスは読みにくくなります。専用のマージ ツールを呼び出すことをお勧めします。
git mergetool
これにより、次のようなものが始まりますMeld、P4Merge、または VS Code他のツールを使用して、ベース バージョン (Base)、ローカル バージョン (Local)、およびリモート バージョン (Remote) の 3 つのバージョンを並べて比較します。
ファイルを手動で編集し、どのコードを保持するかを決定した後、次の手順を実行してマージを完了する必要があります。
<<<<, ====, >>>>マーク。git add <file>(解決されたファイルを一時記憶領域に追加します)。git commit(マージコミットを完了します)。GitHub は、主にソフトウェア開発に使用されるクラウドベースのバージョン管理およびコラボレーション プラットフォームです。それは使用しますGitバージョン管理を実装すると、開発者はプロジェクトのソース コードを管理し、変更を追跡し、他のユーザーと共同作業できるようになります。
GitHub は、個人の開発者、オープンソース コミュニティ、エンタープライズ チームなど、あらゆるタイプの開発者に適しています。小規模プロジェクトから大規模なソフトウェア プロジェクトまでのバージョン管理とコラボレーションのニーズを満たすことができます。
git pull --rebasegit pull --rebase従来のマージを使用する代わりに、リモート ブランチから最新の変更を取得し、ローカルの変更を最新のリモート コミットに再適用します。
git pull --rebase
--rebase?--rebase冗長なマージ コミットを使用せずに、コミット履歴を簡潔に保つことができます。ローカルでいくつかの変更をコミットし、リモート エンドに新しいコミットがあると仮定します。git pull --rebaseミーティング:
ローカル コミットの再生中に競合が発生した場合、Git は手動による競合解決を要求します。
git add解決されたファイルをステージングします。git rebase --continueコミットの再生を続けます。git rebase --abort現状に戻ります。git pull --rebaseこれは、Git 送信履歴をクリーンに保つための重要なツールです。特に複数人でのコラボレーションに適しています。冗長なマージ送信を回避し、コードベースの送信記録を線形に保つことができます。
他の開発者がプロジェクトに参加できるようにするには、リポジトリの設定ページを通じて他の開発者をコラボレーターとして追加する必要があります。操作プロセスは次のとおりです。
個人アカウント リポジトリの場合、招待者は通常、デフォルトで読み取りおよび書き込み権限を持っています。組織アカウントの場合は、より詳細な設定を行うことができます。
| 許可レベル | 説明する |
|---|---|
| Read | コードの読み取りとコピーのみが可能で、純粋な閲覧者に適しています。 |
| Triage | Issue と Pull Request を管理できますが、コードを書くことはできません。 |
| Write | コードをリポジトリに直接プッシュできます。 |
| Maintain | 書き込みに加えて、リポジトリの一部の設定を管理することもできます。 |
| Admin | リポジトリの削除や他のコラボレーターの管理などを完全に制御できます。 |
これは最も一般的で直感的な削除方法です。リポジトリを削除すると、バックアップがない限り復元できないことに注意してください。
ユーザー名/リポジトリ名)。GitHub のコマンド ライン ツール (gh) がインストールされている場合は、ターミナルからすぐに削除できます。
gh repo delete <ユーザー名>/<リポジトリ名> - 確認する
知らせ:--confirmこのパラメーターは確認ステップを直接スキップします。注意して使用してください。
GitHub 上のリモート リポジトリが削除された後も、コンピューター上のローカル フォルダーは残ります。完全に削除するには、フォルダーを手動で削除します。
rm -rf <フォルダ名>
rd /s /q <フォルダー名>
---
| 動作モード | 影響範囲 | 回復可能ですか? |
|---|---|---|
| Webインターフェースの削除 | GitHub リモート サーバー上のデータのみを削除してください。 | いいえ (サポートまたはフォークに連絡しない限り) |
| rm -rfコマンド | コンピュータのローカル ファイルのみを削除してください。 | いいえ(ごみ箱がない場合) |
| .gitフォルダーを削除する | ファイルは保持しますが、通常のフォルダーに戻します (バージョン管理機能は失われます)。 | はい (git init を再実行) |
Visual Studio には Git 統合機能が組み込まれていますが、バージョン管理操作 (コミット、プッシュ、プル、マージなど) を実行するには、Git 実行可能ファイルをシステムにインストールする必要があります。
git --version
git version 2.x.x、インストールされていることを意味します。 「認識できない git コマンド」が表示される場合は、Git をインストールする必要があります。コマンド プロンプトをオンにして、ユーザー名と電子メールを設定します。
git config --global user.name "あなたの名前" git config --global user.email "あなたのメールアドレス@example.com"
この情報は各コミットに追加され、開発者を識別するために使用されます。
Visual Studio 2022 以降を使用している場合は、インストール プロセス中に確認できます。「Git for Windows」オプション。このようにして、Visual Studio は手動構成を行わなくても、Git を自動的にインストールして統合します。
設定が完了したら、Visual Studio で次の操作を直接完了できます。
Azure DevOps は、Microsoft が提供する統合開発およびコラボレーション プラットフォームで、コード管理、構築、自動テストから展開までの完全な DevOps プロセスをサポートします。さまざまなプログラミング言語とフレームワークに適しており、個人のプロジェクトや大企業のチーム開発に使用できます。
Azure DevOps Pipelines、Repos、または Boards の使用時にアクセス許可制限の問題が発生した場合は、まずアクセス レベルが次のとおりであるかどうかを確認してください。Basicまたはそれ以上。
CMake は、オープンソースのクロスプラットフォームの「メタビルド システム」です。プログラムコード自体を直接コンパイルするのではなく、設定ファイル(CMakeLists.txt)を読み込むことで、現在のOSや開発環境に適したプロジェクトファイルを自動生成します。たとえば、Windows では Visual Studio ソリューションが生成され、Linux では Makefile または Ninja 構成ファイルが生成されます。
さまざまなオペレーティング システムに CMake をインストールする方法は次のとおりです。
brew install cmake。 .dmg ファイルをダウンロードして手動でインストールすることもできます。sudo apt update && sudo apt install cmake。CMake は、複雑なソフトウェア プロジェクトの管理を簡素化するように設計されています。マルチレベルのディレクトリ構造をサポートし、ライブラリ間の依存関係を処理し、システムにインストールされているライブラリを自動的に検索します。さらに、テスト (CTest) およびパッケージ化 (CPack) 機能も提供し、開発からリリースまでの完全なライフサイクルをカバーします。
| ステップ | コマンド例 | 説明する |
|---|---|---|
| 1. 設定する | cmake -S . -B build |
設定を読み取り、システム環境を検出します。 |
| 2. 生成する | (自動実行) | Makefile または VS プロジェクト ファイルを生成します。 |
| 3. 構築する | cmake --build build |
コンパイラを呼び出して実際のコンパイルを実行します。 |
| 4. インストール | cmake --install build |
生成された実行ファイルを指定したパスに移動します。 |
CMake には、優れたクロスアーキテクチャ サポート機能があります。 Windows 環境では、開発者は次のようにパラメータを通じてターゲット アーキテクチャを指定できます。-A x64または-A ARM64。最新の Apple Silicon の場合、CMake はユニバーサル バイナリの生成をサポートしており、Intel と Apple M シリーズ プロセッサの両方でプログラムを実行できるようになります。
従来の Makefile は保守が難しく、クロスプラットフォームの汎用性がありません。 CMake を使用すると、開発者は一連の構成ファイルを簡単に作成でき、世界中の開発者が好みの IDE (VS Code、CLion、Xcode など) でプロジェクトを簡単に開いてコンパイルできます。これが、現在主流のオープンソース C++ プロジェクトのほとんどが CMake を標準ツールとして使用している理由です。
アプリケーションのデプロイメントは、開発されたアプリケーションを開発環境からテスト環境または運用環境に移動して、ユーザーが実際に使用できるようにするプロセスです。これにより、システムがさまざまな環境で安定して再現可能に動作できることが保証されます。
# GitHub Actions を使用してサンプルをデプロイする
名前: Web アプリのデプロイ
に:
プッシュ:
ブランチ: [ "メイン" ]
仕事:
デプロイ:
実行: ubuntu-最新
手順:
- 使用:actions/checkout@v4
- 名前: Docker イメージのビルド
実行: docker build -t myapp 。
- 名前: サーバーにデプロイ
実行: docker run -d -p 80:80 myapp
Docker (コンテナー テクノロジー) は、アプリケーションのデプロイメント、スケーリング、管理を自動化するためのオープンソース プラットフォームです。 「コンテナ」を使用してアプリケーションとその依存関係をパッケージ化し、さまざまな環境で一貫した実行を保証します。
docker pull [イメージ名]:画像ファイルをダウンロードdocker run [イメージ名]:実行コンテナdocker ps: 実行中のコンテナを表示するdocker stop [コンテナID]:コンテナを停止しますdocker rm [コンテナID]: コンテナの削除docker build -t [名前] 。: Dockerfileを元にイメージファイルを作成しますdocker images:画像ファイル一覧を表示# Python イメージファイルを使用する
Pythonから:3.10
# 作業ディレクトリを設定する
WORKDIR/アプリ
# プログラムファイルをコピーする
コピー ./app
#依存関係パッケージをインストールする
pip install -r required.txt を実行します。
#コンテナ起動時に実行する命令を指定する
CMD ["python", "app.py"]
Docker Compose は、複数のコンテナ アプリケーションを定義できるツールです。使用docker-compose.ymlファイルは各サービスを定義します。
version: '3'
services:
web:
build: .
ports:
- "8000:8000"
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: example
モジュール依存関係分析は、アプリケーションの実行時に依存する外部ファイル (DLL、ライブラリ、フレームワークなど) を特定し、追跡するために使用されるソフトウェア エンジニアリング手法です。これは、ソフトウェアがさまざまな環境で正しく動作することを保証するために非常に重要です。
| 目的 | 詳細な説明 |
|---|---|
| トラブルシューティング | DLL の欠落またはバージョンの不一致によって引き起こされるプログラムのクラッシュを見つけます。 |
| セキュリティ監査 | プログラムが不正なサードパーティコンポーネントを読み込んでいるかどうか、またはセキュリティ上の脆弱性があるかどうかを識別します。 |
| パフォーマンスの最適化 | 依存するモジュールが多すぎる場合の起動時間とメモリ使用量への影響を評価し、不要な参照を削除します。 |
| 移植可能性の評価 | .NET ランタイムや VC++ ライブラリなどの特定の開発環境がインストールされていないコンピューターでソフトウェアを実行するかどうかを決定します。 |
dependency Walker (一般に depends.exe として知られる) は、Windows アプリケーションのファイル構造 (.exe、.dll、.sys など) を分析するための無料ツールです。これは主に、32 ビットまたは 64 ビットの Windows モジュールをスキャンし、関連するすべての依存モジュールの階層ツリーを構築するために使用されます。
| シーン | 説明する |
|---|---|
| システムエラーのトラブルシューティング | 0xc000007b (並列構成エラー) や指定されたモジュールが見つからないなどのシステム エラーを解決します。 |
| ソフトウェアの導入 | 開発者は、インストーラーに必要な実行ライブラリ (VC++ 再頒布可能パッケージなど) がすべて含まれていることを確認します。 | システム パス内に同じ名前の異なるバージョンの DLL が存在し、プログラムが異常な動作をしていないかどうかを確認してください。 |
dependency Walker は長年更新されていないため、最新の Windows 10/11 の一部の機能 (API セットや遅延ロード DLL など) のサポートが不十分で、偽の赤い警告が頻繁に表示されます。この場合、次のオープンソースの代替ツールが推奨されます。
dependency は、長年にわたって廃止されていたDependency Walker (Depends.exe) を置き換えるように設計された、オープンソースの最新の依存関係分析ツールです。 Windows 10 および Windows 11 のシステム アーキテクチャ向けに完全に最適化されており、最新のソフトウェア環境でモジュールの関連付けを正確に分析できます。
api-ms-win-*で始まる仮想 DLL は、誤った循環依存関係の警告やファイル欠落エラーを生成しません。| 特性 | 依存関係ウォーカー (旧バージョン) | 依存関係 (最新バージョン) |
|---|---|---|
| Windows 10/11のサポート | 悪い (頻繁な誤検知) | 優れた (ネイティブ サポート) |
| API セットの処理 | 認識されません (赤色で表示されます) | エンティティ DLL に正しくマッピングされました |
| 開発状況 | 更新停止 (2006) | 継続メンテナンス中(GitHub) |
| コア技術 | C++ / MFC | C# / WPF (一部の低レベル C++) |
dependency はインストール不要の環境に優しいソフトウェアで、通常は GitHub からダウンロードできます。lucasg/Dependenciesリポジトリは、コンパイルされたリリース バージョンをダウンロードします。使用時は、解析したい.exeまたは.dllファイルをウィンドウ内にドラッグするだけで解析が開始されます。
2 つのツールには異なる設計理念があります。Dependency Walker (Depends.exe) には動的アナライザー (プロファイラー) が含まれているのに対し、最新の dependency は静的分析と API セットの解析に重点を置いています。
「Executor」を使用して、実行中にのみ発生する DLL エラー (読み込みの遅延やパス検索の問題など) をトラブルシューティングする必要がある場合は、Dependency Walker のプロファイル機能を引き続き使用できます。
| アドバンテージ | 欠点がある |
|---|---|
| 有能Dynamic Loading(ロードライブラリ) エラー。 | Win10/11 で実行すると、ログには大量の誤った API-MS-WIN エラー メッセージが表示されます。 |
| 実際にロードされた DLL ファイルのパスを確認できます (検索パスの順序に関連します)。 | 依存関係が多すぎるためにプログラムがまったく起動しない場合、プロファイラーは有用な情報を取得できない可能性があります。 |
dependency Walker のプロファイラーで誤ったエラーが多すぎて要点がわからない場合は、代わりに次の組み合わせを使用することをお勧めします。
NAME NOT FOUNDこれにより、プログラムがどこで DLL を見つけられなかったのかを正確に知ることができます。GitHub が OpenAI と提携して開発したこのツールは、現在世界で最も広く使用されている AI コーディング アシスタントです。直接埋め込むことができますVisual Studio Code、JetBrains他の一般的な開発環境では、コメントとコンテキストを分析して、コード行または関数全体を即座に提案します。
これは、VS Code アーキテクチャに基づいて開発された独立したソフトウェアです。AIコードエディター。単純なプラグインとは異なり、Cursor は AI をエディターの最下層に深く統合します。プロジェクト全体の構造 (コンテキスト) を理解し、開発者がライブラリ全体と直接対話して、グローバルなリファクタリングやバグ修正を実行できるようにします。
クロードは汎用AIではありますが、3.5 ソネットモデルプログラム ロジック、アーキテクチャ設計、デバッグ機能の点で、最高の選択肢の 1 つとして認識されています。マッチArtifactsこの機能により、開発者は、生成された Web ページのフロントエンド画面や対話型コンポーネントをダイアログ ボックスで直接プレビューできます。
タブナインが重視しているのは、プライバシーとセキュリティ、ソースコードの機密性に対する高い要件がある企業に適しています。完全にローカライズされた展開 (セルフホスティング) をサポートし、コードがトレーニングのためにクラウドにアップロードされないようにし、正確なオートコンプリート機能を提供します。
アマゾン ウェブ サービス (AWS) が提供する開発アシスタント。基本的なコード生成に加えて、特に次の機能が強化されています。AWSクラウドサービスこの統合により、開発者はコードとしてインフラストラクチャ (IaC) を迅速に作成したり、セキュリティ スキャンや更新を処理したりすることができます。
Replit オンライン開発環境に組み込まれた AI エージェント。特徴的なのは、自動展開環境構築では、ユーザーはアプリケーションの機能を記述するだけで、エージェントが自動的にファイルの作成、依存パッケージのインストール、コードの記述を行い、オンラインでの運用が完了します。
ヴェルセル提供フロントエンド開発用AI。ユーザーは自然言語を通じてインターフェイス要件を記述し、v0 は React、Tailwind CSS、Shadcn UI に基づいてフロントエンド コンポーネント コードを直接生成し、UI ステレオタイプの時間を大幅に短縮します。
Agentic AI コーディング アシスタント。このタイプのツールの特徴は、ターミナルに直接アクセスし、ファイルの読み取りと書き込み、テストの実行、およびタスクを個別に計画できることです。
このタイプのツールはクロード コードに最も近く、ターミナルで直接実行されるため、コマンド ライン操作に慣れている開発者に適しています。
このようなツールはエージェント機能をエディターに統合し、より直観的なビジュアル開発エクスペリエンスを提供します。
このようなツールは通常、より独立した操作機能を備えており、需要分析から Web またはスタンドアロン環境での展開までのプロセスを完了できます。
| ツール名 | メインインターフェース | 主な利点 |
|---|---|---|
| Claude Code | CLI(ターミナル) | Anthropic によってネイティブに開発されており、Claude 3.5 の指示に非常に厳密に従っています。 |
| Aider | CLI(ターミナル) | オープンソースで、複数のモデルをサポートし、強力な Git 自動管理を備えています。 |
| Cursor | IDE (編集者) | UI は統合度が最も高く、端末を切り替えるのが苦手な開発者に適しています。 |
| Cline | VSコードプラグイン | オープンソースで完全に透過的であるため、さまざまな API キーを自分で接続できます。 |
Claude Code は、Anthropic によって開発されたエージェントベースのコマンド ライン インターフェイス (CLI) ツールです。開発者の端末内で直接実行され、プログラム コード ライブラリ全体を理解し、端末コマンドを実行し、ファイルを編集し、Git ワークフローの処理を支援できるため、開発者は自然言語を通じて複雑なプログラミング タスクを完了できます。
Claude Code には Node.js 18 以降の環境が必要で、次の方法でインストールできます。
npm install -g @anthropic-ai/claude-code
claudeこれで対話モードを開始できるようになりました。| 関数 | 動作モード/ショートカットキー |
|---|---|
| Plan Mode | Shift + Tab(Mac/Linux) またはAlt + M(Windows)。実行する前に詳細な計画を立ててください。 |
| Auto-accept | すべての変更は自動的に受け入れられ、それぞれを確認する必要はありません。 |
| ファイルを選択 | 入力@予備知識として特定のファイルをすばやく検索して追加します。 |
| 命令の実行 | 使用!セッション内で Bash コマンドを直接実行するためのプレフィックス (例:!ls -la)。 |
/help: 使用可能なすべてのコマンドと指示を表示します。/clear: 現在の会話履歴をクリアし、コンテキスト スペースをリセットします。/stats: 最近のトークンの使用状況と費用の統計を表示します。/doctor:インストール状態が正常かどうかを診断します。/compact: 会話コンテンツを手動で圧縮してスペースを節約します。許可を確認するポップアップが頻繁に表示されたり、ディレクトリ間アクセスが必要な場合は、起動パラメータと組み込みコマンドを使用して最適化設定を行うことができます。
デフォルトでは、Claude Code は危険なコマンド (ファイルの削除やシステム コマンドの実行など) を 1 つずつ確認します。干渉を減らすために「自動モード」に入るには、次のパラメータを使用します。
--auto-acceptこれにより、ツールは質問をやめることなく、提案された指示を自動的に実行します。ただし、以下のような破壊命令を実行する場合は行えませんのでご注意ください。rm)。claude --auto-accept
/approve-all、現在のセッションでの後続の操作に対して一時的な完全な信頼が付与されます。安全上の理由から、クロード コードはデフォルトで開始されるプロジェクト ディレクトリに制限されます。外部パスにアクセスするには、次の 3 つの方法があります。
claude . /path/to/another/project
@そして、外部ファイルへの絶対パスを貼り付け、その内容をコンテキストに追加します。@/etc/nginx/nginx.conf の設定を参照して現在のプロジェクトを変更できるようにしてください。
ln -s /path/to/external_dir ./external_dir
迅速な起動を容易にし、将来的にこれらの設定を反映するには、次のことをお勧めします。.bashrcまたは.zshrc(Cygwin/Linux) エイリアスを追加します。
alias c='claude --auto-accept . /home/user/common_library'
--auto-accept後で、クロードは、あなたが確認していないシェル コマンドを実行する可能性があります。信頼できるプロジェクト環境でのみ使用することをお勧めします。完全に自動化された起動 (確認なし) と外部ディレクトリへのアクセスのニーズに合わせて、Claude Code はこれを実現するための特別な CLI パラメーターを提供します。これらの機能は「YOLO モード」と呼ばれることが多く、信頼できる環境またはサンドボックスでの使用に適しています。
実行したくない場合はls、mkdirまたは、ファイルの編集中に [OK] をクリックし続けると、次の危険なパラメータを使用する可能性があります。
--dangerously-skip-permissions--allow-dangerously-skip-permissions--permission-mode bypassPermissions使用。デフォルトでは、Claude は起動されたディレクトリの読み取りと書き込みのみが可能です。他のパスにアクセスするには、次を使用します--add-dir:
クロード --add-dir <パス>
claude --add-dir ../another-project --add-dir /var/log一度に正しく実行し、障害なく複数のディレクトリ間で直接開発したい場合は、次の組み合わせを使用できます。
claude --dangerously-skip-permissions --add-dir ../library --add-dir ~/shared_configs
| パラメータ名 | 機能説明 | 該当する状況 |
|---|---|---|
--dangerously-skip-permissions |
すべてのツール (Bash、読み取り、書き込み) に対する権限の確認をスキップします。 | サンドボックス環境での大規模な自動リファクタリングまたは操作が必要です。 |
--add-dir <path> |
クロードに現在のディレクトリ外の特定のパスへのアクセスを許可します。 | プロジェクト間の開発では、外部ドキュメントの参照が必要になる場合があります。 |
--permission-mode acceptEdits |
ファイルの変更を自動的に受け入れますが、Bash コマンドの実行時にも尋ねられます。 | 比較的安全な自動モード。 |
--dangerously-skip-permissions破壊的。クロードがコマンドの判断を誤った場合(ファイルを誤って削除した場合など)、システムはコマンドを傍受しません。rootまたはsudoID を使用してこのパラメーターを実行すると、セキュリティ メカニズムによりブロックされる場合があります。一般ユーザー権限で実行することを推奨します。Cursor は、VS Code をベースに開発された AI コードエディタです。これは単なるプラグインではなく、AI 機能をエディターの最下層に深く埋め込んでおり、プロジェクト全体のコンテキストを理解し、コードを自動的に作成、再構築、修復する機能を備えています。 VS Codeを継承しているため、独自の設定や拡張機能をすべて直接インポートできます。
コードエディターで AI を直接呼び出します。
Cmd + K(Windows用Ctrl + K)。サイドバーのチャットダイアログ:
Cmd + Lチャットウィンドウを開きます。@Files、@Codebaseまたは@WebAI参照の範囲を指定します。これは Cursor の最も強力な「エージェント」モードです。
Cmd + Iコンポーザを起動します。| 関数名 | 設定方法 | 説明する |
|---|---|---|
| 機種切り替え | サイドバーの下部メニュー | Claude 3.5 Sonnet、GPT-4o、または Cursor Small を切り替えます。 |
| Rules for AI | Settings > General | AI の応答スタイルをカスタマイズします (例: 常に繁体字中国語を使用し、コードは特定の仕様を満たす必要があります)。 |
| Index Project | Settings > Features | AI がプロジェクトのファイル全体を正確に検索できるように、ローカル インデックス作成を必ずオンにしてください。 |
Cmd + K、AI が複雑なシェル命令の作成を支援します。Aider は、ローカル ソース コードの直接変更をサポートするターミナル ベースの AI ペアリング プログラミング ツールです。インストールする前に、システムが次のことを行っていることを確認してください。Python 3.8上記のバージョンは同じですGit。
python -m pip install aider-chat
開始する前に、AI サービスプロバイダーから提供されるキーを環境変数として設定する必要があります。 Aider は、Anthropic や OpenAI などのさまざまなモデルをデフォルトでサポートしています。
export ANTHROPIC_API_KEY=your-keysetx ANTHROPIC_API_KEY your-key設定が完了したらターミナルに入力しますaiderこれにより、会話インターフェイスが開きます。
Aider は、トークンのコストを節約し、精度を向上させるために、コンテキストに参加するために指定したファイルのみを読み取り、変更します。
自然言語を直接使用して、Aider に「このクラスを 2 つのファイルに分割するのを手伝ってください」や「既存のバグを修正してください」などのタスクを実行するように依頼できます。変更を実行すると、Aider は自動的にGit Commit、変更されたコンテンツに基づいて送信メッセージを自動的に作成します。
| 命令 | 機能説明 |
|---|---|
| /undo | AI によって実行された最新のコード変更と Git コミットを元に戻します。 |
| /diff | 現在の AI に加えられた変更を元のバージョンと比較してプレビューします。 |
| /chat-mode | 会話モードを切り替えます (例: コード モードはファイルの変更に使用され、質問モードは Q&A のみに使用されます)。 |
| /help | 組み込みコマンドの完全なリストを表示します。 |
| /exit | Aider プログラムを終了します。 |
Aider は、ローカルで実行される無料のオープンソース モデルとインターフェイスするための複数の方法をサポートしています。最も一般的な方法は、Ollama、LM StudioまたはLocalAIツールが OpenAI API 仕様と互換性のあるローカル サーバーを作成するのを待ってから、Aider にサーバー アドレスをポイントさせます。
これは現在、最もシンプルで最も主流のローカリゼーション ソリューションです。
ollama pull deepseek-coder-v2(または、Qwen2.5-Coder などのプログラムに最適化されたモデルを選択します)。--modelパラメーターは Ollama モデルのパスを指定します。aider --model ollama/deepseek-coder-v2
| パラメータ | 機能説明 |
|---|---|
| --model | モデル名を指定します。ローカル モデルは通常、次の形式です。ollama/<model_name>。 |
| --openai-api-base | LM Studio を使用する場合は、ローカル API URL (例:http://localhost:1234/v1)。 |
| --no-stream | ローカル推論のパフォーマンスが不十分で接続が不安定な場合は、ストリーミング出力をオフにすることで安定性を高めることができます。 |
すべてのモデルが Aider との使用に適しているわけではありません。以下は、プログラム開発タスクにおいてパフォーマンスが優れているとコミュニティによって現在認識されているローカル オープン ソース モデルです。
ソフトウェアコード、設計文書、ユーザーマニュアルなどはすべて著作権保護の対象となります。著作権保護は作成完了時に自動的に確立され、登録は不要で、無断でコピー、改変、配布、商用利用することは禁止されています。
ソフトウェアに技術革新や独自のアルゴリズムが含まれている場合は、特許保護を申請できます。特許は審査と承認の対象であり、技術的ソリューションに対する発明者の独占的権利を保護しますが、純粋なプログラム ロジックは通常、特許によって保護されません。
ソフトウェア名、ロゴ、およびブランド アイデンティティは、ブランド イメージと市場の差別化を保護し、他者が混乱を引き起こすために使用することを防ぐために商標として登録できます。
非公開のプログラミングの詳細、アルゴリズム、データベース構造などは企業秘密です。企業は機密保持契約や情報管理システムなどを通じてこれを保護する必要があります。
例えば、個人情報法や情報セキュリティ管理法では、ソフトウェア開発過程において個人データの適切な取り扱いと情報セキュリティの確保が求められています。違反すると、行政責任または刑事責任が問われる可能性があります。
ソフトウェア開発には、契約契約、共同開発契約、ソフトウェアライセンス条項などが含まれることが多く、法的紛争を避けるために、両当事者の権利と義務、プログラムコードの所有権、保守責任、機密保持義務などが明確に定義されています。
ソフトウェアのオンライン操作には、ネットワークサービス、電子決済、オンラインでの知的財産権の保護などが含まれ、電子署名法や電子取引法などの規制を遵守する必要があります。
ソフトウェアコードは著作権保護の範囲内にあり、開発者は追加の登録をしなくても自動的に著作権を所有します。著作権保護の対象となるのは、ソースコード、デザインファイル、ユーザーマニュアルなどです。
ソフトウェアに新規性や技術革新が伴う場合は、特許保護を申請できる場合があります。例には、技術的問題を解決する独自のアルゴリズムや方法が含まれますが、純粋なコード ロジックは通常、特許保護の範囲外です。
ソフトウェアの名前とロゴは、さまざまな供給元の製品を区別し、市場の混乱を避けるために商標として登録できます。
非公開のプログラミングの詳細、データベース構造、アルゴリズムは企業秘密によって保護できます。社内の機密保持契約とそれを維持するための管理手段に依存する必要があります。
ソフトウェアは、プロプライエタリ ソフトウェア、フリー ソフトウェア、オープン ソース ライセンス (GPL、MIT など) など、さまざまなライセンス モデルを通じてリリースできます。ライセンス モデルの違いは、ユーザーの変更および再配布の権利に影響します。
他人のコード、画像、アルゴリズムを許可なく使用すると、著作権侵害となる可能性があります。開発プロセスでは、法的紛争を避けるために、プログラム コードのソースが合法であることを確認する必要があります。
知的財産権には領土がありますが、ベルヌ条約や TRIPS 協定などの国際条約を通じて、多くの国である程度の保護を得ることができます。
2026 年には、適切なソフトウェア販売プラットフォームの選択は、ソフトウェアの種類とターゲット市場によって決まります。主流のプラットフォームの分類と特徴は次のとおりです。
| 需要目標 | 推奨プラットフォーム | 主な利点 |
|---|---|---|
| グローバルな税務処理を自動化する | Paddle / Lemon Squeezy | さまざまな国での納税申告の手間を省きます。 |
| 最大トラフィックの追求 | Steam / App Store | 既製の大規模なユーザーベース |
| ブランド公式ウェブサイトを素早く構築 | Shopify / SHOPLINE | 高度にカスタマイズされたショッピング体験 |
| シードユーザーの早期獲得 | AppSumo | プロモーションを通じてすぐに現金を手に入れる |
email: [email protected]