2016. 3. 17. 12:58

DirectX SDK (June 2010) 을 Windows 7 에 설치하던 중에 Error Code S1023 이 뜰때 해결법입니다.


윈도우 + R을 눌러서


CMD를 입력해 도스창을 실행합니다.


다음과 같이 입력하세요.


MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}


MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7}



2가지 전부 삭제후, DirectX SDK를 재설치 하시면 됩니다.


Posted by 시리시안
2016. 3. 3. 14:25


안녕하세요.


xml데이터를 만들어야하는데, 손으로 일일히 메모장에 전체를 적을수는 없으니..


제일 간단한 엑셀로 만드는법을 적어보겠습니다.


제일 먼저 엑셀로 만들기 위하면 스키마를 작성해주어야 하는데요


스키마 작성은 노트패드(메모장 또는 기타등등)을 열어서 다음과 같이 적습니다.


한국어, 영어, 중국어 3개로 로컬라이징을 하기위한 언어 스키마입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<root>
             <texts>                           
                           <index/>
                           <menu/>
                           <kor/>
                           <eng/>
                           <chi/>
             </texts>
             <texts>                           
                           <index/>
                           <menu/>
                           <kor/>
                           <eng/>
                           <chi/>
             </texts>
</root>
cs

꼭 texts는 마음대로 변경하셔도 되지만, 스키마에 한글을 적으시면 안됩니다.

그리고 반복된다는것을 알리기위해 꼭 2번 적어야합니다.


자 이렇게 작성했다면, 이를 저장합니다.


단, 저장시 확장자명을 .xml로 저장해주셔야합니다.


자 이제 엑셀을 켜봅시다.


먼저 엑셀의 개발도구를 열어야하는데요.


개발도구를 왼쪽 리본의서 메뉴에서 설정가능합니다..


모르면 구글링하면 친절한 블로그들이 있을꺼애요



개발도구에서 원본을 클릭합시다.



그러면 우측에  XML원본이라는 창이 뜰텐데요.

 그밑에 XML맵을 누르면 다음과 같은 창이 뜹니다.



그러면 밑에 추가를 누르신후 아까 저장한 xml파일을 눌러 줍시다.

그럼 다음과 같은 경고창이 하나 뜰텐데. 바로 확인 눌러줍니다.



그러면 아까 만든 맵이 이곳에 이렇게 뜰꺼애요! 아까 적은 글자 대로 뜰껍니다. 그럼 확인을 누릅시다.



그럼 우측에 다음과 같이 생성된걸 볼수있습니다.


그럼 위에 데이터를 넣기위해 간단하게 엑셀에 데이터를 적어봅시다.


첫줄은 아무상관없으니, 적기 편하게 구분을 지어주시고, 그다음부터 데이터를 적어나가면 됩니다.



자 저는 이렇게 적었어요. 정말 간단하죠?


그다음 첫열 즉 A열을 전부 드래그 한후 우측의 인덱스를 더블클릭합니다.


그러면 값들이 알아서 매핑됩니다.


이처럼 말이죠.


그럼 남은 값들도 전부 매핑 해봅시다.



자 이제 저장만 하면 됩니다.


주의할점은 엑셀로 저장하는것이 아닌 xml로 저장하는겁니다.


역시 저장할때 경고창이 뜰텐데 무시하고 저장합시다.


(나중에 수정을 하려면 엑셀파일로도 저장해두는게 좋아요, 어차피 스키마는 유지됩니다.)


그리고 저장한 파일을 열어보면

짜잔, 다음과같이 값이 알맞게 매핑되어 저장된것을 볼수있습니다.

Posted by 시리시안
2016. 2. 29. 16:11
XML만들기는 다음 포스팅을 확인해주세요


이미 만들어진 XML은 다음과 같은 코드로 불러올수있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using UnityEngine;
using System.Collections;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System.Collections.Generic;
/**
@date 2016/02/29
@author 조원우(jjgaa2@naver.com)
@brief App에서 관리해야하는 모든 텍스트를, 처음에 XMl파일을 읽어와 알맞은 텍스트를 반환합니다.
*/
public class TextManager : MonoBehaviour
{
 
    void Awake()
    {
        LoadingText();
    }
 
