반응형

std::tuple은 두 개 이상의 변수나 객체를 하나로 묶어 전달 할 때 사용된다.

 

1. 사용법

#include <tuple>

std::tuple< var-type1, ..., var-typeN > var;

 

(1) 인자
  1-1) var-type : 변수나 객체의 타입을 지정

 

 

2. 사용 예제

#include <iostream>
#include <vector>
#include <tuple>

// 이름, 나이, 키
using Type = std::tuple<std::string,int,float>;

void print(const Type& param)
{
    // std::get을 사용하여 값에 접근
    std::cout << "Name:" << std::get<0>(param) << ", Age:" << std::get<1>(param)
        << ", Height:" << std::get<2>(param) << std::endl;
}

int main()
{
    // 선언과 함께 값 추가
    std::tuple<std::string,int,float> t1{"name1", 10, 164.2};
    print(t1);

    // std::make_tuple을 사용하여 값 추가
    Type t2{std::make_tuple<std::string,int,float>("name2", 20, 183.2)};
    print(t2);

    // tuple 사이즈 알아오기
    std::cout << "tuple size: " << std::tuple_size<Type>() << std::endl;

    // auto를 사용하여 값에 접근
    auto& [name, age, height] = t1;
    std::cout << "Name:" << name << ", Age:" << age << ", Height:" << height << std::endl;

    // std::tie를 사용하여 값에 접근
    std::string n{};
    int a{0};
    float h{0.0f};
    std::tie(n, a, h) = t2;
    std::cout << "Name:" << n << ", Age:" << a << ", Height:" << h << std::endl;

    // 벡터와 함께 사용
    std::vector<Type> vTuple;
    vTuple.emplace_back(t1);
    vTuple.emplace_back(t2);
    vTuple.emplace_back(std::make_tuple<std::string,int,float>("name3", 30, 172.2));
    vTuple.emplace_back(Type("name4", 40, 166.7));

    for (const Type& v : vTuple) print(v);
    
    return 0;
}


 
 
 

반응형
반응형

 

std::pair는 두 개의 변수나 객체를 하나로 묶어 전달 할 때 사용된다.

 

1. 사용법

#include <utility>

std::pair< var-type1, var-type2 > var;

 

(1) 인자

  1-1) var-type : 변수나 객체의 타입을 지정

 

2. 사용 예제

#include <iostream>
#include <vector>
#include <utility>
#include <tuple>

using Type = std::pair<int, std::string>;

void print(const Type& param)
{
    std::cout << param.first << " = " << param.second << std::endl;
}

int main()
{
    // 선언과 함께 값 추가
    std::pair<int,std::string> p1{1, "one"};
    // 값에 직접 접근 (first, second)
    std::cout << p1.first << " = " << p1.second << std::endl; // 1 = one

    // std::make_pair를 사용하여 값 추가
    std::pair<int,std::string> p2{std::make_pair<int,std::string>(2, "two")};
    // std::get을 사용하여 값에 접근
    std::cout << std::get<0>(p2) << " = " << std::get<1>(p2) << std::endl; // 2 = two

    // auto를 사용하여 값에 접근
    auto& [num, str] = p1;
    std::cout << num << " = " << str << std::endl; // 1 = one

    // std::tie를 사용하여 값에 접근
    // #include <tuple> 필요
    int n{0};
    std::string s{};
    std::tie(n, s) = p2;
    std::cout << n << " = " << s << std::endl; // 2 = two

    // 벡터와 함께 사용
    std::vector<Type> vPair;
    vPair.emplace_back(p1);
    vPair.emplace_back(p2);
    vPair.emplace_back(std::make_pair<int,std::string>(3, "three"));
    vPair.emplace_back(Type(4, "four"));

    for (const Type& v : vPair) print(v);

    // 값 수정
    p1.first = 11;
    p1.second = "eleven";
    print(p1); // 11 = eleven

    return 0;
}


 
 
 

 

 

 

 

 

반응형
반응형

