foreach 

배열과 컬렉션를 위한 반복문

 

기본적인 for문

 

int[] numbers = new int[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

for (int i = 0; i < numbers.Length; i++)

{

    Console.Write(numbers[i] + " ");

}

Console.WriteLine("");

 

C# 프로그래밍에서 기본적으로 사용되는 배열 반복문은 위의 코드와 같이 for문을 사용한다.. C#의 배열은 기본적으로 배열 안에 있는 요소의 수를 Length 프로퍼티로 알려주기 때문에 C++처럼 for문을 사용하다가 Index Out Of Range Exception이 발생할 가능성은 적다.

 

List<int> numList = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

for (int i = 0; i < numList.Count; i++)

{

    Console.Write(numbers[i] + " ");

}

Console.WriteLine("");

 

for문을 이용한 리스트의 순회 역시 배열의 순회와 거의 같은 형태를 취하기 때문에 사용에 큰 어려움은 없다고 느낄 수 있다.

 

Dictionary<int, int> numDictionary = new Dictionary<int, int>() { { 0, 0 }, { 1, 1 }, { 2, 2 } };

for(var enumerator = numDictionary.GetEnumerator(); enumerator.MoveNext(); )

{

    Console.Write(enumerator.Current.Key + ":" + enumerator.Current.Value + " ");

}

Console.WriteLine("");

 

하지만 for문을 사용해서 딕셔너리를 순회하려고 하면 위의 코드와 같이 열거자를 활용해서 코드를 작성해야하기 때문에 코드가 길어지고 열거자에 대해서 아직 익숙하지 않은 개발자라면 쉽게 사용하기가 어렵다.

 

 

foreach문을 사용한 컬렉션 순회

 

그렇다면 이제 foreach문을 사용한 예시 코드를 보자.

 

int[] numbers = new int[10] { 01234, 56789 };

foreach(var num in numbers)

{

    Console.Write(num + " ");

}

Console.WriteLine("");

 

List<int> numList = new List<int>() { 0123456789 };

foreach (var num in numList)

{

    Console.Write(num + " ");

}

Console.WriteLine("");

 

Dictionary<intint> numDictionary = new Dictionary<intint>() { { 0}, { 11 }, { 22 } };

foreach (var num in numDictionary)

{

    Console.Write(num.Key + ":" + num.Value + " ");

}

Console.WriteLine("");

 

이번에는 배열, 리스트, 딕셔너리의 예시를 한꺼번에 작성했다. foreach문을 사용해서 딕셔너리를 순회하면 열거자를 사용할 때보다 훨씬 코드가 짧아지고 리스트나 배열에서도 조금 더 작성이 편해지는 것을 알 수 있다.

 

List<int> numList = new List<int>() { 0123456789 };

foreach (var num in numList)

{

    Console.Write(num + " ");

}

Console.WriteLine("");

 

간단하게 리스트를 순회하는 foreach문을 예시로 들어서 설명해보자면 foreach (var 임시변수 in 순회하고자 하는 컬렉션)으로 매 반복마다 순회하고자 하는 컬렉션의 요소를 받아와서 사용하는 방식이다. foreach는 컬렉션의 순회가 끝나면 자동으로 반복을 중지하기 때문에 Index Out Of Range Exception이 발생할 염려가 없다.

 

 

foreach문의 다차원 배열 순회

 

int[,] array = new int[2, 3]

{

    { 0, 1, 2 },

    { 3, 4, 5 },

};

 

for (int i = 0; i < 2; i++)

{

    for (int j = 0; j < 3; j++)

    {

        Console.WriteLine(string.Format("multiLayerArray[{0},{1}] :: {2}", i, j, array[i, j]));

    }

}

 

foreach (var num in array)

{

    Console.WriteLine(num);

}

 

foreach문을 사용하면 다차원 형태의 배열 역시 순회가 손쉽게 가능하다. for문을 이용해서 다차원 배열을 순회하려면 n차원에 대해서 n중 for문을 구현해야하지만 foreach문을 이용하면 단 하나의 for문으로 다차원 배열의 순회가 가능해진다.

 

하지만 이것은 각각의 장단점이 명확하게 갈린다. 다차원 배열의 경우, foreach문으로 순회하면 코드가 간단해지는 장점이 있지만, for문을 통한 다차원 배열의 순회처럼 각각의 인덱스에 대한 처리가 어려워진다.

 

 

foreach를 활용한 enum 순회

 

public enum DayOfWeek { Monday = 1, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

 

foreach (int dow in Enum.GetValues(typeof(DayOfWeek)))

{

    Console.WriteLine(string.Format("{0}번째 요일", dow));

 

}

 

foreach (string dow in Enum.GetNames(typeof(DayOfWeek)))

{

    Console.WriteLine(dow);

}

 

foreach와 Enum 클래스를 이용해서 enum에 대한 순회역시 가능하다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

 

반응형

Thread 

스레드 생성 시 반복문의 인덱스를 매개변수로 받을 때

 

스레드(Thread)를 생성할 때, 반복문으로 여러 개의 스레드를 생성하면서 그 반복문의 인덱스를 매개변수로 전달하는 방법을 쓸 때가 있다.

 

class ThreadTestProgram

{

    public static int DeviceNum = 10;

 

    public static void Main(string[] args)

    {

        for (int i = 0; i < DeviceNum; i++)

        {

            new Thread(() => Run(i)).Start();

        }

    }

 

    public static void Run(int idx)

    {

        // 디바이스 인덱스에 따라서 스레드 별로 각 디바이스와 연결하는 작업...

        Console.WriteLine(idx);

    }

}

 

위의 예시 코드가 바로 그것이다. 여러 개의 디바이스에 연결해서 스레드로 작업을 처리해야 할 때의 코드인데, 스레드 함수에서는 반복문에서 디바이스의 인덱스를 전달받아서 연결하도록 설계된 코드이다.

 

물론 스레드이기 때문에 실행 순서 자체는 보장할 수 없지만, 적어도 각 스레드가 매개변수의 값으로 0, 1, 2, 3, 4, 5, 6, 7, 8, 9를 전달받는 것을 기대하고 설계된 코드라고 볼 수 있다.

 

 

하지만 실행결과를 보면 각 스레드가 전달받은 매개변수 값은 1, 2, 3, 4, 5, 5, 6, 8, 8, 10으로 0, 7, 9를 전달받은 스레드는 없고 5와 8을 전달받은 스레드는 두 개씩 있는 엉망진창인 상태인 것을 볼 수 있다.

 

이 상황이 의미하는 것은 스레드의 매개변수로 넣은 반복문의 인덱스 값이 스레드가 시작되기 전에 변경되면 스레드의 매개변수 값 역시 영향을 받는다는 것이다.

 

// int i = 0 -> 반복문에 사용될 인덱스 값 설정

for(int i = 0; i < DeviceNum; i++)

{// i < DeviceNum -> 인덱스 값이 반복문 내의 코드 블럭을 실행하기에 유효한지 검사

    new Thread(() => Run(i)).Start(); // 스레드 생성 

    // i 값이 증가하기 전에 스레드가 시작되면 원래 값이 들어간다.

}// i++ 값 증가 // i 값이 증가한 이후에 스레드가 시작되면 i + 1 값이 들어간다.

 

각 코드 진행 상황에 대한 해설을 달자면 위와 같다. i값이 증가한 이후에 스레드가 시작되는 것이 문제로 스레드가 시작되기 전까지 전달되는 값이 변하지 않을 것에 대한 보장이 필요한 상태이다.

 

이를 위해서 코드를 다음과 같이 변경해보자.

 

class ThreadTestProgram

{

    public static int DeviceNum = 10;

 

    public static void Main(string[] args)

    {

        for (int i = 0; i < DeviceNum; i++)

        {

            int idx = i; // i 값이 바뀌어도 상관없도록 임시 변수에 값을 전달하여 스레드의 매개 변수로 사용

            new Thread(() => Run(idx)).Start();

        }

    }

 

    public static void Run(int idx)

    {

        // 디바이스 인덱스에 따라서 스레드 별로 각 디바이스와 연결하는 작업...

        Console.WriteLine(idx);

    }

}

 

위의 임시 코드처럼 i의 값을 임시 변수에 전달해서 스레드에 매개변수로 전달하면 i값이 증가해도 idx의 값은 증가하지 않기 때문에 스레드가 실행될 때까지 값이 변조되지 않을 것이다.

 

 

실제로 코드를 컴파일해보면 실행순서는 섞여있지만 각 스레드가 디바이스 인덱스로 0, 1, 2, 3, 4, 5, 6, 7, 8, 9를 받은 것을 확인할 수 있다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Programming 

Coroutine 내에서의 무한 루프 작성시 주의점

 

유니티 엔진을 이용해서 게임을 제작하다 보면 코루틴을 자주 사용하게 된다. 몇 초후에 문이 자동으로 열렸다가 닫힌다든지, 화상 데미지로 1초마다 데미지가 얼마씩 들어온다든지 하는 형식으로 말이다.

 

특정한 경우에는 코루틴을 실행시킨 다음에 안에 무한 루프문을 작동시키는 방식으로 코루틴을 유지하면서 사용하는 방법도 있다.

 

IEnumerator CoroutineFunction()

{

yield return null;

while(true)

{

Function();

}

}

 

다만 코루틴 내에서 무한 루프를 처리할 때 주의할 점이 있는데 위의 코드처럼 코루틴을 작성하면 유니티 에디터에서 실행하든 빌드를 해서 실행을 하든 프로그램이 응답없음이 뜨면서 정지를 할 것이다. 이 문제를 해결하는 방법은 매우 간단한데, 바로 while 무한 반복문 안에 yield return을 넣어주는 것이다.

 

올바른 코루틴 내의 무한 루프 사용법

IEnumerator CoroutineFunction()

{

while(true)

{

yield return null;

Function();

}

}

 

이 사태의 원인은 코루틴이 돌리는 무한 반복문이 시스템에 독점적으로 돌아가는 상태가 되었기 때문이다. 그렇기 때문에 이를 해결하기 위해서 반복문안에 반드시 yield return을 이용해서 시스템을 다른 코드에 양보해주는 것이 필수이다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

C++ 11부터 지원되는 Range-based for(범위 기반 for)는 기존의 C++ STL의 컨테이너, 배열 등에서 반복문을 좀 더 쉽게 사용하게 해주는 기능이다.

 

이 기능은 Microsoft의 Visual C++ 기능인 for each문과 그 기능과 사용법이 비슷해서 쉽게 사용할 수 있다.

 

기존의 for문과 iterator를 이용한 방법과 Visual C++ for each문을 이용한 방법 그리고 C++ 11 표준의 Range-based for문을 이용한 방법을 비교하자면 아래와 같다.

 

vector<Object*> vect;

// 기존의 for문과 auto 키워드를 이용한 iterator 반복 처리
for (auto obj = vect.begin(); obj != vect.end(); obj++)
{
    // Object에 처리
}

// Visual C++ 타입의 for each문을 이용한 반복 처리
for each(auto obj in vect)
{
    // Object에 처리
}
// C++ 11타입의 Range-based for문을 이용한 반복 처리
for (auto obj : vect)
{
    // Object에 처리
}

 

코드를 살펴보면 분명하게 미세하게나마 코드의 양이 줄어드는 것이 보인다. 같은 동작을 하는 데도 기존의 for문과 auto 형식의 복잡한 타이핑 없이 처리할 수 있다는 것은 프로그래머의 피로도를 상당히 줄여준다.(물론 auto 키워드가 나오기 전에는 더더욱 복잡했었다.)

 

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

'C++' 카테고리의 다른 글

[C++11] enum class  (1) 2017.07.17
[C++ 11] static_assert  (0) 2017.05.23
[C++ 11] Auto Vectorization  (1) 2016.11.01
[C++ 11] Range-Based For  (0) 2016.11.01
[C++ 11] Scoped Lock  (0) 2016.11.01

+ Recent posts