    List<LocalWord> AllText = new List<LocalWord>();    ///< 이곳에 모든 Text가 쌓입니다.
    /**
@brief 변수 AllText에 xml로 만들어진 데이터를 불러와 짚어 넣습니다.
*/
    void LoadingText()
    {
        TextAsset textAsset = (TextAsset)Resources.Load("Texts");
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.LoadXml(textAsset.text);
        //xml생성
        XmlNodeList Index_Table = xmldoc.GetElementsByTagName("index");
        XmlNodeList menu_Table = xmldoc.GetElementsByTagName("menu");
        XmlNodeList kor_Table = xmldoc.GetElementsByTagName("kor");
        XmlNodeList eng_Table = xmldoc.GetElementsByTagName("eng");
        XmlNodeList chi_Table = xmldoc.GetElementsByTagName("chi");
        for (int i = 0; i < Index_Table.Count; i++)
        {
            LocalWord mWord = new LocalWord();
            mWord.Index = System.Convert.ToInt32(Index_Table[i].InnerText);
            mWord.kor = kor_Table[i].InnerText;
            mWord.eng = eng_Table[i].InnerText;
            mWord.chi = chi_Table[i].InnerText;
            AllText.Add(mWord);
        }
    }
 
    public enum Enum_Language { kor, eng, chi };
    public Enum_Language Language = Enum_Language.kor;
 
    public string GetLocalizingText(int Index)
    {
        if (AllText[Index].Index == Index)
        {
            switch (Language)
            {
                case Enum_Language.kor:
                    return AllText[Index].kor;
                case Enum_Language.eng:
                    return AllText[Index].eng;
                case Enum_Language.chi:
                    return AllText[Index].chi;
            }
        }
        for (int i = 0; i < AllText.Count; i++)
        {
            if (AllText[i].Index == Index)
            {
                switch (Language)
                {
                    case Enum_Language.kor:
                        return AllText[Index].kor;
                    case Enum_Language.eng:
                        return AllText[Index].eng;
                    case Enum_Language.chi:
                        return AllText[Index].chi;
                }
            }
        }
 
        Debug.Log("[Error] 반환된 Text가 없습니다.");
        return "[Error] 반환된 Text가 없습니다.";
    }
 
}
 
/**
@date 2016/02/29
@author 조원우(jjgaa2@naver.com)
@brief 텍스트 데이터 클래스.    
*/
public class LocalWord
{
    public int Index;
    public string kor;
    public string eng;
    public string chi;
}
 
 
cs

.



Posted by 시리시안
2016. 2. 28. 23:41



가장 먼저 상단에 

using UnityEngine.SceneManagement;

을 추가 해줍니다.



유니티는 더이상 Application.LoadLevel 을 사용하지 않습니다.


대신 밑의 코드를 참고하세요




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
 
/**
@class SceneExample.cpp
@Date 2016/02/28
@author 조원우(jjgaa2@naver.com)
@brief 씬 매니저 사용
*/
public class SceneExample: MonoBehaviour {
 
    public void NextScene()
    {
        SceneManager.LoadScene("SceneName");
    }
 
}
 
 
cs


Posted by 시리시안
2016. 2. 25. 16:49

c언어에서의 파일입출력은

1. 파일을 연다

2. 파일에 입출력 작업을 한다.

3. 파일을 닫는다.

로 요약됩니다.


입출력 할 때 파일포인터가 필요하기 때문에

FILE *f; 와 같은식으로 파일 포인터를 선언해준다.


1. 파일 열기

파일을 열기 위해서는 fopen() 함수를 사용하게 됩니다.

따로 경로가 없다면 현재 소스파일이있는 그 경로를 나타냅니다.

파일명은 확장자 까지 포함한 풀 네임이며, 모드가 있는데,

w : 쓰기 모드, 만약 파일이 존재 하지 않는다면 파일을 새로 만든다.

r : 읽기 모드, 만약 파일이 존재 하지 않는다면 NULL을 리턴한다.

a : 추가 모드. 파일이 존재 하지 않는다면 파일을 새로 만든다.

w+ : 읽기/쓰기

r+ : 읽기/쓰기

a+ : 읽기/추가

b : binary


2. 입출력 작업

입출력을 하기 위해서는 파일입출력 함수들이 이용됩니다.

문자 : fgetc(), fputc();

문자열 : fgets(), fputs();

fscanf(), fprintf(); 


간단한 입출력 예제

1
2
3
4
5
6
7
8
#include <stdio.h>
int main()
{
    FILE *f;
    f=fopen("a.txt","w");
    fprintf(f,"Hello World");
    fclose(f);
}
cs

 

이렇게 입력후 실행하면!?

도스창엔 아무것도 안뜨게 됩니다.