일반 배열은 길이 정보가 없어서 인자로 넘기려면 길이 정보를 같이 넘겨야 하고, 인덱스를 조금만 벗어나도 Buffer Overflow 와 같은 문제가 발생하므로 안전하지 않다.

C++20 이후에는 모든 연속 객체(배열, 문자열, 벡터, ...)를 안전하게 참조할 수 있도록 해주는 std::span을 사용할 수 있다.

연속 객체를 std::span으로 참조하게 되면 순차 컨테이너에서 제공하는 함수를 사용할 있다. (길이 정보와 반복자를 가짐)

 

1. 사용법

#include <span>

std::span< var-type > var; // 동적 길이를 가지는 span
std::span< var-type, size > var; // 정적 길이를 가지는 span

 

(1) 인자

  1-1) var-type : 변수나 객체의 타입을 지정

  1-2) size : span 사이즈를 지정하여 정적 span으로 사용

 

2. 사용 예제

#include <iostream>
#include <string>
#include <span>

template <typename T>
void printContainer(const std::span<T>& param)
{
    if (param.empty())
    {
        std::cout << "empty." << std::endl;
        return;
    }

    std::cout << "value:";
    for (const auto& v : param)
    {
        std::cout << " " << v;
    }
    std::cout << ", size: " << param.size() << std::endl;
}

int main()
{
    int iArr[5]{1,2,3,4,5};

    // 배열을 정적 span으로 설정
    std::span<int, 5> spArr{iArr};
    for (auto it = spArr.begin(); it != spArr.end(); ++it)
    {
        std::cout << *it << std::endl; // 1 2 3 4 5
    }

    // 배열을 동적 span으로 설정하여 인자로 사용
    printContainer(std::span<int>{iArr}); // value: 1 2 3 4 5, size: 5

    // 문자열을 동적 span으로 설정
    std::string pStr{"abcdefg"};
    std::span<char> spStr{pStr};
    printContainer(spStr); // value: 1 2 3 4 5, size: 5

    // 빈 span을 인자로 사용
    printContainer(std::span<int>{}); // empty.

    return 0;
}


 
 

 

 

 

 

반응형
반응형

bool 변수의 값이 false일 경우에만 특정 작업을 수행하고, true로 변경하는 경우가 빈번하게 발생한다.

기존에는 보통 아래와 같이 코드를 작성했다.

bool isFirst{false};

if (isFirst == false)
{
    // 작업을 수행
    ...
    ...
    isFirst = true;
}

 

C++14 이후에는 std::exchange를 사용하여 간결한 코드로 작성할 수 있으며, bool형 이외의 변수값을 변경할 수도 있다.

 

1. 사용법

#include <utility>

std::exchange( var, new-value )

 

(1) 인자

  1-1) var : 값을 변경할 변수나 객체

  1-2) new-value : 변경할 값

(2) 반환값 : 변경전의 var 값

 

2. 사용 예제

bool isFirst{false};

if (std::exchange(isFirst, true) == false)
{
    // 작업을 수행
    ...
    ...
}

 

3. 사용 예제 (컨테이너에 사용)

#include <iostream>
#include <utility>
#include <vector>

template <typename T>
void printContainer(const T& pContainer)
{
    for (const auto& v : pContainer)
    {
        std::cout << v << " ";
    }
    std::cout << std::endl;
}

int main()
{
    std::vector<int> vec{};

    // vector에 값을 저장
    std::exchange(vec, {1,2,3,4});
    printContainer(vec); // 1 2 3 4

    // vector의 값을 변경
    std::vector<int> oldVec{std::exchange(vec, {5,6,7,8})};
    printContainer(oldVec); // 1 2 3 4
    printContainer(vec); // 5 6 7 8

    return 0;
}

 

4. 사용 예제 (함수에 사용)

#include <iostream>
#include <utility>
#include <functional>

int main()
{
    std::function<void()> fFunc{[](){
        std::cout << "Original Function" << std::endl;
    }};
    fFunc(); // Original Function

    std::function<void()> fOldFunc{std::exchange(fFunc, [](){
        std::cout << "New Function" << std::endl;
    })};
    fFunc(); // New Function
    fOldFunc(); // Original Function
    
    return 0;
}


 

 

