소프트웨어 개발



프로그래밍 언어

정의

프로그래밍 언어 (프로그래밍 언어)는 사람과 컴퓨터 사이의 다리입니다. 명령을 작성하고 컴퓨터 작동을 제어하며 다양한 응용 프로그램을 구현하는 데 사용됩니다.

분류

일반적인 프로그래밍 언어

언어를 선택할 때 고려해야 할 요소

프로그래밍 언어의 응용 분야

연구 제안



종합 프로그램 개발 링크 목록

  • Microsoft 기술 학습 센터/Microsoft Learn
  • vscode/Vidual Studio Code
  • 메타/페이스북 개발자
  • 크롬 개발자

    프로그래밍 언어 순위

    최신 프로그래밍 언어 순위에 따르면 2024년 상위 20개 프로그래밍 언어는 다음과 같습니다.



    람다 식

    1. 람다 표현식이란 무엇입니까?

    람다 식은 특히 작은 함수나 콜백을 전달해야 할 때 코드를 단순화하는 데 자주 사용되는 익명 함수입니다. 람다 표현식의 구문은 간결하며 함수 로직을 한 줄로 정의할 수 있습니다. 람다 표현식은 다음에서 가장 일반적으로 사용됩니다. C++, JavaScript, Python 및 C#과 같은 언어.

    2. 람다 표현식의 기본 구문

    람다 표현식의 기본 구문에는 일반적으로 매개변수, 화살표 기호가 포함됩니다.=>그리고 함수 본문은 다음과 같습니다.

    (매개변수) => 함수 본문

    정확한 구문은 언어마다 다릅니다. 예를 들면 다음과 같습니다.

    3. 다양한 언어의 람다 표현 예시

    C++ 예

    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    int main() {
        std::vector숫자 = {1, 2, 3, 4, 5};
    
        // 람다 식을 사용하여 짝수의 합을 계산합니다.
        정수 합계 = 0;
        std::for_each(numbers.begin(), number.end(), [&sum](int n) {
            if (n % 2 == 0) sum += n;
        });
    
        표준::cout << "짝수의 합: " << 합계 << 표준::endl;
        0을 반환합니다.
    }

    파이썬 예제

    # 람다 표현식을 사용하여 두 숫자의 합을 계산합니다.
    추가 = 람다 x, y: x + y
    print(add(5, 10)) # 출력: 15

    C# 예

    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    class Program {
        static void Main() {
            List numbers = new List{1, 2, 3, 4, 5 };
            
            // 람다 표현식을 사용하여 짝수를 필터링하고 합계를 계산합니다.
            int sum = 숫자.Where(n => n % 2 == 0).Sum();
            
            Console.WriteLine($"짝수의 합: {sum}");
        }
    }

    4. 람다 표현식의 적용 시나리오

    5. 장점과 단점



    Reflection

    개념

    리플렉션을 사용하면 프로그램이 실행 중에 유형(범주/구조), 속성, 필드, 메서드 및 주석(메타데이터)을 동적으로 검사하고 조작할 수 있습니다. 멤버를 읽고 쓰거나 메서드를 호출하기 위해 컴파일 타임에 정확한 유형을 알 필요는 없습니다.

    일반적인 용도

    장점과 단점

    언어 지원 현황

    전형적인 예

    # Python: 객체 속성 나열 및 읽기
    클래스 사용자:
        def __init__(self): self.id = 0; self.name = "앤"
    u = 사용자()
    vars(u).items()의 k, v에 대해:
        print(k, v) # id 0 / 이름 Ann
    // C#: 필드/속성을 가져오고 값을 읽습니다.
    시스템 사용;
    System.Reflection 사용;
    
    var t = typeof(MyType);
    foreach(t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic)의 var p)
        Console.WriteLine($"{p.Name}={p.GetValue(obj)}");
    // JavaScript: 동적 열거 및 호출
    const obj = { x: 1, y: 2, add(){ return this.x + this.y; } };
    for (Object.entries(obj)의 const [k,v]) console.log(k, v);
    console.log(obj["add"]()); // 3
    // Java: 리플렉션을 사용하여 필드 읽기/쓰기
    import java.lang.reflect.*;
    클래스 U { 개인 int ID = 42; }
    U u = 새로운 U();
    필드 f = U.class.getDeclaredField("id");
    f.setAccessible(true);
    System.out.println(f.getInt(u)); // 42
    // Go: 방문 구조 반영
    "반영" 가져오기
    func 덤프(v 모든) {
        발 := 반영.값의(v)
        나는 := 0; 나는 < val.NumField(); 나++ {
            이름 := val.Type().Field(i).이름
            fmt.Println(이름, val.Field(i).Interface())
        }
    }

    모범 사례

    피해야 할 때



    모든 구조가 모두 0인지 확인합니다.

    개념 요약

    언어 지원 비교

    언어지원하다설명하다
    Python동적, 완전 반사, 간편한 재귀 개체/컨테이너 검사.
    JavaScript / TypeScript객체는 키-값이며 사용 가능합니다.Object.values재귀.
    Rubyinstance_variables반성회원.
    PHPget_object_vars()아니면 반사.
    C# (.NET)Reflection은 필드/속성을 획득하며 유형 안전성이 우수합니다.
    Javajava.lang.reflect스캔 가능한 필드.
    KotlinJava와 유사하게 JVM 반영이 완료되었습니다.
    Goreflect구조체 필드에 액세스할 수 있습니다.
    SwiftMirror방문은 가능하지만 장면이 제한되어 추가적인 처리가 필요합니다.
    C++(C++23으로)런타임 반영이 없으므로 유형 검사를 수동으로 작성해야 합니다.
    Rust런타임 반영이 없으며 종종 파생/특성으로 구현됩니다.

    파이썬 예제

    def is_all_zero(obj, eps=1e-6):
        if isinstance(obj, (int, float)): # 기본 숫자 값
            반환 ABS(obj) < EPS
        elif isinstance(obj, (list, tuple, set)): # 시퀀스/세트
            obj의 x에 대해 all(is_all_zero(x, eps)를 반환합니다)
        elif isinstance(obj, dict): # 사전
            obj.values())의 v에 대해 all(is_all_zero(v, eps)를 반환합니다.
        elif hasattr(obj, "__dict__"): # 일반 객체
            vars(obj).values())의 v에 대해 all(is_all_zero(v, eps)를 반환합니다.
        그 외:
            거짓을 반환
    
    # 테스트
    수업 포인트:
        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]])) # 참
    print(is_all_zero(Line(Point(0,0),Point(0,0)))) # 참
    print(is_all_zero(Line(Point(1,0),Point(0,0)))) # 거짓

    자바스크립트 예시

    함수 isAllZero(obj, eps = 1e-6) {
      const isNumZero = n => Math.abs(n) < EPS;
      if (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에 따라 다름

    C#(.NET) 예

    시스템 사용;
    System.Linq 사용;
    System.Reflection 사용;
    
    공개 정적 클래스 ZeroCheck {
        공개 정적 bool IsAllZero(개체 obj, 이중 EPS = 1e-6) {
            if (obj == null) true를 반환합니다.
            스위치(obj) {
                케이스 int i: return i == 0;
                긴 경우 l: return l == 0;
                case float f: Math.Abs​​(f) <를 반환합니다. EPS;
                case double d: Math.Abs​​(d) <를 반환합니다. EPS;
            }
    
            var t = obj.GetType();
            if (t.IsArray)
                return ((Array)obj).Cast<object>().All(x => IsAllZero(x, eps));
    
            //필드 및 속성 스캔
            foreach(t.GetFields(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic)의 var f)
                if (!IsAllZero(f.GetValue(obj), eps)) return false;
    
            foreach(t.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic)의 var p)
                if (p.CanRead && !IsAllZero(p.GetValue(obj, null), eps)) return 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
        }
    }
    

    C++/Rust 제한 사항 및 사례

    실용적인 제안



    메시지 대기열

    정의 및 기능

    MQ(Message Queue)는 소프트웨어 시스템 간의 비동기 통신을 위한 아키텍처 패턴입니다. 이를 통해 독립적인 애플리케이션이나 서비스가 서로 직접 호출하거나 서로의 실시간 상태에 의존하지 않고도 메시지를 보내고 받음으로써 정보를 교환할 수 있습니다. MQ의 핵심 역할은 의도한 수신자가 메시지를 처리할 준비가 될 때까지 메시지를 임시로 저장하는 중간 계층 역할을 하는 것입니다.

    주요 구성품

    일반적인 메시지 패턴

    스키마 이름 설명하다 일반적인 애플리케이션 시나리오
    지점 간(P2P) 메시지는 대기열로 전송되며 **한 명의 수신자**만 해당 메시지를 대기열에서 꺼내어 메시지를 소비합니다. 일단 소비되면 메시지는 삭제됩니다. 주문 처리, 작업 파견 및 작업 부하 분산.
    게시/구독, 게시/구독 메시지는 주제에 게시되며 해당 주제를 구독하는 **모든** 수신자(구독자)는 메시지 사본을 받게 됩니다. 시스템 이벤트 방송, 로그 수집, 데이터 변경 알림.

    메시지 큐의 주요 이점

    결론

    메시지 대기열은 최신 분산 시스템, 마이크로서비스 아키텍처 및 고가용성 애플리케이션의 초석입니다. 시간과 공간에 간접적인 요소를 도입하여 시스템의 탄력성, 확장성 및 견고성을 크게 향상시킵니다.



    메시지 큐와 HTTP API

    통신 모드의 차이점

    특성 메시지 큐(MQ) HTTP API (REST/RPC)
    통신 유형 비동기식 동기식
    연결 낮은 결합(발신자와 수신자가 직접 상호 작용하지 않음) 높은 결합도(클라이언트는 서버의 주소를 알고 응답을 기다려야 함)
    데이터 흐름 단방향, 중간 Broker를 통과함 양방향, 요청 및 응답(요청-응답)
    내결함성 높음이면 브로커가 메시지를 저장하며 수신자가 오프라인인 경우에도 메시지가 손실되지 않습니다. 낮음 - 서버가 오프라인이거나 시간 초과되어 요청이 실패합니다.
    확장성 높음, 부하를 처리하기 위해 여러 소비자를 쉽게 추가할 수 있음 상대적으로 낮음(로드 밸런서에 의존하여 요청 분산)

    적용 상황 비교

    MQ(Message Queuing)의 장점 및 응용 시나리오

    HTTP API의 장점 및 적용 시나리오

    결론적으로

    MQ와 HTTP API는 대체 기술이 아니지만 다양한 문제를 위해 설계되었습니다.

    최신 분산 시스템에서는 두 가지 모드가 서로 공존하고 협력하여 서로 다른 비즈니스 요구 사항을 충족하는 경우가 많습니다.




    메시지 큐에 적합한 애플리케이션 예

    1. 비동기 작업 처리

    많은 네트워크 애플리케이션에서 일부 작업은 시간이 많이 걸리며 사용자가 동시에 기다리게 되면 사용자 경험이 저하됩니다. MQ를 사용하면 이러한 작업을 비동기식으로 실행할 수 있습니다.

    2. 트래픽 피크 감소 및 버퍼링

    MQ는 일시적인 트래픽이 많은 시나리오를 처리하는 데 중요하며 백엔드 서비스가 충돌하지 않도록 보호할 수 있습니다.

    3. 시스템 분리 및 마이크로서비스 통신

    복잡한 분산 시스템 및 마이크로서비스 아키텍처에서 MQ는 서비스를 격리하고 상호 의존성을 줄이는 데 사용됩니다.

    4. 로그 수집 및 모니터링

    프런트엔드 애플리케이션이나 서버에서 중앙 처리 시스템으로 대량의 로그 데이터를 수집합니다.

    5. 데이터 스트리밍 처리

    특히 Apache Kafka와 같은 처리량이 높은 MQ/스트리밍 플랫폼은 실시간 데이터의 연속 스트림을 처리하는 데 이상적입니다.



    HTTP API는 이미지와 비디오를 전송합니다.

    대규모 바이너리 데이터 전송의 과제

    이미지 및 비디오와 같은 대규모 바이너리 데이터(바이너리 데이터)를 전송하기 위해 HTTP API를 사용할 때의 주요 과제는 다음과 같습니다.

    사진/동영상을 업로드(보내기)하는 HTTP API 방법

    1. multipart/form-data 형식 사용(파일 업로드에 가장 일반적으로 사용됨)

    이는 브라우저나 클라이언트 애플리케이션이 파일을 업로드하는 가장 표준적이고 일반적인 방법입니다.

    2. 바이너리 본문을 직접 사용

    단일 파일만 업로드해야 하는 경우 파일의 바이너리 콘텐츠를 요청 제목으로 직접 사용할 수 있습니다.

    3. Base64 인코딩 사용(대용량 파일에는 권장되지 않음)

    바이너리 데이터를 ASCII 문자열로 변환하고 전송을 위해 JSON 또는 XML과 같은 텍스트 형식에 포함시킵니다.

    사진/비디오를 다운로드(수신)하는 HTTP API 방법

    바이너리 데이터를 다운로드하는 것은 비교적 간단합니다. 서버는 파일의 원본 바이너리 콘텐츠를 HTTP 응답 본문(응답 본문)으로 직접 반환합니다.

    영상 전송 최적화: 청크 전송 및 스트리밍

    특히 대용량 파일(특히 비디오)의 경우 신뢰성과 효율성을 향상시키기 위해 다음 기술을 권장합니다.



    스트리밍 핵심 기술

    1. 전송 프로토콜(프로토콜)

    스트리밍 전송의 핵심은 오디오 및 비디오 콘텐츠를 서버에서 클라이언트로 어떻게 효율적이고 안정적이며 짧은 지연 시간으로 전송하는가에 있습니다.

    2. 핵심기술 및 개념

    적응형 비트 전송률 스트리밍(ABR)

    이는 현대 스트리밍 서비스의 초석입니다. 서버는 동일한 비디오 콘텐츠를 다양한 품질(비트 전송률, 해상도)의 여러 버전으로 인코딩합니다.

    콘텐츠 전달 네트워크(CDN)

    글로벌 사용자를 대상으로 하는 스트리밍 서비스에는 CDN이 필수입니다.

    오디오 및 비디오 코덱(코덱)

    파일 크기를 줄이기 위해 오디오 및 비디오 데이터를 압축 및 압축 해제하는 데 사용됩니다.

    3. 콘텐츠 보호 및 수익화



    Shell

    Bash - $?

    배쉬에서는 $? 마지막으로 실행된 명령의 종료 상태 코드(Exit Status)를 나타냅니다. 일반적으로 이전 명령이 성공적으로 실행되었는지 여부를 확인하는 데 사용되는 정수 값입니다.

    종료 상태 코드의 의미

    예시 1: 성공적으로 실행된 명령 확인

    #!/bin/bash
    ㅋㅋㅋ
    echo "이전 명령의 종료 상태 코드는: $?"

    이 예에서는ls이 명령은 디렉터리 내용을 나열합니다. 성공적으로 실행한 후,$?값은 0이 됩니다.

    예시 2: 실패한 명령 확인

    #!/bin/bash
    ls /존재하지 않는 디렉터리
    echo "이전 명령의 종료 상태 코드는: $?"

    이 예에서는ls존재하지 않는 디렉터리를 나열하려고 하면 명령이 실패하게 됩니다.$?값은 0이 아닌 숫자가 됩니다.

    예시 3: 조건부 판단을 위한 종료 상태 코드 사용

    #!/bin/bash
    cp 파일1.txt /some/directory/
    만약 [ $? -eq 0]; 그럼
        echo "파일이 성공적으로 복사되었습니다."
    그렇지 않으면
        echo "파일 복사에 실패했습니다."
    fi

    이 예에서는 명령의 종료 상태에 따라 표시할 메시지를 결정합니다.



    배쉬 if

    기본 문법

    if [조건]; 그럼
        지침
    fi

    AND를 사용하세요.

    if 에서 여러 조건을 동시에 충족하려면 다음을 사용하세요.

    1. 사용-a(구식이지만 사용 가능)

    if [ "$a" -gt 0 -a "$b" -gt 0 ]; 그럼
        echo "a와 b는 모두 0보다 큽니다."
    fi

    2. 사용[[ ]] &&(추천하다)

    if [[ "$a" -gt 0 && "$b" -gt 0 ]]; 그럼
        echo "a와 b는 모두 0보다 큽니다."
    fi

    3. 여러 개의 if 조합을 ​​사용하세요&&

    if [ "$a" -gt 0 ] && [ "$b" -gt 0 ]; 그럼
        echo "a와 b는 모두 0보다 큽니다."
    fi

    또는 사용

    다음 조건 중 하나가 true인 경우 실행할 수 있습니다.

    1. 사용-o(구식이지만 사용 가능)

    if [ "$a" -eq 0 -o "$b" -eq 0 ]; 그럼
        echo "a 또는 b는 0입니다."
    fi

    2. 사용[[ ]] ||(추천하다)

    if [[ "$a" -eq 0 || "$b" -eq 0 ]]; 그럼
        echo "a 또는 b는 0입니다."
    fi

    3. 여러 개의 if 조합을 ​​사용하세요||

    if [ "$a" -eq 0 ] || [ "$b" -eq 0 ]; 그럼
        echo "a 또는 b는 0입니다."
    fi

    AND와 OR를 혼합하세요.

    우선 순위를 제어하기 위해 괄호와 함께 사용할 수 있습니다.

    if [[ ( "$a" -gt 0 && "$b" -gt 0 ) || "$c" -eq 1 ]]; 그럼
        echo "a와 b는 모두 0보다 크거나, c는 1과 같습니다."
    fi

    NOT의 일반적인 사용법

    배쉬에서는if지침은 일반적으로 다음과 쌍을 이룹니다.[ ](테스트 명령) 또는[[ ]](확장 테스트 명령)을 사용합니다. NOT을 표현하려면 느낌표를 사용하세요.!

    만약에 [ ! 상태 ]; 그럼
        # 조건이 거짓일 때 실행되는 코드
    fi

    1. 파일이나 디렉터리가 존재하는지 확인하세요.

    예를 들어, 파일이 "존재하지 않는" 경우 파일을 생성하는 것이 가장 일반적인 사용법입니다.

    # config.txt라는 파일이 존재하지 않는 경우
    만일 [ ! -f "config.txt" ]; 그럼
        echo "파일이 존재하지 않습니다. 생성 중입니다..."
        config.txt를 터치하세요.
    fi
    
    # 디렉토리가 존재하지 않는 경우
    만일 [ ! -d "/var/log/myapp" ]; 그럼
        mkdir -p "/var/log/myapp"
    fi

    2. 문자열 비교

    문자열이 "같지 않음" 또는 "비어 있지 않음"인지 확인하십시오.

    STR="안녕하세요"
    
    # 변수가 "world"와 같지 않은지 확인합니다.
    if [ "$STR" != "세계" ]; 그럼
        echo "문자열이 일치하지 않습니다"
    fi
    
    # 문자열이 비어 있지 않은지 확인합니다(! -z는 -n과 동일합니다)
    만일 [ ! -z "$STR" ]; 그럼
        echo "변수에 데이터가 있습니다."
    fi

    3. 수치비교

    수치는 상대적이지만-ne(같지 않음) 그러나 일치할 수도 있음!사용.

    숫자=10
    
    만일 [ ! "$NUM" -eq 20 ]; 그럼
        echo "숫자가 20이 아닙니다."
    fi

    조건부 논리 비교표

    연산자 설명하다
    ! -f 파일이 존재하지 않습니다 [ ! -f file ]
    ! -d 디렉토리가 존재하지 않습니다 [ ! -d dir ]
    != 문자열이 다음과 같지 않습니다. [ "$a" != "$b" ]
    ! -z 문자열이 비어 있지 않습니다. [ ! -z "$str" ]
    -ne 값이 다음과 같지 않습니다. [ "$n" -ne 5 ]

    이중 괄호 [[ ]] 사용의 장점

    보다 현대적인 Bash 스크립트에서는 다음을 사용하는 것이 좋습니다.[[ ]], 처리 중입니다.!로직과 결합하면 더욱 강력해지고 오류 발생 가능성은 줄어듭니다.

    # 여러 조건 결합: 디렉터리가 아니고 읽을 수 없는 경우
    만약 [[ ! -d $경로 && ! -r $경로 ]]; 그럼
        echo "잘못된 경로이거나 권한이 부족합니다."
    fi

    주의할 점



    Bash 조건부 분기

    기본 문법 구조

    case구문은 변수의 값을 여러 패턴(패턴)과 비교하는 데 사용되며, 그 기능은 다른 언어와 유사합니다.switch. 문법적 구조는 다음과 같습니다.

    케이스 변수
        모드 1)
            # 명령을 실행
            ;;
        모드 2)
            # 명령을 실행
            ;;
        *)
            # 기본 실행 명령(기본값과 유사)
            ;;
    에삭

    일반적인 사용 예

    1. 간단한 메뉴 판단

    이는 사용자 입력에 따라 다양한 작업을 수행하는 가장 일반적인 사용법입니다.

    read -p "입력하세요(예/아니요): " 입력
    
    "$input"의 경우
        "예")
            echo "예를 선택하셨습니다"
            ;;
        "아니요")
            echo "아니요를 선택하셨나요?"
            ;;
        *)
            echo "입력 오류"
            ;;
    에삭

    2. 여러 패턴 결합(OR)

    사용|기호를 사용하면 여러 모드에서 동일한 명령 블록을 실행할 수 있습니다.

    read -p "월 약어를 입력하세요: " Month
    
    "$month"의 경우
        1월|2월|3월)
            에코 "시즌 1"
            ;;
        4월|5월|6월)
            에코 "시즌 2"
            ;;
        *)
            "다른 달"을 에코하세요.
            ;;
    에삭

    3. 와일드카드 사용

    패턴 비교는 파일 경로와 같은 확장 기호를 지원합니다(예:*, ?, [a-z])。

    read -p "문자를 입력하세요: " char
    
    케이스 "$char" in
        [a-z])
            echo "소문자입니다"
            ;;
        [AZ])
            echo "대문자입니다"
            ;;
        [0-9])
            echo "이것은 숫자입니다"
            ;;
        *)
            echo "특수 기호이거나 여러 문자입니다."
            ;;
    에삭

    주요 기호 설명

    상징 기능 설명
    ) 패턴의 종료 태그입니다.
    ;; 명령 블록의 끝 표시(와 유사)break)。
    * 일반적으로 기본 옵션으로 마지막에 배치되는 문자열을 비교합니다.
    | 여러 일치 패턴("또는"을 나타냄)을 구분하는 데 사용됩니다.
    esac case철자를 거꾸로 쓰면 문법 블록의 끝을 나타냅니다.

    사용상의주의 사항

    대소문자 구분

    기본 동작: 대소문자를 구분합니다. 표준 Bash 환경에서는case성명서는대소문자 구분의. 즉, "A"와 "a"는 서로 다른 패턴으로 처리됩니다.

    read -p "문자를 입력하세요: " char
    케이스 "$char" in
        a) echo "이것은 소문자 a입니다." ;;
        A) echo "대문자 A입니다" ;;
    에삭
    ---

    방법 1: nocasematch 옵션 사용

    전체를 원하신다면case이 명령문은 대소문자를 무시하고 사용할 수 있습니다.shopt명령 활성화됨nocasematch설정. 이는 이후의 모든 문자열 비교에 영향을 미치며case판사.

    # 대소문자 무시 활성화
    shopt -s nocasematch
    
    read -p "yes 또는 YES를 입력하세요: " 입력
    "$input"의 경우
        예) echo "일치 성공(대소문자 무시)" ;;
    에삭
    
    # 대소문자 무시 끄기(기본값 복원)
    shopt -u nocasematch
    ---

    방법 2: 패턴의 범위를 수동으로 지정

    전역 설정을 변경하지 않으려면 스키마에서 직접 사례 범위를 정의하는 것이 가장 표준적이고 일관된 접근 방식입니다.

    read -p "문자를 입력하세요: " char
    케이스 "$char" in
        [aA])
            echo "a 또는 A를 입력하셨습니다."
            ;;
        [b-zB-Z])
            echo "추가 문자를 입력하셨습니다"
            ;;
    에삭
    ---

    방법 3: 파이프 기호 결합(OR)

    특정 단어의 경우 다음을 사용할 수 있습니다.|가능한 모든 철자를 나열합니다.

    "$input"의 경우
        중지|중지|중지)
            echo "실행 중지"
            ;;
    에삭
    ---

    설정 방법 비교

    방법 이점 결점
    shopt -s nocasematch 프로그램 코드는 간결하며 대규모 비교에 적합합니다. 이는 전체 스크립트의 동작에 영향을 미치므로 수동으로 끄는 것을 잊지 마십시오.
    [a-zA-Z]범위 다른 부분에 영향을 주지 않고 정밀하게 제어할 수 있습니다. 말이 너무 길면 글쓰기가 매우 번거로워질 것입니다.
    파이프 캐릭터| 특정 몇 단어에 적합한 높은 가독성. 임의의 대소문자 조합(예: Yes)을 처리할 수 없습니다.


    Bash 작업 우선 순위

    (( )) 안에 괄호를 사용하세요.

    Bash의 산술 확장(( ))내부적으로는 괄호만 사용할 수 있습니다.( )C 또는 대부분의 프로그래밍 언어의 논리와 일치하여 작업의 우선 순위를 명시적으로 지정합니다. 이는 복잡한 논리(AND, OR, 덧셈, 뺄셈, 곱셈 및 나눗셈 결합)를 처리할 때 매우 중요합니다.

    # 예: (A와 B) 또는 C
    if (( (MIN > 91 && MIN< 110) || FORCE_MODE == 1 )); then
        echo "條件成立"
    fi

    우선순위 규칙

    존재하다(( ))내부에서 작업의 우선 순위는 표준 수학적 및 논리적 규칙을 따릅니다.

    1. 괄호 안의 항목: ( )가장 높은 우선순위.
    2. 곱셈과 나눗셈: *, /, %
    3. 덧셈과 뺄셈: +, -
    4. 비교 작업: <, >, <=, >=
    5. 논리 연산: &&(AND)가 우선합니다.|| (OR)。

    복잡한 조건 예

    값이 범위 내에 있어야 하고 (특정 배수이거나 강제 모드여야 함) 다음을 결정해야 한다고 가정합니다.

    if (( MIN > 91 && (MIN % 5 == 0 || FORCE_MODE == 1) )); 그럼
        {
            echo "복합 조건부 판단 트리거"
            IS_SHUTDOWN=참
        } |& tee -a "$LOGFILE"
    fi

    비교 및 권장 사항

    구문 유형 그룹화 기호 주의할 점
    (( ... )) ( ) 가장 직관적인 기호는 이스케이프할 필요가 없으며 순수한 수치 연산에 권장됩니다.
    [[ ... ]] ( ) 존재하다[[ ]]논리적 그룹화를 위해 안에 괄호를 사용하는 것도 합법적입니다.
    [ ... ] \( ... \) 전통test구문, 대괄호는 백슬래시로 이스케이프해야 하며 이는 권장되지 않습니다.


    Bash 종료 사용법

    종료 명령 및 상태 코드

    Bash 스크립트에서는exit스크립트 실행을 종료하고 상태 코드(종료 상태)를 상위 프로그램에 반환하는 데 사용됩니다.

    if [ -f "config.txt" ]; 그럼
        echo "파일이 존재합니다"
        0번 출구
    그렇지 않으면
        echo "오류: 프로필을 찾을 수 없습니다"
        1번 출구
    fi

    종료 상태 코드 받기

    스크립트나 명령어를 실행한 후 특수 변수를 사용할 수 있습니다.$?이전 프로그램을 얻으려면exit상태 코드.

    ./script.sh
    echo "스크립트 종료 상태: $?"

    백틱`` 또는 $()를 사용하여 출력 값을 가져옵니다.

    당신이 전화할 때.sh파일의 "내용을 출력"하고 싶습니다(예:echo변수의 내용을 저장할 때 백틱이나 백틱을 사용할 수 있습니다.$(). 이를 명령 대체라고 합니다.

    샘플 스크립트(get_name.sh)

    #!/bin/bash
    # 이것은 출력 내용이며 캡처됩니다.
    에코 "Ubuntu_User"
    # 이것이 최종 상태이며 백틱으로 캡처되지 않습니다.
    0번 출구

    다른 스크립트 또는 터미널에서 호출

    # 역따옴표를 사용하세요
    결과=`./get_name.sh`
    
    # $() 사용(현대적인 글쓰기 권장)
    결과=$(./get_name.sh)
    
    echo "얻은 결과는 다음과 같습니다: $RESULT"

    중요한 차이점: 반환 값과 출력 내용

    목표 획득 방법 사용
    종료 상태(상태 코드) $? 명령 실행이 성공했는지(0 또는 1) 확인합니다.
    표준 출력(출력 내용) ` `또는$( ) 스크립트가 실행된 후 생성된 문자열 데이터를 가져옵니다.

    두 가지를 동시에 얻으려면 다음 예를 참조하세요.

    출력=$(./script.sh)
    상태=$?
    
    echo "내용은: $OUTPUT"
    echo "상태 코드는: $STATUS"


    Bash 반환 사용법

    수익의 기본 정의

    배쉬에서는return지침은 특별히 다음과 같은 용도로 사용됩니다.기능또는 통해source실행할 스크립트입니다. 현재 함수나 스크립트의 실행을 중지하고 지정된 상태 코드를 호출자에게 반환하지만 현재 쉘 프로그램을 닫지는 않습니다.

    1. 함수 내에서 return을 사용하세요.

    이것이 가장 일반적인 사용법입니다.return반환되는 것은 문자열 데이터가 아닌 상태 코드(0-255)입니다.

    샘플 스크립트(func_test.sh)

    #!/bin/bash
    
    # 함수 정의
    check_file() {
        if [ -f "$1" ]; 그럼
            0을 반환 # 성공
        그렇지 않으면
            1을 반환 # 실패
        fi
    }
    
    # 통화 기능
    check_file "test.txt"
    결과=$?
    
    if [ $RESULT -eq 0 ]; 그럼
        echo "파일이 존재합니다"
    그렇지 않으면
        echo "파일이 존재하지 않습니다"
    fi

    2. .sh 파일에서 return(소스 포함)을 사용합니다.

    스크립트가 실행된 후 변수와 환경을 현재 터미널에 유지하려면 일반적으로 다음을 사용합니다.source. 이때 꼭 써먹어야 할return오히려exit

    수신자(sub_script.sh)

    # 논리적 판단을 시뮬레이션
    if [ "$USER" != "루트" ]; 그럼
        echo "권한이 부족합니다. 루트 사용자에게만 해당됩니다."
        # 종료를 사용하면 터미널이 바로 닫힙니다. return을 사용하면 이 스크립트의 실행만 중지됩니다.
        1을 반환
    fi
    
    내보내기 APP_STATUS="준비"
    0을 반환

    호출자(CMD 또는 다른 스크립트에서 직접)

    소스 ./sub_script.sh
    echo "스크립트가 상태를 반환합니다: $?"
    echo "환경 변수 가져오기: $APP_STATUS"

    3. 반환 메커니즘을 통해 "반환 값"을 얻는 방법

    왜냐하면return숫자(상태 코드)만 반환될 수 있습니다. 문자열이나 대량의 데이터를 얻으려면 결합하는 것이 좋습니다.echo그리고명령 대체

    수신자(get_data.sh)

    #!/bin/bash
    계산() {
        로컬 값=$(( $1 + $2 ))
        # 결과를 stdout으로 출력
        에코 "$val"
        # 실행 상태 코드를 반환합니다.
        0을 반환
    }
    
    10 20을 계산하다

    방문객

    # 출력 내용을 가져옵니다
    데이터=$(./get_data.sh)
    # 반품 상태 코드를 가져옵니다.
    상태=$?
    
    echo "계산 결과는 $DATA입니다."
    echo "실행 상태: $STATUS"

    사용법 요약 및 비교

    키워드 적용 범위 메인 프로그램에 미치는 영향
    exit 0/1 독립적인 스크립트 및 서브루틴 전체 현재 셸을 종료합니다(소스로 실행되는 경우).
    return 0/1 함수, 소스 스크립트 로드됨 현재 범위만 종료하고 기본 프로그램 셸에는 영향을 주지 않습니다.
    echo "..." 어딘가에 실제 "데이터 콘텐츠"를 호출자에게 전달하는 데 사용됩니다.


    변수가 비어 있는지 Bash 확인

    Bash에서는 조건부 판단을 사용하여 변수가 비어 있는지 확인할 수 있습니다. 다음은 몇 가지 일반적인 방법입니다.

    예 1: 사용-z변수가 비어 있는지 확인

    #!/bin/bash
    
    var=""
    if [ -z "$var" ]; 그럼
        echo "변수가 비어있습니다."
    그렇지 않으면
        echo "변수가 비어있지 않습니다."
    fi

    -z변수가 비어 있는지 확인하는 데 사용됩니다. 변수가 비어 있으면 조건은 true입니다.

    예 2: 사용-n변수가 비어 있지 않은지 확인하십시오.

    #!/bin/bash
    
    var="일부 값"
    if [ -n "$var" ]; 그럼
        echo "변수가 비어있지 않습니다."
    그렇지 않으면
        echo "변수가 비어있습니다."
    fi

    -n변수가 비어 있지 않은지 확인하는 데 사용됩니다. 변수에 값이 있으면 조건은 true입니다.

    예 3: 큰따옴표 비교를 사용하여 변수가 비어 있는지 확인

    #!/bin/bash
    
    var=""
    if [ "$var" == "" ]; 그럼
        echo "변수가 비어있습니다."
    그렇지 않으면
        echo "변수가 비어있지 않습니다."
    fi

    이 방법은 변수를 빈 문자열과 직접 비교하여 변수가 비어 있는지 확인합니다.



    Bash의 배열 구조

    소개

    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

    연관 배열

    정의 및 사용법(Bash 4+ 필요)

    declare -A capital
    capital["Taiwan"]="Taipei"
    capital["Japan"]="Tokyo"

    접근 및 통과

    echo "${capital["일본"]}" # 도쿄
    
    "${!capital[@]}"의 키에 대해; 하다
        echo "$key의 대문자는 ${capital[$key]}입니다."
    완료

    주의할 점

    결론적으로

    Bash 배열은 여러 데이터 조각을 저장하는 중요한 구조로, 매개변수 목록, 디렉터리 집합, 키-값 쌍 등의 데이터 처리에 적합합니다.



    Bash는 두 배열을 병합합니다.

    기본 문법

    combined=("${array1[@]}" "${array2[@]}")

    이렇게 하면 두 배열의 모든 요소가 새 배열로 병합됩니다.combined

    완전한 예

    array1=("사과" "바나나")
    array2=("체리" "날짜")
    
    결합=("${array1[@]}" "${array2[@]}")
    
    echo "결합된 배열:"
    "${combined[@]}" 항목의 경우; 하다
        에코 "$ 항목"
    완료

    원래 배열로 병합

    array1+=("${array2[@]}")

    이것은array2콘텐츠가 직접 추가됩니다.array1뒤쪽.

    주의할 점



    Bash는 문자열이 특정 단어로 시작하는지 확인합니다.

    문자열 패턴 비교 사용(권장)

    str="안녕하세요 세상"
    
    if [[ "$str" == 안녕하세요* ]]; 그럼
        echo "문자열은 hello로 시작합니다"
    fi

    설명하다:사용[[ ]]쉘 패턴 비교 지원,*모든 문자를 나타냅니다.

    정규 표현식 사용

    if [[ "$str" =~ ^hello ]]; 그럼
        echo "문자열은 hello로 시작합니다"
    fi

    설명하다: ^시작을 나타냅니다.[[ ]]~에=~정규작업입니다.

    사용case말하다

    케이스 "$str" in
      hello*) echo "hello로 시작하는 문자열" ;;
      *) echo "hello로 시작하지 않습니다" ;;
    에삭

    설명하다: case간결하고 가독성이 높은 문자열 패턴을 처리하는 데 좋은 도구입니다.

    사용expr(오래된 글쓰기 스타일)

    if expr "$str" : '^hello' &> /dev/null; 그럼
        echo "문자열은 hello로 시작합니다"
    fi

    설명하다:사용expr이전 버전의 셸에 적합한 일반 일치 기능입니다.

    주의할 점



    Bash는 파일이나 디렉토리가 존재하는지 확인합니다.

    존재 여부를 확인합니다.-e

    -e유형에 관계없이 파일이나 디렉터리가 존재하는지 확인하는 데 사용됩니다.

    파일="/etc/passwd"
    
    if [ -e "$FILE" ]; 그럼
        echo "$FILE이 존재합니다"
    그렇지 않으면
        echo "$FILE이 존재하지 않습니다"
    fi

    디렉터리가 존재하지 않는지 확인합니다.! -d

    -d디렉토리인지 확인하는데 사용되며,!부정적인 작업입니다.

    디렉터리="/tmp/내폴더"
    
    만일 [ ! -d "$DIR" ]; 그럼
        echo "$DIR이 존재하지 않습니다. 생성 중입니다..."
        mkdir -p "$DIR"
    그렇지 않으면
        echo "$DIR이 이미 존재합니다"
    fi

    기타 일반적으로 사용되는 조건 옵션

    예: 검사와 생성 결합

    PATH_TO_CHECK="/홈/사용자/구성"
    
    if [ -e "$PATH_TO_CHECK" ]; 그럼
        echo "$PATH_TO_CHECK가 이미 존재합니다"
    그렇지 않으면
        echo "$PATH_TO_CHECK가 존재하지 않으며 생성 중입니다..."
        mkdir -p "$PATH_TO_CHECK"
    fi

    제안



    모든 하위 디렉터리를 나열하고 배열에 저장합니다.

    예: 어레이에 저장

    target_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)

    설명하다

    예제 출력

    for dir in "${subdirs[@]}"; do
        echo "$dir"
    done

    대체 간단한 글쓰기(특수문자가 없는 경우)

    subdirs=( "$target_dir"/*/ )
    

    이 작성 방법은 와일드카드를 사용하여 하위 디렉터리를 일치시키지만 파일을 제외하거나 공백 및 특수 문자를 처리할 수는 없습니다.



    ~를 포함하는 실제 경로를 가져옵니다.

    방법 1: eval을 사용하여 확장

    path="~/myfolder/file.txt"
    realpath "$(eval echo "$path")"
    

    방법 2: $HOME으로 바꾸기

    path="~/myfolder/file.txt"
    realpath "$(echo "$path" | sed "s|^~|$HOME|")"
    

    방법 3: 읽기 링크 사용

    path="~/myfolder/file.txt"
    readlink -f "$(eval echo "$path")"
    

    권장 사용법

    realpath "$(eval echo "$path")"
    


    grep

    기본 검색

    grep "키워드" 파일 이름

    대소문자 무시

    grep -i "키워드" 파일 이름

    줄 번호 표시

    grep -n "키워드" 파일 이름

    재귀 검색

    grep -r "키워드" 디렉토리 경로

    일치하는 텍스트만 표시

    grep -o "키워드" 파일 이름

    파일 이름도 표시

    grep -H "키워드" 파일 이름

    두 세트의 키워드가 함께 나타납니다(AND).

    grep "키워드 1" 파일 이름 | grep "키워드 2"

    두 키워드 중 하나가 나타남(OR)

    #방법 1: 정규식
    grep -E "키워드 1 | 키워드 2" 파일 이름
    
    #방법 2: 여러 -e 매개변수
    grep -e "키워드 1" -e "키워드 2" 파일 이름

    바이너리 파일 일치 문제 해결

    #방법 1: 파일을 강제로 텍스트로 처리합니다.
    grep -a "키워드" 파일 이름
    
    #방법2: 파일 인코딩을 UTF-8로 변환 후 검색
    iconv -f 원래 인코딩 -t UTF-8 파일 이름 | grep "키워드"
    
    # 예(BIG5에서 UTF-8로 변환)
    iconv -f BIG5 -t UTF-8 파일 이름 | grep "키워드"

    일반적인 조합

    grep -rin "키워드" 디렉토리 경로


    -d $'\0' 읽기로 -print0

    사용 지침

    공백이나 특수 기호(예: 공백, 따옴표, 줄 바꿈)가 포함된 파일 이름이나 경로를 처리할 때 기존의find유통라인xargs또는read오판이 발생할 수 있습니다.

    -print0허용 가능findnull(\0) 문자를 출력 구분 기호로 사용하고,read -d $'\0'각 파일/경로를 정확하게 구분하기 위해 Null로 구분된 콘텐츠를 정확하게 읽을 수 있습니다.

    기본 예: 모든 하위 디렉터리 수집

    subdirs=()
    while IFS= read -r -d $'\0' dir; do
        subdirs+=("$dir")
    done < <(find . -type d -print0)

    설명하다

    예 1: 모든 .txt 파일의 절대 경로 나열

    txt_files=()
    while IFS= read -r -d $'\0' file; do
        txt_files+=("$file")
    done < <(find "$(pwd)" -type f -name "*.txt" -print0)

    예 2: 처리를 위해 명령으로 파일 보내기(보안)

    찾다 . -유형 f -print0 | IFS= 읽기 -r -d $'\0' 파일; 하다
        echo "처리 중: $file"
        # your_command "$file"
    완료

    예시 3: 공백이 포함된 디렉터리만 처리

    찾다 . -유형 d -print0 | IFS= read -r -d $'\0' dir; 하다
        if [[ "$dir" == *" "* ]]; 그럼
            echo "공백이 포함된 디렉터리: $dir"
        fi
    완료

    줄 바꿈을 사용하지 않는 이유는 무엇입니까?

    전통적인 사용법은 다음과 같습니다.

    find . -type f | while read file; do ...

    그러나 파일 이름에 개행 문자가 포함되어 있으면read구문 분석이 잘못되어 여러 줄이라도 여러 파일로 잘못 판단됩니다.

    결론적으로



    읽기 전용에서는 하나의 디렉토리 문제가 발생합니다.

    문제 진술

    일부 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` 無法持續讀取。

    수정: `read -d ''`(또는 `readarray -d`)와 함께 파이프라인을 사용하세요.

    방법 1: `찾기 | while` 파이프라인 조합-print0

    subdirs=()
    find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0 | while IFS= read -r -d $'\0' dir; do
        subdirs+=("$dir")
    done

    **참고**: 메인 프로그램에서 `subdirs`를 사용하려면 이 방법이 적합하지 않습니다(`while ... |` 하위 쉘이 배열을 반환할 수 없기 때문입니다).

    방법 2: 배열로 변경하고 다시 처리

    mapfile -d '' -t subdirs < <(find "$target_dir" -mindepth 1 -maxdepth 1 -type d -print0)

    mapfile(또는readarray)은 null로 구분된 문자열을 배열로 올바르게 읽을 수 있습니다.
    이것이 메인 쉘에 보관하는 가장 안정적인 방법입니다.

    예제 출력

    "${subdirs[@]}"의 dir에 대해; 하다
        echo "찾은 디렉터리: $dir"
    완료

    요약



    변수 내용에서 데이터 읽기(읽기 사용)

    변수에 여러 줄의 텍스트가 있다고 가정합니다.

    var="line1
    line2
    line3"

    한 줄씩 읽으려면 읽는 동안 사용하세요.

    IFS= 읽기 -r 라인 동안; 하다
        echo "읽기: $line"
    완료 <<< "$var"

    해설

    한 줄 읽기

    읽기 -r first_line <<< "$var"
    echo "첫 번째 줄: $first_line"

    배열로 읽기

    readarray -t lines <<< "$var"
    for line in "${lines[@]}"; do
        echo "$line"
    done


    문자열에서 시작하는 디렉토리를 찾고 날짜순으로 정렬

    전체 지침(디렉터리 수정 시간별로 정렬)

    find . -mindepth 1 -maxdepth 1 -type d -name "abc*" -printf "%T@ %p\n" | sort -nr | cut -d' ' -f2-

    설명하다

    예제 출력

    ./abc_latest
    ./abc_old
    ./abc_2020

    Bash 배열에 저장해야 하는 경우

    readarray -t abc_dirs << <(
      . -minlength 1 -max깊이 1 -type d -name "abc*" -printf "%T@ %p\n" |
      정렬 -nr | 잘라내기 -d' ' -f2-
    )
    
    "${abc_dirs[@]}"의 dir에 대해; 하다
      echo "발견: $dir"
    완료

    메모



    Bash는 저장 장치가 쓰기 가능한지 확인합니다.

    방법 1: 디렉터리에 쓰기 권한이 있는지 확인

    디렉터리="/mnt/usb"
    
    if [ -w "$DIR" ]; 그럼
        echo "$DIR은 쓰기 가능합니다"
    그렇지 않으면
        echo "$DIR에는 쓸 수 없습니다"
    fi

    -w디렉토리에 "쓰기 권한"이 있는지 확인합니다. 그러나 디렉터리 자체는 쓰기 가능하지만 실제 장치는 읽기 전용인 경우(예: 마운트가 읽기 전용인 경우) 이 방법이 작동하지 않을 수 있습니다.

    방법 2: 실제로 테스트 파일에 쓰기를 시도합니다.

    디렉터리="/mnt/usb"
    TESTFILE="$DIR/.write_test"
    
    "$TESTFILE" 2>/dev/null을 터치하면; 그럼
        echo "$DIR은 쓰기 가능합니다"
        rm "$TESTFILE"
    그렇지 않으면
        echo "$DIR에는 쓸 수 없습니다"
    fi

    이 방법은 가장 안정적이며 마운트 상태 또는 물리적 장치가 실제로 쓰기 가능한지 여부를 감지할 수 있습니다.

    방법 3: 사용mount마운트가 읽기 전용인지 확인하는 명령

    MNT="/mnt/usb"
    
    마운트하는 경우 | grep "$MNT" | grep -q "(ro,"; 그런 다음
        echo "$MNT는 읽기 전용으로 마운트되었습니다"
    그렇지 않으면
        echo "$MNT는 쓰기 가능한 마운트입니다"
    fi

    이 메서드는 장치가 읽기 전용인지 확인해야 합니다(ro) 방법.

    제안



    쉘 리디렉션 사용 지침

    1. 표준 출력 리디렉션: `>`

    셸에서 `>`를 사용하여 명령의 표준 출력(stdout)을 파일이나 장치로 리디렉션합니다. 파일이 이미 존재하는 경우 내용을 덮어씁니다.

    echo "Hello" > output.txt

    이 지침은"Hello"쓰다output.txt파일.

    2. 출력 리디렉션 추가: `>>`

    `>>`를 사용하면 원본 내용을 덮어쓰지 않고 지정된 파일 끝에 표준 출력이 추가됩니다.

    echo "Hello again" >> output.txt

    이 명령줄은"Hello again"에 추가하다output.txt끝.

    3. 표준 오류 리디렉션: `2>`

    셸에서 `2>`는 표준 오류(stderr)를 지정된 위치로 리디렉션하는 데 사용됩니다. 예를 들어:

    ls non_existent_file 2> error.log

    이 명령줄은 오류 메시지를 다음에 기록합니다.error.log파일.

    4. 오류 리디렉션 추가: `2>>`

    오류 메시지 파일을 덮어쓰지 않으려면 `2>>`를 사용하여 파일 끝에 오류 메시지를 추가할 수 있습니다.

    ls non_existent_file 2>> error.log

    이 명령줄은 다음에 오류 메시지를 추가합니다.error.log

    5. 표준 출력과 오류를 동시에 리디렉션: `&>`

    표준 출력과 표준 오류를 동일한 파일이나 장치로 리디렉션하려면 `&>`를 사용하세요.

    command &> all_output.log

    이 명령줄은command모든 출력(표준 출력 및 오류)은 다음 위치에 기록됩니다.all_output.log

    6. 표준 오류를 표준 출력에 병합합니다: `2>&1`

    `2>&1`은 표준 오류를 표준 출력에 병합하여 통합 관리를 용이하게 합니다. 예를 들어:

    command > output.log 2>&1

    이 명령줄은 표준 출력과 오류 모두에 기록됩니다.output.log

    7. 모든 출력을 비활성화합니다: `>/dev/null 2>&1`

    출력을 표시하지 않으려면 모든 출력을 다음으로 지정할 수 있습니다./dev/null,좋다:

    command >/dev/null 2>&1

    이 명령줄은command모든 출력이 삭제됩니다.



    UTF-8 인코딩 파일 변환 및 출력

    사용 중tee명령이 출력을 파일에 추가하면 다음을 전달할 수 있습니다.iconv출력을 UTF-8 인코딩으로 변환하여 파일 내용이 UTF-8로 저장되도록 합니다. 다음은 구체적인 지침과 예시입니다.

    명령 형식

    다음은 출력을 UTF-8 인코딩으로 저장합니다.tee지시 형식:

    command | iconv -t utf-8 | tee -a output.txt

    다음 예에서는 다음 방법을 보여줍니다.ls명령의 출력은 UTF-8 인코딩으로 기록됩니다.output.txt

    ls | iconv -t utf-8 | tee -a output.txt

    이 명령을 실행한 후,output.txt인코딩 오류를 방지하기 위해 콘텐츠는 UTF-8 인코딩으로 저장됩니다.



    Windows cmd

    개폐방식

    일반적인 명령

    고급 작업

    관리자 모드



    cmd /k 다음에 두 번째 명령을 실행합니다.

    동일한 창에서 여러 명령 실행

    사용될 수 있다&&&또는||지침을 계속하려면:

    cmd /k "첫 번째 명령 및 두 번째 명령"

    다른 배치 파일 호출

    첫 번째 명령어 뒤에 추가call, 다른 배치 파일을 계속 실행할 수 있습니다.

    cmd /k "첫 번째 명령 및 second.bat 호출"

    실행 후 /c를 사용하여 닫습니다.

    창을 열어 둘 필요가 없다면 다음을 사용할 수 있습니다./c

    cmd /c "첫 번째 명령 및 두 번째 명령"

    /c모든 명령을 실행한 후 자동으로 창을 닫습니다./k창은 그대로 유지됩니다.



    CMD 변수

    CMD 변수란 무엇입니까?

    Windows 명령 프롬프트(CMD)에서 변수는 데이터나 설정을 저장하는 데 사용되는 네임스페이스입니다. 환경(환경 변수)에 저장하거나 배치 파일(지역 변수)에서 정의하여 사용할 수 있습니다.

    변수 유형

    변수를 사용하는 방법

    변수 값 읽기

    변수 값을 얻으려면 일반적으로 변수 이름 앞과 뒤에 백분율 기호를 추가해야 합니다.%

    NAME=CMD 사용자 설정
    echo 내 이름은 %NAME%입니다.

    산출:내 이름은 CMD 사용자입니다

    배치 파일에서 지역 변수 설정

    @에코 꺼짐
    set MESSAGE=이것은 배치 메시지입니다
    에코%메시지%
    일시 중지

    변수를 설정하지만 변수가 존재하지 않는 경우에만 해당

    당신은 사용할 수 있습니다IF DEFINED또는IF NOT DEFINED변수가 이미 존재하는지 또는 정의되었는지(비어 있지 않은지) 확인하는 문입니다.

    @에코 꺼짐
    
    rem은 MY_DEFAULT_VALUE 변수가 정의되었는지(비어 있지 않은지) 확인합니다.
    MY_DEFAULT_VALUE가 정의되지 않은 경우(
        MY_DEFAULT_VALUE=Default_Setting 설정
        에코 변수 MY_DEFAULT_VALUE는 정의되지 않았으며 기본값으로 설정되었습니다.
    ) 기타(
        에코 변수 MY_DEFAULT_VALUE가 이미 존재합니다. 값은 %MY_DEFAULT_VALUE%입니다.
    )
    
    rem이 한 번 실행되면 변수는 Default_Setting으로 설정됩니다.
    rem을 다시 실행하면 이미 존재한다고 표시됩니다.
    
    MY_DEFAULT_VALUE=Existing_Setting 설정
    
    다시 확인해봐
    MY_DEFAULT_VALUE가 정의되지 않은 경우(
        MY_DEFAULT_VALUE=Another_Default 설정
        에코 변수 MY_DEFAULT_VALUE가 정의되지 않았으며 Another_Default로 설정되었습니다.
    ) 기타(
        에코 변수 MY_DEFAULT_VALUE가 이미 존재합니다. 값은 %MY_DEFAULT_VALUE%입니다.
    )
    
    일시 중지

    또 다른 멋진 트릭은 변수 증대의 기본값 기능을 활용하는 것입니다(그러나 이는 주로 루프 및 매개변수 처리에 사용되며 표준에서는set"설정되지 않은 경우 설정" 논리는 명령에 직접 적용할 수 없습니다. 그러므로,IF NOT DEFINED이것이 가장 표준적인 접근 방식입니다. )

    지연된 환경 변수 확장 활성화(Delayed Expansion)

    루프 또는 조건문에서 표준 백분율 기호 변수 확장은 명령문 구문 분석 중에 한 번 발생합니다. 루프가 반복될 때마다 변수의 새 값을 읽을 수 있으려면 지연 확장을 활성화하고 느낌표를 사용해야 합니다.!변수를 참조합니다.

    @에코 꺼짐
    setlocal 활성화 지연 확장
    setCOUNTER=0
    :루프
        %COUNTER% LSS 5인 경우(
            /A카운터+=1로 설정
            현재 카운트를 에코합니다: !COUNTER!
            루프로 이동
        )
    로컬 끝

    특수변수/시스템변수

    변하기 쉬운 설명하다
    %DATE% 현재 날짜.
    %TIME% 현재 시간.
    %CD% 현재 디렉터리 경로입니다.
    %ERRORLEVEL% 이전 명령의 종료 코드입니다(대개 성공의 경우 0).
    %RANDOM% 0에서 32767 사이의 임의의 10진수입니다.
    %~dp0 배치 파일이 실행되는 드라이브 및 경로입니다.

    매개변수 변수의 고급 사용법

    매개변수 변수의 경우(예:%1) 또는 루프 변수(예:%%A), 수정자를 사용하여 경로의 다른 부분을 추출할 수 있습니다.

    에코 전체 경로: %~1
    에코 드라이브: %~d1
    에코 경로: %~p1
    에코 파일 이름: %~n1
    에코 파일 확장자: %~x1

    이는 아카이브 경로로 작업할 때 유용합니다.



    CMD에서 키워드 필터링

    찾기 명령을 사용하세요

    디렉토리 | find "txt" :: "txt"를 포함하는 파일만 표시
    IP구성 | find "IPv4" :: IPv4가 포함된 행만 표시
    작업 목록 | find "chrome" :: 크롬이 포함된 실행 프로그램 필터링

    공통 매개변수

    다중 키워드 검색

    type log.txt | find "Error" | find "2025"
    type log.txt | findstr /I "error warning fail"

    고급: findstr 사용

    디렉토리 | findstr /R ".*\.txt$" :: 정규식을 사용하여 .txt 파일 찾기
    log.txt를 입력하세요 | findstr /I "시간 초과 오류 실패"


    CMD는 시작할 때 자동으로 설정 방법을 실행합니다.

    컨셉 노트

    방법 1: 자동 실행을 사용하여 값 로그인

    HKEY_CURRENT_USER\Software\Microsoft\Command Processor
    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor
    
    AutoRun = "C:\Users\YourName\cmd_startup.bat"

    방법 2: CMD 바로가기 수정

    %SystemRoot%\System32\cmd.exe /k "C:\Users\YourName\cmd_startup.bat"

    방법 3: 로그인을 사용하여 배치 파일 시작

    %AppData%\Microsoft\Windows\Start Menu\Programs\Startup

    대응 주의 사항

    Linux bash Windows CMD 대응 방법
    ~/.bash_profile 또는 ~/.bashrc 로그인 양식 AutoRun 또는 CMD /k는 배치 파일을 시작합니다.
    사용자 정의 명령을 자동으로 실행 사용자 정의된 환경 변수 및 경로 설정을 배치 파일에 배치할 수 있습니다.


    CMD AutoRun의 배치 파일을 자동으로 설정합니다.

    기능 설명

    샘플 배치 파일 내용

    @에코 꺼짐
    세트로컬
    
    :: AutoRun으로 실행할 배치파일 경로를 설정합니다.
    "AUTORUN_PATH=C:\Users\%USERNAME%\cmd_startup.bat"를 설정합니다.
    "REG_PATH=HKCU\Software\Microsoft\Command Processor"를 설정합니다.
    
    echo CMD 자동 실행 설정을 확인하세요...
    
    :: 로그인 코드가 존재하는지 확인하세요
    reg 쿼리 "%REG_PATH%" >nul 2>&1
    오류 수준이 1인 경우(
        echo [정보] 명령 프로세서 코드를 찾을 수 없습니다. 생성 중...
        reg 추가 "%REG_PATH%" /f >nul
    )
    
    :: 자동실행이 설정되어 있는지 확인하세요
    reg 쿼리 "%REG_PATH%" /v 자동 실행 >nul 2>&1
    오류 수준이 1인 경우(
        echo [정보] AutoRun을 찾을 수 없습니다. 새 값을 생성하는 중입니다...
        reg add "%REG_PATH%" /v 자동 실행 /d "%AUTORUN_PATH%" /f >nul
        echo [완료] 자동 실행이 다음으로 설정되었습니다: %AUTORUN_PATH%
    ) 다른 (
        echo [확인] 자동 실행이 이미 존재하며 변경되지 않았습니다.
    )
    
    로컬 끝
    일시 중지

    설명하다



    배치 파일 작업 터미널 결정

    샘플 배치 파일

    @에코 꺼짐
    
    :: 파워셸 감지
    PSModulePath가 정의된 경우(
        echo는 현재 PowerShell에서 실행됩니다.
        고토 :eof
    )
    
    :: Cygwin 감지
    CYGWIN을 정의한 경우(
        echo는 현재 Cygwin에서 실행됩니다.
        고토 :eof
    )
    정의된 경우 SHELL(
        echo는 현재 Cygwin에서 실행됩니다(SHELL=%SHELL%).
        고토 :eof
    )
    
    ::기본값은 CMD입니다
    echo는 현재 CMD에서 실행됩니다.

    판단 근거



    PowerShell

    개폐방식

    일반적인 명령

    고급 작업

    관리자 모드



    PowerShell의 모든 변수 나열

    명령 방법

    # 모든 변수 나열
    변수 가져오기
    
    # 변수 이름만 표시
    변수 가져오기 | 선택 개체 이름
    
    # 특정 변수의 값을 표시합니다.
    변수 가져오기 경로 | 형식 목록 *
    
    #가변 드라이버 방식 사용
    Get-ChildItem 변수:

    설명하다



    C 및 C++ 언어

    고효율

    정적 유형 시스템

    자원 통제

    문법적 유연성

    광범위한 응용 분야

    크로스 플랫폼



    C/C++ 전처리기 지시문

    개요

    전처리기 지시문은 C 또는 C++ 프로그램 코드가 컴파일러에 의해 공식적으로 처리(컴파일)되기 전에 "전처리기"라는 프로그램 모듈에 의해 실행되는 명령입니다. 이러한 지침 앞에는 파운드 기호(#) 앞에 세미콜론(;) 마지막에.

    전처리기의 역할은 텍스트 교체, 파일 포함, 조건부 컴파일 및 기타 작업을 수행하여 컴파일러에서 사용할 최종 "번역 단위"를 생성하는 것입니다.

    주요 명령 범주 및 예

    1. 파일 포함

    현재 파일에 다른 파일의 내용을 삽입하는 데 사용됩니다.

    #include <iostream> // 표준 I/O 라이브러리 포함
    #include "my_utility.h" // 사용자 정의 헤더 파일 포함

    2. 매크로 정의 및 대체

    기호 상수 또는 코드 조각을 정의하는 데 사용되는 리터럴 대체 매크로입니다.

    #define MAX_SIZE 100 //기호 상수 정의
    #define SUM(a, b) ((a) + (b)) // 매개변수가 있는 매크로 정의
    
    정수 메인() {
        정수 크기 = MAX_SIZE; // 전처리 후에는 int size = 100이 됩니다.
        int total = SUM(5, 3); // 전처리 후에는 int가 됩니다. total = ((5) + (3));
        0을 반환합니다.
    }

    3. 조건부 컴파일

    전처리기 매크로의 값을 기반으로 특정 코드 블록을 컴파일해야 하는지 여부를 결정할 수 있습니다.

    #DEBUG_MODE 1 정의
    
    #if DEBUG_MODE
        표준::cout << "디버그 모드 활성화됨" << 표준::endl;
    #else
        표준::cout << "프로덕션 모드 실행 중" << 표준::endl;
    #endif
    
    #ifndef MY_HEADER_H
    #defineMY_HEADER_H
        // ... 헤더 파일 내용 (Guard 예시 포함)
    #endif

    4. 오류 및 경고

    #ifndef VERSION_DEFINED
    #error "버전 번호 매크로 VERSION_DEFINED를 정의해야 합니다!"
    #endif

    5. 기타 지시문



    #pragma once

    정의 및 기능

    #pragma onceC 및 C++ 언어 중 하나입니다.전처리기 지시어. 핵심 기능은 이 지시어가 포함된 헤더 파일이 단일 컴파일 프로세스 중에 컴파일러에 의해서만 처리되도록 하는 것입니다.한 번

    이 지시문의 목적은 헤더 파일이 반복적으로 포함되는 문제를 해결하고 여러 소스 코드 파일 또는 다중 레벨 헤더 파일 포함 관계로 인해 동일한 코드 조각(예: 클래스 정의, 함수 프로토타입 또는 상수 선언)이 컴파일러에서 여러 번 표시되는 것을 방지하는 것입니다.재정의컴파일 오류.

    인클루드 가드와의 비교

    C/C++ 표준에서는 전통적으로가드 포함반복 포함을 방지하는 목적을 달성하기 위해.#pragma once더 깨끗한 대안을 제공합니다.

    가드 포함(표준 방법)

    이는 조건부 컴파일 지시문을 사용하는 표준적이고 이식 가능한 접근 방식입니다.

    #ifndef MY_HEADER_H
    #defineMY_HEADER_H
    
    // 헤더 파일 내용
    
    #endif // MY_HEADER_H

    고유한 매크로 이름(예:MY_HEADER_H) 콘텐츠 포함 여부를 제어합니다.

    #pragma Once(비표준 방법)

    한 줄 지시어를 사용하세요:

    #pragma한번
    
    // 헤더 파일 내용

    컴파일러는 현재 컴파일 세션에서 이 파일을 이미 처리했는지 여부를 자동으로 추적하고, 그렇다면 파일의 나머지 내용을 건너뜁니다.

    장점과 단점

    #pragma Once의 장점:

    #pragma Once의 단점:

    결론적으로

    최신 개발 환경에서는 특히 Visual Studio 또는 주류 컴파일러를 사용할 때#pragma once단순성과 편의성으로 인해 헤더 파일이 반복적으로 포함되는 것을 방지합니다.일반 및 권장관행.



    #pragma warning

    정의 및 사용

    #pragma warning특정 코드 블록 내에서 사용되는 C 및 C++ 언어의 전처리기 지시문입니다.컴파일러 경고의 심각도를 선택적으로 억제, 복원 또는 수정합니다.

    이 지시문의 주요 목적은 프로젝트 수준 설정보다 더 세부적인 제어를 제공하는 것입니다. 예를 들어, 많은 경고를 생성하는 이전 버전의 라이브러리를 포함해야 하지만 경고를 전체적으로 끄고 싶지 않은 경우 이 명령을 사용합니다.

    주요 연산 구문(MSVC 형식)

    하지만#pragma warning구체적인 구현은 컴파일러마다 약간 다를 수 있지만(특히 MSVC가 가장 널리 사용됨) 핵심 작업은 다음 유형으로 나뉩니다.

    1. 경고 비활성화(Disable)

    이 시점부터 컴파일러는 지정된 경고 코드를 무시합니다.

    #pragma warning( 비활성화 : 4996 ) // C4996 비활성화(예: 안전하지 않은 기능 사용에 대한 경고)
    // C4996을 생성하는 코드를 포함하거나 작성합니다.

    2. 복구 경고(기본값)

    지정된 경고를 프로젝트 또는 명령줄에서 설정된 기본 동작으로 복원합니다.

    #pragma warning(기본값: 4996) //C4996을 기본 상태로 복원

    3. 상태 저장 및 복원(Push 및 Pop)

    이것은 가장 안전하고 가장 권장되는 모드입니다. 특정 코드 블록을 처리하는 동안 경고 설정을 수정할 수 있으며, 부작용을 방지하기 위해 블록이 끝난 후 원래 경고 상태가 즉시 복원되도록 보장합니다.

    #pragma warning( push ) // 1. 현재 경고 설정을 저장합니다.
    #pragma warning( 비활성화 : 4996 4244 ) // 2. 여러 특정 경고를 비활성화합니다.
    // 타사 헤더 파일 또는 레거시 코드가 포함되어 있습니다.
    #pragma warning( pop ) // 3. 원래 설정으로 복원
    // 후속 코드는 복원된 설정을 사용합니다.

    4. 경고 수준 높이기(오류)

    특정 경고 코드를 컴파일 오류로 승격합니다. 경고가 발생하면 컴파일이 실패합니다.

    #pragma warning( error : 4005 ) // 경고 4005를 오류로 처리합니다.

    주의할 점



    C++ 표준 네임스페이스

    개요

    C++ 프로그래밍에서는std::표준 네임스페이스를 나타냅니다. 함수, 클래스, 템플릿, 매크로 및 개체를 포함하여 C++ 언어 핵심 및 해당 표준 라이브러리(표준 라이브러리)의 모든 표준 엔터티를 포함하는 컨테이너입니다.

    사용std::피하는 것이 주요 목적입니다.이름 충돌. 표준 기능(예:cout또는vector)은 별도의 네임스페이스에 배치되지 않습니다. 사용자가 동일한 이름을 가진 엔터티를 정의하면 컴파일러는 어떤 엔터티를 사용해야 할지 알 수 없습니다.

    std::의 주요 내용

    C++ 표준 라이브러리의 대부분의 기능은 다음 위치에 있습니다.std::네임스페이스 내에서. 주요 카테고리 및 기능은 다음과 같습니다.

    1. 입출력 스트림(I/O 스트림)

    2. 표준용기(용기)

    데이터를 저장하는 데 사용되는 컬렉션 카테고리:

    3. 알고리즘

    컨테이너 및 범위 작업을 위한 일련의 공통 기능:

    4. 기타 핵심 도구(유틸리티)

    표준 사용::

    접근하다std::네임스페이스의 엔터티에는 두 가지 주요 메서드가 있습니다.

    1. 정규화된 이름

    사용할 때마다 명확하게 적어주세요std::접두사. 이는 전역 네임스페이스 오염을 방지하기 위해 특히 헤더 파일에서 가장 안전하고 권장되는 접근 방식입니다.

    
    int main() {
        std::cout << "Hello World" << std::endl;
        std::vector<int> numbers;
        return 0;
    }
    

    2. 선언 사용(지시문 사용)

    사용using namespace std;전체std::네임스페이스의 내용이 현재 범위에 도입되며 이름은 별도의 작업 없이 직접 사용할 수 있습니다.std::접두사.

    #include <iostream>
    네임스페이스 std 사용; // std:: 네임스페이스를 소개합니다.
    
    정수 메인() {
        cout << "안녕하세요" << 끝; // std:: 접두사가 필요하지 않습니다.
        벡터 숫자;
        0을 반환합니다.
    }

    하지만using namespace std;편리하지만 이름 충돌 위험이 높아지므로 대규모 프로젝트나 헤더 파일에서는 피해야 합니다.



    std::string

    1. 선언 및 초기값

    C++에서는std::string카테고리(클래스)입니다. 당신이 선언할 때std::string변수에 초기값이 제공되지 않으면 기본 생성자를 호출합니다.

    #include <string>
    #include <iostream>
    
    무효 초기화_예제() {
        표준::문자열 s; // 선언되었지만 값이 제공되지 않았습니다.
        
        표준::cout << "길이: " << s.length() << 표준::endl; // 출력: 0
        표준::cout << "콘텐츠: '" << s << "'" << 표준::endl; // 출력: ''
    }

    2. 비어있는지(Empty) 확인하는 방법

    문자열에 문자가 포함되어 있지 않은지 확인하려면 가장 권장되는 방법은 다음을 사용하는 것입니다.empty()확인하는 것보다 나은 멤버 함수length() == 0일부 컨테이너에서는 더 의미 있고 더 효율적입니다.

    무효 check_empty(std::string s) {
        if (s.empty()) {
            표준::cout << "이것은 빈 문자열입니다." << 표준::endl;
        }
    }

    3. Null인지 어떻게 확인하나요?

    이것은 일반적인 오해입니다.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 스타일 문자열 포인터가 비어 있는지 확인

    4. 문자열을 삭제하는 방법

    기존 문자열을 원래 빈 상태로 복원하려면 다음 방법을 사용할 수 있습니다.

    무효 클리어_예제() {
        std::string s = "안녕하세요";
        
        s.clear(); // 방법 1: 가장 일반적으로 사용됨
        s = ""; // 방법 2: 재할당
        s = std::string(); // 방법 3: 기본 개체 할당
    }


    std::string으로 부동

    1. std::to_string 사용(가장 간단한 방법)

    이는 숫자 값을 문자열로 변환하는 C++11에 도입된 가장 간단한 방법입니다. 기본적으로 소수점 이하 6자리가 유지됩니다.

    #include <string>
    #include <iostream>
    
    무효 simple_convert() {
        부동 소수점 값 = 3.14159f;
        std::string s = std::to_string(val);
        
        표준::cout << s << 표준::endl; // 출력 예: "3.141590"
    }

    2. std::stringstream(사용자 정의 정밀도)을 사용하십시오.

    소수점 이하 자릿수나 특정 형식을 제어해야 하는 경우stringstream가장 유연한 옵션입니다. 그것은 결합한다<iomanip>출력을 정밀하게 제어하는 ​​라이브러리입니다.

    #include <sstream>
    #include <iomanip>
    
    무효 정밀도_변환() {
        부동 소수점 값 = 3.1415926f;
        표준::문자열스트림 ss;
        
        // 고정 소수점 계산 방법(고정)을 설정하고 소수점 2자리를 유지합니다.
        ss << 표준::고정 << std::setprecision(2) << 발;
        
        std::string s = ss.str();
        표준::cout << s << 표준::endl; // 출력: "3.14"
    }

    3. std::format(C++20의 효율적인 방법)을 사용하세요.

    C++20에서는 형식 문자열을 사용하여 가장 간결한 구문으로 형식 변환과 정밀도 제어를 동시에 처리할 수 있습니다.

    #include <형식>
    
    무효 현대 형식() {
        부동 소수점 값 = 123.456f;
        
        // {:.2f}는 float 유형을 나타내며 소수점 이하 두 자리를 유지합니다.
        std::string s = std::format("{:.2f}", val);
        
        표준::cout << s << 표준::endl; // 출력: "123.46"(자동으로 반올림됨)
    }

    4. 관련 처리 사용법: 끝에 추가 0을 제거합니다.

    std::to_string종종 "3.140000"과 같은 추가 0이 있습니다. 당신은 결합할 수 있습니다find_last_not_of그리고erase문자열을 정리합니다.

    std::string Remove_trailing_zeros(float val) {
        std::string s = std::to_string(val);
        
        // 0이 아닌 문자가 나타날 때까지 후행 '0'을 제거합니다.
        s.erase(s.find_last_not_of('0') + 1, std::string::npos);
        
        // 마지막 문자가 소수점인 경우에도 제거합니다.
        if (s.back() == '.') {
            s.pop_back();
        }
        반환 s;
    }

    변환 방법 비교

    방법 특징 제안된 시나리오
    std::to_string 구문이 가장 짧고 성능도 괜찮습니다. 소수 자릿수에 대한 요구 사항이 없는 경우 빠른 디버깅
    std::stringstream 고도로 맞춤화 가능(제로 패딩, 너비, 캐리) 출력 형식을 엄격하게 제어해야 하는 경우
    std::format 유형 안전성, 성능 및 최신 구문 C++20 환경에서 선호되는 솔루션
    스프린트프(C 스타일) 매우 빠르지만 덜 안전함 성능을 극도로 추구하여 오래된 코드를 유지 관리합니다.


    std::문자열 구분 기호 구문 분석

    1. std::string::find 루프 분석을 사용하세요.

    이는 외부 라이브러리에 의존하지 않는 C++의 가장 표준적인 접근 방식입니다. ~을 통해find구분 기호의 위치를 ​​찾아 사용하십시오.substr하위 문자열을 검색합니다.

    #include <iostream>
    #include <벡터>
    #include <string>
    
    무효 분할_by_3_chars() {
        std::string text = "사과---바나나---체리---날짜";
        std::string 구분 기호 = "---";
        std::벡터<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 = 위치 + delimiter.length();
        }
        
        //마지막 조각 넣기
        tokens.push_back(text.substr(last_pos));
    
        //결과 출력
        for (const auto& t : 토큰) std::cout << "[" << t << "]" << 표준::endl;
    }

    2. std::string_view 사용(C++17 성능 최적화)

    문자열이 매우 큰 경우 다음을 사용하십시오.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;
    }
    

    3. 정규 표현식을 사용하세요

    코드를 더 간결하게 보이도록 하거나 구분 기호가 변경될 수 있는 경우 다음을 사용할 수 있습니다.std::regex. 그러나 정규 표현식의 실행 성능은 일반적으로 수동 표현식보다 우수합니다.find느린.

    #include <regex>
    
    무효 regex_split() {
        std::string text = "하나###두###세";
        std::regex ws_re("###"); // 3개의 문자 구분 기호를 정의합니다.
        
        std::copy(std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),
                  표준::sregex_token_iterator(),
                  std::ostream_iterator<std::string>(std::cout, "\n"));
    }

    분석 방법의 비교

    방법 이점 결점
    std::find + substr 최고의 호환성(C++98+)과 안정적인 성능. 코드가 길고 마지막 조각을 수동으로 처리해야 합니다.
    string_view 가장 효과적, 추가 메모리 복사본이 생성되지 않습니다. C++17 지원이 필요하며 원래 문자열 수명 주기에 주의를 기울여야 합니다.
    std::regex 구문은 가장 간결하고 확장 가능합니다. 실행 속도가 가장 느리고 컴파일 시간이 길어집니다.


    std::벡터가 비어 있는지 확인하세요.

    개요

    C++에서 확인하려면std::vector컨테이너에 요소가 없는 경우(즉, 크기가 0인 경우) 가장 표준적이고 권장되는 방법은 해당 멤버 함수를 사용하는 것입니다.empty(). 이는empty()기능은 일반적으로 직접 확인보다 낫습니다.size()특히 일부 컨테이너 구현에서는 0이 더 효율적입니다.

    확인방법

    1.empty() 함수 사용(권장)

    이는 벡터가 비어 있는지 확인하는 데 선호되는 방법입니다. 부울 값을 반환합니다. 벡터에 요소가 없으면 반환됩니다.true; 그렇지 않으면 반환false

    #include <벡터>
    #include <iostream>
    #include <string>
    
    void check_empty(const std::벡터<std::string>& vec)
    {
        if (vec.empty()) {
            표준::cout << "벡터가 비어 있습니다(empty() == true)." << 표준::endl;
        } 그렇지 않으면 {
            표준::cout << "벡터가 비어 있지 않습니다(empty() == false). 요소 수: " << vec.size() << 표준::endl;
        }
    }
    
    정수 메인()
    {
        std::벡터<std::string> 비어있는_vec;
        std::벡터<std::string> non_empty_vec = {"사과", "바나나"};
    
        check_empty(empty_vec);
        check_empty(non_empty_vec);
    
        0을 반환합니다.
    }

    2. size() 함수 확인

    유효하기는 하지만 이는 빈 상태를 확인하는 가장 관용적이거나 잠재적으로 가장 효율적인 방법은 아닙니다. 벡터의 요소 개수가 0인지 직접 확인합니다.

    void check_size(const std::벡터<int>& vec)
    {
        if (vec.size() == 0) {
            표준::cout << "벡터가 비어 있습니다(size() == 0)." << 표준::endl;
        } 그렇지 않으면 {
            표준::cout << "벡터가 비어 있지 않습니다(size() != 0)." << 표준::endl;
        }
    }

    효율성 고려사항

    ~을 위한std::vector측면에서empty()그리고size() == 0벡터는 크기를 멤버 변수로 저장하므로 시간 복잡도는 $O(1)$입니다. 그러나 일부 다른 C++ 표준 컨테이너(예:std::list또는std::forward_list), 표준 권장 사항은 항상 사용하는 것입니다.empty(), 이는 일반적으로 빈 상태를 확인하기 위한 C++ 표준 컨테이너 라이브러리에서 가장 일반적이고 빠른 관용구이기 때문입니다.



    C++ 문자열을 문자열 벡터로 구문 분석

    개요

    C++에서 공백이나 탭 문자(\t) 분리된 문자열은 개별 단어나 토큰으로 구문 분석되어 다음 위치에 저장됩니다.std::vector<std::string>, 가장 일반적인 방법은 **를 사용하는 것입니다.std::stringstream**. 파일 스트리밍 카테고리std::stringstream인 메모리 스트림과 마찬가지로 기본적으로 읽기 작업을 위한 구분 기호로 공백 문자(공백, 탭 및 줄 바꿈 포함)를 사용합니다.

    코드 예시

    다음이 사용됩니다std::stringstream이 작업을 수행하는 C++ 코드의 예:

    #include <iostream>
    #include <sstream> // 문자열 스트림 포함
    #include <string>
    #include <벡터>
    
    네임스페이스 std 사용;
    
    /**
     * 입력 문자열을 공백 문자(공백 또는 탭)로 구분하고 벡터에 저장합니다.
     * @param input_str 구문 분석할 문자열입니다.
     * @return 분리된 모든 단어를 포함하는 벡터입니다.
     */
    벡터<string> Split_string_by_whitespace(const string& input_str)
    {
        벡터<string> 토큰;
        
        // 1. stringstream 객체를 생성하고 입력 문자열로 초기화합니다.
        문자열스트림 ss(input_str);
        
        문자열 토큰;
        
        // 2. 루프 읽기
        // 스트림 추출 연산자(>>)는 공백 문자(공백, 탭 등)를 구분 기호로 사용하여 다음 토큰을 자동으로 읽습니다.
        // 토큰이 성공적으로 읽혀지면 연산자는 true를 반환하고, 그렇지 않으면(문자열 끝에 도달하면) false를 반환합니다.
        while(ss >> 토큰)
        {
            tokens.push_back(토큰);
        }
        
        토큰 반환;
    }
    
    정수 메인()
    {
        //입력 문자열에 여러 개의 공백과 탭 기호(\t)가 포함되어 있습니다.
        string test_string = "안녕하세요 \tWorld \ta 테스트 문자열입니다.";
        
        cout << "원래 문자열: " << test_string << 끝;
        
        벡터<string> 결과 = Split_string_by_whitespace(test_string);
        
        cout << "--- 별도의 결과 ---" << 끝;
        
        for (size_t i = 0; i < result.size(); ++i)
        {
            cout << "토큰" << 나는 + 1 << ": [" << 결과[i] << "]" << 끝;
        }
        
        0을 반환합니다.
    }

    주요 메커니즘 설명



    0으로 초기화된 C++ 다차원 배열

    std::array를 사용하여 초기화됨

    C++에서는 다음을 사용할 수 있습니다.std::array다차원 배열을 0으로 초기화합니다.

    #include <iostream>
    #include <배열>
    네임스페이스 std 사용;
    
    정수 메인() {
        배열, 3>; 도착 = {0}; // 모든 요소를 0으로 초기화
    
        for (int i = 0; i < 3; i++) {
            for(int j = 0; j < 4; j++) {
                cout << arr[i][j] << " ";
            }
            cout << 끝;
        }
        0을 반환합니다.
    }

    주의할 점



    C++ 표준 배열 루프 방법

    개요

    C++에서 루핑은 컨테이너나 배열의 모든 요소를 ​​반복하는 기본 작업입니다.std::vector(동적 크기의 컨테이너) 및std::array(고정 크기 컨테이너)는 다양한 표준 및 안전한 방식으로 요소를 반복할 수 있는 C++ 표준 라이브러리(STL)의 컨테이너입니다.

    1. 범위 기반 for 루프

    이는 C++11에 도입된 가장 현대적이고 안전하며 간결한 순회 방법입니다. 모든 표준 컨테이너(포함)에서 작동합니다.std::vector그리고std::array)。

    적용 가능성:

    #include <iostream>
    #include <벡터>
    #include <배열>
    
    무효 range_based_loop_example()
    {
        std::벡터<int> vec = {10, 20, 30};
        std::배열 도착 = {1, 2, 3, 4};
        
        // 자동&를 사용합니다. 참조로 순회하는 것이 효율적이며 요소 수정을 허용합니다.
        표준::cout << "--- 벡터(수정 가능) ---" << 표준::endl;
        for (auto& 요소: vec) {
            요소 += 1; // 요소 수정
            표준::cout << 요소 << " ";
        }
        표준::cout << 표준::endl;
        
        // const auto&를 사용합니다. 안전하고 요소 수정을 허용하지 않는 상수 참조로 이동합니다.
        표준::cout << "--- 배열(읽기 전용) ---" << 표준::endl;
        for (const auto& 요소: arr) {
            표준::cout << 요소 << " ";
        }
        표준::cout << 표준::endl;
    }

    2. 인덱스 기반 for 루프

    이는 전통적이고 보편적인 방법이다. 요소 인덱스에 액세스해야 하는 상황에 적합합니다(예: 두 개의 컨테이너 또는 배열을 동시에 작동해야 하거나 특정 인덱스에서 종료해야 하는 경우).

    적용 가능성:

    #include <iostream>
    #include <벡터>
    #include <배열>
    
    무효 index_loop_example()
    {
        std::벡터<std::string> 이름 = {"앨리스", "밥", "찰리"};
        표준::배열 가격 = {10.5, 20.99, 5.0};
        
        // 인덱스 유형이 올바르고 경계가 안전한지 확인하려면 size()와 함께 size_t 또는 auto를 사용하세요.
        for (size_t i = 0; i < names.size(); ++i) {
            // 요소에 접근하려면 연산자[]를 사용하세요.
            표준::cout << "이름: " << 이름[i] << ", 가격: " << 가격[i] << 표준::endl;
        }
    }

    참고: 사용[]C++에서는 연산자가 요소에 액세스할 때 경계 검사를 수행하지 않습니다. 경계 확인이 필요한 경우 다음을 사용하십시오.at()함수(경계를 벗어나면 던집니다.std::out_of_range이상).

    3. 반복자 루프

    이는 C++에서 가장 유연한 순회 방법이며 모든 표준 컨테이너에서 작동합니다. C++ 표준 라이브러리(STL) 알고리즘과 상호 작용할 때 반복자가 필요합니다.

    적용 가능성:

    #include <iostream>
    #include <벡터>
    
    무효 iterator_loop_example()
    {
        표준::벡터<더블> 값 = {100.0, 50.0, 10.0};
        
        // auto를 사용하여 반복자 유형을 단순화하고 범위를 얻기 위해 Begin() 및 end()를 사용합니다.
        for (auto it = value.begin();
             !=values.end();
             ++그것)
        {
            *그것은 /= 10.0; // *반복자를 역참조하고 요소에 액세스합니다.
            표준::cout << *그것은 << " ";
        }
        표준::cout << 표준::endl;
        
        // cbegin() 및 cend()를 사용하여 읽기 전용 순회를 위해 반복자가 const인지 확인합니다.
        for (auto cit = value.cbegin(); cit != value.cend(); ++cit)
        {
            // 시도 중 *cit = 5; 컴파일 오류가 발생합니다
            표준::cout << *cit << " ";
        }
        표준::cout << 표준::endl;
    }

    요약 및 권장 사항

    루프 방식 적용 가능한 용기 이점 적용 시간
    범위 기반 std::벡터, std::배열, 모든 표준 컨테이너 가장 깨끗하고 안전하며 현대적인 C++ 관용어입니다. 인덱스는 필요하지 않으며 각 요소만 순회하면 됩니다.
    인덱스 기반 std::vector, std::array 인덱스는 접근이 가능하고 활용도가 높습니다. 요소의 인덱스를 알거나 조작해야 하는 경우.
    반복자 모든 표준 용기 매우 유연하며 다음과 같은 STL 알고리즘과 함께 사용할 수 있습니다.std::find) 완벽하게 맞습니다. STL 알고리즘을 사용하거나 컨테이너에서 복잡한 작업을 수행해야 하는 경우.


    다차원 std::array의 내용을 복사하는 방법

    문제 상황

    std::array<std::array<std::array<float, 2>, 2>, 2> twoLines;
    std::array<std::array<std::array<float, 2>, 2>, 2> twoLinesCopy;
    

    해결 방법 1: 직접 지정(= 연산자)

    std::array얕은 수준에서 깊은 수준까지 완전한 복사를 지원하므로 직접 사용할 수 있습니다.=

    twoLinesCopy = twoLines;
    

    해결 방법 2: std::copy 사용

    std::copy(twoLines.begin(), twoLines.end(), twoLinesCopy.begin());
    

    해결 방법 3: std::memcpy 사용(POD 유형에 적합, 여기에는 float가 적용 가능함)

    std::memcpy(&twoLinesCopy, &twoLines, sizeof(twoLines));
    

    제안



    C++ 캡처 표시기 메모리 액세스 오류

    개요

    C++에서는 포인터를 조작하거나 인덱스를 사용하여 배열/메모리에 액세스할 때 유효하지 않거나 범위를 벗어난 메모리 위치에 액세스할 때 이런 일이 발생합니다.정의되지 않은 동작. 이 동작은 일반적으로 프로그램으로 나타납니다.충돌, 세그먼트화 오류 또는 액세스 위반 오류 등이 있습니다.

    C++ 표준try-catch이 메커니즘은 주로 프로그램 코드에서 명시적으로 발생하는 C++ 예외(예외)를 포착하는 데 사용되지만 운영 체제에서 발생한 하드웨어 또는 메모리 액세스 오류를 직접 포착할 수는 없습니다.

    메모리 액세스 오류를 try-catch할 수 없는 이유는 무엇입니까?

    C++ 프로그램이 유효하지 않은 메모리에 액세스하려고 시도하는 경우, 예를 들면 다음과 같습니다.

    1. 범위 밖 접근:배열이 끝난 후 메모리에 액세스합니다.
    2. 널 포인터 역참조:주소에서 읽거나 쓰려고 했습니다.nullptr기억의.
    3. 무료 사용 후 사용:액세스가 통과되었습니다.delete또는free메모리가 해제되었습니다.

    이러한 작업은 기본 운영 체제의 보호 메커니즘(예: Windows의 액세스 위반 또는 Unix/Linux의 SIGSEGV 신호)을 트리거하고 운영 체제에 의해 프로그램이 종료됩니다. 이러한 오류는 C++ 언어 수준 예외 개체(예:std::exception), 그래서 표준try-catch그들을 붙잡을 방법이 없습니다.

    오류 예(표준 try-catch가 작동하지 않음)

    #include <iostream>
    #include <벡터>
    
    네임스페이스 std 사용;
    
    무효 crash_function()
    {
        // 범위를 벗어난 배열 액세스 예시
        벡터 vec = {10, 20};
        cout << "범위를 벗어난 색인에 액세스하려고 시도했습니다..." << 끝;
        
        // 이는 정의되지 않은 동작이며 액세스 위반 충돌로 이어질 가능성이 높습니다.
        int 값 = vec[100]; // 오류: 잘못된 인덱스에 액세스 중입니다.
        cout << "값: " << 값 << 끝;
    }
    
    정수 메인()
    {
        시도하다
        {
            crash_function();
            //프로그램은 위의 vec[100]에서 충돌이 발생하고 여기서는 실행되지 않습니다.
            // 그리고 catch 블록은 실행되지 않습니다.
        }
        catch (const 예외&e)
        {
            // 운영 체제 수준 오류는 여기서 캡처할 수 없습니다.
            cerr << "C++ 예외 발생: " << e.what() << 끝;
        }
        잡기(...)
        {
            // 여전히 메모리 액세스 오류를 포착할 수 없습니다.
            cerr << "알 수 없는 예외가 발생했습니다." << 끝;
        }
    
        0을 반환합니다.
    }

    이런 종류의 오류를 처리하는 방법은 무엇입니까?

    1. 안전한 C++ 메커니즘 사용(선호)

    가장 좋은 접근 방식은 이러한 오류를 잡기보다는 코드 설계 단계에서 이러한 오류가 발생하지 않도록 방지하는 것입니다.

    무효 safe_function()
    {
        벡터 vec = {10, 20};
        시도하다
        {
            int 값 = vec.at(100); // std::out_of_range 예외 발생
            cout << "값: " << 값 << 끝;
        }
        잡기(const std::out_of_range&e)
        {
            // C++ 예외를 성공적으로 포착했습니다.
            cerr << "안전 캡처: " << e.what() << 끝;
        }
    }

    2. 플랫폼별 구조적 예외 처리(SEH) 사용

    Windows 환경에서는 Microsoft의 확장된 구조적 예외 처리(SEH)를 사용하여 액세스 위반을 포함한 운영 체제 수준 오류를 포착할 수 있습니다. 이는 일반적으로 다음을 사용하여 수행됩니다.__try그리고__except키워드.

    참고: SEH는 비표준이므로 이식 가능한 C++ 코드에 사용하지 않는 것이 좋습니다. C++/CLI 프로젝트에서는 .NET을 사용할 수 있습니다.try/catch일부 SEH 예외를 포착하세요. 하지만 이를 위해서는 특정 컴파일러 설정이 필요합니다(예:/EHa)。



    C++ 배열 인덱스 메모리 액세스 오류 잡기

    개요

    C++에서 인덱싱 작업에 원시 배열(C 스타일 배열) 또는 포인터를 사용할 때 배열 범위를 벗어나거나 유효하지 않은 메모리 위치에 액세스하는 경우 발생합니다.정의되지 않은 동작. 이 동작으로 인해 프로그램이 운영 체제 수준에서 실행되는 경우가 많습니다.충돌, 액세스 위반 또는 분할 오류 등이 있습니다.

    핵심 사항은 다음과 같습니다.C++ 표준try-catch이 메커니즘은 프로그램 코드에서 명시적으로 발생하는 C++ 예외(예외)를 포착하도록 설계되었습니다. 운영 체제에서 발생한 하드웨어 또는 메모리 보호 오류는 포착할 수 없습니다.

    표준 try-catch가 작동하지 않는 이유는 무엇입니까?

    C++ 프로그램이 유효하지 않은 메모리에 액세스하려고 시도하는 경우(예: 정적 배열 액세스)arr[100], 그러나 배열에는 요소가 10개만 있음) 이는 운영 체제의 메모리 보호 규칙을 위반합니다. 운영 체제가 개입하여 신호나 예외를 보내 프로그램을 종료함으로써 시스템이나 다른 프로그램이 손상되는 것을 방지합니다. 이러한 오류는 C++ 언어 수준이 아닙니다.std::exception객체이므로 표준에서 사용할 수 없습니다.try-catch블록 캡처.

    오류 데모(표준 try-catch는 충돌을 포착할 수 없음)

    #include <iostream>
    #include <stdException> // 표준 예외 포함
    
    네임스페이스 std 사용;
    
    무효 crash_function()
    {
        // C 스타일 기본 배열
        int raw_array[5] = {1, 2, 3, 4, 5};
        cout << "범위를 벗어난 색인에 액세스하려고 시도했습니다..." << 끝;
        
        // 범위를 벗어난 배열 액세스: 이는 정의되지 않은 일반적인 동작입니다.
        // 프로그램에 접근 권한이 없는 메모리에 접근하면 즉시 접근 위반이 발생하여 프로그램이 중단됩니다.
        int 값 = raw_array[100]; // 오류: 잘못된 인덱스에 액세스 중입니다.
        cout << "값(연결 가능한 경우): " << 값 << 끝;
    }
    
    정수 메인()
    {
        시도하다
        {
            crash_function();
            // 프로그램은 raw_array[100]에서 종료되며 여기서는 실행되지 않습니다.
        }
        catch (const 예외&e)
        {
            // 운영 체제 수준 메모리 액세스 오류는 여기서 캡처할 수 없습니다.
            cerr << "C++ 예외 발생: " << e.what() << 끝;
        }
    
        0을 반환합니다.
    }

    올바른 취급 및 예방방법(선호)

    가장 좋은 방법은 범위를 벗어난 액세스를 완전히 피하거나 오류가 발생할 때 포착 가능한 C++ 예외를 발생시키는 C++에서 제공하는 안전한 컨테이너 및 메서드를 사용하는 것입니다.

    1. std::벡터::at()를 사용하세요.

    ~을 위한std::vector용기, 사용at()원본 대신 멤버 함수[]연산자. 접근 범위를 벗어나면,at()** 던질 것이다std::out_of_range**예외. 이는 표준 C++ 예외이며try-catch잡아서 안전하게 폐기했습니다.

    #include <벡터>
    // ... (기타 포함)
    
    무효 safe_Vector_access()
    {
        std::벡터<int> vec = {10, 20};
        시도하다
        {
            // 경계 확인을 위해 at()을 사용합니다.
            int 값 = vec.at(100);
            표준::cout << "값: " << 값 << 표준::endl;
        }
        잡기(const std::out_of_range&e)
        {
            // C++ 예외를 성공적으로 포착했습니다.
            표준::cerr << "범위를 벗어난 예외가 안전하게 포착되었습니다. " << e.what() << 표준::endl;
        }
    }

    2. 원시 배열 사용을 피하고 대신 std::array를 사용하세요.

    C++11을 사용하여 도입됨std::arrayC 스타일 배열을 대체합니다. 하지만std::array~의[]운영자는 확인되지 않았지만at()이 함수는 또한std::out_of_range이상.

    #include <배열>
    // ...
    
    무효 safe_array_access()
    {
        std::배열 arr = {1, 2, 3, 4, 5};
        시도하다
        {
            int 값 = arr.at(5); // 범위를 벗어난 접근, 예외 발생
        }
        잡기(const std::out_of_range&e)
        {
            표준::cerr << "std::array 범위를 벗어난 캡처: " << e.what() << 표준::endl;
        }
    }

    플랫폼별 구조적 예외 처리(고급/비표준)

    Windows와 같은 특정 플랫폼에서는 **구조적 예외 처리(SEH)**를 사용하여 운영 체제에서 발생한 하드웨어 예외(예: 액세스 위반)를 포착할 수 있습니다. 여기에는 일반적으로 Microsoft 확장 프로그램 사용이 포함됩니다.__try그리고__except키워드. 이 방법은 플랫폼 비표준이며 코드 이식성을 희생하며 일반적으로 일상적인 오류 처리 메커니즘으로 권장되지 않습니다.



    C++/CLI 목록 액세스가 범위를 벗어났습니다.

    1. 인덱스가 범위를 벗어나면 어떻게 되나요?

    C++/CLI에서System::Collections::Generic::List<T>, 존재하지 않는 인덱스에 액세스하려고 시도하는 경우(예:size1이지만 액세스index1), 프로그램습관기본값(예: 0 또는 null)이 주어지면 예외가 즉시 발생합니다.


    2. 안전한 접근 관행

    인덱스에 접근하기 전에 항상 확인해야 할 사항Count속성 또는 사용try-catch블록은 잠재적인 오류를 포착합니다.

    //방법 A: 사전 검사(가장 권장됨, 최상의 성능)
    if (숫자->개수 > 1) {
        int 값 = 숫자[1];
        // 처리 로직
    } 그렇지 않으면 {
        // 인덱스 부족 상황 처리
    }
    
    //방법 B: 예외 잡기
    {를 시도해보세요
        int 값 = 숫자[1];
    } catch (System::ArgumentOutOfRangeException^ ex) {
        System::Diagnostics::Debug::WriteLine("인덱스가 범위를 벗어났습니다!");
    }

    3. 다양한 상황에서의 성능

    문맥 결과 주목
    인덱스가 존재합니다 (e.g., Count=5, index=1) 올바른 값을 반환 정상 작동.
    인덱스가 존재하지 않습니다 (e.g., Count=1, index=1) ArgumentOutOfRangeException이 발생합니다. 프로그램이 실행을 중단합니다.
    네이티브 C++ 배열/std::벡터 [ ] 정의되지 않은 동작 잘못된 코드가 발생하거나 충돌이 발생할 수 있지만 .NET 예외가 적극적으로 발생하지는 않습니다.

    4. 예방 조치 요약



    C++ 표준 최대값 및 최소값

    1. C++ 표준 라이브러리 함수: std::min 및 std::max

    C++에서 가장 일반적으로 사용되는 도구는 다음에 정의되어 있습니다.<algorithm>~에std::min그리고std::max. 기본 유형, 객체 및 초기화 목록까지 지원합니다.

    #include <알고리즘>
    #include <iostream>
    #include <벡터>
    
    무효 기본_사용() {
        정수 a = 10, b = 20;
    
        // 1. 두 숫자를 비교합니다.
        int small = std::min(a, b);
        int Large = std::max(a, b);
    
        // 2. 초기화 목록 비교(C++11)
        int 최저 = std::min({5, 1, 9, 3}); // 1을 반환
    
        // 3. std::minmax (C++11) - 최대값과 최소값을 동시에 가져옵니다.
        자동 결과 = std::minmax({10, 20, 30, 40});
        표준::cout << "최소: " << 결과.첫번째 << ", 최대: " << 결과.초;
    }

    2. 숫자 제한: FLT_MAX 및 std::numeric_limits

    "최소" 변수를 초기화해야 하는 경우 일반적으로 해당 변수를 유형이 표현할 수 있는 가장 큰 양수로 설정하여 첫 번째 비교에서 업데이트되도록 합니다.

    C 스타일 제한(에서)

    C++ 스타일 제한(<limits> 사용 권장)

    std::numeric_limits숫자 속성을 얻기 위한 일관되고 템플릿화된 방법을 제공합니다. 이는 일반 코드를 작성할 때 매우 유용합니다.

    #include <한계>
    
    무효 제한_예제() {
        // 최대값을 구한다
        float max_f = std::numeric_limits<float>::max();
        int max_i = std::numeric_limits<int>::max();
    
        // "최소 양수"를 가져옵니다. (참고: 부동 소수점 숫자의 경우 min()은 최대 음수 대신 최소 양수를 반환합니다.)
        float min_긍정적_f = std::numeric_limits<float>::min();
    
        // "최저값"(실제 가장 작은 음수)을 구합니다.
        float lower_f = std::numeric_limits<float>::lowest();
    }

    3. 컬렉션의 최대값과 최소값: std::min_element

    당신이 다루고 있다면std::vector또는 배열을 사용해야 합니다.std::min_element또는std::max_element, 그들이 반환하는 것은반복자

    #include <벡터>
    #include <알고리즘>
    
    무효 collection_example() {
        표준::벡터<float> 점수 = {88.5f, 92.0f, 79.5f, 100.0f};
    
        // 최대값의 반복자를 가져옵니다.
        자동 it = std::max_element(scores.begin(), Scores.end());
    
        if (it != Score.end()) {
            표준::cout << "최고 점수: " << *그것;
        }
    }

    4. 주요 차이점과 함정

    이름 사용 주의할 점
    FLT_MAX 최소값 검색 초기화 에 정의됨<cfloat>는 C의 레거시 매크로입니다.
    std::min 두 숫자 또는 목록 비교 매개변수 유형이 일관되지 않은 경우(예: int 및 long) 템플릿을 명시적으로 지정해야 합니다.std::min<long>(a, b)
    lowest() 가장 작은 음수를 얻으세요 부동 소수점 숫자에서는min()0에 가까운 가장 작은 양수이고,lowest()최대 음수 값입니다.
    min_element 검색 컨테이너 반환되는 것은 Iterator이며, 이를 사용하기 전에 컨테이너가 비어 있는지 확인해야 합니다.


    C++ std는 파이를 얻습니다.

    개요

    C++ 표준 수학 라이브러리에서는 $\pi$의 상수 정의가 C++20까지 공식적으로 표준화되지 않았지만 다양한 C++ 버전 및 컴파일러 환경에서 pi의 대략적인 값을 얻기 위해 일반적으로 사용되는 몇 가지 방법이 있습니다.

    코드 이식성과 정확성을 보장하기 위해 가장 권장되는 접근 방식은std::numbers::pi

    1. C++20 표준 상수 사용(권장)

    C++20부터 표준 라이브러리는 다음과 같습니다.<numbers>정확하고 유형이 안전한 수학 상수가 헤더 파일에 제공됩니다.

    헤더 파일:

    사용 방법:

    #include <iostream>
    #include <숫자> // C++20에 도입됨
    
    use_cpp20_pi() 무효
    {
        // std::numbers::pi_v<T> T 유형에 따라 정확한 값을 제공하는 템플릿 변수입니다.
        // std::numbers::pi(<T> 제외)는 std::numbers::pi_v<double>와 동일합니다.
        
        double pi_double = std::숫자::pi;
        float pi_float = std::numbers::pi_v<float>
        long double pi_long_double = std::numbers::pi_v<long double>
    
        표준::cout.precision(16); // 출력 정밀도 설정
        표준::cout << "C++20(이중): " << pi_double << 표준::endl;
        표준::cout << "C++20(부동 소수점): " << pi_float << 표준::endl;
    }

    2. 기존 C 언어(C++17 이하)의 매크로를 사용하세요.

    C++20 이전에는 많은 개발자가 C 수학 라이브러리(<cmath>또는<math.h>)은 비표준 매크로를 제공합니다. 이러한 매크로는 대부분의 최신 시스템에 존재하지만 C++ 표준의 일부가 아니며 모든 환경에서 작동이 보장되지는 않습니다.

    헤더 파일:

    사용 방법:

    #include <iostream>
    #include <cmath> // 전통적인 C 수학 라이브러리
    
    무효 use_c_macro_pi()
    {
        // M_PI는 가장 일반적인 PI 매크로로, 일반적으로 double 유형으로 정의됩니다.
        // 참고: 이 매크로를 활성화하려면 일부 시스템에서 _USE_MATH_DEFINES 매크로를 정의해야 할 수도 있습니다.
        
        #ifdef M_PI
            이중 pi_value = M_PI;
            표준::cout.precision(16);
            표준::cout << "C 매크로(M_PI): " << pi_값 << 표준::endl;
        #else
            표준::cout << "M_PI 매크로가 정의되지 않았습니다. _USE_MATH_DEFINES를 정의해야 할 수도 있습니다." << 표준::endl;
        #endif
    }

    3. 스스로 계산하거나 정의하십시오.

    C++20 또는 C 매크로를 사용할 수 없는 경우 $\pi$를 상수로 정의하거나 수학 함수를 사용하여 계산할 수 있습니다(예: $\arccos(-1)$).

    사용 방법:

    #include <iostream>
    #include <cmath>
    
    무효 정의 또는 계산_pi()
    {
        // 수학적 연산을 통해 정의합니다.
        const double PI_CUSTOM_CALC = std::acos(-1.0);
        
        // 상수로 직접 정의합니다.
        const double PI_CUSTOM_DEFINE = 3.14159265358979323846;
    
        표준::cout.precision(16);
        표준::cout << "사용자 정의 계산: " << PI_CUSTOM_CALC << 표준::endl;
        표준::cout << "사용자 정의: " << PI_CUSTOM_DEFINE << 표준::endl;
    }

    권장 요약



    목록의 표준 편차 계산

    샘플 프로그램

    #include <cmath>
    #include <iostream>
    네임스페이스 시스템 사용;
    네임스페이스 System::Collections::Generic 사용;
    
    정수 메인()
    {
        //테스트 데이터 생성
        Dictionary^>^ data = gcnew Dictionary^>();
        data->Add(1, gcnew List({ 1.2f, 2.3f, 3.4f }));
        data->Add(2, gcnew List({ 4.5f, 5.5f, 6.5f, 7.5f }));
        data->Add(3, gcnew List<float>()); // 빈 목록 테스트
    
        // 각 키의 표준편차를 계산합니다.
        각각에 대해 (KeyValuePair^> 데이터 항목)
        {
            int 키 = 항목.키;
            List^ 값 = 항목.값;
    
            if (값 == nullptr || 값->개수 == 0)
            {
                Console::WriteLine("키 {0}: 데이터 없음", key);
                계속하다;
            }
    
            // 평균 계산
            이중 합계 = 0.0;
            각각에 대해 (값에 v를 띄움)
            {
                합계 += v;
            }
            이중 평균 = 합계 / 값 -> 개수;
    
            // 돌연변이 수(모계 돌연변이 수)를 계산합니다.
            이중 분산 = 0.0;
            각각에 대해 (값에 v를 띄움)
            {
                이중 차이 = v - 평균;
                분산 += diff * diff;
            }
            분산 /= 값->개수; // 샘플 변형을 원하면 (values->Count - 1)로 변경합니다.
    
            // 표준편차
            double stddev = Math::Sqrt(분산);
    
            Console::WriteLine("키 {0}: 표준 편차 = {1:F4}", key, stddev);
        }
    
        0을 반환합니다.
    }

    설명하다

    출력 예

    핵심 1: 표준편차 = 0.8981
    핵심 2: 표준편차 = 1.1180
    핵심 3: 정보 없음


    std::sort

    1. 기본 사용법

    std::sortC++ 표준 템플릿 라이브러리(STL)에서 가장 일반적으로 사용되는 정렬 알고리즘입니다. 위치해있습니다<algorithm>헤더 파일에서 기본적으로 범위 내의 요소는 다음과 같습니다.오름차순정렬합니다.

    #include <알고리즘>
    #include <벡터>
    #include <iostream>
    
    무효 기본_정렬() {
        std::벡터<int> 숫자 = {5, 2, 9, 1, 5, 6};
        
        // 정렬 범위: 시작 반복자부터 끝 반복자까지
        std::sort(nums.begin(), nums.end());
        
        // 결과: 1, 2, 5, 5, 6, 9
    }

    2. 사용자 정의 정렬 기준(내림차순 또는 특정 조건)

    세 번째 매개변수(비교 함수 또는 람다 식)를 전달하여 정렬 논리를 변경할 수 있습니다.

    // 1. 지수화를 위해 미리 정의된 std::greater를 사용합니다.
    std::sort(nums.begin(), nums.end(), std::greater<int>());
    
    // 2. 람다 표현식을 사용하여 로직 사용자 정의
    std::sort(nums.begin(), nums.end(), [](int a, int b) {
        a > b를 반환합니다. // true가 반환되면 a가 b보다 먼저 순위가 매겨집니다.
    });

    3. 구조 또는 카테고리 정렬

    사용자 정의 유형의 경우 비교 논리를 제공해야 합니다. 그렇지 않으면 컴파일러는 크기를 비교하는 방법을 모르기 때문에 오류를 보고합니다.

    구조체 학생 {
        표준::문자열 이름;
        정수 점수;
    };
    
    무효 sort_students() {
        std::벡터<학생> 학생 = {{"앨리스", 90}, {"밥", 85}, {"찰리", 95}};
        
        // 높은 점수에서 낮은 점수 순으로 정렬
        std::sort(students.begin(), Students.end(), [](const Student& a, const Student&b) {
            a.score > b.score를 반환합니다.
        });
    }

    4. 기본 원칙: 내부 정렬(Introsort)

    std::sort단일 정렬 알고리즘이 아닌, 각 알고리즘의 장점을 결합하고 최악의 시나리오를 방지하도록 설계된 하이브리드 알고리즘입니다. 그 운영 논리는 다음과 같습니다.


    성능 및 기능 요약

    특성 설명하다
    평균 시간 복잡도 $O(n \log n)$
    최악의 시간 복잡도 $O(n \log n)$ (Introsort 메커니즘의 이점)
    공간 복잡도 $O(\log n)$ (재귀 호출 스택)
    안정 불안정한(동일한 요소의 상대적 위치는 변경될 수 있습니다.) 안정적인 정렬이 필요한 경우 이용해주세요.std::stable_sort


    점과 직선 방정식의 상대적 위치 판단

    1. 수학적 원리: 포인트 값 대체

    선 $ax + by + c = 0$과 점 $P(x_0, y_0)$의 방정식이 주어지면 점과 선 사이의 관계를 결정하는 가장 빠른 방법은 다음을 계산하는 것입니다.거리 계수 $d$

    $$d = a \cdot x_0 + b \cdot y_0 + c$$

    $d$ 기호를 기반으로 선의 어느 쪽에 점이 있는지 알 수 있습니다. 그러나 주목해야 할 점은"위" 또는 "오른쪽"의 정의는 $a$ 및 $b$ 기호의 영향을 받습니다.


    2. 판정점은 선 위쪽(y가 작음)

    대부분의 컴퓨터 그래픽 좌표계에서 y축은 아래쪽 방향으로 양수입니다. y값이 작을수록 화면 위쪽으로 멀어집니다. 포인트 $P$가 선 위에 있는지 확인하기 위해 포인트가 선에서 동일한 $x_0$일 때 포인트의 $y_0$를 $y_{line}$과 비교합니다.

    // 직선의 방정식: ax + by + c = 0 => y = (-ax - c) / b
    bool isAbove(std::array<float, 3> line, float x0, float y0) {
        float a = 라인[0];
        float b = 라인[1];
        float c = 라인[2];
    
        // b가 0이면 수직선을 나타내며, 상한과 하한을 정의할 수 없다.
        if (std::abs(b) < 1e-6) 반환 false;
    
        float y_on_line = (-a * x0 - c) / b;
        
        // y가 작을수록 상단을 나타냅니다.
        y0 <를 반환합니다. y_on_line;
    }

    3. 판정점은 선의 오른쪽(x가 크다)

    같은 방식으로 한 지점의 $x_0$를 선의 동일한 $y_0$에 있는 $x_{line}$와 비교합니다.

    // 직선의 방정식: ax + by + c = 0 => x = (-by - c) / a
    bool isRight(std::array<float, 3> line, float x0, float y0) {
        float a = 라인[0];
        float b = 라인[1];
        float c = 라인[2];
    
        // a가 0이면 수평선을 나타내며, 왼쪽과 오른쪽을 정의할 수 없다.
        if (std::abs(a) < 1e-6) 반환 false;
    
        float x_on_line = (-b * y0 - c) / a;
    
        // 더 큰 x는 오른쪽을 나타냅니다.
        x0 > x_on_line을 반환합니다.
    }

    4. 빠른 판단표(표준화 가정)

    $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$ (가로가 아닌 선)

    구현 고려 사항



    직선 방향성 판단

    1. 판단논리 : 기울기와 계수의 비교

    직선 $ax + by + c = 0$의 방정식이 주어지면, 그것이 "수평선"으로 치우쳐 있는지 "직선"으로 치우쳐 있는지를 결정하는 가장 직관적인 방법은 직선과 좌표축 사이의 각도를 보는 것입니다. ~에 의해45도구분선은 $|a|$와 $|b|$의 크기를 비교하는 것과 동일합니다.


    2. 프로그램 코드 구현

    사용std::abs비교하다line[0]($a$) 및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]);
    
        만약 (a < b) {
            LineOrientation::Horizontal을 반환합니다.
        } else if (a > b) {
            LineOrientation::Vertical을 반환합니다.
        } 그렇지 않으면 {
            LineOrientation::Diagonal을 반환합니다.
        }
    }

    3. |a|를 비교하는 것으로 충분한 이유는 무엇입니까? 그리고 |b|?

    기울기 공식 $m = -\frac{a}{b}$에서:


    4. 판정기준표

    상태 분류 특징
    |a| < |b| 수평의 X축과의 각도가 작아서 "선 위/아래 지점"을 판단하는 데 적합합니다.
    |a| > |b| 수직의 Y축과의 각도가 작아서 "선의 왼쪽/오른쪽 점"을 판단하는 데 적합합니다.
    a = 0 절대 수평선 X축과 정확히 평행합니다.
    b = 0 절대 수직선 Y축과 정확히 평행합니다.

    실용적인 제안

    점대선 위치를 판단할 때 먼저 이 점검을 수행하는 것이 좋습니다.



    C++ 템플릿

    1. 템플릿이란 무엇입니까?

    C++에서 템플릿은 특정 데이터 유형을 지정하지 않고도 함수나 범주를 작성하여 코드를 더 쉽게 재사용할 수 있게 해주는 일반 프로그래밍 도구입니다. 템플릿은 중복된 함수나 클래스 정의를 방지하여 단일 코드에서 다양한 유형의 데이터를 처리하는 데 도움이 됩니다.

    2. 기능 템플릿

    함수 템플릿을 사용하면 다양한 유형을 처리할 수 있는 함수를 작성할 수 있습니다. 함수 템플릿의 구문은 다음과 같습니다.

    template <typename T>
    T add(T a, T b) {
        return a + b;
    }

    이 예에서는add이 함수는 다음과 같은 추가 작업을 지원하는 모든 유형을 처리할 수 있습니다.intfloat또는double

    이를 사용할 때 다음과 같이 호출할 수 있습니다.

    int 결과 = add(3, 4); // int형을 사용한다
    double result2 = add(3.5, 2.7); // 이중 유형 사용

    3. 클래스 템플릿

    카테고리 템플릿을 사용하면 여러 유형에 적용할 수 있는 카테고리를 만들 수 있습니다. 카테고리 템플릿의 구문은 다음과 같습니다.

    template <typename T>
    class MyClass {
    private:
        T data;
    public:
        MyClass(T data) : data(data) {}
        T getData() { return data; }
    };

    이 예에서는MyClass카테고리는 모든 유형의 데이터를 다음과 같이 사용할 수 있습니다.data

    다음과 같이 사용할 수 있습니다.

    MyClass<int> obj1(5); // 정수형
    MyClass obj2(3.14); // 이중 유형

    4. 다중 템플릿 매개변수

    템플릿은 다음과 같은 여러 매개변수를 허용할 수 있습니다.

    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);

    5. 템플릿 전문화

    템플릿 전문화를 통해 특정 유형의 템플릿을 구체적으로 정의할 수 있습니다. 예를 들어:

    템플릿 <>
    class MyClass<int> {
    공개:
        MyClass(int data) { /* 특수 동작 */ }
    };

    이 코드는 전문적입니다.MyClass오른쪽int다른 유형과 다르게 만드는 유형의 동작입니다.

    6. 비유형 템플릿 매개변수

    템플릿은 상수 값과 같은 비유형 매개변수도 허용할 수 있습니다.

    template <typename T, int Size>
    class Array {
    private:
        T data[Size];
    public:
        int getSize() const { return Size; }
    };

    여기,Size배열의 크기를 나타내는 비유형 매개변수입니다.

    사용 예:

    배열 arr; // 크기가 10인 int형 배열을 만듭니다.

    7. 결론

    C++ 템플릿은 강력하여 코드를 더욱 다양하게 만들고 중복을 줄입니다. 함수 템플릿, 카테고리 템플릿, 템플릿 전문화 등의 기술 사용 방법을 이해하면 프로그래밍의 유연성과 성능이 크게 향상됩니다.



    C++ 클래스 상호 참조

    1. 문제 배경

    C++에서 두 클래스가 서로 의존하고 동시에 서로의 멤버를 참조해야 하는 경우 해당 클래스에서 직접.h파일에#include상대방의 정의로 인해 순환 참조 문제가 발생하여 컴파일에 실패하게 됩니다. 해결책은 순환 참조를 피하기 위해 "정방향 선언"을 사용하는 것입니다.

    2. 해결 단계

    3. 코드 예시

    ClassA.h

    // 클래스A.h
    #ifndef CLASSA_H
    #CLASSA_H 정의
    
    // 전방 선언 ClassB
    클래스 B 클래스;
    
    클래스 클래스 A {
    공개:
        클래스A();
        무효 setB(ClassB* b); // 포인터를 ClassB로 설정
        무효 showBData(); // ClassB 데이터 표시
    
    비공개:
        클래스B* b; // ClassB에 대한 포인터
    };
    
    #endif

    ClassB.h

    // 클래스B.h
    #ifndef CLASSB_H
    #CLASSB_H 정의
    
    // 전방 선언 ClassA
    클래스 A 클래스;
    
    클래스 클래스B {
    공개:
        ClassB(정수 데이터);
        int getData(); // 데이터 가져오기
        무효 setA(ClassA* a); // 포인터를 ClassA로 설정
        무효 showAInfo(); // ClassA 정보 표시
    
    비공개:
        정수 데이터;
        클래스A* a; // ClassA에 대한 포인터
    };
    
    #endif

    ClassA.cpp

    
    #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;
        }
    }
            

    ClassB.cpp

    
    #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();
        }
    }
            

    4. 구현 지침



    C++ Friend

    C++에서는friend함수나 클래스에 키워드를 사용하면 다른 함수나 클래스가 클래스의 비공개 및 보호 멤버에 액세스할 수 있습니다. 이러한 설계를 통해 외부 함수나 클래스가 캡슐화 원칙을 위반하지 않고 작동할 수 있습니다.

    1. 친구 기능

    Friend 함수는 다른 클래스의 private 및 protected 멤버에 대한 액세스 권한이 부여된 외부 함수입니다. 카테고리 내에서 선언되면 다음으로 끝납니다.friend키워드를 수정하면 됩니다.

    예는 다음과 같습니다:

    #include <iostream>
    네임스페이스 std 사용;
    
    클래스 박스 {
    비공개:
        이중 너비;
    
    공개:
        상자(더블 w) : 너비(w) {}
    
        //친구 함수 선언
        친구 void showWidth(Box &b);
    };
    
    //Friend 함수 정의, Box 클래스의 비공개 멤버에 액세스할 수 있음
    void showWidth(박스 &b) {
        cout << "상자 너비: " << b.폭 << 끝;
    }
    
    정수 메인() {
        박스박스(10.5);
        showWidth(상자); // 비공개 멤버 너비에 액세스합니다.
        0을 반환합니다.
    }

    이 예에서는showWidthBox 카테고리 밖의 일반 함수임에도 불구하고, friend 함수로 선언되어 있기 때문에 Box 카테고리의 private 멤버에 계속 접근할 수 있습니다.width

    2. 친구 카테고리

    Friend 클래스를 사용하면 한 클래스가 다른 클래스의 모든 멤버에 액세스할 수 있습니다. 이러한 설정은 카테고리가 긴밀하게 함께 작동해야 할 때 유용하지만 너무 많은 내부 세부 정보가 노출되지 않도록 주의해서 사용해야 합니다.

    예는 다음과 같습니다:

    #include <iostream>
    네임스페이스 std 사용;
    
    클래스 스퀘어; // 전방 선언
    
    클래스 직사각형 {
    비공개:
        이중 너비, 높이;
    
    공개:
        직사각형(더블 w, 더블 h) : 너비(w), 높이(h) {}
    
        // Square 카테고리를 친구로 선언합니다.
        친구 클래스 광장;
    };
    
    클래스 광장 {
    공개:
        double AreaOfRectangle(사각형 &사각형) {
            각형.너비 * 각형 높이를 반환합니다.
        }
    };
    
    정수 메인() {
        직사각형 직사각형(5.0, 3.0);
        정사각형 정사각형;
        cout << "직사각형의 면적: " << square.areaOfRectangle(직사각형) << 끝;
        0을 반환합니다.
    }

    이 예제에서는 Square 클래스가 Rectangle 클래스의 friend 클래스로 선언되었으므로 Square 클래스의 멤버 함수가 Rectangle 클래스의 전용 멤버에 직접 액세스할 수 있습니다.width그리고height

    3. 친구 기능 및 친구 카테고리 적용 시나리오

    C++에서 친구 함수와 친구 클래스를 사용할 때는 주의하세요. 과도하게 사용하면 클래스의 캡슐화가 파괴됩니다. 따라서 friend 키워드는 일반적으로 긴밀한 협력이 필요한 클래스나 함수를 설계할 때만 사용됩니다.



    C++ 파일을 한 줄씩 읽습니다.

    개요

    C++에서 텍스트 파일을 한 줄씩 읽는 가장 표준적이고 권장되는 방법은 표준 라이브러리의 파일 스트리밍 클래스를 사용하는 것입니다.std::ifstream맞잡다std::getline기능.

    std::ifstream파일 스트리밍 열기 및 관리를 담당하며,std::getline개행 문자가 나타날 때까지 스트림에서 전체 텍스트 줄을 읽는 일을 담당합니다.\n)에 저장하고std::string개체에서.

    코드 예시

    다음은 다음과 같은 파일을 한 줄씩 읽는 방법을 보여주는 완전한 C++ 예제입니다.example.txt파일 내용.

    #include <iostream>
    #include <fstream> // 파일 스트리밍 라이브러리 포함
    #include <string> // 문자열 카테고리 포함
    
    네임스페이스 std 사용;
    
    void read_file_line_by_line(const string& 파일명)
    {
        // 1. std::ifstream 객체 생성
        //지정된 파일을 열려고 시도합니다.
        ifstream input_file(파일명);
        
        // 2. 파일이 성공적으로 열렸는지 확인
        if (!input_file.is_open())
        {
            cerr << "오류: 파일을 열 수 없습니다." << 파일명 << 끝;
            반품;
        }
        
        스트링라인;
        int line_number = 1;
        
        // 3. std::getline 함수를 사용하여 한 줄씩 읽습니다.
        // 루프 조건(getline(stream, string))은 읽기가 성공할 때마다 true를 반환합니다.
        // 파일 끝(EOF)에 도달하거나 오류가 발생하면 false를 반환하고 루프가 종료됩니다.
        while (getline(input_file, line))
        {
            cout << "라인" << line_number << ": " << 라인 << 끝;
            line_number++;
        }
        
        // 4. 파일 스트리밍 닫기
        // input_file 객체가 범위를 초과하면 소멸자는 자동으로 파일을 닫습니다.
        // 하지만 close()를 명시적으로 호출하는 것도 허용됩니다.
        input_file.close();
        
        cout << "파일 읽기가 완료되었습니다." << 끝;
    }
    
    정수 메인()
    {
        read_file_line_by_line("example.txt");
        0을 반환합니다.
    }

    주요 개념



    C++ 파일을 한 줄씩 쓰고 필드 정렬

    개요

    C++에서 데이터 구조 변환(예:std::vector<std::string>파일을 한 줄씩 쓰고(토큰 읽기) 각 열(토큰)이 줄에서 고정 너비 정렬을 유지하는지 확인하려면 **를 사용해야 합니다.std::ofstream** **I/O 스트림 조작기**를 사용하여 출력 형식을 제어합니다.

    주요 형식 제어 도구는 다음과 같습니다.

    코드 예시

    다음은 여러 필드가 포함된 2차원 데이터 구조를 변환하는 방법에 대한 C++ 예제입니다(사용).std::vector<std::vector<std::string>>시뮬레이션) 파일을 작성하고 각 토큰 필드의 너비가 15자로 고정되어 있고 왼쪽 정렬되어 있는지 확인하세요.

    #include <iostream>
    #include <fstream> // 파일 출력 스트림 포함
    #include <string>
    #include <벡터>
    #include <iomanip> // I/O 스트림 조작기 포함(setw, 왼쪽/오른쪽)
    
    네임스페이스 std 사용;
    
    // 2차원 데이터 구조를 시뮬레이션합니다. 각 행에는 여러 필드(토큰)가 포함됩니다.
    TableData = 벡터<벡터>string>>을 사용하여;;
    
    void write_aligned_data(const string& 파일명, const TableData& 데이터, int 컬럼_폭)
    {
        // 1. std::ofstream 객체를 생성하고 파일을 엽니다.
        ofstream 출력_파일(파일명);
        
        // 2. 파일이 성공적으로 열렸는지 확인
        if (!output_file.is_open())
        {
            cerr << "오류: 파일을 열 수 없습니다. " << 파일명 << "글을 쓰기 위해." << 끝;
            반품;
        }
    
        //전역 정렬 설정: 왼쪽 정렬(L-Justified)
        출력_파일 << 왼쪽;
        
        // 3. 한 줄씩 데이터 쓰기
        for(const auto&row : 데이터)
        {
            // 4. 토큰별로 토큰을 쓰고 너비를 설정합니다.
            for(const auto&token : 행)
            {
                // setw(width)는 바로 다음 출력 항목에만 영향을 미칩니다.
                출력_파일 << setw(column_width) << 토큰;
            }
            
            // 5. 줄 끝 뒤에 개행 문자를 삽입하여 새 줄을 시작합니다.
            출력_파일 << "\N";
        }
        
        // 6. 파일 스트리밍 닫기
        출력_파일.닫기();
        
        cout << "데이터가 파일에 성공적으로 기록되었습니다: " << 파일명 << 끝;
    }
    
    정수 메인()
    {
        //샘플 데이터: 4개의 행을 포함하며 각 행에는 3개의 필드가 있습니다.
        TableData 데이터 = {
            {"이름", "품목", "가격"},
            {"앨리스", "책", "19.99"},
            {"밥존슨", "펜세트", "4.50"},
            {"찰리", "노트북", "800.75"}
        };
        
        const int COLUMN_WIDTH = 15; // 각 열의 너비를 정의합니다.
        
        write_aligned_data("output_aligned.txt", 데이터, COLUMN_WIDTH);
        
        0을 반환합니다.
    }

    핵심기술 분석



    vcpkg C++ 패키지 관리자

    1. vcpkg 소스 코드 다운로드

    vcpkg는 설치 파일을 통해 설치되지 않고, GitHub에서 로컬로 소스 코드를 직접 복사합니다. 디스크의 루트 디렉터리(예:C:\vcpkg) 너무 길거나 공백이 포함된 경로를 피합니다. 터미널(CMD 또는 PowerShell)을 열고 다음을 실행하십시오.

    git clone https://github.com/microsoft/vcpkg.git
    cd vcpkg

    2. 초기 컴파일 수행(부트스트랩)

    다운로드한 후 스크립트를 실행하여 vcpkg의 실행 파일을 컴파일해야 합니다.vcpkg.exe

    3. 개발 환경에 통합

    이 단계를 통해 Visual Studio 등의 개발 도구가 vcpkg에 의해 설치된 패키지를 자동으로 인식할 수 있습니다.

    공통 명령어 비교표

    지침 설명하다
    search 사용 가능한 패키지 검색 vcpkg search libuv
    install 지정된 패키지 설치 vcpkg install libuv:x64-windows
    list 설치된 패키지 나열 vcpkg list
    update 패키지 버전 업데이트 확인 vcpkg update

    환경 변수 설정(권장)

    모든 경로에서 vcpkg를 쉽게 사용하려면 vcpkg 폴더 경로를 시스템에 추가하는 것이 좋습니다.PATH환경 변수에서. 또한 64비트 패키지를 기본으로 설치하려는 경우 환경 변수를 추가할 수 있습니다.VCPKG_DEFAULT_TRIPLET그 값을 다음과 같이 설정합니다.x64-windows

    주의할 점

    Windows에서 vcpkg를 사용하기 전에 vcpkg가 설치되어 있는지 확인하세요.Visual Studio 2015 이상, "C++를 사용한 데스크톱 개발" 워크로드(영어 언어 팩 포함)를 확인하세요. 그렇지 않으면 패키지 컴파일 시 오류가 발생할 수 있습니다.



    주변제어 프로그램 개발

    정의

    주변기기 제어 프로그램은 컴퓨터나 호스트에 연결된 외부 하드웨어 장치(예: 프린터, 스캐너, 모터, PLC, 센서 등)와 통신하고 작동하는 데 사용되는 응용 프로그램입니다.

    일반적인 통신 인터페이스

    공통 개발 언어 및 환경

    언어적용 가능한 상황주목
    Python신속한 개발, 테스트 자동화직렬, USB HID에 적용 가능
    C/C++임베디드 제어 및 드라이버 개발낮은 수준의 메모리 및 하드웨어에 대한 액세스
    C#Windows UI + 제어 장치COM 포트 및 USB 통신에 적합
    Java크로스 플랫폼 제어저가형 장치에서는 덜 일반적으로 사용됩니다.

    예제 1: Python을 사용하여 직렬 포트 제어

    수입 시리얼
    
    ser = serial.Serial('COM3', 9600, 시간 초과=1)
    ser.write(b'ON\n') # 제어 명령 보내기
    응답 = ser.readline()
    print("장치 응답:", response.decode())
    ser.close()

    예제 2: C#은 COM 포트 장치를 제어합니다.

    SerialPort 포트 = new SerialPort("COM4", 9600);
    포트.열기();
    port.WriteLine("MOVE 100");
    문자열 응답 = port.ReadLine();
    Console.WriteLine("응답: " + 응답);
    포트.닫기();

    예 3: USB HID 장치 제어

    예 4: TCP 통신 제어 주변 장치

    수입 소켓
    
    s = 소켓.소켓()
    s.connect(('192.168.1.100', 5000))
    s.sendall(b'START\n')
    데이터 = s.recv(1024)
    print("응답:", data.decode())
    s.닫기()

    적용사례

    주의할 점

    결론적으로

    주변기기 제어 프로그램 개발에는 장치의 인터페이스와 프로토콜을 기반으로 적절한 언어와 기능 라이브러리를 선택하고 직렬, USB, 네트워크 및 기타 통신 방법을 결합해야 하며 이는 다양한 자동화 및 산업 제어 분야에서 널리 사용될 수 있습니다.



    바코드 리더 프로그램 개발

    공통 플랫폼 지원

    일반적인 바코드 유형

    일반적인 개발 키트 및 도구

    Android 개발 예시(ZXing 사용)

    // build.gradle
    구현 'com.journeyapps:zxing-android-embedded:4.3.0'
    
    //Java 호출 스캔 화면
    IntentIntegrator 통합자 = new IntentIntegrator(this);
    integrator.setPrompt("바코드를 스캔해주세요");
    integrator.setBeepEnabled(true);
    integrator.setOrientationLocked(false);
    integrator.initiateScan();
    //onActivityResult가 결과를 받습니다.
    @오버라이드
    protected void onActivityResult(int requestCode, int resultCode, 인텐트 데이터) {
        IntentResult 결과 = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if(결과 != null) {
            if(result.getContents() != null) {
                문자열 바코드 = result.getContents();
                Log.d("바코드 내용", 바코드);
            }
        }
    }

    웹 개발 예제(QuaggaJS 사용)

    <script src="https://unpkg.com/[email protected]/dist/quagga.min.js"></script>
    
    <스크립트>
    Quagga.init({
        입력스트림: {
            이름: "라이브",
            유형: "라이브스트림",
            대상: document.querySelector('#scanner')
        },
        디코더: {
            독자: ["code_128_reader", "ean_reader", "upc_reader"]
        }
    }, 함수(err) {
        만약 (!err) {
            Quagga.start();
        }
    });
    
    Quagga.onDetected(함수(결과) {
        console.log("바코드 내용: ", result.codeResult.code);
    });
    </스크립트>

    플랫폼과 제품군 비교

    플랫폼추천 키트무료인가요?
    AndroidZXing / ML Kit
    WebQuaggaJS / jsQR
    WindowsDynamsoft / ZXing.NET상업용 다이나믹소프트
    PythonZBar / pyzbar

    결론적으로

    바코드 리더를 개발하려면 플랫폼에 따라 적절한 오픈 소스 패키지를 선택할 수 있습니다. ZXing은 가장 널리 지원되는 선택입니다. QuaggaJS는 웹에서 사용할 수 있습니다. 상용 수준의 지원이 필요한 경우 Dynamsoft Barcode SDK를 고려해 볼 수 있습니다.



    제어 문자가 포함된 바코드

    기본 원리

    바코드 판독기는 기본적으로 키보드 입력을 시뮬레이션하는 장치입니다. 바코드가 스캔되면 키보드 입력과 마찬가지로 바코드의 내용을 문자 스트림으로 "출력"합니다.

    그러므로 바코드는제어 코드(Control Code)를 포함할 수 있습니다.,하지만바코드 리더 및 바코드 형식 지원이 필요합니다.괜찮아요.

    바코드의 일반적인 제어 코드 유형

    조건 1: 바코드 형식은 제어 코드를 지원해야 합니다.

    예를 들어, 다음 형식은 제어 코드를 인코딩할 수 있습니다.

    조건 2: 바코드 인코딩 도구는 내장 제어 코드를 지원해야 합니다.

    일부 바코드 생성기는 다음과 같은 특수 문자 삽입을 허용합니다.

    조건 3: 바코드 스캐너는 출력 제어 코드를 지원해야 합니다.

    대부분의 전문 바코드 프린터(예: Zebra, Honeywell)는 공장에서 미리 설정되어 있습니다.제어 코드 출력 비활성화, 스캐너에서 제공하는 "설정 바코드"를 통해 활성화해야 합니다.

    조건 4: 운영 체제와 애플리케이션이 이를 올바르게 수신해야 합니다.

    예를 들어 Windows 애플리케이션의 경우:

    예: Ctrl-C 바코드 콘텐츠 인코딩

    Code128로 ASCII 3 인코딩:

    입력:\x03Hello World

    바코드가 스캔되면 Ctrl+C가 실행되고 "Hello World"가 출력됩니다.

    결론적으로



    안드로이드 개발

    안드로이드 개발 플랫폼

    플랫폼 소개

    안드로이드(Android)는 구글이 개발한 오픈소스 모바일 운영체제로 스마트폰, 태블릿, 기타 스마트 기기에 널리 사용된다. 개발자는 풍부한 API와 도구를 사용하여 다양한 애플리케이션을 만들 수 있습니다.

    개발 도구

  • Android Studio: Google에서 공식적으로 제공하는 통합 개발 환경(IDE)으로 코드 편집, 시뮬레이터 테스트, 디버깅 기능을 지원합니다.
  • Kotlin 및 Java: Android 개발에 사용되는 주요 프로그래밍 언어이며, 그중 Kotlin이 공식적으로 권장되는 언어입니다.
  • Android SDK: 애플리케이션 개발 및 테스트를 지원하기 위한 에뮬레이터, API 라이브러리 및 도구 세트를 제공합니다.
  • Gradle: 종속성을 관리하고 자동화를 구축하기 위한 도구입니다.

    애플리케이션 수명주기

  • 시작(onCreate): 애플리케이션이 리소스를 시작하고 초기화합니다.
  • 실행(onStart): 화면이 사용자에게 표시됩니다.
  • 활동(onResume): 애플리케이션이 대화형 상태로 들어갑니다.
  • Pause(onPause): 애플리케이션이 부분적으로 숨겨지거나 포커스를 잃습니다.
  • 중지(onStop): 완전히 숨겨져 있으며 시스템에서 재활용될 수 있습니다.
  • Destroy(onDestroy): 애플리케이션이 닫히고 모든 리소스가 해제됩니다.

    장점

  • 개방성: 사용자 정의 및 광범위한 장치 호환성을 지원합니다.
  • 시장 규모: Google Play는 글로벌 앱 게시 기회를 제공합니다.
  • 강력한 도구: 풍부한 개발 도구와 파일 리소스는 개발 효율성을 높이는 데 도움이 됩니다.

    학습 자료

  • 공식 문서: Android 개발자는 자세한 문서와 예제를 제공합니다.
  • 개발 커뮤니티: Stack Overflow 및 Reddit과 같은 플랫폼은 기술 지원을 제공합니다.
  • 온라인 강좌: Udemy, Coursera 또는 YouTube에서 관련 강좌를 선택할 수 있습니다.

    결론

    Android 개발 플랫폼은 유연성과 강력한 기능으로 많은 개발자의 관심을 끌었으며 모바일 애플리케이션 개발을 위한 첫 번째 선택 중 하나가 되었습니다.

    Android Studio를 사용하는 Chromebook

    설치 단계

    1. 켜다설정 → 개발자 → Linux 개발 환경(Crostini), 최소 20GB의 디스크 공간과 8GB의 메모리를 할당하십시오.
    2. 업데이트 키트:
      sudo apt update && sudo apt upgrade -y
      sudo apt install -y wget curl unzip zip git ca-certificates
    3. JDK 설치(버전 17 권장):
      sudo apt install -y openjdk-17-jdk
    4. Android 스튜디오를 다운로드하고 설치합니다.
      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
    5. 설치 마법사를 따라 SDK 및 도구 설정을 완료하세요.

    실제 장치로 테스트

    1. ChromeOS에서:설정 → 개발자 → Linux → USB 장치, Linux와 휴대폰을 공유하려면 확인란을 선택하세요.
    2. 전화를 켜세요개발자 옵션 → USB 디버깅, 연결 시 RSA 핑거프린팅을 허용합니다.
    3. Linux 환경 확인 장치:
      sudo apt install -y android-sdk-platform-tools
      adb kill-server
      adb start-server
      adb devices

    성능 및 에뮬레이터 권장 사항

    대안



    Chromebook은 VS Code + Android SDK를 사용합니다.

    VS 코드 설치

    1. Chrome OS를 켜세요설정 → 개발자 → Linux 개발 환경(Crostini)
    2. VS Code Linux 버전(.deb 파일)을 다운로드하여 Linux 컨테이너에 설치합니다.
      sudo dpkg -i ~/Downloads/code_*.deb || sudo apt -f install -y
    3. VS Code를 시작하고 일반적으로 사용되는 확장(예:KotlinFlutterJava Extension Pack)。

    Android SDK 및 도구 설치

    1. 필요한 패키지를 설치합니다:
      sudo apt update && sudo apt install -y openjdk-17-jdk unzip git
    2. Android SDK 명령줄 도구 다운로드:
      wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
      unzip commandlinetools-linux-*_latest.zip -d ~/android-sdk
    3. 환경 변수 설정(추가 가능)~/.bashrc또는~/.zshrc):
      export ANDROID_SDK_ROOT=$HOME/android-sdk
      export PATH=$ANDROID_SDK_ROOT/cmdline-tools/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH
    4. sdkmanager를 사용하여 플랫폼 도구와 필요한 패키지를 설치합니다.
      sdkmanager "platform-tools" "platforms;android-34" "build-tools;34.0.0"

    실제 휴대폰 테스트에 연결

    1. ChromeOS에서:설정 → 개발자 → Linux → USB 장치, 전화 공유를 확인하세요.
    2. 전화를 켜세요개발자 옵션 → USB 디버깅
    3. Linux 컨테이너 확인 장치:
      adb devices
      보다device테스트를 배포할 준비가 되었습니다.

    VS Code에서 개발

    상황에 적합



    안드로이드 앱 예시

    새 프로젝트 만들기

    Android Studio에서 새 프로젝트를 생성하고 "Empty Activity" 템플릿을 선택한 후 프로젝트 이름과 기타 기본 정보를 설정합니다.

    작성 인터페이스(activity_main.xml)

    존재하다res/layout/activity_main.xml파일에 설계된 간단한 사용자 인터페이스(예: 버튼 및 텍스트 표시 영역 포함):

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="수직"
                android:gravity="center">
            
                <버튼
                    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)

    존재하다MainActivity.java, 버튼의 클릭 이벤트를 설정하여 텍스트 표시 영역의 내용을 변경합니다.

    패키지 com.example.simpleapp;
    
            import android.os.Bundle;
            import android.view.View;
            import android.widget.Button;
            import android.widget.TextView;
            androidx.appcompat.app.AppCompatActivity 가져오기;
    
            공개 클래스 MainActivity는 AppCompatActivity를 확장합니다.
                @오버라이드
                protected void onCreate(Bundle saveInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
    
                    버튼버튼 = findViewById(R.id.button);
                    TextView textView = findViewById(R.id.textView);
    
                    버튼.setOnClickListener(새 View.OnClickListener() {
                        @오버라이드
                        공개 무효 onClick(보기 v) {
                            textView.setText("버튼을 클릭하셨습니다!");
                        }
                    });
                }
            }

    애플리케이션 실행

    Android Studio에서 실행 버튼을 클릭하여 에뮬레이터나 연결된 실제 기기에서 앱을 테스트하세요. 버튼을 클릭하면 텍스트가 "버튼을 클릭했습니다!"로 변경됩니다.



    Android는 현재 GPS 위치를 얻습니다.

    권한 설정

    존재하다AndroidManifest.xml다음 권한을 추가합니다.

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    권한 확인 및 요청하기(Android 6.0 이상)

    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 = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    현재 위치 가져오기

    LocationListener locationListener = 새로운 LocationListener() {
        @오버라이드
        공개 무효 onLocationChanged(@NonNull 위치 위치) {
            이중 위도 = location.getLatitude();
            이중 경도 = location.getLongitude();
            Log.d("GPS", "위도: " + 위도 + ", 경도: " + 경도);
        }
    };
    
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        == PackageManager.PERMISSION_GRANTED) {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
            1000, // 밀리초 간격
            1, // 최소 거리(미터)
            위치리스너);
    }

    FusedLocationProviderClient 사용(권장)

    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);
                }
            });
    }


    사운드 제어 Android 앱

    기본 개념

    Siri 또는 Hey Google과 같은 음성 지원 기능을 구현하려면 다음 구성 요소를 결합해야 합니다.

    필요한 권한 추가

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    음성인식 초기화

    SpeechRecognizer recognitionr = SpeechRecognizer.createSpeechRecognizer(this);
    의도 의도 = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    의도.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
    
    recognitionr.setRecognitionListener(새로운 RecognitionListener() {
        @오버라이드
        public void onResults(번들 결과) {
            배열목록<String> 일치 = 결과.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            if (일치 != null && !matches.isEmpty()) {
                문자열 명령 = match.get(0).toLowerCase();
                if (command.contains("카메라 열기")) {
                    // 작업 수행
                }
            }
        }
        //기타 필요한 덮어쓰기 방법은 생략
    });
    
    recognitionr.startListening(의도);

    음성합성(사용자에 대한 응답)

    TextToSpeech tts = new TextToSpeech(this, status -> {
        if (상태 == TextToSpeech.SUCCESS) {
            tts.setLanguage(Locale.TAIWAN);
            tts.speak("안녕하세요, 저는 여기 있습니다.", TextToSpeech.QUEUE_FLUSH, null, null);
        }
    });

    영구 백그라운드 모니터링(선택 사항)

    배경을 유지하고 음성으로 깨우려면 다음을 사용해야 합니다.

    주의할 점



    영구 백그라운드 모니터링

    목적

    영구 백그라운드 모니터링의 목표는 화면이 열려 있지 않을 때에도 앱이 음성 깨우기 단어(예: "Hey Assistant")를 감지하고 해당 기능을 활성화할 수 있도록 하는 것입니다.

    도전

    솔루션 아키텍처

    1. 사용전망 서비스(포그라운드 서비스)는 계속 작동합니다.
    2. 음성 깨우기 채택Porcupine오프라인 핫워드 엔진을 기다립니다.
    3. 성공적으로 깨어난 후 시작하세요.SpeechRecognizer완전한 음성 명령을 인식합니다.

    1단계: 유망 서비스 구축

    공개 클래스 VoiceService는 서비스를 확장합니다.
        @오버라이드
        public int onStartCommand(의도 의도, int 플래그, int startId) {
            알림 알림 = newNotificationCompat.Builder(this, "voice_channel")
                .setContentTitle("음성비서가 작동 중입니다.")
                .setSmallIcon(R.drawable.ic_mic)
                .빌드();
            startForeground(1, 알림);
    
            //핫워드 감지 초기화
            startHotwordDetection();
            START_STICKY 반환;
        }
    
        @오버라이드
        공개 IBinder onBind(의도 의도) {
            null을 반환;
        }
    }

    2단계: 알림 채널 만들기(Android 8+)

    NotificationChannel channel = new NotificationChannel("voice_channel",
        "Voice Assistant", NotificationManager.IMPORTANCE_LOW);
    NotificationManager manager = getSystemService(NotificationManager.class);
    manager.createNotificationChannel(channel);

    3단계: 음성 깨우기에 Porcupine 사용

    Porcupine은 맞춤 키워드를 인식하고 완전히 오프라인으로 작동하는 Android SDK를 제공합니다.

    PorcupineManager porcupineManager = 새로운 PorcupineManager.Builder()
        .setAccessKey("귀하의 키")
        .setKeywordPath("hey_assistant.ppn")
        .set감도(0.7f)
        .build((keywordIndex) -> {
            //깨어났을 때 음성 인식을 위해 SpeechRecognizer를 호출합니다.
            startSpeechRecognition();
        });
    
    고슴도치관리자.start();

    4단계: 서비스 시작

    Intent serviceIntent = new Intent(this, VoiceService.class);
    ContextCompat.startForegroundService(this, serviceIntent);

    주의할 점



    Hey Google Voice Assistant 최적화

    사용자 측 최적화 제안

    개발자 측 최적화 방법

    음성 깨우기 트리거 조건 최적화

    제한 사항에 유의하세요.



    Apple 제품 프로그램 개발

    개발 도구

    개발 환경 설정

    1. 최신 버전의 다운로드 및 설치Xcode

    2. Xcode를 열고 다음으로 이동합니다.Preferences > Accounts, 개발자 기능을 활성화하려면 Apple ID로 로그인하세요.

    3. Xcode를 통해 설치Command Line ToolsSwift 명령줄 도구를 사용합니다.

    개발 플랫폼

    프로젝트 생성

    1. Xcode를 열고 "새 Xcode 프로젝트 만들기"를 선택합니다.

    2. 적합한 애플리케이션 템플릿을 선택합니다.App (iOS/macOS)。

    3. 프로젝트 이름, 번들 식별자 및 언어(Swift 또는 Objective-C)를 설정합니다.

    4. UI 프레임워크(SwiftUI 또는 UIKit)를 선택합니다.

    시뮬레이션 및 테스트

    애플리케이션 게시

    1. 등록Apple Developer Program(연회비 USD $99 필요)

    2. Xcode를 통해 설정App Store Connect그리고 앱을 제출하세요.

    3. Apple의 말을 따르세요App Store Review Guidelines앱이 목록 사양을 충족하는지 확인하세요.



    iOS 개발

    개발 도구

    iOS 개발에서는 주로Xcode, Apple에서 제공하는 공식 통합 개발 환경(IDE)입니다.

    개발 과정

    1. 애플리케이션 아키텍처 및 인터페이스 설계
    2. 기능을 구현하는 코드 작성
    3. 시뮬레이터 또는 실제 머신을 이용한 테스트
    4. 오류 문제 해결 및 성능 최적화 수행
    5. App Store를 통해 제출 및 게시

    필수 지식

    iOS 개발을 배우려면 다음 기본 사항을 숙지해야 합니다.

    자원 개발

    다음은 유용한 학습 및 개발 리소스입니다.



    Xcode

    특징

    Xcode는 macOS, iOS, watchOS 및 tvOS 애플리케이션 개발을 위해 Apple에서 제공하는 IDE(통합 개발 환경)입니다.

    주요 구성품

    1. Code Editor:구문 강조, 코드 완성 및 오류 프롬프트 제공
    2. Interface Builder:직관적인 드래그 앤 드롭 디자인 인터페이스 지원
    3. Simulator:다양한 장치에서 실행되는 애플리케이션을 테스트하고 시뮬레이션하는 데 사용됩니다.
    4. 디버깅 도구:중단점, 메모리 감지 및 성능 분석 지원

    설치 및 업데이트

    Mac App Store 또는 Apple의 공식 개발자 웹사이트에서 최신 버전의 Xcode를 다운로드할 수 있습니다.

    개발 효율성을 향상시키는 실용적인 팁:

    의지

    관련 학습 및 참고 자료:



    Swift

    언어 특징

    Swift는 iOS, macOS, watchOS 및 tvOS 앱 개발을 위한 Apple의 최신 프로그래밍 언어입니다.

    문법 기초

    핵심 개념

    1. 프로토콜을 사용하여 인터페이스 및 프로토콜 구현
    2. 확장을 사용하여 카테고리 기능 확장
    3. 제네릭 지원으로 코드 재사용성 향상
    4. 클로저를 사용하여 고차 함수 구현
    5. 사용자 정의 연산자 및 튜플 지원

    애플리케이션 시나리오

    Swift는 Apple 생태계만을 위한 것이 아니라 서버측 개발 및 크로스 플랫폼 도구에도 사용할 수 있습니다.

    의지

    관련 학습 및 참고 자료:



    Objective-C

    특징

    Objective-C는 원래 NeXT Corporation에서 개발했으며 나중에 Apple에서 macOS 및 iOS 애플리케이션 개발을 위해 널리 사용하는 C 기반 객체 지향 프로그래밍 언어입니다.

    문법 구조

    Objective-C의 구문은 언어 확장을 표시하기 위해 @ 기호를 사용하여 C와 Smalltalk의 기능을 결합합니다.

    핵심 개념

    1. 클래스 및 상속을 포함한 객체 지향 프로그래밍
    2. 프로토콜은 메소드 모음을 정의하는 데 사용됩니다.
    3. 카테고리는 카테고리 기능을 확장하는 데 사용됩니다.
    4. 클로저 및 콜백의 블록 구문

    개발 도구

    Objective-C 개발은 주로 Apple의 Xcode를 사용하여 수행됩니다.

    의지

    학습 및 참고를 위한 몇 가지 리소스는 다음과 같습니다.



    GNews

    지뉴스란 무엇인가요?

    GNews는 사용자가 최신 글로벌 뉴스를 얻을 수 있도록 돕기 위해 Google이 개발한 뉴스 집계 플랫폼입니다. 다양한 뉴스 소스의 콘텐츠를 통합하고 인공 지능 기술을 사용하여 사용자가 관심 있는 뉴스를 개인화하여 추천합니다.

    GNews의 주요 기능

    GNews를 어떻게 사용하나요?

    사용자는 GNews 웹사이트를 방문하거나 앱을 다운로드하여 이 플랫폼을 사용할 수 있습니다. 플랫폼에서 사용자는 관심 있는 주제를 선택하고, 특정 뉴스 소스를 팔로우하고, 필요에 맞게 뉴스 피드를 맞춤 설정할 수 있습니다.

    지뉴스의 장점

    결론적으로

    GNews는 인공 지능 기술을 사용하여 사용자에게 맞춤형 뉴스 경험을 제공하는 강력한 뉴스 수집 도구입니다. 뉴스 정보가 빠르게 변화함에 따라 GNews는 사용자가 세계 동향을 빠르게 파악하고 필요한 정보를 얻을 수 있도록 도와줍니다.



    자동화된 프로세스 도구

    도구 이름 주요 기능 적용 가능한 시나리오 가격
    n8n 고도로 사용자 정의 가능한 프로세스 설계를 제공하고 자체 구축 노드를 지원하는 오픈 소스 자동화 워크플로우 도구입니다. 내부 프로세스 자동화, 대규모 자동화 시스템, API 통합 등에 적합합니다. 무료 오픈 소스이며 유료 클라우드 버전도 제공됩니다.
    Make 시각적인 워크플로 구성을 제공하고 여러 타사 애플리케이션 및 서비스의 통합을 지원하며 단순성과 사용 편의성을 강조합니다. 중소기업의 워크플로우 자동화 및 다양한 서비스의 신속한 통합에 적합합니다. 무료 요금제를 이용할 수 있으며, 유료 요금제는 사용자 요구에 따라 더 많은 고급 기능을 제공합니다.
    Zapier 대부분의 애플리케이션과의 통합을 지원하고 간단하고 사용하기 쉬우며 트리거 및 자동화된 워크플로를 생성할 수 있습니다. 다양한 비즈니스 영역, 특히 소규모 기업 및 스타트업의 자동화에 적합합니다. 무료 요금제를 사용할 수 있으며, 유료 요금제는 사용자 요구에 따라 더 많은 기능을 제공하고 실행됩니다.


    AI 개발 프로그램

    Bolt

    Bolt는 개발자에게 애플리케이션 구축을 위한 간단하고 효율적인 도구를 제공하는 데 초점을 맞춘 빠르고 가벼운 AI 개발 프레임워크입니다. 기능은 다음과 같습니다:

    Cursor

    Cursor는 AI 프로그램 개발을 위해 특별히 설계된 편집기 도구로 지능형 보조 코드 작성 및 디버깅 기능을 제공합니다. 기능은 다음과 같습니다:

    v0

    v0는 사용자가 드래그 앤 드롭 인터페이스를 통해 모델과 애플리케이션을 구축할 수 있는 시각적 개발 기반의 AI 플랫폼입니다. 기능은 다음과 같습니다:

    Codeium

    Codeium은 AI 지능형 지원이 결합된 프로그램 편집기로, 프로그램 개발 효율성과 정확성 향상에 중점을 두고 있습니다. 기능은 다음과 같습니다:



    소프트웨어 공학

    정의

    소프트웨어 공학은 소프트웨어를 체계적이고 계획적인 방식으로 개발, 운영, 유지하는 공학 분야입니다. 목표는 고품질, 유지 관리 가능, 신뢰성 및 까다로운 소프트웨어 시스템을 구축하는 것입니다.

    핵심 목표

    소프트웨어 개발 수명주기(SDLC)

    1. 분석 필요:사용자 요구사항을 수집 및 분석하고 요구사항 사양을 준비합니다.
    2. 시스템 설계:시스템 아키텍처, 모듈, 데이터베이스 및 인터페이스 설계
    3. 구현:디자인을 기반으로 코드 작성
    4. 시험:단위 테스트, 통합 테스트, 시스템 테스트 및 승인 테스트 수행
    5. 배포 및 출시:프로덕션 환경에 시스템 배포
    6. 유지 관리 및 업데이트:오류 수정, 기능 업데이트, 성능 최적화

    일반적인 개발 방법론

    일반적인 도구 및 기술

    품질 속성

    역할분할



    민첩한 개발

    핵심가치

    주요 원칙

    1. 고객의 요구를 최우선으로 해결하고, 조기에 일관된 배송을 통해 가치를 제공합니다.
    2. 요구 사항의 변화를 환영하고 이를 활용하여 개발 후반 단계에서도 고객을 위한 경쟁 우위를 창출합니다.
    3. 작동하는 소프트웨어를 자주 제공하며 리드 타임은 몇 주 또는 몇 달 단위로 측정되는 경우가 많습니다.
    4. 개발팀과 비즈니스팀은 매일 협력하여 의사소통과 이해를 증진해야 합니다.
    5. 의욕이 넘치는 개인을 중심으로 지원을 제공하고 이들이 업무를 완수할 수 있도록 신뢰하십시오.
    6. 대면 의사소통은 가장 효과적인 의사소통 방법이다.
    7. 진행 상황의 주요 척도는 작동하는 소프트웨어입니다.
    8. 지속 가능한 개발 속도를 촉진하고 모든 참가자가 안정적인 속도를 유지할 수 있어야 합니다.
    9. 기술적 우수성과 디자인 단순성을 추구하고 유연성과 품질을 향상시킵니다.
    10. 단순하게 유지하고 필요한 작업을 완료하는 데 집중하세요.
    11. 자기 조직화 팀은 최적의 디자인과 아키텍처를 생산합니다.
    12. 효율성을 높이기 위해 정기적으로 반성하고 행동을 조정하십시오.

    일반적으로 사용되는 프레임워크

    적용 가능한 시나리오



    소프트웨어 개발 요구 사항 문서 템플릿

    프로젝트 이름

    이 프로젝트의 공식 이름을 입력하세요.

    버전 기록

    프로젝트 배경 및 목표

    본 프로젝트의 이유와 배경이슈, 해결해야 할 핵심 이슈를 설명하고, 명확한 프로젝트 목표를 정의합니다.

    시스템 개요

    시스템 아키텍처 다이어그램과 결합할 수 있는 시스템 기능과 전체 아키텍처를 간략하게 설명합니다.

    기능적 요구사항

    비기능적 요구사항

    사용자 역할 및 권한

    화면 및 인터페이스 요구 사항

    기본 화면 스케치나 와이어프레임을 첨부하여 각 화면의 요소와 대화형 프로세스를 설명할 수 있습니다.

    데이터 요구 사항

    주요 데이터 테이블 구조, 필드, 상관관계 등을 나열합니다.

    통합과 상호의존성

    통합이 필요한 외부 시스템, API 또는 기타 소프트웨어 구성 요소를 나열합니다.

    타임라인 및 마일스톤

    위험과 한계

    잠재적 위험, 제약 사항(예: 예산, 인력, 기술 등)을 나열합니다.

    충수

    관련 문서 링크, 참고 자료, 용어 정의 등



    디자인 패턴

    정의

    디자인 패턴은 특정 상황에서 반복되는 디자인 문제를 해결하기 위해 객체 지향 프로그래밍에 주로 사용되는 검증된 소프트웨어 디자인 솔루션 세트입니다.

    세 가지 주요 카테고리

    일반적인 설립 패턴

    일반적인 구조 패턴

    일반적인 행동 패턴

    디자인 패턴의 장점

    사용법 제안



    버전 관리

    정의

    Version Control은 파일 변경 이력을 관리하는 시스템입니다. 소프트웨어 개발에 널리 사용되므로 여러 개발자가 동시에 협업하고 각 변경 사항에 대한 완전한 기록을 유지할 수 있습니다.

    주요 기능

    버전 관리 시스템 유형

    일반적인 도구

    Git 기본 지침

    분기 전략

    혜택



    Git

    소개

    Git은 Linux의 아버지인 Linus Torvalds가 코드 변경 추적, 공동 개발, 버전 관리를 위해 2005년에 개발한 분산형 버전 관리 시스템입니다. 이는 오늘날 가장 널리 사용되는 버전 제어 도구이며 개인 개발, 팀 프로젝트 및 오픈 소스 커뮤니티에서 사용됩니다.

    핵심 개념

    힘내 설치

    1. 이동Git 공식 홈페이지적절한 버전을 다운로드하세요.
    2. 설치 후 명령 프롬프트(CMD) 또는 PowerShell을 엽니다.
    3. 입력하다git --version설치가 성공적으로 완료되었는지 확인합니다.

    초기 설정

    Git을 처음 사용하는 경우 개발자 정보를 설정해야 합니다.

    git config --global user.name "이름"
    git config --global user.email "귀하의 이메일@example.com"

    기본 지침

    git init # 로컬 저장소 초기화
    git clone URL # 원격 저장소 복사
    자식 추가 . # 준비 영역에 변경 사항을 추가합니다.
    git commit -m "description" # 커밋 생성
    git status # 현재 상태 보기
    git log # 커밋 기록 보기
    git Branch # 브랜치 목록 보기
    git checkout 브랜치 이름 # 브랜치 전환
    git merge Branch name # 지정된 브랜치를 병합합니다.
    git push # 원격 끝에 변경 사항을 푸시합니다.
    git pull # 원격 끝에서 업데이트 가져오기

    일반적인 작업 흐름

    1. 저장소 생성 또는 복사(git init또는git clone
    2. 파일 편집 또는 추가
    3. 준비 영역(git add
    4. 변경 사항 커밋(git commit
    5. 원격 끝과 동기화(git push / git pull

    Visual Studio와 통합

    이점

    일반적인 원격 서비스



    Git 재설정 동기화 원격

    핵심 명령: git 재설정

    커밋되지 않은(Uncommitted) 모든 로컬 변경 사항과 커밋되었지만 아직 푸시되지 않은(Local Commits) 모든 로컬 변경 사항을 완전히 삭제하고 원격 끝과 완전히 일치하도록 브랜치를 재설정하려면 아래 단계를 따르세요.

    1. 원격 끝의 최신 상태를 가져옵니다.

    먼저 로컬 인덱스가 원격 측의 최신 진행 상황으로 업데이트되었는지 확인하세요.

    git fetch --all

    2. 원격 지점으로 강제 재설정

    사용--hard매개변수는 현재 분기를 해당 원격 분기로 가리킵니다(분기가 기본 분기라고 가정).

    git reset --hard origin/main

    추적되지 않은 파일 처리(Untracked Files)

    git reset --hardGit에서 이미 추적한 파일만 처리됩니다. 로컬에서 새로 생성한 파일이나 폴더가 있지만 아직 git을 추가하지 않은 경우 그대로 유지됩니다. 모두 삭제하려면 다음을 사용하세요.clean지침:

    추적되지 않는 파일 삭제

    # 먼저 테스트를 실행하여 어떤 파일이 삭제될지 확인합니다.
    git clean -n
    
    # 공식적으로 파일(-f)과 디렉터리(-d)를 삭제합니다.
    자식 청소 -fd

    일반적인 시나리오 비교표

    목표 적용 가능한 지시문
    모든 로컬 수정 사항 취소 git reset --hard origin/<branch_name>
    단일 파일 수정 사항만 삭제 git checkout HEAD -- <file_path>
    현재 변경 사항을 임시로 저장합니다(나중에 복원 가능). git stash
    gitignore 외부의 모든 혼란을 제거하십시오. git clean -fdx

    주의할 점



    Git 충돌 파일 비교

    Git 병합 분기가 충돌하면 파일은 "병합 해제"로 표시됩니다. 이때 Git은 파일에 충돌 표시를 삽입하므로 비교 명령을 사용하여 문제를 찾아 수동으로 수정해야 합니다.


    1. 충돌하는 파일 목록 찾기

    충돌을 해결하기 전에 먼저 충돌하는 파일을 식별하십시오.

    git status

    충돌하는 파일은 다음 위치에 나열됩니다.Unmerged paths섹션 아래.


    2. 상충되는 콘텐츠 비교

    파일에 충돌하는 태그가 포함된 경우 다음 방법을 사용하여 차이점을 확인할 수 있습니다.


    3. 충돌 마커 해석

    Git은 충돌 파일을 직접 수정하며 형식은 다음과 같습니다.

    <<<<<<<<< HEAD(또는 지점 이름)
    현재 브랜치(Ours)의 내용입니다.
    =======
    상대방 지점(Theirs)의 내용입니다.
    >>>>>>> 지점_이름

    4. 비교를 위해 그래픽 도구 사용(권장)

    복잡한 충돌의 경우 텍스트 인터페이스를 읽기가 어렵습니다. 전용 병합 도구를 호출하는 것이 좋습니다.

    git mergetool

    이것은 다음과 같이 시작됩니다Meld, P4Merge 또는 VS Code다른 도구를 사용하여 기본 버전(Base), 로컬 버전(Local) 및 원격 버전(Remote)의 세 가지 버전을 나란히 비교합니다.


    5. 의결 후 조치

    파일을 수동으로 편집하고 유지할 코드를 결정한 후 다음 단계를 수행하여 병합을 완료해야 합니다.

    1. 파일에서 제거<<<<, ====, >>>>표시.
    2. git add <file>(해제된 파일을 임시 저장 영역에 추가합니다.)
    3. git commit(병합 커밋 완료)


    GitHub

    GitHub는 주로 소프트웨어 개발에 사용되는 클라우드 기반 버전 제어 및 협업 플랫폼입니다. 그것은 사용한다Git버전 제어를 구현하여 개발자가 프로젝트의 소스 코드를 관리하고, 변경 사항을 추적하고, 다른 사람들과 협업할 수 있도록 합니다.

    주요 기능

    GitHub 사용의 이점

    적용대상

    GitHub는 개인 개발자, 오픈 소스 커뮤니티, 기업 팀 등 모든 유형의 개발자에게 적합합니다. 소규모 프로젝트부터 대규모 소프트웨어 프로젝트까지의 버전 제어 및 협업 요구 사항을 충족할 수 있습니다.

  • GitHub

    GitHub는git pull --rebase

    git pull --rebase기존 병합을 사용하는 대신 원격 브랜치에서 최신 변경 사항을 가져와 로컬 변경 사항을 최신 원격 커밋에 다시 적용합니다.

    용법

    git pull --rebase

    작업흐름

    1. 원격 지점에서 최신 변경 사항을 가져옵니다.
    2. 로컬 커밋을 일시적으로 제거합니다.
    3. 로컬 브랜치에 원격 커밋을 적용합니다.
    4. 기록을 선형으로 유지하려면 로컬 커밋을 다시 적용하세요.

    왜 사용합니까?--rebase

    사용 예

    일부 변경 사항을 로컬에서 커밋하고 원격 끝에 새로운 커밋이 있다고 가정해 보겠습니다.git pull --rebase회의:

    갈등을 해결하다

    로컬 커밋을 재생하는 동안 충돌이 발생하면 Git은 수동 충돌 해결을 요청합니다.

    1. 충돌을 해결하고 사용git add스테이지 해석 파일.
    2. 사용git rebase --continue커밋을 계속 재생합니다.
    3. 작업을 취소하려면 다음을 사용하세요.git rebase --abort현상 유지로 돌아갑니다.

    요약

    git pull --rebaseGit 제출 기록을 깨끗하게 유지하는 데 중요한 도구입니다. 특히 다중 사용자 협업에 적합합니다. 중복된 병합 제출을 방지하고 코드 베이스의 제출 기록을 선형적으로 유지할 수 있습니다.



    GitHub 사용자 액세스

    다른 개발자가 프로젝트에 참여할 수 있도록 하려면 저장소 설정 페이지를 통해 해당 개발자를 공동 작업자로 추가해야 합니다. 다음은 작업 프로세스입니다.


    작업 단계

    1. 저장소를 입력하세요: GitHub에서 인증하려는 프로젝트의 홈페이지를 엽니다.
    2. 설정 열기: 위 메뉴바의 가장 오른쪽 클릭Settings(기어 아이콘).
    3. 액세스 관리: 왼쪽 사이드바에서Access카테고리 아래Collaborators
    4. 입증: 본인 확인을 위해 GitHub 비밀번호를 다시 입력하거나 2단계 인증을 수행하라는 메시지가 표시될 수 있습니다.
    5. 새 회원 추가:딸깍 하는 소리Add people단추.
    6. 사용자 검색: 팝업창에 상대방의 이름을 입력하세요.GitHub 계정 이름이름또는이메일
    7. 초대장 보내기: 올바른 사용자를 선택한 후,이 저장소에 [이름] 추가

    권한 수준

    개인 계정 저장소의 경우 초대받은 사람은 일반적으로 기본적으로 읽기 및 쓰기 권한을 갖습니다. 조직 계정인 경우 더 자세한 설정을 할 수 있습니다.

    권한 수준 설명하다
    Read 순수 뷰어에게 적합한 코드를 읽고 복사할 수만 있습니다.
    Triage 이슈 및 끌어오기 요청을 관리할 수 있지만 코드를 작성할 수는 없습니다.
    Write 코드를 저장소에 직접 푸시할 수 있습니다.
    Maintain 글쓰기 외에도 저장소의 일부 설정을 관리할 수도 있습니다.
    Admin 리포지토리 삭제 및 다른 공동 작업자 관리를 포함하여 모든 권한을 갖습니다.

    주의할 점



    GitHub 저장소 삭제

    웹 인터페이스를 통해 GitHub 저장소 삭제

    이는 삭제하는 가장 일반적이고 직관적인 방법입니다. 저장소가 삭제되면 백업이 없으면 복원할 수 없다는 점에 유의하세요.

    1. GitHub로 이동하여 삭제하려는 파일로 이동합니다.저장소 메인 페이지
    2. 위 페이징 탭의 가장 오른쪽을 클릭하세요.Settings(설정).
    3. 페이지를 맨 아래로 스크롤하여 빨간색으로 표시된 페이지를 찾으세요.Danger Zone(위험 지역).
    4. 딸깍 하는 소리Delete this repository단추.
    5. 저장소의 전체 이름(일반적으로 형식)을 입력하라는 확인 창이 나타납니다.사용자 이름/저장소 이름)。
    6. 삭제를 확인하려면 아래 버튼을 클릭하세요.
    ---

    GitHub CLI를 사용하여 삭제

    GitHub의 명령줄 도구(gh)가 설치되어 있는 경우 터미널을 통해 빠르게 삭제할 수 있습니다.

    gh repo delete <username>/<저장소 이름> --확인하다

    알아채다:--confirm매개변수는 확인 단계를 직접 건너뛰므로 주의해서 사용하세요.

    ---

    로컬 저장소 폴더 삭제

    GitHub의 원격 저장소가 삭제된 후에도 컴퓨터의 로컬 폴더는 계속 존재합니다. 완전히 제거하려면 폴더를 수동으로 삭제하세요.

    Linux / macOS / ChromeOS

    rm -rf <폴더 이름>

    Windows (CMD)

    rd /s /q <폴더 이름>
    ---

    행동 체크리스트 삭제

    작동 모드 영향 범위 복구 가능합니까?
    웹 인터페이스 제거 GitHub 원격 서버의 데이터만 삭제하세요. 아니요(지원팀에 문의하거나 포크하지 않는 한)
    rm -rf 명령 컴퓨터의 로컬 파일만 삭제하세요. 아니요(휴지통이 없는 경우)
    .git 폴더 삭제 파일을 유지하되 일반 폴더로 다시 이동합니다(버전 제어 기능 상실). 예(다시 Git 초기화)

    주의할 점



    Visual Studio에서는 Git을 사용합니다.

    개요

    Visual Studio에는 Git 통합 기능이 내장되어 있지만 버전 제어 작업(예: 커밋, 푸시, 풀, 병합 등)을 수행하려면 시스템에 Git 실행 파일을 설치해야 합니다.

    1단계: Git이 설치되어 있는지 확인

    1. 명령 프롬프트(CMD) 또는 PowerShell을 엽니다.
    2. 다음 명령을 입력하십시오.
      git --version
    3. 다음과 같은 내용이 표시되면git version 2.x.x, 설치되었음을 의미합니다. "인식할 수 없는 git 명령"이 표시되면 Git을 설치해야 합니다.

    2단계: Git 다운로드 및 설치

    1. 이동Git 공식 다운로드 페이지
    2. 해당 운영 체제 버전(Windows, macOS 또는 Linux)을 선택합니다.
    3. 다운로드 후 설치 프로그램을 실행해 주세요. 기본 설정을 사용하고 끝까지 "다음"을 클릭하는 것이 좋습니다.
    4. 설치가 완료되면 Visual Studio를 다시 시작합니다.

    3단계: Git 사용자 정보 설정

    명령 프롬프트를 켜고 사용자 이름과 이메일을 설정하세요.

    git config --global user.name "이름"
    git config --global user.email "귀하의 이메일@example.com"

    이 정보는 각 커밋에 추가되어 개발자를 식별하는 데 사용됩니다.

    4단계: Visual Studio에서 Git 활성화

    1. Visual Studio를 시작합니다.
    2. 위 메뉴를 클릭하시면보기 → 팀 탐색기
    3. 선택하다연결 → 저장소 복제원격 저장소를 복사합니다.
    4. 또는 기존 프로젝트를 클릭하세요.Git → Git 저장소 생성, 프로젝트를 버전 관리의 일부로 만듭니다.

    5단계: 통합 상태 확인

    보충: Visual Studio에 내장된 Git 설치 사용

    Visual Studio 2022 이상을 사용하는 경우 설치 과정에서 확인할 수 있습니다.「Git for Windows」옵션. 이러한 방식으로 Visual Studio는 수동 구성 없이 Git을 자동으로 설치하고 통합합니다.

    완료 후 효과

    설정이 완료되면 Visual Studio에서 직접 다음 작업을 완료할 수 있습니다.



    Azure DevOps

    플랫폼 소개

    Azure DevOps는 코드 관리, 구성, 자동화된 테스트부터 배포까지 전체 DevOps 프로세스를 지원하는 Microsoft에서 제공하는 통합 개발 및 협업 플랫폼입니다. 다양한 프로그래밍 언어와 프레임워크에 적합하며 개인 프로젝트나 대기업 팀 개발에 사용할 수 있습니다.

    주요 서비스 구성요소

    주요 기능

    일반적인 용도

    용법

    1. 이동Azure DevOps 공식 웹사이트
    2. Microsoft 계정에 로그인하거나 가입하세요.
    3. 새 조직과 프로젝트를 만듭니다.
    4. Repos, Pipelines, Boards와 같은 모듈을 설정하여 개발 및 배포 프로세스를 시작하세요.

    이점

    적용 가능한 시나리오



    Azure DevOps 액세스 계층

    단계 지침

    1. 로그인Azure DevOps
    2. 왼쪽 하단을 클릭하세요조직 설정
    3. 왼쪽 메뉴에서 선택하세요사용자
    4. 시스템에는 조직의 모든 사용자와 해당 사용자가 나열됩니다.액세스 수준

    일반적인 액세스 수준 유형

    고급 작업

    힌트

    Azure DevOps Pipelines, Repos 또는 Boards를 사용할 때 권한 제한 문제가 발생하는 경우 먼저 액세스 수준이 다음인지 확인하세요.Basic또는 그 이상.



    CMake 크로스 플랫폼 빌드 시스템

    CMake 정의

    CMake는 오픈 소스 크로스 플랫폼 "메타 빌드 시스템"입니다. 프로그램 코드 자체를 직접 컴파일하는 것이 아니라, 구성 파일(CMakeLists.txt)을 읽어 현재 운영체제와 개발 환경에 적합한 프로젝트 파일을 자동으로 생성해 줍니다. 예를 들어 Windows에서는 Visual Studio 솔루션을 생성하고 Linux에서는 Makefile 또는 Ninja 구성 파일을 생성합니다.

    CMake 설치

    다양한 운영 체제에 CMake를 설치하는 방법은 다음과 같습니다.

    핵심 기능

    CMake는 복잡한 소프트웨어 프로젝트의 관리를 단순화하도록 설계되었습니다. 다중 레벨 디렉토리 구조를 지원하고 라이브러리 간의 종속성을 처리하며 시스템에 설치된 라이브러리를 자동으로 검색합니다. 또한 개발부터 출시까지 전체 라이프사이클을 포괄하는 테스트(CTest) 및 패키징(CPack) 기능도 제공합니다.

    주류 건설 과정

    단계 명령 예 설명하다
    1. 구성 cmake -S . -B build 설정을 읽고 시스템 환경을 감지합니다.
    2. 생성 (자동으로 실행됨) Makefile 또는 VS 프로젝트 파일을 생성합니다.
    3. 빌드 cmake --build build 실제 컴파일을 수행하려면 컴파일러를 호출하세요.
    4. 설치 cmake --install build 생성된 실행 파일을 지정된 경로로 이동합니다.

    x64 및 ARM64 지원

    CMake는 뛰어난 아키텍처 간 지원 기능을 갖추고 있습니다. Windows 환경에서 개발자는 다음과 같은 매개변수를 통해 대상 아키텍처를 지정할 수 있습니다.-A x64또는-A ARM64. 최신 Apple Silicon의 경우 CMake는 범용 바이너리 생성을 지원하므로 Intel 및 Apple M 시리즈 프로세서 모두에서 프로그램을 실행할 수 있습니다.

    CMake를 선택하는 이유

    기존 Makefile은 유지 관리가 어렵고 플랫폼 간 다양성이 없습니다. CMake를 사용하면 개발자는 간단히 구성 파일 세트를 작성할 수 있으며, 전 세계 개발자는 선호하는 IDE(예: VS Code, CLion, Xcode)에서 프로젝트를 쉽게 열고 컴파일할 수 있습니다. 이것이 바로 대부분의 주류 오픈 소스 C++ 프로젝트가 현재 CMake를 표준 도구로 사용하는 이유입니다.



    프로그램 배포

    정의

    애플리케이션 배포는 개발된 애플리케이션을 사용자가 실제로 사용할 수 있도록 개발 환경에서 테스트 또는 프로덕션 환경으로 이동하는 프로세스입니다. 이는 시스템이 다양한 환경에서 안정적이고 재현 가능하게 작동할 수 있도록 보장합니다.

    배포 프로세스

    1. 짓다:소스 코드를 실행 파일이나 이미지 파일로 컴파일하고 패키징합니다.
    2. 시험:기능, 성능 및 호환성을 확인하십시오.
    3. 배포:애플리케이션 및 구성 파일을 서버에 배포합니다.
    4. 감시 장치:작동 상태를 지속적으로 모니터링하고 로그 및 성능 지표를 기록합니다.

    일반적인 배포 방법

    공통 배포 아키텍처

    자동화된 배포 도구

    배포 예시

    # GitHub Actions를 사용하여 예제 배포
    이름: 웹 앱 배포
    에:
      푸시:
        가지: [ "메인" ]
    직업:
      배포:
        실행: 우분투 최신
        단계:
          - 용도: actions/checkout@v4
          - 이름: Docker 이미지 빌드
            실행: docker build -t myapp .
          - 이름: 서버에 배포
            실행: docker run -d -p 80:80 myapp

    배포 고려 사항

    배포 전략

    모범 사례



    컨테이너화 기술

    정의

    Docker(컨테이너 기술)는 애플리케이션 배포, 확장 및 관리를 자동화하기 위한 오픈 소스 플랫폼입니다. "컨테이너"를 사용하여 애플리케이션과 해당 종속성을 함께 패키지하여 다양한 환경에서 일관된 실행을 보장합니다.

    핵심 개념

    도커의 장점

    기본 지침

    Dockerfile 예

    # Python 이미지 파일 사용
    파이썬:3.10에서
    
    # 작업 디렉토리 설정
    WORKDIR/앱
    
    # 프로그램 파일 복사
    복사 ./app
    
    # 의존성 패키지 설치
    실행 pip install -r 요구 사항.txt
    
    #컨테이너가 시작될 때 실행할 명령을 지정합니다.
    CMD ["python", "app.py"]

    Docker Compose

    Docker Compose는 여러 컨테이너 애플리케이션을 정의할 수 있는 도구입니다. 사용docker-compose.yml파일은 각 서비스를 정의합니다.

    version: '3'
    services:
      web:
        build: .
        ports:
          - "8000:8000"
      db:
        image: mysql:8
        environment:
          MYSQL_ROOT_PASSWORD: example
    

    애플리케이션 시나리오

    관련 기술



    모듈 종속성 분석

    모듈 종속성 분석은 애플리케이션이 실행될 때 의존하는 외부 파일(예: DLL, 라이브러리, 프레임워크)을 식별하고 추적하는 데 사용되는 소프트웨어 엔지니어링 기술입니다. 이는 소프트웨어가 다양한 환경에서 올바르게 작동하는지 확인하는 데 중요합니다.


    핵심 분석 차원


    분석의 주요 목적

    목적 자세한 설명
    문제 해결 DLL 누락 또는 버전 불일치로 인한 프로그램 충돌을 찾아보세요.
    보안 감사 프로그램이 승인되지 않은 타사 구성 요소를 로드하는지 또는 보안 취약점이 있는지 식별합니다.
    성능 최적화 너무 많은 종속 모듈이 시작 시간과 메모리 사용량에 미치는 영향을 평가하고 불필요한 참조를 제거합니다.
    이식 가능성 평가 .NET 런타임 또는 VC++ 라이브러리와 같은 특정 개발 환경이 설치되지 않은 컴퓨터에서 소프트웨어가 실행되는지 여부를 결정합니다.

    일반적인 분석 도구



    Dependency Walker

    종속성 워커(일반적으로 Defines.exe로 알려짐)는 Windows 응용 프로그램(예: .exe, .dll, .sys 등)의 파일 구조를 분석하기 위한 무료 도구입니다. 이는 주로 32비트 또는 64비트 Windows 모듈을 스캔하고 관련된 모든 종속 모듈의 계층적 트리를 구축하는 데 사용됩니다.


    핵심 기능


    일반적인 애플리케이션 시나리오

  • DLL 헬 감지
  • 장면 설명하다
    시스템 오류 문제 해결 0xc000007b(병렬 구성 오류)와 같은 시스템 오류를 해결하거나 지정된 모듈을 찾을 수 없습니다.
    소프트웨어 배포 개발자는 설치 프로그램에 필요한 모든 실행 라이브러리(예: VC++ 재배포 가능 패키지)가 포함되어 있는지 확인합니다.
    시스템 경로에 동일한 이름을 가진 다른 버전의 DLL이 있어 프로그램이 비정상적으로 동작하는지 확인하십시오.

    사용 제한 및 대안

    종속성 워커는 수년 동안 업데이트되지 않았기 때문에 최신 Windows 10/11의 일부 기능(예: API 세트 또는 지연 로드 DLL)에 대한 지원이 부족하고 잘못된 빨간색 경고가 자주 나타납니다. 이 경우 다음과 같은 오픈 소스 대체 도구가 권장됩니다.



    Dependencies

    종속성은 수년 동안 중단된 종속성 워커(Depends.exe)를 대체하도록 설계된 오픈 소스 최신 종속성 분석 도구입니다. Windows 10 및 Windows 11의 시스템 아키텍처에 완전히 최적화되어 있으며 최신 소프트웨어 환경에서 모듈 연결을 정확하게 분석할 수 있습니다.


    종속성을 선택하는 이유


    기능 비교표

    특성 종속성 워커(이전 버전) 종속성(최신 버전)
    윈도우 10/11 지원 나쁨(자주 오탐지) 우수함(기본 지원)
    API 세트 처리 인식되지 않음(빨간색으로 누락된 것으로 표시됨) 엔터티 DLL에 올바르게 매핑되었습니다.
    개발 상태 업데이트 중지됨(2006) 지속적인 유지 관리 중(GitHub)
    핵심기술 C++ / MFC C#/WPF(일부 하위 수준 C++)

    일반적인 바로가기 기능


    획득 및 설치

    종속성은 일반적으로 GitHub에서 다운로드할 수 있는 설치가 필요 없는 친환경 소프트웨어입니다.lucasg/Dependencies저장소는 컴파일된 릴리스 버전을 다운로드합니다. 사용 시 분석하려는 .exe 또는 .dll 파일을 창으로 끌어서 분석을 시작하면 됩니다.



    실행 단계 감지 기능 차이점

    두 도구에는 서로 다른 디자인 철학이 있습니다. 종속성 워커(Depends.exe)에는 동적 분석기(프로파일러)가 포함되어 있는 반면 최신 종속성은 정적 분석 및 API 세트 구문 분석에 중점을 둡니다.


    종속성이 프로그램을 실행하지 않는 이유는 무엇입니까?


    동작 감지를 위해 종속성 워커를 사용하는 방법(프로파일링)

    실행 시에만 발생하는 DLL 오류(예: 지연된 로딩 실패 또는 경로 검색 문제)를 해결하기 위해 "Executor"를 사용해야 하는 경우 종속성 워커의 프로필 기능을 계속 사용할 수 있습니다.

    1. 종속성 워커를 시작하고 .exe를 로드합니다.
    2. 키보드를 누르세요F7아니면 메뉴를 누르시거나Profile -> Start Profiling
    3. 팝업 대화 상자에서 매개변수(예: 작업 디렉터리, 명령줄 매개변수)를 설정한 다음OK
    4. 하단의 로그 창을 확인하세요.: 프로그램이 실행되어 충돌이 발생하면 하단의 로그에 로드하는 동안 오류가 발생한 DLL이 빨간색 텍스트로 표시됩니다.

    모션 감지의 장점과 단점 비교

    이점 결점
    유능한Dynamic Loading(로드라이브러리) 오류. Win10/11에서 실행할 때 로그는 수많은 잘못된 API-MS-WIN 오류 메시지로 채워집니다.
    실제 로드된 DLL 파일 경로를 확인할 수 있습니다(검색 경로 순서 관련). 종속성이 너무 많아 프로그램이 전혀 시작되지 않으면 프로파일러가 유용한 정보를 캡처하지 못할 수 있습니다.

    고급 디버깅 제안

    종속성 워커의 프로파일러에 잘못된 오류가 너무 많아 요점을 볼 수 없는 경우 대신 다음 조합을 사용하는 것이 좋습니다.



    프로그램 개발 AI 도구


    GitHub Copilot

    GitHub가 OpenAI와 협력하여 개발한 이 제품은 현재 전 세계에서 가장 널리 사용되는 AI 코딩 도우미입니다. 에 직접 삽입할 수 있습니다.Visual Studio CodeJetBrains다른 널리 사용되는 개발 환경에서는 주석과 컨텍스트를 분석하여 코드 줄이나 전체 기능을 즉시 제안합니다.


    Cursor

    VS Code 아키텍처를 기반으로 개발된 독립 소프트웨어입니다.AI 코드 편집기. 단순한 플러그인과 달리 Cursor는 AI를 편집기의 하단 레이어에 깊이 통합합니다. 전체 프로젝트의 구조(컨텍스트)를 이해하고 개발자가 전체 라이브러리와 직접 대화하여 글로벌 리팩토링이나 버그 수정을 수행할 수 있습니다.


    Claude 3.5 Sonnet

    클로드는 범용 AI이지만3.5 소네트 모델프로그램 논리, 아키텍처 설계 및 디버깅 기능 측면에서 최고의 선택 중 하나로 인식됩니다. 성냥Artifacts기능을 통해 개발자는 생성된 웹 페이지 프런트 엔드 화면이나 대화 상자에서 대화형 구성 요소를 직접 미리 볼 수 있습니다.


    Tabnine

    Tabnine은 다음을 매우 중요하게 생각합니다.개인 정보 보호 및 보안, 소스 코드 기밀성에 대한 요구 사항이 높은 기업에 적합합니다. 완전히 현지화된 배포(자체 호스팅)를 지원하고, 훈련을 위해 코드가 클라우드에 업로드되지 않도록 보장하며, 정확한 자동 완성 기능을 제공합니다.


    Amazon Q(이전 CodeWhisperer)

    Amazon Web Services(AWS)에서 제공하는 개발 도우미. 기본 코드 생성 외에도 특히 다음과 같은 기능이 향상되었습니다.AWS 클라우드 서비스통합을 통해 개발자는 신속하게 IaC(Infrastructure as Code)를 작성하거나 보안 검색 및 업데이트를 처리할 수 있습니다.


    Replit Agent

    Replit 온라인 개발 환경에 내장된 AI 에이전트. 특징은자동화된 배포환경 구축을 통해 사용자는 애플리케이션의 기능만 설명하면 Agent가 자동으로 파일 생성, 종속 패키지 설치, 코드 작성 및 온라인 작업을 완료할 수 있습니다.


    v0.dev

    제공: Vercel프론트엔드 개발을 위한 AI. 사용자는 자연어를 통해 인터페이스 요구 사항을 설명하고 v0에서는 React, Tailwind CSS 및 Shadcn UI를 기반으로 프런트 엔드 구성 요소 코드를 직접 생성하여 UI 고정관념 시간을 크게 줄입니다.



    에이전트 기반 AI 프로그래밍 도우미

    Agentic AI 코딩 도우미. 이러한 유형의 도구의 특징은 터미널에 직접 액세스하고, 파일을 읽고 쓰고, 테스트를 실행하고, 작업을 독립적으로 계획하는 기능을 갖는 것입니다.


    1. 터미널 및 CLI 도구

    이 유형의 도구는 Claude Code에 가장 가깝고 터미널에서 직접 실행되므로 명령줄 작업에 익숙한 개발자에게 적합합니다.


    2. IDE 및 편집기 도구

    이러한 도구는 에이전트 기능을 편집기에 통합하여 보다 직관적인 시각적 개발 경험을 제공합니다.


    3. 완전 자동화된 AI 엔지니어(완전 자율)

    이러한 도구는 일반적으로 보다 독립적인 운영 기능을 가지며 수요 분석부터 웹 배포 또는 독립 실행형 환경까지의 프로세스를 완료할 수 있습니다.


    핵심 기능 비교표

    도구 이름 메인 인터페이스 핵심 장점
    Claude Code CLI(터미널) Anthropic에서 기본적으로 개발한 이 앱은 Claude 3.5의 지침을 매우 밀접하게 따릅니다.
    Aider CLI(터미널) 오픈 소스는 여러 모델을 지원하며 강력한 Git 자동화 관리 기능을 갖추고 있습니다.
    Cursor IDE(편집기) UI는 통합 수준이 가장 높으며 터미널 전환을 좋아하지 않는 개발자에게 적합합니다.
    Cline VS 코드 플러그인 오픈 소스이며 완전히 투명하므로 다양한 API Key를 직접 연결할 수 있습니다.

    선택 방법



    Claude Code

    Claude Code는 Anthropic에서 개발한 에이전트 기반 명령줄 인터페이스(CLI) 도구입니다. 개발자의 터미널에서 직접 실행되며 전체 프로그램 코드 라이브러리를 이해하고, 터미널 명령을 실행하고, 파일을 편집하고, Git 워크플로 처리를 지원할 수 있으므로 개발자는 자연어를 통해 복잡한 프로그래밍 작업을 완료할 수 있습니다.


    핵심 기능


    설치방법

    Claude Code에는 Node.js 18+ 환경이 필요하며 다음 방법을 통해 설치할 수 있습니다.

    1. npm을 사용하여 설치:
      npm install -g @anthropic-ai/claude-code
    2. 도구를 시작합니다.
      프로젝트 디렉토리에 들어가세요claude이제 대화형 모드를 시작할 수 있습니다.

    작동 모드 및 단축키

    기능 작동 모드/단축키
    Plan Mode Shift + Tab(맥/리눅스) 또는Alt + M(윈도우). 실행하기 전에 상세한 계획을 세우십시오.
    Auto-accept 모든 변경 사항은 각각 확인할 필요 없이 자동으로 승인됩니다.
    파일 선택 입력하다@특정 파일을 빠르게 검색하고 배경지식으로 추가하세요.
    지침 실행 사용!세션에서 Bash 명령을 직접 실행하기 위한 접두사(예:!ls -la)。

    일반적으로 사용되는 내장 명령


    하드웨어 및 시스템 요구 사항


    권한 확인 팝업이 자주 표시되고 디렉토리 간 접근이 필요한 경우 시작 매개변수 및 내장 명령을 통해 최적화 설정을 할 수 있습니다.

    1. 권한 확인 팝업 감소

    기본적으로 Claude Code는 위험한 명령(예: 파일 삭제, 시스템 명령 실행)을 하나씩 확인합니다. 간섭을 줄이기 위해 "자동화 모드"로 들어가려면 다음 매개변수를 사용하십시오.


    2. 현재 디렉토리가 아닌 디렉토리에 접근

    안전상의 이유로 Claude Code는 기본적으로 시작되는 프로젝트 디렉터리로 제한됩니다. 외부 경로에 액세스하려면 다음 세 가지 방법이 있습니다.


    3. 영구 별칭(Alias) 설정

    빠른 시작을 촉진하고 나중에 이러한 설정을 가져오려면 다음을 수행하는 것이 좋습니다..bashrc또는.zshrc(Cygwin/Linux) 별칭 추가:

    alias c='claude --auto-accept . /home/user/common_library'

    주의할 점


    완전히 자동화된 시작(확인 없음) 및 외부 디렉터리에 대한 액세스가 필요한 경우 Claude Code는 이를 달성하기 위한 특수 CLI 매개변수를 제공합니다. 이러한 기능을 흔히 "YOLO 모드"라고 하며 신뢰할 수 있는 환경이나 샌드박스에서 사용하기에 적합합니다.

    1. 완전 자동 실행: 모든 권한 확인을 건너뜁니다.

    실행하고 싶지 않다면lsmkdir또는 파일을 편집할 때 계속해서 확인을 클릭하면 다음과 같은 위험한 매개변수를 사용할 수 있습니다.


    2. 외부 디렉터리 접근: 권한 경로 추가

    기본적으로 Claude는 자신이 시작된 디렉터리만 읽고 쓸 수 있습니다. 다른 경로에 액세스하려면 다음을 사용하세요.--add-dir


    3. 조합 스킬 : 가장 강력한 자동 시작 명령

    한 번에 올바르게 수행하고 방해 없이 여러 디렉터리 간에 직접 개발하려면 다음을 조합하여 사용할 수 있습니다.

    claude --dangerously-skip-permissions --add-dir ../library --add-dir ~/shared_configs

    시동 매개변수 비교표

    매개변수 이름 기능 설명 적용 가능한 상황
    --dangerously-skip-permissions 모든 도구(Bash, 읽기, 쓰기)에 대한 권한 확인을 건너뜁니다. 샌드박스 환경에서 광범위한 자동 리팩토링 또는 작업이 필요합니다.
    --add-dir <path> Claude가 현재 디렉터리 외부의 특정 경로에 액세스할 수 있는 권한을 부여합니다. 프로젝트 간 개발에는 외부 문서 참조가 필요할 수 있습니다.
    --permission-mode acceptEdits 파일 수정 사항을 자동으로 수락하지만 Bash 명령을 실행할 때 계속 묻습니다. 비교적 안전한 자동화 모드.

    안전 알림



    Cursor

    Cursor는 VS Code를 기반으로 개발된 AI 코드 편집기입니다. 단순한 플러그인이 아니라 AI 기능을 에디터 하단 레이어 깊숙이 내장해 전체 프로젝트의 맥락을 이해하고 코드를 자동으로 작성, 재구성, 복구하는 기능을 갖췄습니다. VS Code를 상속하므로 사용자는 원래의 모든 설정과 확장 기능을 직접 가져올 수 있습니다.


    기본 설치

    1. 소프트웨어 다운로드:이동커서 공식 홈페이지, 시스템은 자동으로 운영 체제(Windows, macOS, Linux)를 감지하고 다운로드를 제공합니다.
    2. 가져오기 설정:설치 및 시작 후 Cursor는 VS Code에서 확장 프로그램, 바로가기 및 테마를 가져올 것인지 묻습니다. 개발 습관을 원활하게 통합하려면 가져오기를 선택하는 것이 좋습니다.
    3. 로그인 계정:커서 계정에 등록하고 로그인하세요. 무료 버전(Hobby)은 고차 모델(예: GPT-4o 또는 Claude 3.5 Sonnet)에 대해 제한된 수의 쿼리를 제공한 후 더 작은 모델로 전환합니다.

    핵심 기능 사용법

    1. Cmd + K (Inline Edit)

    코드 편집기에서 직접 AI를 호출합니다.

    2. Cmd + L (Chat Pane)

    사이드바 채팅 대화상자:

    3. Cmd + I (컴포저 모드)

    이는 Cursor의 가장 강력한 "에이전트" 모드입니다.


    고급 설정 기술

    기능 이름 설정방법 설명하다
    모델 전환 사이드바 하단 메뉴 Claude 3.5 Sonnet, GPT-4o 또는 Cursor Small 간에 전환하세요.
    Rules for AI Settings > General AI의 응답 스타일을 사용자 정의합니다(예: 항상 중국어 번체를 사용하고 코드는 특정 사양을 충족해야 함).
    Index Project Settings > Features AI가 전체 프로젝트 파일을 정확하게 검색할 수 있도록 로컬 인덱싱을 꼭 켜주세요.

    자주 사용하는 단축키 비교


    주의할 점



    Aider


    설치하다

    Aider는 로컬 소스 코드의 직접 수정을 지원하는 터미널 기반 AI 페어링 프로그래밍 도구입니다. 설치하기 전에 시스템에 다음이 있는지 확인하십시오.Python 3.8위 버전은 동일합니다.Git

    python -m pip install aider-chat

    API 키 구성

    시작하기 전에 AI 서비스 제공업체에서 제공하는 키를 환경 변수로 설정해야 합니다. Aider는 기본적으로 Anthropic 및 OpenAI와 같은 다양한 모델을 지원합니다.

    설정 완료 후 터미널에 입력aider그러면 대화 인터페이스가 열립니다.


    파일 작업

    Aider는 토큰 비용을 절약하고 정확성을 높이기 위해 컨텍스트에 참여하기 위해 지정한 파일만 읽고 수정합니다.


    코드 편집

    자연어를 직접 사용하여 Aider에게 "이 클래스를 두 개의 파일로 분할하는 데 도움을 주세요" 또는 "기존 버그 수정"과 같은 작업을 수행하도록 요청할 수 있습니다. 수정을 수행한 후 Aider는 자동으로Git Commit, 수정된 콘텐츠를 기반으로 제출 메시지를 자동으로 작성합니다.


    지침

    지침 기능 설명
    /undo AI가 수행한 가장 최근의 코드 수정 및 Git 커밋을 실행 취소합니다.
    /diff 원본 버전과 비교하여 현재 AI의 변경 사항을 미리 봅니다.
    /chat-mode 대화 모드 간 전환(예: 코드 모드는 파일 수정에 사용되며 질문 모드는 Q&A에만 사용됨)
    /help 내장 명령의 전체 목록을 표시합니다.
    /exit Aider 프로그램을 종료합니다.


    Aider는 로컬 모델을 사용합니다.


    타당성 및 원칙

    Aider는 로컬에서 실행되는 무료 및 오픈 소스 모델과 인터페이스하는 다양한 방법을 지원합니다. 가장 일반적인 방법은 다음과 같습니다.OllamaLM Studio또는LocalAI도구가 OpenAI API 사양과 호환되는 로컬 서버를 생성할 때까지 기다린 다음 Aider가 서버 주소를 가리키도록 합니다.


    Ollama를 통해 구현됨

    이는 현재 가장 간단하고 주류를 이루는 현지화 솔루션입니다.

    aider --model ollama/deepseek-coder-v2

    핵심 설정 매개변수

    매개변수 기능 설명
    --model 모델명을 지정하세요. 로컬 모델은 일반적으로 다음과 같은 형식입니다.ollama/<model_name>
    --openai-api-base LM Studio를 사용하는 경우 로컬 API URL(예:http://localhost:1234/v1)。
    --no-stream 로컬 추론 성능이 부족하고 연결이 불안정한 경우 스트리밍 출력을 꺼서 안정성을 높일 수 있습니다.

    로컬 모델의 한계와 과제


    추천 지역 모델

    모든 모델이 Aider와 함께 사용하기에 적합한 것은 아닙니다. 다음은 현재 커뮤니티에서 프로그램 개발 작업에서 더 나은 성능을 발휘하는 것으로 인식되는 로컬 오픈 소스 모델입니다.



    소프트웨어 개발 관련 법률

    저작권법

    소프트웨어 코드, 디자인 문서, 사용자 매뉴얼 등은 모두 저작권 보호를 받습니다. 저작권 보호는 창작 완료와 동시에 자동으로 성립되며 등록이 필요하지 않으며, 무단 복제, 수정, 배포, 상업적 이용을 금지합니다.

    특허법

    소프트웨어에 기술 혁신이나 고유한 알고리즘이 포함된 경우 특허 보호를 신청할 수 있습니다. 특허는 검토 및 승인의 대상이며 기술 솔루션에 대한 발명가의 독점적 권리를 보호하지만 순수한 프로그램 논리는 일반적으로 특허로 보호되지 않습니다.

    상표법

    소프트웨어 이름, 로고, 브랜드 아이덴티티는 브랜드 이미지와 시장 차별화를 보호하고 타인이 사용하여 혼동을 일으키는 것을 방지하기 위해 상표로 등록될 수 있습니다.

    영업비밀보호법

    공개되지 않은 프로그래밍 세부 사항, 알고리즘, 데이터베이스 구조 등은 영업 비밀입니다. 회사는 비밀유지계약, 정보관리시스템 등을 통해 이를 보호해야 합니다.

    정보보안 관련 규정

    예를 들어, 개인정보법 및 정보보안 관리법에서는 사용자가 소프트웨어 개발 과정에서 개인 데이터를 적절하게 처리하고 정보 보안을 보장할 것을 요구합니다. 위반 시 행정적 또는 형사적 책임이 발생할 수 있습니다.

    계약법 및 승인 조항

    소프트웨어 개발에는 법적 분쟁을 피하기 위해 양 당사자의 권리와 의무, 프로그램 코드 소유권, 유지 관리 책임, 기밀 유지 의무 등을 명확하게 정의하는 계약 계약, 협력 개발 계약, 소프트웨어 라이선스 조건 등이 포함되는 경우가 많습니다.

    인터넷 및 전자상거래 관련 규제

    소프트웨어의 온라인 운영에는 네트워크 서비스, 전자결제, 온라인 지적재산권 보호 등이 포함되며, 전자서명법, 전자거래법 등의 규정을 준수해야 합니다.

    소프트웨어 개발에 대한 지적 재산권

    저작권

    소프트웨어 코드는 저작권 보호 범위에 속하며, 별도의 등록 없이 개발자가 자동으로 저작권을 소유하게 됩니다. 저작권 보호에는 소스 코드, 디자인 파일, 사용자 매뉴얼 등이 포함됩니다.

    특허

    소프트웨어에 참신함과 기술적 혁신이 포함되어 있는 경우 특허 보호를 신청할 수 있습니다. 예를 들어 고유한 알고리즘이나 기술적 문제를 해결하는 방법이 있지만 순수한 코드 논리는 일반적으로 특허 보호 범위를 벗어납니다.

    상표권

    소프트웨어 이름과 로고는 상표로 등록되어 다양한 출처의 제품을 구별하고 시장 혼란을 피할 수 있습니다.

    영업비밀

    공개되지 않은 프로그래밍 세부 사항, 데이터베이스 구조 및 알고리즘은 영업 비밀을 통해 보호될 수 있습니다. 이를 유지하려면 회사 내부 비밀 유지 계약 및 관리 조치에 의존해야 합니다.

    인증 모드

    소프트웨어는 독점 소프트웨어, 무료 소프트웨어, 오픈 소스 라이선스(예: GPL, MIT) 등 다양한 라이선스 모델을 통해 출시될 수 있습니다. 다양한 라이센스 모델은 사용자의 수정 및 재배포 권한에 영향을 미칩니다.

    침해 위험

    타인의 코드, 이미지, 알고리즘을 무단으로 사용하는 것은 저작권 침해에 해당할 수 있습니다. 개발 과정에서는 법적 분쟁을 피하기 위해 프로그램 코드의 소스가 합법적인지 확인해야 합니다.

    국제적 보호

    지적 재산권은 영토이지만 베른 협약 및 TRIPS 협정과 같은 국제 조약을 통해 많은 국가에서 어느 정도 보호받을 수 있습니다.



    소프트웨어 쇼핑몰

    소프트웨어 판매 플랫폼

    2026년에 올바른 소프트웨어 판매 플랫폼을 선택하는 것은 소프트웨어 유형과 목표 시장에 따라 달라집니다. 주류 플랫폼의 분류와 특징은 다음과 같습니다.


    범용 디지털 제품 및 SaaS 플랫폼

    게임 및 데스크톱 애플리케이션 배포 플랫폼

    기업 및 모바일 애플리케이션 몰

    대만 현지 전자상거래 플랫폼


    플랫폼 선택 비교표

    수요 목표 추천 플랫폼 핵심 장점
    글로벌 세금 처리 자동화 Paddle / Lemon Squeezy 다양한 국가의 세금 신고 수고를 덜어주세요.
    최대 트래픽 추구 Steam / App Store 준비된 대규모 사용자 기반
    브랜드 공식 웹사이트를 빠르게 구축하세요 Shopify / SHOPLINE 고도로 맞춤화된 쇼핑 경험
    초기 시드 사용자 확보 AppSumo 프로모션을 통해 빠르게 현금을 확보하세요



    email: [email protected]
    
    T:0000
    資訊與搜尋 | 回dev首頁
    email: Yan Sa [email protected] Line: 阿央
    電話: 02-27566655 ,03-5924828