왜냐하면 파일에 작업을 하고있기 때문이죠


소스가 있는 a.txt파일이 보일 것입니다.

텍스트 파일을 열어보면 이와같이 Hello World라는 문구가 출력되어 있습니다.



3. 파일 닫기

위 소스들을 잘 살펴보면 항상 

fclose(f); 라는 함수가 소스의 끝부분에 쓰여 있습니다.

바로 이 함수가 파일을 닫겠다는 의미입니다

Posted by 시리시안
2016. 2. 25. 14:20

코루틴의 특성


1. 특정 작업을 단계적으로 발생하게 한다.

2. 시간이 흐름에 따라 발생하는 루틴을 작성할 수 있다.

3. 다른 연산이 완료될때까지 기다리는 루틴을 작성할 수 있다.

예를 들어, 컷 씬 시퀀스를 조직하거나 또는 단순히 적이 죽는 애니메이션을 기다린 다음, 재생성을 할 수도 있다.


만약 단지 몇 초 동안 특정 연산을 지연시키기를 원한다면, Invoke를 사용하는 것을 고려해보자..


우선, 확실하게 알고 넘어가자, 코루틴은 쓰레드가 아니다. 코루틴은 비동기가 아니다


헷갈릴수 있는데, 쓰레드는 프로그램에서 다른 쓰레드와 함께 비동기로 실행된다.

멀티프로세서 기계에서, 쓰레드는 실제 다른 쓰레드와 함께 동시에 코드가 실행될 수 있다.


그래서 코루틴이 무엇인가?


코루틴은 쓰레드가 아니다. ,  코루틴은 한번에 하나의 코루틴이 싱행되고, 게임의 메인쓰레드에 맞춰서 실행된다. 사실 함수를 호출하는것처럼 게임의 핵심 기능을 호출하는것과 같다,


따라서 코루틴은 쓰레드가 아니며 비동기도 아니기 때문에 사용할때 절대 동기화나 특정 값을 잠금하는것에 대한 걱정이 필요없다.

당신이 yield를 실행하여 완전히 통제 할 수 있기 때문이다.


따라서 코루틴이란, 부분적으로, 그리고 특정한 상황이 맞아 떨어졌을 때 실행되는 함수로써, 그 작업이 완료가 되기전까지, 미래의 어느시점에 재개 될 수 있는 함수이다.




위에 표를 보면 yield로 끈어준 코루틴들이 각각의 알맞는 상황에 호출된다.


밑에 간단한 코루틴을 보자


1
2
3
4
5
6
7
8
IEnumerator TestCoroutine()
{
      while(true)
      {
           Debug.Log(Time.time);
           yield return null;
      }
}
cs



이 코루틴은 영원히 작동하는 루프를 가지고 있다. 이 코루틴은 현재 시간으로 로그를 남기고, 그 다음 yield한다. 다시 재개될 때, 다시 루프를 돌아서 로그를 남기고, 한번 더 yield될 것이다.


루프안에 있는 코드는 정확하게 Update 함수와 같다. 단지 순서에따라 업데이트 다음에 실행될 뿐이다.


StartCoroutine(TestCoroutine())를 호출할 때, 코드는 첫번째 yield를 만날때까지 즉시 실행되며,

유니티 프로세스가 이 객체에 대해서 코루틴을 처리할 때, 다시 재개된다.


위에 있는 도표에 맞춰 코루틴안에서 호울하는 yield에 따라 다음 호출되는 지점이 달라진단느 것을 알 수 있다.


null - Update구문의 수행이 완료될 때까지 대기한다.


WaitForEndOfFrame - 현재 프레임의 렌더링 작업이 끝날 때까지 대기한다.


WaitForFixedUpdate - FixedUpdate구문의 수행이 완료될 때까지 대기한다.


WaitForSeconds - 지정한 초만큼 대기한다.


WWW - 웹에서 데이터의 전송이 완료될 때까지 대기한다.

(WaitForSeconds or null처럼 재시작한다.)


Another coroutine - 새로운 코루틴은 yielder가 재시작되기 전에 완료 될 것이다.



또한 yield break; 명령어를 실행할 수 있다. 이는 즉시 코루틴을 멈춘다.



요약


코루틴은 시간에 따라 혹은 외부의 처리가 완료되었을 때, 연산이 일어나는 순서를 정하는 정말 멋진 방법이다.


코루틴은 쓰레드가 아니다. 그리고 비동기가 아니다(동시에 일어나지 않는다.)