반응형
반응형

보통 함수를 실행한 후 결과값은 하나만 반환받을 수 있다.

함수 실행 결과와 결과값이 모두 필요할 경우에는 함수의 인자로 참조나 포인터 변수를 전달해야 했다.

C++17 이후에는 std::optional을 사용해서 함수의 반환값으로 [함수 실행 결과]와 [결과값]을 한번에 전달받을 수 있다.

 

1. 사용법

#include <optional>

std::optional< var-type > var-name;

 

(1) 인자

  1-1) var-type : 함수 실행 결과값의 타입을 지정

 

2. 사용 예제

#include <iostream>
#include <optional>
#include <string>

std::optional<std::string> toUpper(const std::string& pStr)
{
    if (pStr.empty() == true)
    {
        return std::nullopt;
    }

    std::string str{pStr};
    std::transform(str.begin(), str.end(), str.begin(), [](const char c) {
        return std::toupper(c);
    });

    return std::make_optional<std::string>(str); // return str; 로 대체 가능
}

void printResult(const std::optional<std::string>& pRet)
{
    if (pRet == std::nullopt) // (pRet.has_value() == false)로 대체 가능
    {
        std::cout << "failed !!!" << std::endl;
    }
    else
    {
        std::cout << *pRet << std::endl; // pRet.value()로 사용 가능
    }
}

int main()
{
    std::optional<std::string> ret{toUpper("abcdefg")};
    printResult(ret); // ABCDEFG

    ret = toUpper("");
    printResult(ret); // failed !!!

    return 0;
}


 

반응형
반응형

일반 함수는 [반환형], [함수 이름], [인수] 를 입력하여 선언한다. 

하지만 람다 함수는 이름이 없는 익명 함수로써 아래의 형태로 선언하여 사용하며, std::function 과 함께 사용시 재사용도 가능하다. 

(참고 : std::function - 함수 포인터를 대체하는 키워드)

 

1. 사용법

- 람다 함수는 캡처(Capture), 인자(Parameter), 반환형(Return-Type), 바디(Body) 로 구성되어 있다.
- 캡처와 인자는 콤마(,)로 구분하여 여러 개 지정할 수 있다.

[capture] (parameter) -> return-type { body };

 

(1) 캡처(Capture)

- 캡처는 람다 함수에서 사용할 변수나 상수를 참조나 복사의 형태로 찍어오는 것이다.
- 전역 변수를 참조로 캡처할때는 [&], 복사로 캡처할때는 [=]를 사용한다.
- 지역 변수를 참조로 캡처할때는 [&변수명], 복사로 캡처할때는 [=변수명]을 사용한다.

[&]() { return; } // 모든 변수를 참조로 캡처
[=]() { return; } // 모든 변수를 복사로 캡처
[&var1, var2]() { return; } // var1은 참조, var2는 복사로 캡처
[=, &var1]() { return; } // var1만 참조로 캡처하고, 다른 변수는 복사로 캡처
[&, var2]() { return; } // var2만 복사로 캡처하고, 다른 변수는 참조로 캡처

 

- 복사로 캡처된 변수는 기본적으로 constexpr 타입으로 지정되어 값의 변경이 불가하다.

- mutable로 선언하면 값의 변경이 가능하다.

int var1{0};

[var1]() {
    var1 = 999; // 에러!!! - var1은 constexpr 타입이므로 변경이 불가
}();
[var1]() mutable {
    var1 = 999; // var1은 mutable로 선언되어 변경이 가능, 단 실제 값은 변하지 않음
    std::cout << var1 << std::endl; // 999
}();

std::cout << var1 << std::endl; // 0

 

(2) 인자(Parameter)

- 일반 함수의 인자처럼 람다 함수에서 사용할 인자를 지정한다.

[](int a) -> int { return a; } // 1개의 인자를 설정
[](int a, int b) -> int { return (a+b); } // 2개의 인자를 설정


