Язык программирования (Язык программирования) — это мост между людьми и компьютерами. Он используется для написания инструкций, управления операциями компьютера и реализации различных приложений.
Согласно последнему рейтингу языков программирования, вот 20 лучших языков программирования в 2024 году:
Лямбда-выражение — это анонимная функция, которая часто используется для упрощения кода, особенно когда вам нужно передать небольшие функции или обратные вызовы. Синтаксис лямбда-выражения краток, а логику функции можно определить в одной строке. Лямбда-выражения чаще всего встречаются в Такие языки, как 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};
// Используем лямбда-выражение для вычисления суммы четных чисел
целая сумма = 0;
std::for_each(numbers.begin(), Numbers.end(), [&sum](int n) {
если (n % 2 == 0) сумма += n;
});
std::cout << "Сумма четных чисел: " << сумма << станд::эндл;
вернуть 0;
}
# Используйте лямбда-выражение для вычисления суммы двух чисел
добавить = лямбда 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 = Numbers.Where(n => n % 2 == 0).Sum();
Console.WriteLine($"Сумма четных чисел: {sum}");
}
}
map、filterиreduceПодождите, пока функции более высокого порядка начнут работать с коллекциями.# Python: список и чтение свойств объекта
Класс Пользователь:
защита __init__(self): self.id = 0; self.name = "Энн"
и = Пользователь()
для k, v в vars(u).items():
print(k, v) # id 0 / имя Энн
// C#: получить поле/свойство и прочитать значение
использование системы;
использование System.Reflection;
вар т = тип (MyType);
foreach (var p в 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(истина);
System.out.println(f.getInt(u)); // 42
// Go: отражает структуру посещения
импортировать «отражать»
func Dump(v любой) {
val:= отражения.ValueOf(v)
для я := 0; я < val.NumField(); я++ {
имя:= val.Type().Field(i).Name
fmt.Println(имя, значение.Поле(i).Интерфейс())
}
}
| язык | Поддерживать | иллюстрировать |
|---|---|---|
| Python | ✅ | Динамическая, полная рефлексия, простая рекурсивная проверка объектов/контейнеров. |
| JavaScript / TypeScript | ✅ | Объект имеет ключевое значение и доступен.Object.valuesрекурсия. |
| Ruby | ✅ | instance_variablesрефлексивный член. |
| PHP | ✅ | get_object_vars()Или Отражение. |
| C# (.NET) | ✅ | Отражение получает поля/свойства и имеет хорошую типобезопасность. |
| Java | ✅ | java.lang.reflectСканируемые поля. |
| Kotlin | ✅ | Отражение JVM завершено, как и в Java. |
| Go | ✅ | reflectДоступен для полей структуры. |
| Swift | ◑ | MirrorПосещения возможны, но сцены ограничены и требуется дополнительная обработка. |
| С++ (до С++23) | ❌ | Никакого отражения во время выполнения, вам нужно вручную писать проверки типов. |
| Rust | ❌ | Никакого отражения во время выполнения, часто реализуемого с помощью Derivate/Trait. |
def is_all_zero(obj, eps=1e-6):
if isinstance(obj, (int, float)): # Базовое числовое значение
вернуть abs(obj) < eps
elif isinstance(obj, (list, tuple, set)): # последовательность/набор
вернуть все (is_all_zero (x, eps) для x в obj)
elif isinstance(obj, dict): # Словарь
вернуть все (is_all_zero(v, eps) для v в obj.values())
elif hasattr(obj, "__dict__"): # Общие объекты
вернуть все (is_all_zero(v, eps) для v в vars(obj).values())
еще:
вернуть ложь
# тест
Классовый балл:
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 === "число") 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));
вернуть ложь;
}
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;
переключатель (объект) {
случай int я: вернуть я == 0;
регистр длинный l: вернуть l == 0;
case float f: return Math.Abs(f) < eps;
регистр double d: вернуть Math.Abs(d) < eps;
}
вар т = obj.GetType();
если (t.IsArray)
return ((Array)obj).Cast<object>().All(x => IsAllZero(x, eps));
//Сканируем поля и атрибуты
foreach (var f в t.GetFields(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
if (!IsAllZero(f.GetValue(obj), eps)) возвращает false;
foreach (var p в t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic))
if (p.CanRead && !IsAllZero(p.GetValue(obj, null), eps)) возвращает false;
вернуть истину;
}
}
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) | Сообщение отправляется в очередь, и **только один** получатель извлекает его из очереди и использует сообщение. После использования сообщение удаляется. | Обработка заказов, распределение задач и балансировка рабочей нагрузки. |
| Публикация/подписка, публикация/подписка | Сообщение публикуется в теме, и **все** получатели (подписчики), подписанные на эту тему, получат копию сообщения. | Трансляция системных событий, сбор журналов, уведомление об изменении данных. |
Очереди сообщений являются краеугольным камнем современных распределенных систем, архитектур микросервисов и приложений высокой доступности. Это значительно повышает отказоустойчивость, масштабируемость и надежность системы за счет введения косвенности во времени и пространстве.
| характеристика | Очередь сообщений (MQ) | HTTP API (REST/RPC) |
|---|---|---|
| Тип связи | Асинхронный | синхронный |
| Муфта | Низкая связанность (отправитель и получатель не взаимодействуют напрямую) | Высокая связанность (клиенту необходимо знать адрес сервера и ждать ответа) |
| поток данных | В одну сторону, проходит через промежуточного брокера | Двусторонний, запрос и ответ (Запрос-Ответ) |
| отказоустойчивость | Высокий уровень: Брокер сохраняет сообщение, и оно не будет потеряно, даже если получатель не в сети. | Низкий: сервер находится в автономном режиме или время ожидания истекло, что приводит к сбою запроса. |
| Масштабируемость | Высокий, можно легко добавить несколько потребителей для обработки нагрузки | Относительно низкий, для распределения запросов используется балансировщик нагрузки. |
MQ и HTTP API не являются технологиями замены, а предназначены для решения разных задач.
В современных распределенных системах эти два режима часто сосуществуют и взаимодействуют друг с другом для удовлетворения различных потребностей бизнеса.
Во многих сетевых приложениях некоторые операции занимают много времени, и если пользователи будут вынуждены ждать одновременно, это приведет к ухудшению пользовательского опыта. MQ позволяет выполнять эти задачи асинхронно.
MQ имеет решающее значение для обработки временных сценариев с высоким трафиком и может защитить серверные службы от сбоев.
В сложных распределенных системах и микросервисных архитектурах MQ используется для изоляции сервисов и уменьшения взаимозависимости.
Собирайте большие объемы данных журналов из внешних приложений или серверов в централизованную систему обработки.
В частности, платформы MQ/потоковой обработки с высокой пропускной способностью, такие как Apache Kafka, идеально подходят для обработки непрерывных потоков данных в реальном времени.
Основными проблемами при использовании 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). Это очень важно для потокового видео (Streaming), позволяя плееру загружать только ту часть, которую необходимо воспроизвести, и поддерживает быструю перемотку вперед/назад.Суть потоковой передачи заключается в том, как эффективно, стабильно и с низкой задержкой передавать аудио- и видеоконтент с сервера клиенту.
Это краеугольный камень современных потоковых сервисов. Сервер кодирует один и тот же фрагмент видеоконтента в несколько версий разного качества (битрейт, разрешение).
CDN незаменим для потоковых сервисов, ориентированных на пользователей по всему миру.
Используется для сжатия и распаковки аудио- и видеоданных с целью уменьшения размера файла.
В Баше $? представляет код статуса выхода (Exit Status) последней выполненной команды. Это целочисленное значение, обычно используемое для определения успешности выполнения предыдущей команды.
#!/бин/баш
лс
echo "Код завершения предыдущей команды: $?"
В этом примереlsКоманда выведет список содержимого каталога. После успешного выполнения$?Значение будет 0.
#!/бин/баш
ls/несуществующий-каталог
echo "Код завершения предыдущей команды: $?"
В этом примереlsПопытка указать несуществующий каталог приведет к сбою команды.$?Значение будет ненулевым числом.
#!/бин/баш
cp file1.txt /некоторые/каталог/
если [$? -экв 0 ]; тогда
echo «Файл успешно скопирован».
еще
echo «Не удалось скопировать файл».
фи
В этом примере определяется, какое сообщение отображать, в зависимости от статуса завершения команды.
если [условие]; тогда
инструкции
фи
Чтобы одновременно удовлетворить несколько условий в 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"
фи
Его можно выполнить, пока выполняется одно из условий:
-o(устарело, но доступно)if [ "$a" -eq 0 -o "$b" -eq 0 ]; тогда
эхо "a или b равно 0"
фи
[[ ]] ||(рекомендую)если [[ "$a" -eq 0 || "$b" -eq 0 ]]; тогда
эхо "a или b равно 0"
фи
||если [ "$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Инструкции обычно сопровождаются[ ](тестовая команда) или[[ ]](Используется расширенная тестовая команда). Чтобы выразить НЕ, используйте восклицательный знак!。
если [ ! состояние ]; тогда
# Код, который будет выполнен, если условие ложно
фи
Это наиболее распространенное использование, например: создать файл, если он «не существует».
# Если файла с именем config.txt не существует
если [ ! -f "config.txt"]; тогда
echo "Файл не существует, создаю..."
нажмите config.txt
фи
# Если каталог не существует
если [ ! -d "/var/log/myapp"]; тогда
mkdir -p "/var/log/myapp"
фи
Проверьте, является ли строка «не равной» или «не пустой».
STR="привет"
# Проверяем, не равна ли переменная "world"
if [ "$STR" != "мир"]; тогда
echo "Строка не соответствует"
фи
# Проверьте, не пуста ли строка (! -z эквивалентно -n)
если [ ! -z "$STR"]; тогда
echo "В переменной есть данные"
фи
Хотя числовое значение относительно-ne(не равно), но также может быть сопоставлено!использовать.
ЧИСЛО=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" в
"да")
echo "Вы выбрали Да"
;;
«нет»)
echo "Вы выбрали Нет"
;;
*)
эхо "Ошибка ввода"
;;
выходной
использовать|Символы позволяют нескольким режимам выполнять один и тот же блок инструкций.
read -p "Пожалуйста, введите сокращение месяца: " месяц
случай "$месяц" в
Янв|Февраль|Март)
эхо "первого сезона"
;;
апрель|май|июнь)
эхо "2 сезона"
;;
*)
эхо "другие месяцы"
;;
выходной
Сопоставление с образцом поддерживает расширенные символы, такие как пути к файлам (например,*, ?, [a-z])。
read -p "Пожалуйста, введите символ: " char
регистр "$char" в
[а-я])
echo "Это строчная буква"
;;
[А-Я])
echo "Это заглавная буква"
;;
[0-9])
эхо «Это число»
;;
*)
echo "Это специальный символ или несколько символов"
;;
выходной
| символ | Описание функции |
|---|---|
) |
Конечный тег шаблона. |
;; |
Конечный маркер блока команд (аналогичноbreak)。 |
* |
Сравнивает любую строку, обычно помещаемую последней в качестве опции по умолчанию. |
| |
Используется для разделения нескольких совпадающих шаблонов (обозначающих «или»). |
esac |
caseНаписанное наоборот, оно представляет собой конец грамматического блока. |
"$var"), чтобы избежать синтаксических ошибок, когда переменная имеет нулевое значение.caseбудут сравниваться сверху вниз. Как только матч будет успешным, и вы столкнетесь;;остановится, поэтому, пожалуйста, переведите конкретный режим в общий режим (например,*)До.Поведение по умолчанию: с учетом регистра. В стандартной среде BashcaseЗаявлениеС учетом регистраиз. Это означает, что «А» и «а» рассматриваются как разные шаблоны.
read -p "Введите символ: " char
регистр "$char" в
а) echo "Это строчная буква а" ;;
А) echo «Это заглавная буква А» ;;
выходной
---
Если вы хотите весьcaseОператор игнорирует регистр и может использоватьсяshoptкоманда включенаnocasematchнастраивать. Это повлияет на все последующие сравнения строк иcaseсудить.
# Включить игнорирование регистра
shopt -s nocasematch
read -p "Введите да или ДА: " ввод
случай "$input" в
да) echo "Сопоставление успешное (игнорировать регистр)" ;;
выходной
# Отключить игнорирование регистра (восстановить по умолчанию)
магазин -u nocasematch
---
Если вы не хотите менять глобальную настройку, определение диапазона регистров непосредственно в схеме является наиболее стандартным и последовательным подходом.
read -p "Введите букву: " char
регистр "$char" в
[аА])
echo "Вы ввели A или A"
;;
[б-зБ-З])
echo "Вы ввели дополнительные буквы"
;;
Эсак
---
Для конкретных слов вы можете использовать|перечислить все возможные варианты написания.
случай "$input" в
стоп|СТОП|Стоп)
echo "остановить выполнение"
;;
выходной
---
| метод | преимущество | недостаток |
|---|---|---|
shopt -s nocasematch |
Программный код лаконичен и подходит для масштабных сравнений. | Это повлияет на поведение всего скрипта, поэтому не забудьте отключить его вручную. |
[a-zA-Z]объем |
Точный контроль, не затрагивающий другие детали. | Если слова очень длинные, написание станет очень громоздким. |
трубочный персонаж| |
Высокая читаемость, подходит для нескольких конкретных слов. | Невозможно обрабатывать случайные комбинации регистров (например, Да). |
Арифметические расширения в Bash(( ))Внутри вы можете просто использовать круглые скобки( )для явного указания приоритета операций в соответствии с логикой C или большинства языков программирования. Это очень важно при работе со сложной логикой (сочетание И, ИЛИ, сложения, вычитания, умножения и деления).
# Пример: (A и B) или C
если (( (МИН > 91 && МИН< 110) || FORCE_MODE == 1 )); then
echo "條件成立"
fi
существовать(( ))Внутри порядок приоритета операций соответствует стандартным математическим и логическим соглашениям:
( )Высший приоритет.*, /, %。+, -。<, >, <=, >=。&&(И) имеет приоритет над|| (OR)。Предположим, вам необходимо определить: значение должно находиться в пределах диапазона и (должно быть конкретным кратным или в принудительном режиме):
if (( MIN > 91 && (MIN % 5 == 0 || FORCE_MODE == 1) )); тогда
{
echo "Вызвать сложное условное суждение"
IS_SHUTDOWN=истина
} |& tee -a "$LOGFILE"
фи
| тип синтаксиса | Группировка символов | На что следует обратить внимание |
|---|---|---|
(( ... )) |
( ) |
Самый интуитивно понятный вариант: символы не требуют экранирования и рекомендуются для чисто числовых операций. |
[[ ... ]] |
( ) |
существовать[[ ]]Также разрешено использовать круглые скобки для логической группировки. |
[ ... ] |
\( ... \) |
ТрадицияtestСинтаксис: скобки должны быть экранированы обратной косой чертой, что не рекомендуется. |
В сценарии BashexitИспользуется для прекращения выполнения сценария и возврата кода состояния (статус выхода) родительской программе.
если [ -f "config.txt"]; тогда
эхо "Файл существует"
выход 0
еще
echo «Ошибка: профиль не найден»
выход 1
фи
После выполнения скрипта или инструкции вы можете использовать специальные переменные$?чтобы получить предыдущую программуexitкод состояния.
./script.sh
echo "Состояние завершения сценария: $?"
когда ты звонишь.shфайл и хотите «вывести его содержимое» (т.echoПри сохранении содержимого переменной вы можете использовать обратные кавычки или$(). Это называется заменой команд.
#!/бин/баш
# Это выходной контент, который будет захвачен
эхо "Ubuntu_User"
# Это конечное состояние, и оно не будет фиксироваться обратными кавычками.
выход 0
# Используйте обратные кавычки
РЕЗУЛЬТАТ=`./get_name.sh`
# Используйте $() (рекомендуется современное написание)
РЕЗУЛЬТАТ=$(./get_name.sh)
echo "Полученный результат: $RESULT"
| Цель | Как получить | использовать |
|---|---|---|
| Статус выхода (код состояния) | $? |
Определите, было ли выполнение инструкции успешным (0 или 1). |
| Стандартный вывод (выходное содержимое) | ` `или$( ) |
Получите строковые данные, сгенерированные после выполнения скрипта. |
Если вы хотите получить оба одновременно, вы можете обратиться к следующему примеру:
ВЫХОД=$(./script.sh)
СТАТУС=$?
echo "Содержимое: $OUTPUT"
echo "Код состояния: $STATUS"
В Баше,returnинструкции специально предназначены дляФункцияили черезsourceСкрипт для выполнения. Он останавливает выполнение текущей функции или сценария и возвращает указанный код состояния вызывающей стороне, но не закрывает текущую программу оболочки.
Это наиболее распространенное использование.returnВозвращается код состояния (0–255), а не строковые данные.
#!/бин/баш
# определение функции
check_file() {
если [ -f "$1"]; тогда
вернуть 0 # успех
еще
вернуть 1 # не удалось
фи
}
# Функция вызова
check_file "test.txt"
РЕЗУЛЬТАТ=$?
если [ $RESULT -eq 0 ]; тогда
эхо "Файл существует"
еще
эхо "Файл не существует"
фи
Если вы хотите, чтобы переменные и среда оставались в текущем терминале после выполнения скрипта, вы обычно используетеsource. Необходимо использовать в настоящее времяreturnскорее, чемexit。
# Имитировать логическое суждение
if [ "$USER" != "root"]; тогда
echo "Недостаточно прав, только для root"
# Если вы используете выход, вы сразу закроете терминал. Если вы используете return, вы только остановите выполнение этого скрипта.
вернуть 1
фи
экспортировать APP_STATUS="Готово"
вернуть 0
источник ./sub_script.sh
echo "Скрипт возвращает статус: $?"
echo "Получить переменные среды: $APP_STATUS"
потому чтоreturnВозврату подлежат только числа (коды состояния). Для получения строк или больших объемов данных рекомендуется комбинироватьechoизамена команды。
#!/бин/баш
вычислить() {
локальное значение=$(($1 + $2))
# Вывод результатов на стандартный вывод
эхо "$val"
# Возвращаем код статуса выполнения
вернуть 0
}
вычислить 10 20
# Получаем выходной контент
ДАННЫЕ=$(./get_data.sh)
# Получаем код статуса возврата
СТАТУС=$?
echo "Результат расчета: $DATA"
echo "Статус выполнения: $STATUS"
| Ключевые слова | Область применения | Влияние на основную программу |
|---|---|---|
exit 0/1 |
Независимые скрипты и подпрограммы | Завершит всю текущую оболочку (если выполняется с исходным кодом). |
return 0/1 |
Функция, загружен исходный скрипт | Выход только из текущей области действия и не влияет на основную программу Shell. |
echo "..." |
где угодно | Используется для передачи фактического «содержимого данных» вызывающему объекту. |
В Bash вы можете использовать условное суждение, чтобы проверить, пуста ли переменная. Вот несколько распространенных способов:
-zПроверьте, пуста ли переменная#!/бин/баш
вар=""
если [ -z "$var"]; тогда
echo "Переменная пуста"
еще
echo "Переменная не пуста"
фи
-zИспользуется для проверки того, пуста ли переменная. Если переменная пуста, условие истинно.
-nПроверьте, не пуста ли переменная#!/бин/баш
var="некоторое значение"
если [ -n "$var"]; тогда
echo "Переменная не пуста"
еще
echo "Переменная пуста"
фи
-nИспользуется для проверки того, не является ли переменная пустой. Если переменная имеет значение, условие истинно.
#!/бин/баш
вар=""
if [ "$var" == "" ]; тогда
echo "Переменная пуста"
еще
echo "Переменная не пуста"
фи
Этот метод напрямую сравнивает переменную с пустой строкой, чтобы проверить, пуста ли переменная.
Bash поддерживает два типа массивов:
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["Япония"]}" # Токио
для ключа в "${!capital[@]}"; делать
echo "Капитал $key равен ${capital[$key]}"
сделано
declare -AобъявитьМассив Bash — это важная структура для хранения нескольких фрагментов данных, которая подходит для обработки данных, таких как списки параметров, наборы каталогов и пары «ключ-значение».
combined=("${array1[@]}" "${array2[@]}")
Это объединит все элементы из обоих массивов в новый массив.combined。
array1=("яблоко" "банан")
array2=("вишня" "дата")
комбинированный=("${array1[@]}" "${array2[@]}")
echo "Объединенный массив:"
для элемента в "${combined[@]}"; делать
эхо "$item"
сделано
array1+=("${array2[@]}")
Это будетarray2контент добавляется непосредственно вarray1задний.
"${array[@]}"форма, чтобы предотвратить неправильное раскрытие элементовstr="привет, мир"
if [[ "$str" == привет* ]]; тогда
echo "Строка начинается с приветствия"
фи
проиллюстрировать:использовать[[ ]]Поддержка сравнения шаблонов оболочки,*Представляет любого персонажа.
if [[ "$str" =~ ^привет ]]; тогда
echo "Строка начинается с приветствия"
фи
проиллюстрировать: ^Обозначает начало,[[ ]]в=~это обычная операция.
caseРассказатьрегистр "$str" в
hello*) echo "Строка, начинающаяся с hello" ;;
*) echo "не начинается с приветствия" ;;
Эсак
проиллюстрировать: caseЭто хороший инструмент для обработки строковых шаблонов, краткий и легко читаемый.
expr(Старый стиль письма)if expr "$str" : '^hello' &> /dev/null; тогда
echo "Строка начинается с приветствия"
фи
проиллюстрировать:использоватьexprОбычная функция сопоставления, подходит для старых версий оболочки.
[[ ]]Сравнивать[ ]Более полные функции, рекомендуемые к использованию=~Можно использовать регулярные выражения, но не забывайте добавлять кавычки.-e-eИспользуется для проверки существования файла или каталога (независимо от типа).
ФАЙЛ="/etc/passwd"
если [ -e "$ФАЙЛ"]; тогда
эхо "$FILE существует"
еще
echo "$FILE не существует"
фи
! -d-dИспользуется для проверки того, является ли это каталогом,!Это негативная операция.
КАТАЛОГ="/tmp/мояпапка"
если [ ! -d "$DIR"]; тогда
echo "$DIR не существует, создаю..."
mkdir -p "$КАТАЛ"
еще
echo "$DIR уже существует"
фи
-e: существует ли файл или каталог (независимо от типа)-f: Является ли это «общим файлом»-d: То ли это "каталог"-L: Является ли это «символической ссылкой»PATH_TO_CHECK="/home/user/config"
если [ -e "$PATH_TO_CHECK"]; тогда
echo "$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Допустимоfindс нулем(\0) символы в качестве разделителей вывода, аread -d $'\0'Может точно читать содержимое с нулевыми разделителями, чтобы обеспечить точное разделение каждого файла/пути.
subdirs=()
while IFS= read -r -d $'\0' dir; do
subdirs+=("$dir")
done < <(find . -type d -print0)
-print0: Заканчивайте каждый результат нулевым символом без разрывов строк.-d $'\0':readЧтение одного элемента с нулевым завершением за разIFS=: запретить рассматривать пробелы как разделители полей.-r: Избегайте пропуска символов во время обработки.txt_files=()
while IFS= read -r -d $'\0' file; do
txt_files+=("$file")
done < <(find "$(pwd)" -type f -name "*.txt" -print0)
находить . -тип f -print0 | в то время как IFS= читать -r -d $'\0' файл; делать
echo "Обработка: $файл"
# ваша_команда "$file"
сделано
находить . -тип d -print0 | в то время как IFS= read -r -d $'\0' dir; делать
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
**Примечание**: Если вы хотите, чтобы `подкаталоги` были доступны в основной программе, этот метод не подходит (поскольку подоболочка ` while ... |` не может вернуть массив)
mapfile -d '' -t subdirs < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)
mapfile(илиreadarray) может правильно считывать строки, разделенные нулем, в массивы.
Это самый надежный способ сохранить его в основной оболочке.
для каталога в "${subdirs[@]}"; делать
echo "Найден каталог: $dir"
сделано
mapfile -d '' -tобрабатывает-print0Самый безопасный и наиболее подходящий для Bash способ.var="line1
line2
line3"
в то время как IFS= читать строку -r; делать
echo "Читать: $line"
готово <<< "$вар"
IFS=Избегайте обрезки пробелов-rИзбегайте анализа escape-символов<<<является здесь строкой, обрабатывает содержимое переменной как входные данные, в то время какпрочитайте -r первая_строка <<< "$вар"
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глубина 1 -максглубина 1 -тип d -имя "abc*" -printf "%T@ %p\n" |
сортировать -номер | вырезать -d' ' -f2-
)
для каталога в "${abc_dirs[@]}"; делать
echo "Найдено: $dir"
сделано
-printfЭксклюзивная функция поиска GNU, по умолчанию в macOSfindНе поддерживается, доступноgfindзаменять%T@Представляет «время последнего изменения (в секундах)». Если вам нужно создать время, потребуются дополнительные инструменты.КАТАЛОГ="/mnt/usb"
если [ -w "$DIR"]; тогда
echo "$DIR доступен для записи"
еще
echo "$DIR недоступен для записи"
фи
-wЧтобы проверить, имеет ли каталог «разрешение на запись». Однако если сам каталог доступен для записи, но фактическое устройство доступно только для чтения (например, монтирование доступно только для чтения), этот метод может не работать.
КАТАЛОГ="/mnt/usb"
TESTFILE="$DIR/.write_test"
если коснуться «$TESTFILE» 2>/dev/null; тогда
echo "$DIR доступен для записи"
rm "$TESTFILE"
еще
echo "$DIR недоступен для записи"
фи
Этот метод является наиболее надежным и позволяет определить состояние монтирования или возможность записи на физическое устройство.
mountИнструкция по проверке, доступно ли монтирование только для чтенияМНТ="/мнт/USB"
если монтировать | grep "$MNT" | grep -q "(ро,"; тогда
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и нажмите EntercmdМожно открыть прямо по этому пути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 «Первая команда и вторая команда»
&: независимо от того, удался или не удался первый, будет выполнен следующий.&&: выполнять следующий только в том случае, если первый выполнен успешно.||: выполнять следующий только в том случае, если первый не удалсяПосле первой инструкции добавьтеcall, вы можете продолжить выполнение другого командного файла:
cmd /k «Первая команда и вызов второго.bat»
Если вам не нужно держать окно открытым, вы можете использовать/c:
cmd /c «Первая команда и вторая команда»
/cавтоматически закроет окно после выполнения всех команд и/kОкно сохранится.
В командной строке Windows (CMD) переменные — это пространства имен, используемые для хранения данных или настроек. Они могут храниться в среде (переменные среды) или определяться и использоваться в пакетном файле (региональные переменные).
Переменные, заданные системой или пользователем, доступны на протяжении всего сеанса операционной системы. Например:%PATH%、%TEMP%。
Просмотр переменных среды:использоватьsetЗаказ.
set
Установите/измените переменные среды (только текущий сеанс CMD):
set MY_VAR=Hello
В пакетном файле (.batили.cmdфайл)setПеременные, определенные командой, действительны только во время выполнения этого пакетного файла.
в использованииforПеременные, определенные при цикле и используемые для перебора файлов, папок или числовых последовательностей. Обычно в названии используется одна буква, которой предшествуют два знака процента, например:%%A(в пакетном файле) или один знак процента, например:%A(При выполнении непосредственно из командной строки).
Параметры, передаваемые в командный файл при его выполнении. Например:%1это первый параметр,%2это второй параметр,%0Путь и имя самого командного файла.
Чтобы получить значение переменной, обычно нужно добавить знаки процента до и после имени переменной.%。
установите ИМЯ=Пользователь CMD
echo Меня зовут %NAME%
Выход:Меня зовут Пользователь CMD
@эхо выключено
set MESSAGE=Это пакетное сообщение
эхо%MESSAGE%
пауза
Вы можете использоватьIF DEFINEDилиIF NOT DEFINEDоператор, чтобы проверить, существует ли переменная или определена (не пуста).
@эхо выключено
rem проверяет, определена ли переменная MY_DEFAULT_VALUE (не пуста)
ЕСЛИ НЕ ОПРЕДЕЛЕНО MY_DEFAULT_VALUE (
установите MY_DEFAULT_VALUE=Настройки по умолчанию
Переменная эха MY_DEFAULT_VALUE не определена, и ей присвоено значение по умолчанию.
) ЕЩЕ (
переменная echo MY_DEFAULT_VALUE уже существует, значение: %MY_DEFAULT_VALUE%
)
rem выполняется один раз, переменной будет присвоено значение Default_Setting
Если rem будет выполнен еще раз, это покажет, что оно уже существует.
установите MY_DEFAULT_VALUE=Existing_Setting
проверь еще раз
ЕСЛИ НЕ ОПРЕДЕЛЕНО MY_DEFAULT_VALUE (
установите MY_DEFAULT_VALUE=Другой_по умолчанию
переменная echo MY_DEFAULT_VALUE не определена, ей присвоено значение Another_Default.
) ЕЩЕ (
переменная echo MY_DEFAULT_VALUE уже существует, значение: %MY_DEFAULT_VALUE%
)
пауза
Еще один хитрый трюк — воспользоваться преимуществами функции увеличения переменных по умолчанию (но в основном это используется для циклов и обработки параметров, а также в стандартныхsetЛогика «установить, если не установлено» не применима напрямую к команде. поэтому,IF NOT DEFINEDЭто самый стандартный подход. )
В циклах или условных операторах стандартное расширение переменной знака процента происходит один раз во время анализа оператора. Чтобы иметь возможность читать новое значение переменной на каждой итерации цикла, вам нужно включить отложенное расширение и использовать восклицательный знак!для ссылки на переменные.
@эхо выключено
setlocal включенное расширение
setCOUNTER=0
:ПЕТЛЯ
если %COUNTER% LSS 5 (
установить /СЧЕТЧИК+=1
текущий счетчик эха: !COUNTER!
перейти к циклу
)
локальный
| переменная | описывать |
|---|---|
%DATE% |
текущая дата. |
%TIME% |
текущее время. |
%CD% |
Текущий путь к каталогу. |
%ERRORLEVEL% |
Конечный код предыдущей команды (обычно 0 в случае успеха). |
%RANDOM% |
Случайное десятичное число от 0 до 32767. |
%~dp0 |
Диск и путь, по которому выполняется командный файл. |
Для переменных параметров (таких как%1) или переменную цикла (например,%%A), вы можете использовать модификаторы для извлечения различных частей пути:
эхо полного пути: %~1
эхо-диск: %~d1
путь эха: %~p1
имя эхо-файла: %~n1
расширение эхо-файла: %~x1
Это полезно при работе с путями к архивам.
grep, но вы можете использовать встроенныйfindкоманда достигает аналогичного эффекта.Команда | найди "ключевое слово"режиссёр | найти «txt» :: Показывать только файлы, содержащие «txt»
ipконфигурация | найти «IPv4» :: показывать только строки, содержащие IPv4
список задач | найти «chrome» :: Отфильтровать исполняемые программы, содержащие Chrome
/I: игнорировать регистр, напримерfind /I "error"/V: Отображение строк, не содержащих ключевых слов./C: отображать только количество совпадающих строк.findУсловие И выполнено: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значение, оно будет автоматически создано и установлено как указанный путь к пакетному файлу.@эхо выключено
setlocal
:: Установите путь к пакетному файлу, который будет выполняться автозапуском.
установите "AUTORUN_PATH=C:\Users\%USERNAME%\cmd_startup.bat"
установите «REG_PATH=HKCU\Software\Microsoft\Command Processor»
echo Проверьте настройку автозапуска CMD...
:: Проверьте, существует ли код входа
регулярный запрос "%REG_PATH%" >nul 2>&1
если уровень ошибки 1 (
echo [Информация] Код командного процессора не найден, создается...
reg добавить "%REG_PATH%" /f >nul
)
:: Проверьте, установлен ли автозапуск
reg запрос "%REG_PATH%" /v AutoRun >nul 2>&1
если уровень ошибки 1 (
echo [Информация] AutoRun не найден, создается новое значение...
reg add "%REG_PATH%" /v AutoRun /d "%AUTORUN_PATH%" /f >nul
echo [Готово] Для автозапуска установлено значение: %AUTORUN_PATH%
) еще (
echo [OK] Автозапуск уже существует и не был изменен.
)
локальный
пауза
reg query: используется для проверки существования ключа или значения входа в систему.errorlevel: может использоваться для определения успешности результата запроса (0 означает, что существует, 1 означает, что не существует).reg add: Создайте ключ или значение для входа./f: Нет запроса на принудительное покрытие.%AUTORUN_PATH%Измените его на путь к пакетному файлу, который вы хотите автоматически выполнять при запуске CMD.@эхо выключено
:: Обнаружение PowerShell
если определено PSModulePath (
echo в настоящее время выполняется в PowerShell
иди :эоф
)
:: Обнаружение Сайгвина
если определен CYGWIN (
echo в настоящее время выполняется в Cygwin
иди :эоф
)
если определено SHELL (
echo в настоящее время выполняется в Cygwin (SHELL=%SHELL%)
иди :эоф
)
::По умолчанию — 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:Закрыть PowerShellGet-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 <iostream> // Подключаем стандартную библиотеку ввода/вывода
#include "my_utility.h" // Включаем пользовательский файл заголовка
Макрос буквальной замены, используемый для определения символьных констант или фрагментов кода.
#define: Определить макрос.#undef: отменить определение макроса.#define MAX_SIZE 100 //Определение символьной константы
#define SUM(a, b) ((a) + (b)) // Определить макрос с параметрами
интервал основной() {
размер int = MAX_SIZE; // После предварительной обработки получается int size = 100;
целое число = СУММ (5, 3); // После предварительной обработки получается int total = ((5) + (3));
вернуть 0;
}
Позволяет вам решить, следует ли компилировать конкретный блок кода на основе значения макроса препроцессора.
#ifdef: Если макрос определен, скомпилируйте последующие блоки.#ifndef: Если макрос не определен, скомпилируйте последующие блоки. (обычно используется в Include Guard)#if: Определить, следует ли компилировать на основе значения заданного константного целочисленного выражения.#else / #elif: Замена или последующее решение условной компиляции.#endif: Завершить блок условной компиляции.#define DEBUG_MODE 1
#if DEBUG_MODE
std::cout << «Режим отладки включен» << станд::эндл;
#else
std::cout << «Работает производственный режим» << станд::эндл;
#endif
#ifndef MY_HEADER_H
#defineMY_HEADER_H
// ... содержимое заголовочного файла (пример Include Guard)
#endif
#error: заставляет препроцессор остановить компиляцию при обнаружении этой директивы и отобразить указанное сообщение об ошибке.#warning: Вывести указанное предупреждающее сообщение без остановки компиляции (нестандартная директива, но поддерживается многими компиляторами).#ifndef VERSION_DEFINED
#error "Необходимо определить номер версии макроса VERSION_DEFINED!"
#endif
#pragma: используется для отправки специальных инструкций компилятору, поведение сильно зависит от компилятора (например.#pragma onceи#pragma warning)。#line: используется для изменения текущего номера строки и имени файла, отображаемых, когда компилятор сообщает об ошибках или предупреждениях.#pragma onceЯвляется одним из языков C и C++.Директива препроцессора. Его основная функция — гарантировать, что заголовочный файл, содержащий эту директиву, будет обрабатываться компилятором только во время одного процесса компиляции.один раз。
Целью этой директивы является решение проблемы повторного включения заголовочных файлов и предотвращение многократного просмотра одного и того же фрагмента кода (например, определений классов, прототипов функций или объявлений констант) компилятором из-за нескольких файлов исходного кода или многоуровневых связей включения заголовочных файлов, что приводит к возникновениюПереопределениеошибка компиляции.
В стандарте 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 alert(disable: 4996) // Отключить C4996 (например: предупреждение об использовании небезопасных функций)
// Содержит или записывает код, который будет генерировать C4996
Восстанавливает указанное предупреждение к поведению по умолчанию, заданному проектом или командной строкой.
#pragma alert(по умолчанию: 4996) //Восстанавливаем C4996 в состояние по умолчанию
Это самый безопасный и рекомендуемый режим. Он позволяет изменять настройки предупреждения во время обработки определенного блока кода, а затем гарантирует, что исходное состояние предупреждения восстанавливается сразу после завершения блока, чтобы избежать побочных эффектов.
#pragma warning( push ): сохранение текущего состояния стекирования настроек предупреждений.#pragma warning( pop ):Восстановить последнюю версиюpushСохраненное состояние.#pragma alert( push ) // 1. Сохраняем текущие настройки предупреждения
#pragma alert(disable: 4996 4244) // 2. Отключить несколько конкретных предупреждений
// Содержит сторонние файлы заголовков или устаревший код
#pragma alert( pop ) // 3. Восстановить исходные настройки
// Последующий код будет использовать восстановленные настройки
Повысьте уровень конкретного кода предупреждения до ошибки компиляции. Если появится предупреждение, компиляция завершится неудачно.
#pragma alert( error : 4005 ) // Считаем предупреждение 4005 ошибкой
4996)даспецифичный для компилятора. Вам необходимо найти правильный номер используемого вами компилятора (например, MSVC).#pragma warningфункции, но они обычно предпочитают использовать-W...флаги командной строки или специальные#pragma GCC diagnosticСтруктура для управления предупреждениями.В программировании на С++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::Существует два основных метода для сущностей в пространстве имен:
Пишите это четко каждый раз, когда используете его.std::префикс. Это самый безопасный и рекомендуемый подход, особенно в файлах заголовков, чтобы избежать загрязнения глобального пространства имен.
int main() {
std::cout << "Hello World" << std::endl;
std::vector<int> numbers;
return 0;
}
использоватьusing namespace std;Весьstd::Содержимое пространства имен вводится в текущую область, и имя можно использовать напрямую, безstd::префикс.
#include <iostream>
использование пространства имен std; // Представляем пространство имен std::
интервал основной() {
ок << «Привет, мир» << конец; // Префикс std:: не требуется
вектор<int> цифры;
вернуть 0;
}
хотяusing namespace std;Удобно, но его следует избегать в больших проектах или файлах заголовков, поскольку это увеличивает риск конфликтов имен.
В С++std::stringЯвляется категорией (Class). Когда вы объявляетеstd::stringЕсли переменной не присвоено начальное значение, она вызывает конструктор по умолчанию.
"")。0。NULLиндикатор, но действительный объект.#include <строка>
#include <iostream>
недействительный инициализация_example() {
станд::строка с; // объявлено, но значение не задано
std::cout << "Длина: " << s.length() << станд::эндл; // Output: 0
std::cout << "Содержимое: '" << с << "'" << станд::эндл; // Выход: ''
}
Чтобы проверить, не содержит ли строка каких-либо символов, наиболее рекомендуемый способ — использоватьempty()функции-члены, которые лучше, чем проверкаlength() == 0Более семантично и более эффективно в некоторых контейнерах.
void check_empty(std::string s) {
если (s.empty()) {
std::cout << «Это пустая строка». << станд::эндл;
}
}
Это распространенное недоразумение:Сам объект 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. |
Если вы хотите восстановить существующую строку в исходное пустое состояние, вы можете использовать следующий метод:
недействительный Clear_example () {
std::string s = "Привет";
с.очистить(); // Метод 1: наиболее часто используемый
с = ""; // Способ 2: переназначить
s = станд::строка(); // Способ 3: назначить объект по умолчанию
}
Это самый простой метод, представленный в C++11, преобразующий числовое значение в строку. По умолчанию сохраняется 6 десятичных знаков.
#include <строка>
#include <iostream>
недействительный simple_convert() {
плавающее значение = 3,14159f;
std::string s = std::to_string(val);
std::cout << с << станд::эндл; // Пример вывода: "3.141590"
}
Если вам нужно контролировать количество десятичных знаков или определенный формат,stringstreamЭто самый гибкий вариант. он сочетает в себе<iomanip>библиотека для точного управления выходом.
#include <sstream>
#include <iomanip>
void Precision_convert() {
плавающее значение = 3,1415926f;
станд::stringstream сс;
// Устанавливаем метод подсчета с фиксированной точкой (фиксированный) и сохраняем 2 десятичных знака
сс << std::fixed << std::setprecision(2) << вал;
std::string s = ss.str();
std::cout << с << станд::эндл; // Вывод: "3.14"
}
В C++20 вы можете использовать строки формата для одновременной обработки преобразования типов и контроля точности с максимально кратким синтаксисом.
#include <format>
недействительный современный_формат () {
плавающее значение = 123,456f;
// {:.2f} представляет тип float и сохраняет два десятичных знака
std::string s = std::format("{:.2f}", val);
std::cout << с << станд::эндл; // Вывод: "123,46" (будет автоматически округлено)
}
std::to_stringЧасто встречаются лишние нули типа «3,140000». ты можешь объединитьfind_last_not_ofиeraseчтобы очистить строку.
std::string Remove_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 |
| спринтф (стиль C) | Чрезвычайно быстро, но менее безопасно | Поддержка старого кода с максимальным стремлением к производительности |
Это наиболее стандартный подход в C++, не использующий внешние библиотеки. черезfindНайдите положение разделителя и используйтеsubstrПолучить подстроку.
#include <iostream>
#include <vector>
#include <строка>
void Split_by_three_chars() {
std::string text = "Яблоко --- Банан --- Вишня --- Дата";
std::string delimiter = "---";
std::vector<std::string> жетоны;
size_t поз = 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 : tokens) std::cout << "[" << т << "]" << станд::эндл;
}
Если ваша строка очень большая, используйте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 <regex>
недействительный regex_split() {
std::string text = "Один###Два###Три";
std::regex ws_re("###"); // Определить трехсимвольный разделитель
std::copy(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),
std::sregex_token_iterator(),
std::ostream_iterator<std::string>(std::cout, "\n");
}
| метод | преимущество | недостаток |
|---|---|---|
| std::find + substr | Высочайшая совместимость (C++98+) и стабильная производительность. | Код длинный и требует ручной обработки последнего фрагмента. |
| string_view | Самый эффективный, дополнительная копия памяти не создается. | Требуется поддержка C++17, и необходимо уделять внимание исходному жизненному циклу строки. |
| std::regex | Синтаксис является наиболее кратким и расширяемым. | Скорость выполнения самая медленная, а время компиляции больше. |
В C++ для проверкиstd::vectorЕсли контейнер не содержит элементов (т. е. имеет нулевой размер), наиболее стандартным и рекомендуемым способом является использование его функций-членов.empty(). Это потому, чтоempty()Функции обычно лучше, чем прямые проверкиsize()Равен нулю, что более эффективно, особенно в некоторых реализациях контейнеров.
Это предпочтительный способ проверить, пуст ли вектор. Он возвращает логическое значение: если вектор не имеет элементов, он возвращаетtrue; В противном случае вернитеfalse。
#include <vector>
#include <iostream>
#include <строка>
void check_empty(const std::vector<std::string>& vec)
{
если (vec.empty()) {
std::cout << «Вектор пуст (empty() == true)». << станд::эндл;
} еще {
std::cout << "Вектор не пуст (empty() == false). Количество элементов: " << vec.size() << станд::эндл;
}
}
интервал основной()
{
std::vector<std::string> пустой_век;
std::vector<std::string> non_empty_vec = {"яблоко", "банан"};
check_empty (empty_vec);
check_empty (non_empty_vec);
вернуть 0;
}
Хотя это и допустимо, это не самый идиоматический или потенциально самый эффективный способ проверки пустого статуса. Он напрямую проверяет, равно ли количество элементов в векторе нулю.
void check_size(const std::vector<int>& vec)
{
если (vec.size() == 0) {
std::cout << «Вектор пуст (size() == 0).» << станд::эндл;
} еще {
std::cout << «Вектор не пуст (size()!= 0).» << станд::эндл;
}
}
для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 <iostream>
#include <sstream> // включаем строковый поток
#include <строка>
#include <vector>
использование пространства имен std;
/**
* Разделите входную строку любыми пробелами (пробелом или табуляцией) и сохраните ее в векторе.
* @param input_str Строка для анализа.
* @return Вектор, содержащий все разделенные слова.
*/
вектор<строка> Split_string_by_whitespace(const string& input_str)
{
вектор<строка> жетоны;
// 1. Создайте объект stringstream и инициализируйте его входной строкой
строковый поток сс (input_str);
строковый токен;
// 2. Циклическое чтение
// Оператор извлечения потока (>>) автоматически прочитает следующий токен, используя пробельные символы (пробел, табуляция и т. д.) в качестве разделителей.
// Оператор возвращает true, если токен успешно прочитан, в противном случае (достигнут конец строки) он возвращает false.
while (ss >> токен)
{
токены.push_back(токен);
}
вернуть жетоны;
}
интервал основной()
{
//Входная строка содержит несколько пробелов и символов табуляции (\t)
string test_string = "Привет, \tWorld, это \ta тестовая строка";
ок << "Исходная строка: " << test_string << конец;
вектор<строка> результат = Split_string_by_whitespace (test_string);
ок << "--- отдельные результаты ---" << конец;
for (size_t i = 0; i < result.size(); ++i)
{
ок << "Токен" << я + 1 << ": [" << результат[i] << "]" << конец;
}
вернуть 0;
}
std::stringstream ss(input_str): эта категория рассматривает входную строку как входной поток (Входной поток), и ее функция аналогична той, которая используется при чтении из файла.std::ifstream。>>):
while (ss >> token): это идиоматический цикл чтения потока C++. Пока поток успешно извлекает и сохраняет данные вtokenпеременной, цикл продолжит выполнение.В C++ вы можете использоватьstd::arrayИнициализируйте многомерный массив значением 0:
#include <iostream>
#include <массив>
использование пространства имен std;
интервал основной() {
массив<array<int, 4>, 3> обр = {0}; // Инициализируем все элементы в 0
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
ок << arr[i][j] << " ";
}
ок << конец;
}
вернуть 0;
}
std::arrayКласс-контейнер в стандартной библиотеке C++, подходящий для ситуаций, когда размер фиксируется во время компиляции.std::arrayОбеспечивает больше функциональности и безопасности.В C++ цикл — это базовая операция перебора всех элементов контейнера или массива.std::vector(контейнер динамического размера) иstd::array(контейнеры фиксированного размера) — это контейнеры в стандартной библиотеке C++ (STL), элементы которых можно перебирать различными стандартными и безопасными способами.
Это самый современный, безопасный и краткий метод обхода, представленный в C++11. Работает со всеми стандартными контейнерами (включаяstd::vectorиstd::array)。
std::vector: **Предпочтительно**std::array: **Предпочтительно**#include <iostream>
#include <vector>
#include <массив>
void range_based_loop_example()
{
std::vector<int> век = {10, 20, 30};
std::array<int, 4> обр = {1, 2, 3, 4};
// Использовать auto& перемещаться по ссылке, что эффективно и позволяет изменять элементы
std::cout << "--- Вектор (изменяемый) ---" << станд::эндл;
for (auto& element: vec) {
элемент += 1; // Изменить элемент
std::cout << элемент << " ";
}
std::cout << станд::эндл;
// Используем const auto& переход по постоянной ссылке, что безопасно и не позволяет изменять элементы
std::cout << "--- Массив (только чтение) ---" << станд::эндл;
for (const auto& element: arr) {
std::cout << элемент << " ";
}
std::cout << станд::эндл;
}
Это традиционный и универсальный метод. Подходит для ситуаций, когда вам необходимо получить доступ к индексам элементов (например: вам нужно одновременно работать с двумя контейнерами или массивами или завершить работу по определенному индексу).
std::vector: применимо, используйтеsize()Получите границы.std::array: применимо, используйтеsize()Получите границы.#include <iostream>
#include <vector>
#include <массив>
void index_loop_example()
{
std::vector<std::string> имена = {"Алиса", "Боб", "Чарли"};
std::array<double, 3> цены = {10,5, 20,99, 5,0};
// Используйте size_t или auto с size(), чтобы убедиться, что тип индекса правильный и границы безопасны.
for (size_t i = 0; i
ПРИМЕЧАНИЕ. Используйте[]C++ не выполняет проверку границ при доступе операторов к элементам.at()функция (она выдаст выход за пределыstd::out_of_rangeаномальный).
Это наиболее гибкий метод обхода в C++, который работает со всеми стандартными контейнерами. Итераторы необходимы при взаимодействии с алгоритмами стандартной библиотеки C++ (STL).
std::vector: **Рекомендуется** (когда требуется алгоритм STL или специальный элемент управления)std::array: **Рекомендуется** (когда требуется алгоритм STL)#include <iostream>
#include <vector>
void iterator_loop_example()
{
std::vector<double> значения = {100,0, 50,0, 10,0};
// Упрощаем тип итератора, используя auto, и используем Begin() и End(), чтобы получить диапазон
для (авто это = значения.begin();
это !=values.end();
++ это)
{
*it /= 10,0; // *он разыменовывает итератор и обращается к элементам
std::cout << *это << " ";
}
std::cout << станд::эндл;
// Используйте cbegin() и cend(), чтобы гарантировать, что итератор является константным для обхода только для чтения
for (auto cit =values.cbegin(); cit !=values.cend(); ++cit)
{
// Пробуем *cit = 5; приведет к ошибке компиляции
std::cout << *цитировать << " ";
}
std::cout << станд::эндл;
}
| Петлевой метод | Применимые контейнеры | преимущество | Применимое время |
|---|---|---|---|
| На основе диапазона | 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::copyПодходит для приложений, требующих универсальных методов STL.memcpyПрименимо только к POD (Plain Old Data), без логики конструктора/деконструктора.В C++ это происходит, когда вы обращаетесь к недопустимой или выходящей за пределы области памяти при манипулировании указателями или использовании индексов для доступа к массивам/памяти.Неопределенное поведение. Такое поведение обычно проявляется как программаКрушение, например ошибка сегментации или ошибка нарушения прав доступа.
стандарт С++try-catchЭтот механизм в основном используется для перехвата исключений C++ (Исключения), которые явно создаются в программном коде, но не могут напрямую перехватывать ошибки оборудования или доступа к памяти, выдаваемые операционной системой.
Когда программа C++ пытается получить доступ к недопустимой памяти, например:
nullptrпамяти.deleteилиfreeОсвобожденная память.Эти операции активируют механизм защиты базовой операционной системы (например, нарушение прав доступа в Windows или сигнал SIGSEGV в Unix/Linux), и программа будет завершена операционной системой. Эти ошибки не являются объектами исключений уровня языка C++ (например,std::exception), поэтому стандартtry-catchНет возможности их поймать.
#include <iostream>
#include <vector>
использование пространства имен std;
недействительный краш_функция()
{
// Пример доступа к массиву за пределами границ
вектор<int> век = {10, 20};
ок << "Попытка доступа к индексу за пределами допустимого диапазона..." << конец;
// Это неопределенное поведение, которое может привести к сбою, связанному с нарушением прав доступа.
целое значение = век[100]; // Ошибка: доступ к неверному индексу
ок << "значение: " << значение << конец;
}
интервал основной()
{
попробуй
{
авария_функция();
//Программа аварийно завершает работу в vec[100] выше и здесь не будет выполнена.
// И блок catch не будет выполнен.
}
catch (константное исключение& 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и проверяет, действителен ли указатель, прежде чем разыменовывать его.недействительная безопасная_функция()
{
вектор<int> век = {10, 20};
попробуй
{
целое значение = vec.at(100); // выбрасываем исключение std::out_of_range
ок << "значение: " << значение << конец;
}
catch (const std::out_of_range& e)
{
// Успешно перехвачено исключение C++
церр << "Безопасный захват: " << e.what() << конец;
}
}
В среде Windows вы можете использовать расширенную обработку структурированных исключений (SEH) Microsoft для обнаружения ошибок на уровне операционной системы, включая нарушения прав доступа. Обычно это делается с помощью__tryи__exceptКлючевые слова.
Примечание. SEH не является стандартным и не рекомендуется для использования в переносимом коде C++. В проектах C++/CLI вы можете использовать .NET.try/catchПерехватите некоторые исключения SEH, но для этого требуются определенные настройки компилятора (например,/EHa)。
В C++, когда вы используете необработанный массив (массив в стиле C) или указатель для операций индексирования, это происходит, если осуществляется доступ к ячейке памяти, которая находится за пределами диапазона массива или является недопустимой.Неопределенное поведение. Такое поведение часто приводит к тому, что программы работают на уровне операционной системы.Крушение, например «Нарушение прав доступа» или «Ошибка сегментации».
Ключевые моменты:стандарт С++try-catchМеханизм предназначен для перехвата исключений C++ (Исключения), которые явно создаются в программном коде. Он не может обнаружить ошибки защиты оборудования или памяти, возникающие в операционной системе.
Когда программа C++ пытается получить доступ к недопустимой памяти (например, доступ к статическому массивуarr[100], но в массиве всего 10 элементов), что нарушает правила защиты памяти операционной системы. Операционная система вмешивается и отправляет сигнал или исключение для завершения программы, не позволяя ей повредить систему или другие программы. Эти ошибки не относятся к уровню языка C++.std::exceptionобъект и поэтому не может использоваться стандартомtry-catchЗаблокировать захват.
#include <iostream>
#include <stdException> // Включаем стандартные исключения
использование пространства имен std;
недействительный краш_функция()
{
// Примитивный массив в стиле C
int raw_array[5] = {1, 2, 3, 4, 5};
ок << "Попытка доступа к индексу за пределами допустимого диапазона..." << конец;
// Доступ за пределы массива: это типичное неопределенное поведение
// Если осуществляется доступ к памяти, к которой программа не имеет разрешения, немедленно срабатывает нарушение прав доступа, что приводит к сбою программы.
значение int = raw_array[100]; // Ошибка: доступ к неверному индексу
ок << "Значение (если достижимо): " << значение << конец;
}
интервал основной()
{
попробуй
{
авария_функция();
// Программа завершится на raw_array[100] и не будет выполняться здесь.
}
catch (константное исключение& e)
{
// Ошибки доступа к памяти на уровне операционной системы здесь не могут быть зафиксированы
церр << "Обнаружено исключение C++: " << e.what() << конец;
}
вернуть 0;
}
Лучше всего полностью избегать доступа за пределами границ или использовать безопасные контейнеры и методы, предоставляемые C++, которые выдают перехватываемые исключения C++ при возникновении ошибки:
дляstd::vectorконтейнер, использоватьat()функция-член вместо оригинала[]оператор. Когда доступ выходит за пределы,at()брошу **std::out_of_range**Исключение. Это стандартное исключение C++, которое может бытьtry-catchПойман и безопасно утилизирован.
#include <vector>
// ... (остальное включает)
void Safe_vector_access()
{
std::vector<int> век = {10, 20};
попробуй
{
// Используйте at() для проверки границ
целое значение = vec.at(100);
std::cout << "значение: " << значение << станд::эндл;
}
catch (const std::out_of_range& e)
{
// Успешно перехвачено исключение C++
std::cerr << "Безопасно поймано исключение выхода за пределы: " << e.what() << станд::эндл;
}
}
Введено с использованием C++11std::arrayЗаменяет массивы в стиле C. Хотяstd::arrayиз[]Оператор не проверяется, но егоat()Функция также выдастstd::out_of_rangeаномальный.
#include <массив>
// ...
void Safe_array_access()
{
std::array<int, 5> обр = {1, 2, 3, 4, 5};
попробуй
{
целое значение = arr.at(5); // Доступ за пределами границ, выдача исключения
}
catch (const std::out_of_range& e)
{
std::cerr << "std::array захват за пределами границ: " << e.what() << станд::эндл;
}
}
На некоторых платформах, таких как Windows, вы можете использовать **Структурированную обработку исключений (SEH)** для перехвата аппаратных исключений (например, нарушений доступа), создаваемых операционной системой. This usually involves using a Microsoft extension__tryи__exceptКлючевые слова. Этот метод нестандартен для платформы, жертвует переносимостью кода и обычно не рекомендуется в качестве стандартного механизма обработки ошибок.
в С++/CLISystem::Collections::Generic::List<T>, если вы попытаетесь получить доступ к несуществующему индексу (например.sizeравно 1, но доступindex1), программаНе будетПри значении по умолчанию (например, 0 или null) исключение будет выдано немедленно.
System::ArgumentOutOfRangeExceptionПрежде чем осуществлять доступ к индексу, вы всегда должны проверятьCountатрибут или использоватьtry-catchБлоки фиксируют потенциальные ошибки.
//Метод А: Предварительная проверка (наиболее рекомендуется, наилучшая производительность)
если (числа->Количество > 1) {
целое значение = числа [1];
// Логика обработки
} еще {
// Обработка ситуации недостаточного индекса
}
//Метод Б: перехват исключений
попробуй {
целое значение = числа [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), который возвращает значение типа по умолчанию (0 для int), если индекс не существует.В C++ наиболее часто используемые инструменты определены в<algorithm>вstd::minиstd::max. Они поддерживают базовые типы, объекты и даже списки инициализации.
#include <алгоритм>
#include <iostream>
#include <vector>
недействительными Basic_usage () {
интервал а = 10, б = 20;
// 1. Сравним два числа
int small = std::min(a, b);
int big = std::max(a, b);
// 2. Сравнение списков инициализации (C++11)
int low = std::min({5, 1, 9, 3}); // возвращаем 1
// 3. std::minmax (C++11) — получаем максимальное и минимальное значения одновременно
автоматический результат = std::minmax({10, 20, 30, 40});
std::cout << "Мин: " << результат.первый << ", Макс: " << результат.секунда;
}
Когда вам нужно инициализировать «минимальную» переменную, вы обычно устанавливаете для нее наибольшее положительное число, которое может выразить тип, чтобы гарантировать, что оно будет обновлено при первом сравнении.
floatМаксимальное значение (около $3,4 \times 10^{38}$).doubleмаксимальное значение.intмаксимальное значение.std::numeric_limitsПредоставляет согласованный и шаблонный способ получения числовых свойств, что очень полезно при написании универсального кода.
#include <limits>
недействительные пределы_примера () {
// Получаем максимальное значение
float max_f = std::numeric_limits<float>::max();
int max_i = std::numeric_limits<int>::max();
// Получаем «минимальное положительное число» (примечание: для чисел с плавающей запятой min() возвращает минимальное положительное число вместо максимального отрицательного числа)
float min_positive_f = std::numeric_limits<float>::min();
// Получаем «самое низкое значение» (реальное наименьшее отрицательное число)
float low_f = std::numeric_limits<float>::lowest();
}
Если вы имеете дело сstd::vectorили массив, вам нужно использоватьstd::min_elementилиstd::max_element, то, что они возвращают, этоИтератор。
#include <vector>
#include <алгоритм>
недействительный Collection_example () {
std::vector<float> баллы = {88,5f, 92,0f, 79,5f, 100,0f};
// Получаем итератор максимального значения
auto it = std::max_element(scores.begin(), Scores.end());
if (it != Scores.end()) {
std::cout << "Наивысший балл: " << *это;
}
}
| имя | использовать | На что следует обратить внимание |
|---|---|---|
| FLT_MAX | Инициализировать поиск минимального значения | определено в<cfloat>, является устаревшим макросом из C. |
| std::min | Сравните два числа или списки | Если типы параметров несовместимы (например, int и long), шаблон необходимо указать явно:std::min<long>(a, b)。 |
| lowest() | Получить наименьшее отрицательное число | В числах с плавающей запятой,min()- наименьшее положительное число, близкое к 0,lowest()— максимальное отрицательное значение. |
| min_element | поиск контейнера | Возвращается итератор, и перед его использованием необходимо проверить, пуст ли контейнер. |
В стандартной математической библиотеке C++, хотя определение константы $\pi$ официально не было стандартизировано до C++20, существует несколько часто используемых методов для получения приблизительных значений числа pi в различных версиях C++ и средах компилятора.
Чтобы обеспечить переносимость и точность кода, наиболее рекомендуемым подходом является использованиеstd::numbers::pi。
Начиная с C++20, стандартная библиотека<numbers>Точные и типобезопасные математические константы представлены в заголовочном файле.
#include <numbers>#include <iostream>
#include <numbers> // введено в C++20
недействительный use_cpp20_pi()
{
// std::numbers::pi_v<T> это переменная шаблона, которая предоставляет точное значение на основе типа T
// std::numbers::pi (без <T>) эквивалентно std::numbers::pi_v<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>;
станд::cout.precision(16); // Устанавливаем точность вывода
std::cout << "C++20 (двойной): " << pi_double << станд::эндл;
std::cout << "C++20 (с плавающей запятой): " << pi_float << станд::эндл;
}
До C++20 многие разработчики полагались на математическую библиотеку C (<cmath>или<math.h>) предоставляет нестандартный макрос. Хотя эти макросы существуют в большинстве современных систем, они не являются частью стандарта C++, и их работа во всех средах не гарантируется.
#include <cmath>(или<math.h>)#include <iostream>
#include <cmath> // Традиционная математическая библиотека C
недействительный use_c_macro_pi()
{
// M_PI — наиболее распространенный макрос PI, обычно определяемый как двойной тип.
// Примечание. Чтобы включить этот макрос, в некоторых системах может потребоваться определить макрос _USE_MATH_DEFINES.
#ifdef M_PI
двойное значение pi_value = M_PI;
станд::cout.precision(16);
std::cout << "Макрос C (M_PI): " << pi_value << станд::эндл;
#else
std::cout << «Макрос M_PI не определен. Возможно, вам придется определить _USE_MATH_DEFINES». << станд::эндл;
#endif
}
Если вы не можете использовать макросы C++20 или C, вы можете определить $\pi$ самостоятельно как константу или использовать математическую функцию для ее вычисления (например, $\arccos(-1)$).
#include <iostream>
#include <cmath>
void define_or_calculate_pi()
{
// Определить с помощью математических операций:
const double PI_CUSTOM_CALC = std::acos(-1.0);
// Определим его напрямую как константу:
const double PI_CUSTOM_DEFINE = 3,14159265358979323846;
станд::cout.precision(16);
std::cout << "Пользовательский расчет: " << PI_CUSTOM_CALC << станд::эндл;
std::cout << "Пользовательское определение: " << PI_CUSTOM_DEFINE << станд::эндл;
}
std::numbers::pi。const double PI = 3.14159...;M_PIМакро, но помните о его нестандартности.#include <cmath>
#include <iostream>
использование пространства имен System;
используя пространство имен System::Collections::Generic;
интервал основной()
{
//Создаем тестовые данные
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, List<float>^> запись в данных)
{
int ключ = запись.Ключ;
Список<float>^ значений = вход.Значение;
if (значения == nullptr || значения->Count == 0)
{
Console::WriteLine("Ключ {0}: нет данных", key);
продолжать;
}
// Вычисляем среднее значение
двойная сумма = 0,0;
для каждого (float v в значениях)
{
сумма += v;
}
двойное среднее = сумма/значения->Количество;
// Подсчитаем количество мутаций (количество материнских мутаций)
двойная дисперсия = 0,0;
для каждого (float v в значениях)
{
двойной диф = v – среднее;
дисперсия += разница * разница;
}
дисперсия /= значения->Количество; // Если вам нужен вариант образца, измените его на (values->Count - 1)
// стандартное отклонение
двойной stddev = Math::Sqrt(дисперсия);
Console::WriteLine("Ключ {0}: стандартное отклонение = {1:F4}", key, stddev);
}
вернуть 0;
}
values->Count - 1。Ключ 1: Стандартное отклонение = 0,8981. Ключ 2: Стандартное отклонение = 1,1180. Ключ 3: Нет информации
std::sortЭто наиболее часто используемый алгоритм сортировки в стандартной библиотеке шаблонов C++ (STL). он расположен<algorithm>В заголовочном файле по умолчанию элементы внутри диапазона будутвосходящийсортировать.
#include <алгоритм>
#include <vector>
#include <iostream>
недействительный Basic_sort () {
std::vector<int> числа = {5, 2, 9, 1, 5, 6};
// Диапазон сортировки: от начального итератора до конечного итератора
std::sort(nums.begin(), nums.end());
// Результат: 1, 2, 5, 5, 6, 9
}
Вы можете изменить логику сортировки, передав третий параметр (функцию сравнения или лямбда-выражение).
// 1. Использовать предопределённый std::greater для возведения в степень
std::sort(nums.begin(), nums.end(), std::greater<int>());
// 2. Используйте лямбда-выражения для настройки логики
std::sort(nums.begin(), nums.end(), [](int a, int b) {
вернуть а > б; // Когда возвращается true, a будет ранжироваться перед b
});
Для пользовательских типов должна быть предусмотрена логика сравнения, иначе компилятор сообщит об ошибке, поскольку он не знает, как сравнивать размеры.
структура Студент {
std::имя строки;
средний балл;
};
void sort_students() {
std::vector<Студент> студенты = {{"Алиса", 90}, {"Боб", 85}, {"Чарли", 95}};
// Сортировка по баллам от большего к меньшему
std::sort(students.begin(), студенты.end(), [](const Student& a, const Student& b) {
вернуть a.score > b.score;
});
}
std::sortНе единый алгоритм сортировки, а гибридный алгоритм, призванный объединить преимущества каждого алгоритма и избежать худшего сценария. Логика его работы следующая:
| характеристика | иллюстрировать |
|---|---|
| средняя временная сложность | $O(n \log n)$ |
| Худшая временная сложность | $O(n \log n)$ (воспользуйтесь преимуществами механизма Introsort) |
| космическая сложность | $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$ над линией, мы сравниваем $y_0$ точки с $y_{line}$, когда точка совпадает с $x_0$ на линии.
// Уравнение прямой: ax + by + c = 0 => y = (-ax - c) / b
bool isAbove(std::array<float, 3> line, float x0, float y0) {
плавать а = строка [0];
плавающий b = строка [1];
плавающий c = строка [2];
// Если b равно 0, это представляет вертикальную линию, а верхнюю и нижнюю невозможно определить
if (std::abs(b) < 1e-6) возвращает false;
float y_on_line = (-a * x0 - c)/b;
// Меньший y представляет вершину
вернуть y0 < y_on_line;
}
Таким же образом мы сравниваем $x_0$ в точке с $x_{line}$ в той же $y_0$ на линии.
// Уравнение прямой: ax + by + c = 0 => x = (-by - c) / a
bool isRight(std::array<float, 3> line, float x0, float y0) {
плавать а = строка [0];
плавающий b = строка [1];
плавающий 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 больше) | $x_0 > \frac{-by_0 - c}{a}$ | $a \neq 0$ (негоризонтальная линия) |
aилиbЕсли он равен 0, рекомендуется использовать минимальное значение (например,1e-6) для сравнения, чтобы избежать проблем с точностью.Учитывая уравнение прямой $ax + by + c = 0$, наиболее интуитивный способ определить, смещена ли она в сторону «горизонтальной линии» или «прямой линии», — это посмотреть на угол между ней и осью координат. к45 градусов— разделительная линия, эквивалентная сравнению размеров $|a|$ и $|b|$.
использоватьstd::absСравниватьline[0]($а$) иline[1]Абсолютное значение ($b$).
#include <iostream>
#include <массив>
#include <cmath>
класс перечисления LineOrientation {
Горизонтально, // горизонтальная линия (< 45 градусов)
Вертикально, // прямая линия (>45 градусов)
Диагональ // Ровно 45 градусов
};
LineOrientation checkOrientation(std::array<float, 3> line) {
float a = std::abs(line[0]);
float b = std::abs(line[1]);
если (а < б) {
return LineOrientation::Horizontal;
} иначе, если (а > б) {
вернуть 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 результат = добавить (3, 4); // используем тип int
двойной результат2 = добавить(3.5, 2.7); // используем двойной тип
Шаблоны категорий позволяют нам создавать категории, которые можно применять к нескольким типам. Синтаксис шаблона категории следующий:
template <typename T>
class MyClass {
private:
T data;
public:
MyClass(T data) : data(data) {}
T getData() { return data; }
};
В этом примереMyClassКатегории могут использовать любой тип данных в качествеdata。
Вы можете использовать его следующим образом:
МойКласс<int> объект1(5); // тип int
МойКласс<двойной> объект2(3.14); // двойной тип
Шаблоны могут принимать несколько параметров, например:
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; }
};
Такой класс шаблона может хранить два разных типа данных:
Pair<int, double> pair1(1, 3.14);
Специализация шаблонов позволяет нам конкретно определять шаблоны конкретных типов. Например:
template <>
класс 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Нетиповой параметр, указывающий размер массива.
Пример использования:
Массив<int, 10> обр; // Создаем массив типа int размером 10
Шаблоны C++ — это мощные инструменты, которые делают код более универсальным и сокращают дублирование. Понимание того, как использовать такие технологии, как шаблоны функций, шаблоны категорий и специализация шаблонов, значительно повысит гибкость и производительность программирования.
В C++, когда два класса зависят друг от друга и должны одновременно ссылаться на члены друг друга, непосредственно в соответствующих.hв файле#includeОпределение другой стороны вызовет проблему циклической ссылки, что приведет к сбою компиляции. Решение состоит в том, чтобы использовать «форвардное объявление», чтобы избежать циклических ссылок.
.hФайл только заявляет о существовании категории другой стороны и не включает напрямую заголовочный файл другой стороны..cppФайл содержит заголовочные файлы друг друга, что позволяет компилятору получить полное определение класса.// КлассA.h
#ifndef CLASSA_H
#define CLASSA_H
// Форвардное объявление ClassB
класс КлассB;
класс КлассА {
публика:
КлассА();
недействительный setB (КлассB * b); // Устанавливаем указатель на ClassB
недействительный showBData(); // Отображение данных класса B
частный:
КлассБ* б; // указатель на ClassB
};
#endif
// КлассB.h
#ifndef CLASSB_H
#define CLASSB_H
// Предварительное объявление ClassA
класс КлассА;
класс КлассB {
публика:
КлассB (целое число данных);
ИНТ GetData(); // Получаем данные
недействительный setA (КлассA * а); // Устанавливаем указатель на ClassA
недействительный showAInfo(); // Отображение информации о классе A
частный:
целочисленные данные;
КлассА* а; // указатель на класс A
};
#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Архив содержит заголовочный файл другой стороны, что гарантирует получение полного определения категории другой стороны при использовании индикатора.В С++friendКлючевые слова можно использовать в функциях или классах, чтобы позволить другим функциям или классам получать доступ к частным и защищенным членам класса. Такая конструкция позволяет внешним функциям или классам работать, не нарушая принцип инкапсуляции.
Функция Friend — это внешняя функция, которой предоставляется доступ к закрытым и защищенным членам другого класса. При объявлении внутри категории заканчивайте наfriendПросто измените ключевые слова.
Примеры следующие:
#include <iostream>
использование пространства имен std;
класс Коробка {
частный:
двойная ширина;
публика:
Коробка (двойная ш): ширина (ш) {}
//Объявляем функцию друга
друг void showWidth(Box &b);
};
//Определение функции друга, может получить доступ к закрытым членам класса Box
void showWidth(Box &b) {
ок << "Ширина поля: " << ширина полосы << конец;
}
интервал основной() {
Коробка коробчатая(10,5);
showWidth (коробка); // Доступ к ширине закрытого члена
вернуть 0;
}
В этом примереshowWidthХотя функция является обычной функцией вне категории Box, она все равно может обращаться к закрытым членам категории Box, поскольку она объявлена как дружественная функция.width。
Класс Friend позволяет одному классу получать доступ ко всем членам другого класса. Такая настройка полезна, когда категории должны тесно взаимодействовать друг с другом, но ее следует использовать с осторожностью, чтобы не раскрыть слишком много внутренних деталей.
Примеры следующие:
#include <iostream>
использование пространства имен std;
класс Площадь; // форвардное объявление
класс Прямоугольник {
частный:
двойная ширина, высота;
публика:
Прямоугольник (двойная ш, двойная высота): ширина (ш), высота (ч) {}
// Объявляем категорию Square как друга
друг класса Квадрат;
};
класс Площадь {
публика:
двойная областьOfRectangle(Прямоугольник &прямоугольник) {
вернуть rect.width * rect.height;
}
};
интервал основной() {
Прямоугольник прямоугольник(5.0, 3.0);
Квадратный квадрат;
ок << "Площадь прямоугольника: " << Square.areaOfRectangle(прямоугольник) << конец;
вернуть 0;
}
В этом примере класс Square объявлен как дружественный класс класса Rectangle, поэтому функции-члены класса Square могут напрямую обращаться к закрытым членам класса Rectangle.widthиheight。
Будьте осторожны при использовании дружественных функций и дружественных классов в C++. Чрезмерное использование разрушит инкапсуляцию класса. Поэтому ключевое слово «Friend» обычно используется только при разработке классов или функций, требующих тесного сотрудничества.
В C++ наиболее стандартным и рекомендуемым способом построчного чтения текстового файла является использование класса потоковой передачи файлов из стандартной библиотеки.std::ifstreamСотрудничатьstd::getlineфункция.
std::ifstreamОтвечает за открытие и управление потоковой передачей файлов, а такжеstd::getlineотвечает за чтение всей строки текста из потока (пока не встретится символ новой строки\n) и сохраните его вstd::stringв объекте.
Ниже приведен полный пример C++, демонстрирующий, как читать построчно файл с именемexample.txtсодержимое файла.
#include <iostream>
#include <fstream> // Подключаем библиотеку потоковой передачи файлов
#include <строка> // Включаем категорию строки
использование пространства имен std;
void read_file_line_by_line (константная строка и имя файла)
{
// 1. Создать объект std::ifstream
//Попробуем открыть указанный файл.
ifstream input_file (имя файла);
// 2. Проверяем, успешно ли открыт файл
если (!input_file.is_open())
{
церр << «Ошибка: невозможно открыть файл» << имя файла << конец;
возвращаться;
}
струнная линия;
int номер_строки = 1;
// 3. Используйте функцию std::getline для чтения построчно
// Условие цикла (getline(stream, string)) возвращает true каждый раз, когда чтение успешно.
// Когда достигается конец файла (EOF) или возникает ошибка, возвращаем false и цикл завершается.
в то время как (getline(входной_файл, строка))
{
ок << «Линия» << номер_строки << ": " << строка << конец;
номер_строки++;
}
// 4. Закрываем потоковую передачу файлов
// Когда объект input_file выходит за пределы своей области действия, деструктор автоматически закроет файл.
// Но явный вызов close() также приемлем.
входной_файл.закрыть();
ок << «Чтение файла завершено». << конец;
}
интервал основной()
{
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, Resource Acquisition Is Initialization).В C++ преобразование структуры данных (например, изstd::vector<std::string>Чтобы записать файл построчно (читать токены) и гарантировать, что каждый столбец (токен) поддерживает фиксированное выравнивание ширины в строке, вам необходимо использовать **std::ofstream** Используйте **Манипуляторы потоков ввода-вывода** для управления форматом вывода.
Основными инструментами управления форматом являются:
std::setw(width): Установите минимальную ширину следующего выходного поля.std::left / std::right: установка выравнивания текста в столбце (слева или справа).Ниже приведен пример C++, как преобразовать двумерную структуру данных, содержащую несколько полей (с использованиемstd::vector<std::vector<std::string>>Simulate) и запишите файл, убедившись, что каждое поле токена имеет фиксированную ширину в 15 символов и выровнено по левому краю.
#include <iostream>
#include <fstream> // Включаем поток вывода файла
#include <строка>
#include <vector>
#include <iomanip> // Включаем манипулятор потока ввода-вывода (setw, влево/вправо)
использование пространства имен std;
// Имитируем двумерную структуру данных, каждая строка содержит несколько полей (токенов)
используя TableData = вектор<vector<string>>;
void write_aligned_data (const string& имя файла, const TableData& data, int columns_width)
{
// 1. Создайте объект std::ofstream и откройте файл
ofstream выходной_файл (имя файла);
// 2. Проверяем, успешно ли открыт файл
если (!output_file.is_open())
{
церр << «Ошибка: невозможно открыть файл» << имя файла << «для письма». << конец;
возвращаться;
}
//Устанавливаем глобальное выравнивание: по левому краю (L-Justified)
выходной_файл << левый;
// 3. Запись данных построчно
for (const auto& row: data)
{
// 4. Записываем токен за токеном и устанавливаем ширину
for (const auto& token: row)
{
// setw(width) влияет только на следующий элемент вывода, следующий сразу за ним
выходной_файл << setw(column_width) << жетон;
}
// 5. Вставьте символ новой строки после конца строки, чтобы начать новую строку
выходной_файл << "\п";
}
// 6. Закрываем потоковую передачу файлов
выходной_файл.закрыть();
ок << "Данные успешно записаны в файл: " << имя файла << конец;
}
интервал основной()
{
//Пример данных: содержит четыре строки, каждая строка имеет три поля
Данные Таблицы = {
{"Имя", "Товар", "Цена"},
{"Алиса", "Книга", "19.99"},
{"БобДжонсон", "PenSet", "4.50"},
{"Чарли", "Блокнот", "800,75"}
};
константный интервал COLUMN_WIDTH = 15; // Определяем ширину каждого столбца
write_aligned_data("output_aligned.txt", данные, COLUMN_WIDTH);
вернуть 0;
}
std::ofstream: Категория потоковой передачи файлов. Используется для записи данных в файлы.#include <iomanip>: Этот заголовочный файл должен быть включен для использования манипулятора потока ввода-вывода.output_file << left;:
rightилиinternalкрышка.output_file << setw(column_width) << token;:
setw(width): установите минимальную ширину данных, которые будут выводиться в следующий раз. Если длина выходной строки меньше установленной ширины, она будет дополнена пустыми символами.setwДействует только для следующей операции вывода, следующей сразу за ней, поэтому ее необходимо вызывать один раз перед каждым выходным токеном.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。
Прежде чем использовать vcpkg в Windows, убедитесь, что он установлен.Visual Studio 2015 или новееи проверьте рабочую нагрузку «Разработка настольных компьютеров с использованием C++» (включая пакет английского языка), иначе при компиляции пакета могут возникнуть ошибки.
Программы управления периферией — это приложения, используемые для связи и управления внешними аппаратными устройствами (такими как принтеры, сканеры, двигатели, ПЛК, датчики и т. д.), подключенными к компьютеру или хосту.
| язык | Применимые ситуации | Примечание |
|---|---|---|
| Python | Быстрая разработка, автоматизация тестирования | Применимо к последовательному порту, USB HID |
| C/C++ | Встроенное управление и разработка драйверов | Доступ к низкоуровневой памяти и оборудованию |
| C# | Пользовательский интерфейс Windows + устройство управления | Подходит для COM-порта и USB-связи. |
| Java | Межплатформенный контроль | Реже используется в бюджетных устройствах. |
импортный серийный номер
ser = серийный.Serial('COM3', 9600, таймаут=1)
ser.write(b'ON\n') # Отправляем команды управления
ответ = ser.readline()
print("Ответ устройства:", response.decode())
сер.закрыть()
Порт SerialPort = новый SerialPort("COM4", 9600);
порт.Открыть();
port.WriteLine("ПЕРЕМЕСТИТЬ 100");
строковый ответ = port.ReadLine();
Console.WriteLine("Ответ: " + ответ);
порт.Закрыть();
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())
с.закрыть()
Разработка программы управления периферийными устройствами требует выбора соответствующего языка и библиотеки функций на основе интерфейса и протокола устройства, а также сочетания последовательного, USB, сетевого и других методов связи, которые могут широко использоваться в различных областях автоматизации и промышленного управления.
// build.gradle
реализация «com.journeyapps:zxing-android-embedded:4.3.0»
//Экран сканирования вызовов Java
Интегратор IntentIntegrator = новый IntentIntegrator(this);
integrator.setPrompt("Пожалуйста, отсканируйте штрих-код");
integrator.setBeepEnabled(истина);
integrator.setOrientationLocked(false);
интегратор.initiateScan();
//onActivityResult получает результат
@Override
protected void onActivityResult (int requestCode, int resultCode, данные намерения) {
Результат IntentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
если (результат! = ноль) {
если (result.getContents() != ноль) {
Строковый штрих-код = result.getContents();
Log.d("Содержимое штрих-кода", barcode);
}
}
}
<script src="https://unpkg.com/[email protected]/dist/quagga.min.js"></script>
<скрипт>
Квагга.init({
входной поток: {
название: «Живой»,
тип: «Прямая трансляция»,
цель: document.querySelector('#scanner')
},
декодер: {
читатели: ["code_128_reader", "ean_reader", "upc_reader"]
}
}, функция (ошибка) {
если (!ошибка) {
Квагга.старт();
}
});
Quagga.onDetected(функция(результат) {
console.log("Содержимое штрих-кода: ", result.codeResult.code);
});
</скрипт>
| платформа | Рекомендуемый комплект | Это бесплатно? |
|---|---|---|
| Android | ZXing / ML Kit | да |
| Web | QuaggaJS / jsQR | да |
| Windows | Dynamsoft / ZXing.NET | Dynamsoft для коммерческого использования |
| Python | ZBar / pyzbar | да |
Для разработки Barcode Reader вы можете выбрать соответствующий пакет с открытым исходным кодом в зависимости от платформы. ZXing — наиболее широко поддерживаемый вариант. QuaggaJS доступен для Интернета. Если вам нужна поддержка коммерческого уровня, вы можете рассмотреть Dynamsoft Barcode SDK.
Считыватели штрих-кодов — это, по сути, устройства, имитирующие ввод с клавиатуры. Когда штрих-код сканируется, он «выводит» содержимое штрих-кода в поток символов, точно так же, как ввод с клавиатуры.
Поэтому штрих-кодМожет содержать контрольный код (Control Code),ноТребуется считыватель штрих-кодов и поддержка формата штрих-кода.Просто отлично.
Например, следующий формат может кодировать управляющие коды:
Некоторые генераторы штрих-кодов позволяют встраивать специальные символы, например:
\x0Dозначает «Ввод»\x03означает Ctrl-C^C、[CTRL+C]Специальный синтаксис зависит от инструментаБольшинство профессиональных принтеров штрих-кодов (например, Zebra, Honeywell) предварительно настроены на заводе.Отключить вывод управляющего кода, необходимо включить через «Штрих-код настроек», предоставленный сканером:
Например, в приложении Windows:
keydownиCtrlСоответствующая обработка сочетаний клавиш.Кодирование ASCII 3 с помощью Code128:
Ввод:\x03Привет, мир!
После сканирования штрих-кода сработает сочетание клавиш 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, выберите шаблон «Пустое действие» и укажите имя проекта и другую основную информацию.
существовать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: ориентация = "вертикально"
андроид:гравитация="центр">
<Кнопка
android:id="@+id/кнопка"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
android:text="Нажмите меня" />
<текстовое представление
android:id="@+id/textView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
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;
публичный класс MainActivity расширяет AppCompatActivity {
@Override
protected void onCreate (Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_main);
Кнопка Кнопка = findViewById(R.id.button);
TextView textView = findViewById(R.id.textView);
button.setOnClickListener(new View.OnClickListener() {
@Override
общественная недействительность onClick (Просмотр 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 = новый LocationListener() {
@Override
public void onLocationChanged(@NonNull Местоположение) {
двойная широта = location.getLatitude();
двойная долгота = location.getLongitude();
Log.d("GPS", "Широта: " + широта + ", Долгота: " + долгота);
}
};
если (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
1000, // миллисекундный интервал
1, // Минимальное расстояние (метры)
местоположениеСлушатель);
}
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 или «Эй, Google», вам необходимо объединить следующие компоненты:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET"/>
Распознаватель SpeechRecouncer = SpeechRecouncer.createSpeechRecouncer(this);
Намерение намерение = новое намерение (RecouncerIntent.ACTION_RECOGNIZE_SPEECH);
намерение.putExtra(RecouncerIntent.EXTRA_LANGUAGE_MODEL,
RecouncerIntent.LANGUAGE_MODEL_FREE_FORM);
Intent.putExtra(RecouncerIntent.EXTRA_LANGUAGE, Locale.getDefault());
распознаватель.setRecognitionListener(новый RecognitionListener() {
@Override
public void onResults (результаты пакета) {
ArrayList<String> совпадения = результаты.getStringArrayList(SpeechRecouncer.RESULTS_RECOGNITION);
if (соответствует != null && !matches.isEmpty()) {
Строковая команда = match.get(0).toLowerCase();
if (command.contains("Открыть камеру")) {
// выполняем операции
}
}
}
//Другие необходимые методы перезаписи опущены
});
Распознаватель.startListening(намерение);
TextToSpeech tts = новый TextToSpeech(this, status -> {
если (статус == TextToSpeech.SUCCESS) {
tts.setLanguage(Locale.TAIWAN);
tts.speak("Привет, я здесь.", TextToSpeech.QUEUE_FLUSH, null, null);
}
});
Если вы хотите сохранить фон и разбудить его голосом, вам нужно использовать:
RECORD_AUDIOразрешения.Цель постоянного фонового мониторинга — позволить приложению распознавать слова голосового пробуждения (например, «Эй, помощник») и активировать соответствующие функции, даже если экран не открыт.
SpeechRecognizerДлинный фоновый бег.SpeechRecognizerРаспознавайте полные голосовые команды.публичный класс VoiceService расширяет сервис {
@Override
public int onStartCommand (Намерение, int flags, int startId) {
Уведомление = новый NotificationCompat.Builder(this, "voice_channel")
.setContentTitle("Голосовой помощник работает")
.setSmallIcon(R.drawable.ic_mic)
.build();
startForeground(1, уведомление);
//Инициализируем обнаружение горячих слов
startHotwordDetection();
вернуть START_STICKY;
}
@Override
public IBinder onBind (Намерение) {
вернуть ноль;
}
}
NotificationChannel channel = new NotificationChannel("voice_channel",
"Voice Assistant", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
Porcupine предоставляет Android SDK, который распознает пользовательские ключевые слова и работает полностью автономно.
PorcupineManager porcupineManager = новый PorcupineManager.Builder()
.setAccessKey("ваш ключ")
.setKeywordPath("hey_assistant.ppn")
.setSensitivity(0.7f)
.build((keywordIndex) -> {
//Вызов SpeechRecouncer для распознавания речи при пробуждении
startSpeechRecognition();
});
дикобразМенеджер.старт();
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 Toolsиспользовать инструменты командной строки Swift.
1. Откройте Xcode и выберите «Создать новый проект Xcode».
2. Выберите подходящий шаблон приложения, например.App (iOS/macOS)。
3. Задайте имя проекта, идентификатор пакета и язык (Swift или Objective-C).
4. Выберите платформу пользовательского интерфейса (SwiftUI или UIKit).
1. ЗарегистрируйтесьApple Developer Program(Требуется годовая плата в размере 99 долларов США).
2. Установить через XcodeApp Store Connectи отправьте приложение.
3. Следуйте за AppleApp Store Review GuidelinesУбедитесь, что ваше приложение соответствует требованиям листинга.
Разработка iOS в основном используетXcode, официальная интегрированная среда разработки (IDE), предоставляемая Apple.
Изучение разработки под iOS требует овладения следующими основами:
Вот несколько полезных ресурсов для обучения и развития:
Xcode — это интегрированная среда разработки (IDE), предоставляемая Apple для разработки приложений macOS, iOS, watchOS и tvOS.
Вы можете загрузить последнюю версию Xcode из Mac App Store или с официального сайта разработчика Apple.
Практические советы по повышению эффективности разработки:
Сопутствующие учебные и справочные ресурсы:
Swift — это современный язык программирования Apple для разработки приложений для iOS, macOS, watchOS и tvOS.
varиlet?и!Обрабатывает наличие или отсутствие значенияif、switch、for、whilefuncОпределение, поддерживает метки параметров и несколько возвращаемых значений.classиstructSwift предназначен не только для экосистемы Apple, его также можно использовать для разработки серверных и кроссплатформенных инструментов.
Сопутствующие учебные и справочные ресурсы:
Objective-C — это объектно-ориентированный язык программирования на основе C, первоначально разработанный NeXT Corporation, а затем широко используемый Apple для разработки приложений для macOS и iOS.
Синтаксис Objective-C сочетает в себе функции C и Smalltalk с использованием символа @ для обозначения расширений языка.
@interfaceи@implementation[object method]@propertyи@synthesizeРазработка Objective-C в основном осуществляется с использованием Apple Xcode.
Вот некоторые ресурсы для обучения и справки:
GNews — это платформа агрегирования новостей, разработанная Google и предназначенная для того, чтобы помочь пользователям получать последние мировые новости. Он объединяет контент из различных источников новостей и использует технологию искусственного интеллекта для персонализации рекомендаций новостей, представляющих интерес для пользователей.
Пользователи могут использовать эту платформу, посетив веб-сайт GNews или загрузив ее приложение. На платформе пользователи могут выбирать интересующие темы, следить за конкретными источниками новостей и настраивать новостные ленты в соответствии со своими потребностями.
GNews — это мощный инструмент агрегирования новостей, который использует технологию искусственного интеллекта, чтобы предоставить пользователям персонализированный опыт новостей. Поскольку новостная информация быстро меняется, GNews помогает пользователям быстро идти в ногу с мировыми тенденциями и получать необходимую им информацию.
| Название инструмента | Основные особенности | Применимые сценарии | цена |
|---|---|---|---|
| n8n | Инструмент автоматизированного рабочего процесса с открытым исходным кодом, который обеспечивает широкие возможности настройки процесса и поддерживает самостоятельно создаваемые узлы. | Подходит для внутренней автоматизации процессов, крупномасштабных систем автоматизации, интеграции API и т. д. | Бесплатный и с открытым исходным кодом, доступна платная облачная версия. |
| Make | Обеспечивает визуальное построение рабочего процесса, поддерживает интеграцию множества сторонних приложений и сервисов, а также подчеркивает простоту и удобство использования. | Подходит для автоматизации рабочих процессов малых и средних предприятий и быстрой интеграции различных сервисов. | Доступен бесплатный план, а платный план предлагает более расширенные функции в зависимости от потребностей пользователя. |
| Zapier | Поддерживает интеграцию с большинством приложений, прост и удобен в использовании, может создавать триггеры и автоматизированные рабочие процессы. | Подходит для автоматизации в различных сферах бизнеса, особенно малого бизнеса и стартапов. | Доступен бесплатный план, а платный план предоставляет больше функций и работает в зависимости от потребностей пользователя. |
Bolt — это быстрая и легкая среда разработки искусственного интеллекта, которая предоставляет разработчикам простые и эффективные инструменты для создания приложений. Особенности включают в себя:
Курсор — это инструмент-редактор, разработанный специально для разработки программ искусственного интеллекта и обеспечивающий интеллектуальные вспомогательные функции написания и отладки кода. Особенности включают в себя:
v0 — это платформа искусственного интеллекта, основанная на визуальной разработке, которая позволяет пользователям создавать модели и приложения с помощью интерфейса перетаскивания. Особенности включают в себя:
Codeium — это редактор программ в сочетании с интеллектуальной помощью искусственного интеллекта, ориентированный на повышение эффективности и точности разработки программ. Особенности включают в себя:
Программная инженерия — это инженерная дисциплина, которая разрабатывает, эксплуатирует и обслуживает программное обеспечение систематическим и плановым образом. Целью является создание высококачественных, удобных в сопровождении, надежных и требовательных программных систем.
Пожалуйста, введите официальное название этого проекта.
Объясните причину этого проекта, основные проблемы и основные проблемы, которые необходимо решить, а также определите четкие цели проекта.
Опишите функции системы и общую архитектуру, которые можно сопоставить со схемой архитектуры системы.
Вы можете прикрепить эскизы или каркасы главного экрана для описания элементов и интерактивных процессов каждого экрана.
Перечислите структуру основной таблицы данных, поля, корреляции и т. д.
Перечислите внешние системы, API или другие программные компоненты, которые необходимо интегрировать.
Перечислите потенциальные риски, ограничения (такие как бюджет, рабочая сила, технологии и т. д.).
Ссылки на соответствующие документы, справочные материалы, определения терминов и т. д.
Шаблоны проектирования — это набор проверенных решений для проектирования программного обеспечения, которые в основном используются в объектно-ориентированном программировании для решения повторяющихся проблем проектирования в конкретных ситуациях.
Контроль версий — это система, которая управляет историей изменений файлов. Он широко используется при разработке программного обеспечения, позволяя нескольким разработчикам одновременно сотрудничать и сохраняя полную запись каждого изменения.
git init:Инициализировать библиотеку версийgit клон [url]:Копировать удаленный проектgit добавить [файл]:Добавьте изменения в промежуточную область.git commit -m "сообщение": Отправить измененияgit push: Отправить изменения в удаленный репозиторий.git pull: получение и объединение удаленных изменений.git branch: просмотр или создание ветвейgit merge: объединить веткиGit — это децентрализованная система контроля версий, разработанная Линусом Торвальдсом (отцом Linux) в 2005 году для отслеживания изменений кода, совместной разработки и управления версиями. Сегодня это наиболее широко используемый инструмент контроля версий, который используется в личном развитии, командных проектах и сообществах с открытым исходным кодом.
git --versionчтобы подтвердить, что установка прошла успешно.При первом использовании Git вам необходимо указать информацию о разработчике:
git config --global user.name "ваше имя" git config --global user.email "Ваш адрес электронной почты@example.com"
git init # Инициализировать локальный репозиторий git clone URL # Скопируйте удаленный репозиторий git добавить. # Добавляем изменения в промежуточную область 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)Если вы хотите полностью отменить все локальные изменения, которые не были зафиксированы (незафиксированы) или зафиксированы, но еще не отправлены (локальные фиксации), и сбросить ветку, чтобы она полностью соответствовала удаленному концу, выполните следующие действия.
Во-первых, убедитесь, что ваш локальный индекс обновлен с учетом последних изменений на удаленном конце:
git fetch --all
использовать--hardПараметр указывает текущую ветку на соответствующую удаленную ветку (при условии, что ваша ветка является основной):
git reset --hard origin/main
git reset --hardБудут обработаны только файлы, уже отслеживаемые Git. Если вы недавно создали файлы или папки локально, но еще не добавили их в git, они останутся. Чтобы удалить их все, используйтеcleanинструкция:
# Сначала выполните тест, чтобы увидеть, какие файлы будут удалены
git очистить -n
# Официально удалить файлы (-f) и каталоги (-d)
git очистить -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).
После того как вы вручную отредактируете файлы и решите, какой код сохранить, вам необходимо выполнить следующие шаги для завершения слияния:
<<<<, ====, >>>>отметка.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 | Может управлять проблемами и запросами на включение, но не может писать код. |
| Write | Код можно отправить непосредственно в репозиторий. |
| Maintain | Помимо записи, вы также можете управлять некоторыми настройками репозитория. |
| Admin | Иметь полный контроль, включая удаление репозиториев и управление другими соавторами. |
Это самый распространенный и интуитивно понятный способ удаления. Обратите внимание, что после удаления репозитория его невозможно восстановить, если у вас нет резервной копии.
Имя пользователя/имя репозитория)。Если у вас установлен инструмент командной строки GitHub (gh), вы можете быстро удалить его через терминал:
gh repo delete <имя пользователя>/<имя репозитория> --подтверждать
Уведомление:--confirmПараметр пропустит этап подтверждения напрямую, используйте его с осторожностью.
После удаления удаленного репозитория на GitHub локальная папка на вашем компьютере все равно будет существовать. Чтобы удалить полностью, удалите папку вручную:
rm -rf <имя папки>
rd /s /q <имя папки>
---
| Режим работы | Сфера влияния | Это подлежит восстановлению? |
|---|---|---|
| Удаление веб-интерфейса | Удаляйте данные только на удаленном сервере GitHub. | Нет (если не обратитесь в службу поддержки или вилку) |
| команда rm -rf | Удаляйте только файлы, локальные на вашем компьютере. | Нет (если нет мусорной корзины) |
| Удалить папку .git | Сохраните файл, но переместите его обратно в обычную папку (теряя функциональность контроля версий). | Да (перезапустить инициализацию) |
Visual Studio имеет встроенную функцию интеграции с Git, но вам все равно необходимо установить исполняемый файл Git в систему для выполнения операций контроля версий (таких как Commit, Push, Pull, Merge и т. д.).
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, сначала подтвердите, соответствует ли ваш уровень доступаBasicили выше.
CMake — это кроссплатформенная «система метасборки» с открытым исходным кодом. Он не компилирует непосредственно сам программный код, а автоматически генерирует файлы проекта, подходящие для текущей операционной системы и среды разработки, путем чтения файла конфигурации (CMakeLists.txt). Например, в 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-серии.
Traditional Makefiles are difficult to maintain and do not have cross-platform versatility. CMake позволяет разработчикам просто писать набор файлов конфигурации, а разработчики по всему миру могут легко открывать и компилировать проекты в предпочитаемой ими IDE (например, VS Code, CLion, Xcode). This is why most mainstream open source C++ projects currently use CMake as a standard tool.
Развертывание приложения — это процесс перемещения разработанного приложения из среды разработки в среду тестирования или производственную среду, чтобы пользователи могли его использовать. It ensures that the system can perform stably and reproducibly in different environments.
# Разверните пример с помощью действий GitHub.
имя: Развертывание веб-приложения
на:
нажать:
ветки: ["основной"]
вакансии:
развернуть:
запуск: Ubuntu-последний
шаги:
- использует: действия/checkout@v4
- имя: Создать образ Docker.
запустить: docker build -t myapp.
- имя: Развертывание на сервере
запустить: docker run -d -p 80:80 myapp
Docker (контейнерная технология) — платформа с открытым исходным кодом для автоматизации развертывания, масштабирования и управления приложениями. Он использует «контейнеры» для упаковки приложений и их зависимостей, чтобы обеспечить согласованное выполнение в различных средах.
docker pull [имя изображения]: загрузить файл изображенияdocker run [имя изображения]: Контейнер выполненияdocker ps: Просмотр выполняющихся контейнеровостановка докера [идентификатор контейнера]: Остановить контейнерdocker rm [идентификатор контейнера]: Удалить контейнерdocker build -t [имя] .: Создать файл образа на основе Dockerfile.docker images: просмотреть список файлов изображений# Используем файл изображения Python
ИЗ питона: 3.10
# Установить рабочий каталог
РАБОЧИЙ ДИАПОР/приложение
# Копируем файлы программы
КОПИРОВАТЬ ./приложение
#Установить пакеты зависимостей
ЗАПУСК pip install -r требования.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, библиотеки, платформы), от которых приложение зависит при выполнении. This is crucial to ensure that the software performs correctly in different environments.
| Цель | Подробное описание |
|---|---|
| Поиск неисправностей | Найдите сбои программы, вызванные отсутствием DLL или несоответствием версий. |
| аудит безопасности | Определяет, загружает ли программа несанкционированные сторонние компоненты или имеет ли она уязвимости безопасности. |
| Оптимизация производительности | Оцените влияние слишком большого количества зависимых модулей на время запуска и использование памяти и удалите ненужные ссылки. |
| Оценка трансплантации | Определите, будет ли программное обеспечение работать на компьютере, на котором не установлена определенная среда разработки, например среда выполнения .NET или библиотеки VС++. |
Dependency Walker (широко известный как Depends.exe) — это бесплатный инструмент для анализа файловой структуры приложений Windows (таких как .exe, .dll, .sys и т. д.). В основном он используется для сканирования любого 32-битного или 64-битного модуля Windows и построения иерархического дерева всех связанных зависимых модулей.
| сцена | описывать |
|---|---|
| Устранение системных ошибок | Устраните системные ошибки, такие как 0xc000007b (ошибка параллельной конфигурации) или указанный модуль не найден. |
| Развертывание программного обеспечения | Разработчики проверяют, что установщик включает все необходимые библиотеки выполнения (например, распространяемый компонент VC++). | Проверьте, нет ли в системном пути разных версий DLL с одинаковым именем, вызывающих ненормальное поведение программы. |
Поскольку Dependency Walker не обновлялся в течение многих лет, он плохо поддерживает некоторые функции современной Windows 10/11 (например, наборы API или библиотеки DLL с отложенной загрузкой), и часто появляются ложные красные предупреждения. В этом случае рекомендуются следующие альтернативные инструменты с открытым исходным кодом:
Зависимости — это современный инструмент анализа зависимостей с открытым исходным кодом, разработанный для замены Dependency Walker (Depends.exe), выпуск которого прекращен уже много лет. Он полностью оптимизирован для системной архитектуры Windows 10 и Windows 11 и может точно анализировать ассоциации модулей в современных программных средах.
api-ms-win-*Виртуальные библиотеки DLL, начинающиеся с, не будут генерировать ложные предупреждения о циклических зависимостях или ошибки отсутствия файлов.| характеристика | Dependency Walker (старая версия) | Зависимости (современная версия) |
|---|---|---|
| Поддержка Windows 10/11 | Плохо (частые ложные срабатывания) | Отлично (встроенная поддержка) |
| Обработка наборов API | Неопознанный (отсутствует красным) | Правильно сопоставлен с объектной DLL. |
| статус развития | Обновления остановлены (2006 г.) | На постоянной поддержке (GitHub) |
| основная технология | C++ / MFC | C#/WPF (немного низкоуровневого C++) |
Зависимости — это экологически чистое программное обеспечение, не требующее установки, которое обычно можно загрузить с GitHub.lucasg/DependenciesРепозиторий загружает скомпилированную версию Release. При его использовании просто перетащите файл .exe или .dll, который вы хотите проанализировать, в окно, чтобы начать анализ.
Эти два инструмента имеют разную философию проектирования: Dependency Walker (Depends.exe) включает динамический анализатор (Profiler), тогда как современные зависимости ориентированы на статический анализ и анализ наборов API.
Если вам нужно использовать «Исполнитель» для устранения ошибок DLL, которые возникают только во время работы (например, сбои отложенной загрузки или проблемы с поиском пути), вы можете продолжать использовать функцию профиля Dependency Walker:
| преимущество | недостаток |
|---|---|
| СпособныйDynamic Loading(LoadLibrary) ошибка. | При работе на Win10/11 журналы будут заполнены большим количеством ложных сообщений об ошибках API-MS-WIN. |
| Можно подтвердить фактический путь к загруженному файлу DLL (связанный с порядком пути поиска). | Если программа вообще не запускается из-за слишком большого количества зависимостей, Profiler, возможно, не сможет получить полезную информацию. |
Если у вас слишком много ложных ошибок в профилировщике Dependency Walker и вы не видите в этом смысла, вместо этого рекомендуется использовать следующую комбинацию:
NAME NOT FOUNDзаписи, которые могут точно сказать вам, где программе не удалось найти DLL.Разработанный GitHub в сотрудничестве с OpenAI, он в настоящее время является наиболее широко используемым помощником по программированию с использованием искусственного интеллекта в мире. Его можно встроить непосредственно вVisual Studio Code、JetBrainsВ других популярных средах разработки он анализирует комментарии и контекст, чтобы мгновенно предлагать строки кода или целые функции.
Это независимое программное обеспечение, разработанное на основе архитектуры VS Code.Редактор кода ИИ. В отличие от простого плагина, Cursor глубоко интегрирует искусственный интеллект в нижний уровень редактора. Он понимает структуру (контекст) всего проекта и позволяет разработчикам напрямую общаться со всей библиотекой для выполнения глобального рефакторинга или исправления ошибок.
Хотя Клод — ИИ общего назначения, его3.5 Модель сонетаОн признан одним из лучших вариантов с точки зрения программной логики, архитектурного проектирования и возможностей отладки. соответствоватьArtifactsФункция позволяет разработчикам напрямую просматривать созданный внешний экран веб-страницы или интерактивные компоненты в диалоговом окне.
Табнин придает большое значениеКонфиденциальность и безопасность, подходит для предприятий с высокими требованиями к конфиденциальности исходного кода. Он поддерживает полностью локализованное развертывание (самостоятельное размещение), гарантирует, что код не будет загружен в облако для обучения, и обеспечивает точную функцию автозаполнения.
Помощник по разработке, предоставляемый Amazon Web Services (AWS). Помимо базовой генерации кода, он особенно улучшен за счетОблачные сервисы AWSИнтеграция может помочь разработчикам быстро писать инфраструктуру как код (IaC) или выполнять проверки безопасности и обновления.
Агент искусственного интеллекта, встроенный в онлайн-среду разработки Replit. Он характеризуетсяАвтоматизированное развертываниеПри построении среды пользователям нужно только описать функции приложения, а Агент может автоматически создавать файлы, устанавливать зависимые пакеты, писать код и выполнять онлайн-работу.
Представлено ВерселемИИ для фронтенд-разработки. Пользователи описывают требования к интерфейсу на естественном языке, а v0 будет напрямую генерировать код интерфейсных компонентов на основе React, Tailwind CSS и пользовательского интерфейса Shadcn, что значительно сокращает время стереотипов пользовательского интерфейса.
Агентские помощники по кодированию ИИ. Характеристиками этого типа инструмента являются его способность напрямую обращаться к терминалу, читать и записывать файлы, выполнять тесты и иметь возможность самостоятельно планировать задачи.
Этот тип инструмента наиболее близок к Claude Code и запускается непосредственно в вашем терминале, что делает его подходящим для разработчиков, привыкших к операциям из командной строки.
Такие инструменты интегрируют возможности агента в редактор, обеспечивая более интуитивно понятный процесс визуальной разработки.
Такие инструменты обычно обладают более независимыми рабочими возможностями и могут завершить процесс от анализа спроса до развертывания в Интернете или в автономной среде.
| Название инструмента | Основной интерфейс | Основные преимущества |
|---|---|---|
| Claude Code | CLI (терминал) | Разработанный Anthropic, он очень точно следует инструкциям Claude 3.5. |
| Aider | CLI (терминал) | Открытый исходный код, поддержка нескольких моделей и мощное автоматизированное управление Git. |
| Cursor | IDE (редактор) | Пользовательский интерфейс имеет высочайшую степень интеграции и подойдет разработчикам, которые не любят переключать терминалы. |
| Cline | Плагин VS-кода | Открытый исходный код и полностью прозрачный, вы можете самостоятельно подключить различные ключи API. |
Claude Code — это инструмент с интерфейсом командной строки (CLI), основанный на агентах, разработанный Anthropic. Он запускается непосредственно в терминале разработчика и может понимать всю библиотеку программного кода, выполнять команды терминала, редактировать файлы и помогать в обработке рабочего процесса Git, позволяя разработчикам выполнять сложные задачи программирования с помощью естественного языка.
Для Claude Code требуется среда Node.js 18+, которую можно установить следующими способами:
npm install -g @anthropic-ai/claude-code
claudeТеперь вы можете запустить интерактивный режим.| Функция | Режим работы/горячие клавиши |
|---|---|
| Plan Mode | Shift + Tab(Mac/Linux) илиAlt + M(Окна). Перед выполнением составьте подробный план. |
| Auto-accept | Все изменения принимаются автоматически без необходимости подтверждения каждого. |
| Выберите файл | входить@Быстро находите и добавляйте определенные файлы в качестве базовых знаний. |
| Выполнить инструкции | использовать!префикс для выполнения команд Bash непосредственно в сеансе (например:!ls -la)。 |
/help: показывает все доступные команды и инструкции./clear: очистить текущую историю разговоров и сбросить контекстное пространство./stats: Отобразить недавнюю статистику использования токенов и расходов./doctor: проверьте, нормально ли состояние установки./compact: вручную сжать содержимое разговора для экономии места.При частых всплывающих окнах с подтверждением разрешений и необходимости межкаталогового доступа настройки оптимизации можно выполнить с помощью параметров запуска и встроенных команд.
По умолчанию Claude Code будет подтверждать опасные команды (например, удаление файлов и выполнение системных команд) одну за другой. Для входа в «режим автоматизации» для уменьшения помех используйте следующие параметры:
--auto-accept, что заставляет инструмент автоматически выполнять предложенные инструкции, не переставая спрашивать. Однако обратите внимание, что это невозможно при выполнении деструктивных инструкций, таких какrm).claude --auto-accept
/approve-all, который предоставляет временное полное доверие для последующих операций в текущем сеансе.По соображениям безопасности Claude Code будет ограничен каталогом проекта, в котором он запускается по умолчанию. Для доступа к внешним путям существует три метода:
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Или, если вы продолжаете нажимать «ОК» при редактировании файла, вы можете использовать следующие опасные параметры:
--dangerously-skip-permissions--allow-dangerously-skip-permissions--permission-mode bypassPermissionsиспользовать.По умолчанию Клод может читать и записывать только каталог, в котором он запущен. Чтобы получить доступ к другим путям, используйте--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, Read, Write). | Требуется обширный автоматический рефакторинг или работа в изолированной среде. |
--add-dir <path> |
Разрешает Клоду доступ к определенным путям за пределами текущего каталога. | Межпроектная разработка может потребовать ссылки на внешнюю документацию. |
--permission-mode acceptEdits |
Автоматически принимать изменения файлов, но по-прежнему спрашивать при выполнении команд Bash. | Относительно безопасный режим автоматизации. |
--dangerously-skip-permissionsРазрушительный. Если Клод неверно оценит команду (например, случайно удалит файл), система не перехватит ее.rootилиsudoВыполнение этого параметра с использованием удостоверения может быть заблокировано из-за механизмов безопасности. Рекомендуется выполнять его с правами общего пользователя.Cursor — редактор кода AI, разработанный на основе VS Code. Это не просто плагин, он внедряет возможности искусственного интеллекта глубоко в нижний уровень редактора, позволяя ему понимать контекст всего проекта и иметь возможность автоматически писать, реконструировать и исправлять код. Поскольку он наследует VS Code, пользователи могут напрямую импортировать все исходные настройки и расширенные функции.
Вызовите ИИ прямо в редакторе кода:
Cmd + K(Окна дляCtrl + K)。Диалоговое окно чата на боковой панели:
Cmd + LОткройте окно чата.@Files、@Codebaseили@Webчтобы указать диапазон ссылки AI.Это самый мощный «агентский» режим Cursor:
Cmd + IЗапустите Композитор.| Имя функции | Метод установки | иллюстрировать |
|---|---|---|
| Переключение модели | Нижнее меню боковой панели | Переключайтесь между Claude 3.5 Sonnet, GPT-4o или Cursor Small. |
| Rules for AI | Settings > General | Настройте стиль ответа ИИ (например: всегда используйте традиционный китайский язык, код должен соответствовать определенным спецификациям). |
| Index Project | Settings > Features | Обязательно включите локальное индексирование, чтобы ИИ мог точно искать файлы всего проекта. |
Cmd + K, позвольте ИИ помочь вам написать сложные инструкции Shell.GitHub Copilot — это помощник по написанию кода с искусственным интеллектом, разработанный GitHub (Microsoft). Он интегрирован в редактор и может выполнять функции завершения кода, генерации, объяснения и диалога в режиме реального времени. Он использует модель OpenAI и подходит для различных языков программирования. В настоящее время это один из наиболее широко используемых инструментов программирования искусственного интеллекта.
| план | цена | иллюстрировать |
|---|---|---|
| Бесплатная версия | $0 | Ограниченное количество завершений и разговоров в месяц |
| Персональная версия | 10 долларов США в месяц | Неограниченное завершение и диалог |
| Корпоративная версия | 19 долларов США в месяц на человека | Плюс организационное управление, индивидуальные модели и т. д. |
Ctrl+Shift+X)GitHub Copilot| действие | Способ |
|---|---|
| Принять предложения по завершению | в соответствии сTab |
| Пропустить предложения | в соответствии сEsc |
| Открыть чат второго пилота | в соответствии сCtrl+Alt+I |
| Вопрос по выбранному коду | После выбора щелкните правой кнопкой мыши и выберите опцию Copilot. |
| Функция | Copilot | Cursor |
|---|---|---|
| Способ установки | Плагин VS Code | Автономный редактор |
| цена | 10 долларов США в месяц | 20 долларов США в месяц |
| завершение кода | мощный | мощный |
| Понять весь проект | обычный | Сильнее |
| Пользовательская модель ИИ | нет | Дополнительный Claude/GPT и т. д. |
| стоимость обучения | Низкий (унаследован от VS Code) | Средний (нужно адаптироваться к новому интерфейсу) |
Aider — это инструмент программирования сопряжения AI на базе терминала, который поддерживает прямую модификацию локального исходного кода. Перед установкой убедитесь, что системаPython 3.8Вышеуказанные версии аналогичныGit。
python -m pip install aider-chat
Перед запуском ключ, предоставленный поставщиком услуг ИИ, необходимо установить в качестве переменной среды. Aider по умолчанию поддерживает различные модели, такие как Anthropic и OpenAI:
export ANTHROPIC_API_KEY=your-keysetx ANTHROPIC_API_KEY your-keyПосле завершения настройки войдите в терминалaiderОткроется интерфейс разговора.
Aider будет читать и изменять только те файлы, которые вы укажете для присоединения к контексту, чтобы сэкономить затраты на токены и повысить точность:
Вы можете напрямую использовать естественный язык, чтобы попросить Айдера выполнить задачи, например: «Помогите мне разделить этот класс на два файла» или «Исправить существующие ошибки». После выполнения модификации Aider автоматическиGit Commitи автоматически составить сообщение об отправке на основе измененного содержимого.
| инструкция | Описание функции |
|---|---|
| /undo | Отмените последнюю модификацию кода и фиксацию Git, выполненную искусственным интеллектом. |
| /diff | Предварительный просмотр изменений, внесенных в текущий ИИ, по сравнению с исходной версией. |
| /chat-mode | Переключение между режимами разговора (например, режим кода используется для изменения файлов, режим вопросов используется только для вопросов и ответов). |
| /help | Отображение полного списка встроенных команд. |
| /exit | Выйдите из программы Aider. |
Aider поддерживает несколько способов взаимодействия с локально исполняемыми бесплатными моделями и моделями с открытым исходным кодом. Наиболее распространенным методом является использованиеOllama、LM StudioилиLocalAIПодождите, пока инструмент создаст локальный сервер, совместимый со спецификацией OpenAI API, а затем позвольте Aider указать адрес сервера.
На данный момент это самое простое и распространенное решение для локализации:
ollama pull deepseek-coder-v2(Или выберите модель, оптимизированную для таких программ, как Qwen2.5-Coder).--modelПараметр указывает путь к модели Олламы.aider --model ollama/deepseek-coder-v2
| параметр | Описание функции |
|---|---|
| --model | Укажите название модели. Локальные модели обычно имеют форматollama/<model_name>。 |
| --openai-api-base | Если вы используете LM Studio, вам необходимо вручную указать URL-адрес локального API (например,http://localhost:1234/v1)。 |
| --no-stream | Если производительность локального вывода недостаточна и соединение нестабильно, вы можете отключить потоковый вывод, чтобы повысить стабильность. |
Не все модели подходят для использования с Aider. Ниже приведены локальные модели с открытым исходным кодом, которые в настоящее время признаны сообществом более эффективными в задачах разработки программ:
Коды программного обеспечения, проектная документация, руководства пользователя и т. д. защищены авторскими правами. Защита авторских прав устанавливается автоматически по завершению создания, регистрация не требуется, несанкционированное копирование, изменение, распространение или коммерческое использование запрещено.
Если программное обеспечение включает в себя технологические инновации или уникальные алгоритмы, вы можете подать заявку на патентную защиту. Патенты подлежат рассмотрению и утверждению и защищают исключительные права изобретателя на технические решения, но чистая программная логика обычно не защищается патентами.
Названия программного обеспечения, логотипы и фирменные знаки могут быть зарегистрированы в качестве товарных знаков, чтобы защитить имидж бренда и дифференциацию рынка, а также предотвратить их использование другими лицами для создания путаницы.
Нераскрытые детали программирования, алгоритмы, структуры баз данных и т. д. являются коммерческой тайной. Компания должна защищать ее посредством соглашений о конфиденциальности, систем управления информацией и т. д.
Например, Закон о личной информации и Закон об управлении информационной безопасностью требуют от пользователей правильного обращения с личными данными и обеспечения информационной безопасности в процессе разработки программного обеспечения. За нарушения может грозить административная или уголовная ответственность.
Разработка программного обеспечения часто включает контрактные контракты, контракты на совместную разработку, условия лицензирования программного обеспечения и т. д., которые четко определяют права и обязанности обеих сторон, владение программным кодом, обязанности по обслуживанию, обязательства по конфиденциальности и т. д., чтобы избежать юридических споров.
Работа программного обеспечения в Интернете включает в себя сетевые услуги, электронные платежи, онлайн-защиту прав интеллектуальной собственности и т. д. и должна соответствовать таким нормам, как Закон об электронной подписи и Закон об электронных транзакциях.
Программный код подпадает под защиту авторских прав, и авторские права автоматически принадлежат разработчикам без дополнительной регистрации. Защита авторских прав распространяется на исходный код, файлы дизайна, руководства пользователя и т. д.
Если программное обеспечение связано с новизной и технологическими инновациями, можно подать заявку на патентную защиту. Примеры включают уникальные алгоритмы или методы решения технических проблем, но логика чистого кода обычно выходит за рамки патентной защиты.
Названия и логотипы программного обеспечения могут быть зарегистрированы в качестве товарных знаков, чтобы отличать продукты из разных источников и избежать путаницы на рынке.
Нераскрытые детали программирования, структуры баз данных и алгоритмы могут быть защищены коммерческой тайной. Ему необходимо полагаться на внутреннее соглашение компании о конфиденциальности и меры управления для его соблюдения.
Программное обеспечение может выпускаться с использованием различных моделей лицензирования, таких как проприетарное программное обеспечение, бесплатное программное обеспечение и лицензии с открытым исходным кодом (например, GPL, MIT). Различные модели лицензирования влияют на права пользователей на изменение и распространение.
Несанкционированное использование кода, изображений или алгоритмов другого лица может представлять собой нарушение авторских прав. Процесс разработки должен гарантировать, что источник программного кода является законным, чтобы избежать юридических споров.
Права интеллектуальной собственности являются территориальными, но могут получить определенную степень защиты во многих странах посредством международных договоров, таких как Бернская конвенция и Соглашение ТРИПС.
В 2026 году выбор правильной платформы для продажи программного обеспечения будет зависеть от типа вашего программного обеспечения и целевого рынка. Ниже приведены классификации и характеристики основных платформ:
| целевой показатель спроса | Рекомендуемая платформа | Основные преимущества |
|---|---|---|
| Автоматизируйте глобальную обработку налогов | Paddle / Lemon Squeezy | Избавьте себя от необходимости декларирования налогов в разных странах. |
| Стремитесь к максимальному трафику | Steam / App Store | Готовая огромная база пользователей |
| Быстро создайте официальный сайт бренда | Shopify / SHOPLINE | Персонализированный опыт покупок |
| Раннее привлечение пользователей | AppSumo | Быстро получайте деньги по акциям |
email: [email protected]