코루틴이 실행되고 있을 때, 다른 어떤 것들도 실행되지 않는다.


코루틴은 yield 문의 조건을 만족시켰을 때, 재개될 것이다.



Posted by 시리시안
2016. 2. 25. 13:10

기본적으로 많이 사용하는 형식의 데이터형만 기본 데이터로써 정의되고있고, 나머지는 프로그래머가 필요에따라 정의해서 사용할 수 있도록 만들수있습니다.


그래서 기본 데이터 형인 char, int, float, double등을 제공하고 나머지는 프로그래머가 배열, 포인터,구조체, 공용체, 혹은 typedef 같은 문법을 사용해 직접 정의 해서 사용합니다.


배열과 같은 무법으로 사용자 정의 데이터형을 만들게 되면 동일한 데이터 형만을 그룹지을 수 있습니다. 단순한 형태만 정의 가능하다는 단점이 있지만, 이를 보완하기 위해 만들어 진것이 구조체 입니다.


구조체는 서로 다른 데이터형을 하나의 데이터로 군집화 하여 사용 할 수 있도록 하는 사용자 정의 데이터 형입니다.


1. 구조체 정의하기

 

구조체를 정의 할 때에는 다음과 같이 사용합니다.


struct 구조체명 {

데이터형 변수명;

...

};

이렇게 선언된 구조체명이 새로 쓸수있는 데이터형의 이름입니다. 즉, int char처럼 사용가능합니다.


구조체는 struct 키워드를 앞에 명시한 다음에 사용할 구조체명을 적어서 정의합니다. 이 때 구조체

     내부를 구성하는 데이터는 미리 정의되어 있어야 하며, 각 데이터는 세미콜론(" ; ") 키워드로 

분리해야합니다. 

예를 들어 이름, 나이, 키, 몸무게와 같은 인적사항을 저장하는 People 이라는 구조체를 정의하면 다음과 같습니다.


1
2
3
4
5
6
7
 
    struct People {
        char name[20];
        int age;
        double height;
        double weight;
    };
cs

    위에서도 말했듯이 구조체 내부의 데이터는 미리 정의된 데이터형이여야하기 때문에 char, int, double

    등과 같은 기본 데이터형 외에 다른 구조체나 사용자가 따로 정의한 데이터형을 사용하고 싶으면

    이 구조체보다 앞서 정의되어 있어야합니다.

 

    일반적이지는 않지만 한번만 선언해서 사용하는 경우 아래와 같이 구조체명을 생략해서 사용하는 경우도 있습니다.

즉, 구조체를 정의함과 동시에 data 라는 변수를 선언하여 사용하기 때문에 이 데이터형을 다시 사용할 필요가 없다면 구조체명도 필요없기 때문에 생략 가능합니다.

 

 

1
2
3
4
5
6
    struct {
        char name[20];
        int age;
        double height;
        double weight;
    } data;
cs

 

 

2. 구조체 사용하기

 

    정의된 구조체는 구조체명을 이용하여 변수를 선언하듯이 선언해주면 되는데, C 언어에서는 구조체를

    이용하여 변수를 선언할 때에는 반드시 구조체명 앞에 "struct" 키워드를 붙여주어야합니다.

 

    // People 구조체를 사용하여 data 변수를 선언한다.

    struct People data;

 

    C++ 언어로 구조체를 선언할 때에는 struct 키워드를 생략하여 선언할 수 있지만 C 언어의 경우에는

    구조체를 선언할 때마다 struct 키워드를 명시해야 하기때문에 (굉장히 불편합니다.)

해결법으로는 아래와 같이 typedef 명령어를 이용하여 구조체를 또다른 데이터 타입으로 정의하여 사용하기도 합니다.

 

    typedef struct People PEOPLE;

 

    이렇게 선언하면 C 언어에서도  People 구조체를 사용하여 변수를 선언할때 struct 키워드를

    적지 않게되어 좀더 편리하게 사용할수 있습니다.

 

    PEOPLE data;  // struct People data;

 

    하지만, 구조체 정의 따로 typedef 정의 따로 사용하는 방식이 프로그램을 이해하기에 불편할수도

    있기 때문에 이것을 아래와 같이 한번에 사용하여 구조체를 정의하기도 합니다.

 

1
2
3
4
5
6
7
8
 
 // struct people { ... } 구조체를 PEOPLE 이라는 데이터형으로 정의한다.
    typedef struct People{
        char name[20];
        int age;
        double height;
        double weight;
    } PEOPLE;
cs

 