(3) 반환형(Return-Type)

- 람다 함수의 실행 결과를 반환할 반환 타입을 지정한다.


(4) 바디(Body)

- 람다 함수에서 수행할 작업을 기술한다.

 

2. 사용 예제

#include <iostream>
#include <functional>

int main()
{
    // 간단한 람다 함수
    []() {
        std::cout << "Simple Lamda Function" << std::endl;
    }();
    
    // 인자 2개를 더해서 sum에 저장하고, 더한 값을 반환하는 람다 함수
    int sum{0};
    // std::function 에 람다 함수를 정의
    std::function<int(int,int)> fSum{[&sum](int a, int b) -> int {
        sum = a + b;
        return sum;
    }};

    std::cout << fSum(10, 20) << std::endl; // 30
    std::cout << sum << std::endl; // 30
    
    return 0;
}

 

3. 사용 예제 (클래스에서 사용)

#include <iostream>
#include <functional>
#include <string>

class Person
{
public:
    Person(std::string&& pName, int pAge, std::function<std::string(std::string&, int)>&& pFunc)
        : mName(std::move(pName))
        , mAge(pAge)
        , mTagFunc(std::move(pFunc)) // 람다 함수로 전달받은 임시 함수(r-value)를 std::move를 사용해 저장
    {
        // 출력 람다 함수에서 클래스의 멤버 변수를 사용하기 위해 this를 캡처한다.
        mPrintFunc = [this]() {
            std::cout << "Name: " << mName << ", Age: " << mAge
                << ", Tag: " << mTag << std::endl;
        };
    }

    void executeTagFunc()
    {
    	// 태그 생성 람다 함수 호출
        mTag = mTagFunc(mName, mAge);
    }

    void executePrintFunc()
    {
    	// Person 정보 출력 람다 함수 호출
        mPrintFunc();
    }

private:
    std::function<std::string(std::string&, int)> mTagFunc{};
    std::function<void()> mPrintFunc{};

    std::string mName{};
    std::string mTag{};
    int mAge{0};
};

int main()
{
    // 객체 생성시 [이름], [나이], [태그 생성 함수]를 인자로 받음
    Person ps("Simson", 44, [](std::string& pName, int pAge) -> std::string {
        return std::string(pName + "-" + std::to_string(pAge));
    });

    ps.executeTagFunc();
    ps.executePrintFunc();

    return 0;
}


 

반응형
반응형

std::function은 기존의 함수 포인터를 대체하는 키워드로 C++11에서 추가되었으며, 잘 사용하면 짧은 코드로 많은 기능을 구현할 수 있다.

 

1. 사용법

#include <functional>

std::function< return-type (parameter-type) > var-name = function;

 

(1) 인자

  1-1) return-type : 함수의 실행 결과를 반환할 반환 타입을 지정

  1-2) parameter-type

    - 함수에서 사용할 인자의 타입을 지정

    - 인자가 여러 개일 경우 콤마(,)로 구분

 

2. 사용 예제 (1)

#include <iostream>
#include <functional>

void simpleFunc()
{
    std::cout << "Simple Function" << std::endl;
}

void executeFunc(std::function<void()>& func)
{
    func();
}

int main()
{
    // 기존 함수로 생성
    std::function<void()> func{simpleFunc};

    // 람다 함수로 생성
    std::function<void()> lambdaFunc{[](){
        std::cout << "Simple Lambda Function" << std::endl;
    }};

    // 함수 실행
    func();
    lambdaFunc();

    // 함수의 인자로 넘겨서 사용
    executeFunc(func);
    executeFunc(lambdaFunc);
    
    return 0;
}

 

3. 사용 예제 (2)

#include <iostream>
#include <functional>

std::function<void(unsigned char)> moveLEFT{[](unsigned char key){
    std::cout << "[" << key << "] move LEFT" << std::endl;
}};

std::function<void(unsigned char)> moveRIGHT{[](unsigned char key){
    std::cout << "[" << key << "] move RIGHT" << std::endl;
}};

std::function<void(unsigned char)> moveUP{[](unsigned char key){
    std::cout << "[" << key << "] move UP" << std::endl;
}};

std::function<void(unsigned char)> moveDOWN{[](unsigned char key){
    std::cout << "[" << key << "] move DOWN" << std::endl;
}};

void keyHandler(const unsigned char key)
{
    switch (key) {
        case 'a': return moveLEFT(key);
        case 'd': return moveRIGHT(key);
        case 'w': return moveUP(key);
        case 's': return moveDOWN(key);
    };
}

int main()
{
    unsigned char key{};

    while (true)
    {
        std::cout << "Input key: ";
        std::cin >> key;

        if (key == 'q') break;

        keyHandler(key);
    }


    return 0;
 }


 

 

반응형
반응형

기존 C++ 포인터는 동적 할당 메모리를 생성(new) 해서 사용한 후 반드시 삭제(delete) 해줘야 한다.

프로그래머가 수동으로 관리하다보니 삭제가 누락되면 메모리 릭이 발생하곤 한다.

C++11 에서 추가된 Smart Pointer를 사용하면 메모리 삭제에 대한 부분을 신경쓰지 않아도 된다.

Smart Pointer에는 3가지(unique_ptr, shared_ptr, weak_ptr)가 있으며, weak_ptr은 사용 빈도가 매우 낮으므로 unique_ptr shared_ptr 에 대해 알아보자.

 

1. 사용법

#include <memory>

std::unique_ptr< var-type > var;
std::shared_ptr< var-type > var;

 

(1) 인자

  1-1) var-type : 변수나 객체의 타입을 지정

 

2. 일반 포인터 사용

- 포인터를 생성하여 사용한 후 반드시 삭제를 해줘야 한다.

- 프로그래머의 실수로 삭제가 누락될 경우 메모리 릭이 발생할 우려가 있다.

#include <iostream>
#include <string>

using Type = std::string;

int main()
{
    Type* str{new Type("Hello world !!!")};
    std::cout << *str << std::endl;
    
    delete str; // 동적 메모리 사용 후 삭제 필요

    return 0;
}

 

3. std::unique_ptr

- 소유권을 하나만 가질 수 있는 포인터이다.

- 객체를 선언하여 사용한 후 사용 범위가 종료될 때 소멸자가 호출되어 메모리를 자동으로 삭제한다. 

- 소유권을 이전하기 위해서는 std::move()를 사용해야거나 참조로 전달해야 한다.

- C++14 이후에는 std::make_unique() 함수를 통해 포인터를 생성할 수 있다.

#include <iostream>
#include <string>
#include <memory>

using Type = std::string;

void print(std::unique_ptr<Type>& pStr4)
{
    std::unique_ptr<Type> pStr5{std::move(pStr4)};
    std::cout << pStr4 << std::endl; // 0
    std::cout << pStr5 << std::endl; // 0x141fc20
    
    // 함수가 종료되면 pStr5는 삭제됨.
}

int main()
{
    std::unique_ptr<Type> pStr{new Type("Hello world !!!")};
    //std::unique_ptr<Type> pStr{std::make_unique<Type>("Hello world !!!")}; // C++14 이후
    std::cout << pStr << std::endl; // 0x141fc20
    
    Type* ppStr{pStr.get()}; // 주소값 가져오기
    std::cout << ppStr << std::endl; // 0x141fc20
    
    //std::unique_ptr<Type> pStr2{pStr}; // 컴파일 에러!! (소유권은 하나만 가능)
    std::unique_ptr<Type> pStr3{std::move(pStr)}; // 소유권 이전 가능
    std::cout << pStr << std::endl; // 0
    std::cout << pStr3 << std::endl; // 0x141fc20
    
    print(pStr3); // 인자로 넘겨서 참조로 받기 가능
    std::cout << pStr3 << std::endl; // 0
    
    // 동적 메모리 사용 후 삭제가 필요하지 않음.

    return 0;
}

 