최근에는 C++ 를 사용하는 사람들이 많아짐에따라 struct 가 생략가능해지면서 typedef 을 사용하는 형식도 점차 줄어들고 있습니다.    (Class가 있으니..)

   

구조체로 선언한 데이터형도 기본데이터형(char, int, ...)과 동일한 데이터 형이기 때문에 변수 선언 배열, 포인터 문법을 아래와 같이 그대로 사용할수 있습니다.

 

PEOPLE data;      // 일반 변수

PEOPLE list[20];  // 배열

PEOPLE *p;         // 포인터

 

이렇게 선언된 구조체 변수는 아래의 코드처럼 구조체의 요소에 접근할 때에는 " . " 를 이용하여 구조체의 "변수명.요소명" 과 같은 형식을 사용합니다.

     

1
2
3
4
5
6
PEOPLE one;
 
    strcpy(one.name, "운영진");
    one.age = 23;
    one.height = 179.9;
    one.weight = 70;
cs

 

3. 구조체의 크기와 메모리 배열 ( struct member alignment )

 

구조체의 크기는 일반적으로 구조체를 구성하는 데이터형의 크기를 합산한 값입니다.


    Windows 32비트 운영체제는 레지스터의 크기, 데이터 버스의 크기, 데이터 처리 단위, 포인터의 크기

    등이 모두 4 바이트로 되어 있어서 해당 크기로 연산하고, 처리하는 것이 속도가 더 빠릅니다. 그래서 

    컴파일 옵션에 따라서 구조체를 해석할때 그 배열을 짝수 또는 4의 배수로 재구성하는 작업

    수행하기 때문에 실제로 구조체가 구성되는 것이 조금 다를 수 있습니다.

 

1
2
3
4
5
6
7
typedef struct Test {
        char a;       // 1 바이트의 데이터 크기를 가짐
        int b;          // 4 바이트의 데이터 크기를 가짐
        short int c;  // 2 바이트의 데이터 크기를 가짐
        int d;          // 4 바이트의 데이터 크기를 가짐
        char e;       // 1 바이트의 데이터 크기를 가짐
    } TEST;
cs

 

위와 같이 정의된 TEST 구조체를 선언하면 12 바이트의 메모리가 할당된다고 생각할 수도 있지만

구조체를 구성하고 저장하는 단위가 4 바이트이기 때문에 b 나 d 같은 4 바이트 이상의 크기를 가지는

변수가 4의 배수 주소 값에 위치하도록 아래와 같은 형태로 메모리가 사용되어 20 바이트의 메모리가 할당됩니다.

 

그렇기때문에 쓸데없는 메모리의 낭비를 막기 위해서는 아래와 같이 데이터를 구성하는 순서를변경하여 구조체를 정의하는 것이 좋습니다.

 

   

1
2
3
4
5
6
7
typedef struct Test {
        int b;          // 4 바이트의 데이터 크기를 가짐
        int d;          // 4 바이트의 데이터 크기를 가짐
        short int c;  // 2 바이트의 데이터 크기를 가짐
        char a;       // 1 바이트의 데이터 크기를 가짐
        char e;       // 1 바이트의 데이터 크기를 가짐
    } TEST;
cs

 

   

 

이처럼 구조체를 정의할 때 어떻게 배치하는가에 따라 구조체의 크기가 변경될 수 있기때문에 메모리를 낭비하지 않도록 주의해야합니다,

프로그래밍을 하다가 구조체의 크기를 명시해야하는 경우에는 수치 값이 아닌 sizeof 매크로를 사용하여 구조체의 크기를 반환받아 사용해야합니다. 

Posted by 시리시안
2016. 2. 25. 11:49

함수 

Component GetComponent<type Stirng>

설명

만약 게임 오브젝트에 type에 맞는 컴포넌트가 있다면 그 컴포넌트를 찾아서 돌려주고,, 없으면 null 를 돌려준다


 

1
2
3
4
5
6
7
8
9
10
using UnityEngine;
using System.Collections;
 
public class mGetcomponentExample: MonoBehaviour {
    void Start() {
        Transform mTransform;
        mTransform = gameObject.GetComponent<Transform>();
        mTransform = gameObject.transform;
    }
}
cs


Posted by 시리시안
2016. 2. 25. 11:38

함수 

Component GetComponentInChildren<type>() 

설명

게임오브젝트에서 type 타입의 컴포넌트나 depth-frist 찾기를 해서 얻은 그것의 자녀들 중 가장 빠른 자식을 돌려준다.