4. std::shared_ptr

- 소유권을 여러개 가질 수 있는 포인터이다.

- 소유자 수의 관리는 내부적으로 참조 카운터(Reference Counter)를 통해 이루어진다.

- 참조 카운터가 0이 되면 메모리를 자동으로 삭제한다.

- C++14 이후에는 std::make_shared() 함수를 통해 포인터를 생성할 수 있다.

#include <iostream>
#include <string>
#include <memory>

using Type = std::string;

void print(std::shared_ptr<Type>& pStr3)
{
    std::shared_ptr<Type> pStr4{std::move(pStr3)};
    std::cout << pStr4 << " - " << pStr4.use_count() << std::endl; // 0x2274c20 - 2
    pStr4.reset(); // 명시적으로 메모리 해제
    
    // 함수가 종료되면 참조 카운트가 1 감소됨.
}

int main()
{
    std::shared_ptr<Type> pStr{new Type("Hello world !!!")};
    //std::shared_ptr<Type> pStr{std::make_shared<Type>("Hello world !!!")}; // C++14 이후
    std::cout << pStr << " - " << pStr.use_count() << std::endl; // 0x2274c20 - 1

    Type* ppStr{pStr.get()}; // 주소값 가져오기
    std::cout << pStr << " - " << pStr.use_count() << std::endl; // 0x2274c20 - 1

    std::shared_ptr<Type> pStr2{pStr}; // 소유권 여러개 가능
    std::cout << pStr2 << " - " << pStr2.use_count() << std::endl; // 0x2274c20 - 2

    print(pStr2); // 인자로 넘겨서 참조로 받기 가능
    std::cout << pStr2 << " - " << pStr2.use_count() << std::endl; // 0 - 0

    print(pStr);
    std::cout << pStr << " - " << pStr.use_count() << std::endl; // 0 - 0
    
    // 동적 메모리 사용 후 삭제가 필요하지 않음.
    
    return 0;
}

 



 

반응형
반응형

1. 설명

- 원자적으로 처리할 변수에 대해 정의한다.

- 쓰레드 동작시 공유 변수의 동시성(Concurrency) 문제에 대해 해결해 준다.

 

 

2. 문제 상황

- 아래의 코드를 실행해보면 전역 변수 num을 2개의 쓰레드가 각각 더하거나 뺀다.

- 더하거나 빼는 과정에 문맥교환(Context Switching)이 일어나면 연산이 완료되기 전에 제어권을 빼앗길 수 있다.

- 더하거나 빼는 연산을 원자적으로 처리하기 위해 atomic 변수로 선언이 필요하다.

#include <iostream>
#include <thread>

int num{0};

void ThreadHandler(const bool isAdd)
{
    for (int i=0; i<1000000; i++)
    {
    	if (isAdd) num++;
        else num--;
    }
    
    std::cout << "num=" << num << std::endl;
}

int main()
{
    std::jthread thr1{ThreadHandler, true};
    std::jthread thr2{ThreadHandler, false};
    
    return 0;
}

 

3. 사용법

#include <atomic>

std::atomic< var-type > var;

 

(1) 인자

  1-1) var-type : 변수나 객체의 타입을 지정

 

4. 사용 예제

- 위에서 문제가 됐던 num 변수의 타입을 std::atomic<int>로 변경해 준다.

- 이제 num 변수의 원자성이 보장되기 때문에 마지막 출력값은 항상 0이 된다.

#include <iostream>
#include <thread>
#include <atomic>

std::atomic<int> num{0}; //atomic 변수 선언

void ThreadHandler(const bool isAdd)
{
    for (int i=0; i<1000000; i++)
    {
    	if (isAdd) num.fetch_add(1); //atomic 값을 증가 (num++ 사용가능)
        else num.fetch_sub(1); //atomic 값을 감소 (num-- 사용가능)
    }
    
    std::cout << "num=" << num.load() << std::endl; //atomic 값을 출력
}