오직 활성 컴포넌트만 검사한다. 


1
2
3
4
5
6
7
8
9
10
using UnityEngine;
using System.Collections;
 
public class example : MonoBehaviour {
    public ScriptName mScript;
    void Start() {
        mScript = gameObject.GetComponentInChildren<ScriptName>();
        mScript.DoSomething();
    }
}
cs


Posted by 시리시안
2016. 2. 23. 20:35


try, throw, catch 를 이용한 예외 처리 방법



예외 ( Exception ) 란? : 프로그램의 정상적인 실행을 방해는 조건이나 상태를 말합니다. ( 에러가 아닙니다.)


1
2
3
4
5
6
7
8
9
10
11
#include<iostream>
 
 
void main()
{
    int a = 0;    
    int b =20;
    
    int c = b/a;
 
}
cs

위 상황을 봅시다. a의 값이 0이 할당된 상태에서 b를 a로 나누려고 합니다. 아직까진 오류가 아니지만, ( 물론 컴파일러에 따라서 오류로 판단할수 있습니다.) 

하지만, 오류가 아니라 판단되면, 다음식을 쓰레기값을 뱉을수 밖에없습니다. 그럴때 try catch문을 사용합니다.

try
1. 예외가 발생할만한 코드 블록을 지정합니다.
2. try{} 괄호 안에 예외 처리 대상 코드를 작성합니다. 
3. 이블록안에서 예외가 발생했을 때 throw 명령으로 예외를 던집니다.

throw
1. 프로그램이 정상적으로 실행될 수 없는 상활일 때 이 명령으로 예외를 던집니다.
2. thorw다음에 던지고자하는 예외객체를 넘김. 예외 던지면 catch문으로 이동(단: 예외 객체 타입이 맞을때만 적용됨 ), (오버로딩 가능)

catch
1. if-else문처럼 try-catch문으로 한쌍으로 쓰입니다.
2. try안에서 throw한 예외 객체에 대한 예외처리를 합니다
3. catch블록을 예외 핸들러라고 부릅니다..

사용법
try{
    if(예외조건)
       throw 예외객체;
} catch ( 타입 예외객체 ){
      예외처리;
}

사용 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
 
 
void main()
{
    int a = 0;    
    int b =20;
    
    try{
    if(a == 0)
        throw a;
    int c = b/a;
    }
    catch(int ex){
        std::cout<<"예외 처리 발생, a가 0입니다."<<std::endl;
    }
}
cs

그냥 if문으로 바로 처리하면 되는데, 왜 굳이 catch까지 쓰나요?

라고 물어볼수 있는데, 이는 Stack Unwinding(스택 풀기) 를 이해하면 쉽다.

다음 예제를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
 
 
int AddValue_abs (int a, int b)
{
    if(a<0)
        throw a;
    if(b<0)
        throw b;
 
 
    return a+b;
}
void main()
{
    int a,b;
    
    std::cin>>a>>b;
    
    try{
        //바로 보이는 이곳엔 throw가 없다.
        std::cout<<AddValue_abs(a,b)<<std::endl;
    }
    catch(int ex){
        //예외처리가 생기면 실행
        std::cout<<"예외 처리 발생"<<std::endl;
    }
}
cs


AddValue_abs라는 함수에서 try도 없는데, 그렇다고 catch도 없는데 뜬금없이 조건 검사후 throw를 던집니다.
여기서 Stack Winding(스택풀기)를 볼수있는데, throw가 던져진 시점에서 바로 뒤에 코드는 읽지 않습니다.
그리고 뒤로 스택을 풀어 나가며, throw로 던져진 변수 타입과 같은 인자를 지닌, catch를 찾습니다.

만약 예외 처리를 if문으로 검사하게되면, 여러 조건에 따라 함수 자체의 반환값에 예외를 하거나, 예외후 처음부터 다시해야하는 번거로움이 있는데, 이걸 사용할 경우 간편하게 할수가 있습니다.

또한 Throw로 클래스 자체를 넘겨버리면, Catch에서 calss를 인자로 받아올수 있다는점..!








 




'프로그래밍 > Language' 카테고리의 다른 글

파일 입출력에 대하여  (0) 2016.02.25
구조체에 대하여  (0) 2016.02.25
포인터에 대하여  (0) 2016.02.23
C언어 연산자에 대하여 - 비트연산  (0) 2016.02.23
C언어 연산자에 대하여  (0) 2016.02.23
Posted by 시리시안