int main()
{
    num.store(0); //atomic 변수 초기화
    
    std::jthread thr1{ThreadHandler, true};
    std::jthread thr2{ThreadHandler, false};
    
    return 0;
}

 

 

 

 

반응형
반응형

                                                 


void printfBinary(int input){  

    int i, check=1;                                                                        

    char bit;                                                                              

    for(i=31; i>=0; i--){                                                                  

        bit = (input &(1<<i))?1:0;                                                         

        printf("%d", bit);                                                                 

        if(i%8==0) printf(" ");                                                            

    }                                                                                      

    printf("\n");                                                                          

} 















반응형
반응형

1. 배열


스칼라값들의 목록,독립적인 스칼라값들이므로 숫자,문자열,undef값을 가질수 있다.

But, 한 스칼라값으로 공통사용하는걸 추천

초기값은 당연히 undef




#!perl
##################################
##		Test 1
##################################
$student[0] = "Jenny";
$student[1] = "Paul";
$student[2] = "Mike";

for($i=0; $i<3; $i++)
{
	print "student[".$i."]:". $student[$i]."\n";
}

##################################
##		Test 2
##################################
$student[1] = "Jimmy";
$student[2] = "Ray";
print "\n\n----Change Array-----\n";
for($i=0; $i<3; $i++)
{
	print "student[".$i."]:". $student[$i]."\n";
}


- test 1

student라는 배열에 0번째인덱스에 Jenny, 1번째인덱스에 Paul, 2번째인덱스에 Mike를 넣었다.

- test 2

student라는 배열에 1번째인덱스에 Jimmy, 2번째인덱스에 Ray로 변경한다.




















반응형

'Programming Language > Perl' 카테고리의 다른 글

Perl - While문  (0) 2014.01.24
Perl 사용자 입력 받기  (0) 2014.01.13
Perl 비교연산자와 if제어  (0) 2013.12.27
perl 스칼라 값 할당  (0) 2013.12.24
Perl 내장경고  (0) 2013.12.24
반응형

1. While문


조건문에 해당하는 부분이 참이 되어야 실행소스가 구동됩니다.


while ( 조건문 )

 - 실행소스

 }




- 예제소스

#!perl

$count = 0;

while( $count < 20 ){
	$count += 1;
	print "count = $count\n";
}



count값이 1씩 20번 증가한걸 확인할 수 있습니다.






2. undef값

Perl에선 변수들은 값을 할당받기전 undef라는 값을 지니게됩니다.
변수가 숫자라면  이 값은 0이고,
변수가 문자열이라면 이 값은 빈문자열이 됩니다.

앞서, 반복문 예제에 count초기화부분을 제거하고
문자열 undef값을 테스트 해보기로 해요. 


- 예제소스
#!perl

//정수변수 test
while( $count < 20 ){
	$count += 1;
	print "count = $count\n";
}

print "\n\n";

//문자열변수 test
$str .= "String is null"; //str변수에 "String is null" 문자열을 추가
print $str."\n"



count값에 아무 영향이 없고, 문자열이 빈문자열로 시작하는걸 확인할수 있습니다.











반응형

'Programming Language > Perl' 카테고리의 다른 글

Perl - 배열  (0) 2014.01.27
Perl 사용자 입력 받기  (0) 2014.01.13
Perl 비교연산자와 if제어  (0) 2013.12.27
perl 스칼라 값 할당  (0) 2013.12.24
Perl 내장경고  (0) 2013.12.24
반응형

1. STDIN

끝에 줄바꿈문자(return)을 포함한 문자열이 들어올때까지 기다림

입력받은 문자의 끝에 줄바꿈 문자가 있음

#!perl
$input = ;
if( $input eq "\n"){
	print "input is blank line\n";
}
else{
	print "input is : $input\n";
}



- 빈라인 입력




- abcdefg 입력




2. chomp 연산자

STDIN으로 받은 입력문자열의 끝에 위치한 줄바꿈문자를 제거

return : 삭제한 문자의 개수

#!perl
$input = ;
print "before> input is : $input\n";
$r_num = chomp($input);
print "after> input is : $input\n";
print "remove num: $r_num\n"




- abcdefg 입력시, chomp를 하기전과 후의 줄바꿈문자가 사라진걸 확인할수 있습니다.




3. defined 함수

<STDIN>은 undef값 즉,null값을 반환하기 때문에 빈문자열인지 확인하려면 defined함수를 사용합니다. 

 

return value : 

false:undef값(즉,null) true:그외값




#!perl
$input = ;
if( defined($input)){
    print "input is : $input\n";
}
else{
    print "input is blank line\n";
}


- 빈문자열테스트



- 그외 테스트














반응형

'Programming Language > Perl' 카테고리의 다른 글

Perl - 배열  (0) 2014.01.27
Perl - While문  (0) 2014.01.24
Perl 비교연산자와 if제어  (0) 2013.12.27
perl 스칼라 값 할당  (0) 2013.12.24
Perl 내장경고  (0) 2013.12.24
반응형

1. 비교연산자


비교

 숫자

 문자열

 같음

== 

eq 

 같지 않음

!= 

ne 

 작음

lt 

 큼

gt 

 작거나 같음

<= 

le 

 크거나 같음

>= 

ge 



2. if 제어


- if

만약 ~라면


 if( 조건문 ) 




- else

if 외 다른 선택이 필요하다면

     

  if( 7 != 2+5 ){

print("case 1\n");

}

 else{

print("case 1 besides\n");

 }





#숫자-같지않음
if( 7 != 2+5){
    print("7 != 2+5 true\n");
}
else{
	print("7 != 2+5 false\n");
}
#숫자-같음
if( 7 == 2+5){
    print("7 == 2+5 true\n");
}
else{
	print("7 == 2+5 false\n");
}
#문자열-작음(<)
if( 'banana' lt 'apple'){
	print("'banana' lt 'apple' true\n");
}
else{
	print("'banana' lt 'apple' false\n");
}
#문자열-큼(>)
if( 'banana' gt 'apple'){
	print("'banana' gt 'apple' true\n");
}
else{
	print("'banana' gt 'apple' false\n");
}
#문자열-같음(==)
if( 'banana' eq 'apple'){
	print("'banana' eq 'apple' true\n");
}
else{
	print("'banana' eq 'apple' false\n");
}

















반응형

'Programming Language > Perl' 카테고리의 다른 글

Perl - While문  (0) 2014.01.24
Perl 사용자 입력 받기  (0) 2014.01.13
perl 스칼라 값 할당  (0) 2013.12.24
Perl 내장경고  (0) 2013.12.24
스칼라 데이터  (0) 2013.12.19
반응형

1. 스칼라 값 할당

다른 언어와 할당하는건 별반 다르지 않습니다.

#!perl
$age = 18;          #정수 할당
print("\$age = 18;          ---->".$age."\n");

$str = 'Hello';     #문자열 할당
print("\$str = 'Hello';     ---->".$str."\n");

$str = $age + 5;    #$age의 현재값에 5를 추가하여 str에 할당
print("\$str = \$age + 5;    ---->".$str."\n");

$str = $str * 2;    #$str의 현재값에 2를 곱한값을 할당
print("\$str = \$str * 2;    ---->".$str."\n");




2. 스칼라 이원할당 연산자

#!perl
# 더하기
$age = $age + 5;    # 이원할당자 미사용
$age += 5;          # 이원할당자 사용

#곱하기
$age = $age * 2;    # 이원할당자 미사용
$age *= 2;          # 이원할당자 사용

#문자열
$str = $str . " ";  # 이원할당자 미사용
$str .= " ";        # 이원할당자 사용


















반응형

'Programming Language > Perl' 카테고리의 다른 글

Perl 사용자 입력 받기  (0) 2014.01.13
Perl 비교연산자와 if제어  (0) 2013.12.27
Perl 내장경고  (0) 2013.12.24
스칼라 데이터  (0) 2013.12.19
Perl 윈도우 설치  (0) 2013.12.18

+ Recent posts