Class vs Struct/Enum

소스코드


열거형과 구조체는 값 타입이며, 클래스는 참조 타입이라는 것이 가장 큰 차이입니다. 또한, 클래스는 상속이 가능하지만 구조체와 열거형은 상속이 불가능합니다.

struct ValueType {
    var property = 1
}

class ReferenceType {
    var property = 1
}

// 첫 번째 구조체 인스턴스
let firstStructInstance = ValueType()
// 두 번째 구조체 인스턴스에 첫 번째 인스턴스 값 복사
var secondStructInstance = firstStructInstance
// 두 번째 구조체 인스턴스 프로퍼티 값 수정
secondStructInstance.property = 2

// 두 번째 구조체 인스턴스는 첫 번째 구조체를 똑같이 복사한 
// 별도의 인스턴스이기 때문에 
// 두 번째 구조체 인스턴스의 프로퍼티 값을 변경해도
// 첫 번째 구조체 인스턴스의 프로퍼티 값에는 영향이 없음
print("first struct instance property : \(firstStructInstance.property)")    // 1
print("second struct instance property : \(secondStructInstance.property)")  // 2


// 클래스 인스턴스 생성 후 첫 번째 참조 생성
let firstClassReference = ReferenceType()
// 두 번째 참조 변수에 첫 번째 참조 할당
let secondClassReference = firstClassReference
secondClassReference.property = 2

// 두 번째 클래스 참조는 첫 번째 클래스 인스턴스를 참조하기 때문에
// 두 번째 참조를 통해 인스턴스의 프로퍼티 값을 변경하면
// 첫 번째 클래스 인스턴스의 프로퍼티 값을 변경하게 됨
print("first class reference property : \(firstClassReference.property)")    // 2
print("second class reference property : \(secondClassReference.property)")  // 2


관련문서

The Swift Programming Language - Enumerations

The Swift Programming Language - Classes and Structures





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 


저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

프로퍼티 - Property  (2) 2017.06.26
클로저 - Closure  (0) 2017.06.22
클래스, 구조체, 열거형 비교  (0) 2017.06.19
열거형 - Enumerations  (0) 2017.06.15
클래스  (0) 2017.06.12
구조체  (2) 2017.06.08
Posted by yagom

열거형


소스코드



정의 문법

스위프트의 열거형은 다른 언어의 열거형과는 많이 다릅니다. 잘 살펴보아야 할 스위프트의 기능 중 하나입니다.

  • enum은 타입이므로 대문자 카멜케이스를 사용하여 이름을 정의합니다
  • 각 case는 소문자 카멜케이스로 정의합니다
  • 각 case는 그 자체가 고유의 값입니다
  • 각 케이스는 한 줄에 개별로도, 한 줄에 여러개도 정의할 수 있습니다

enum 이름 {
	case 이름1
	case 이름2
	case 이름3, 이름4, 이름5
	// ...
}


열거형 사용

enum Weekday {
    case mon
    case tue
    case wed
    case thu, fri, sat, sun
}

// 열거형 타입과 케이스를 모두 사용하여도 됩니다
var day: Weekday = Weekday.mon

// 타입이 명확하다면 .케이스 처럼 표현해도 무방합니다
day = .tue

print(day) // tue

// switch의 비교값에 열거형 타입이 위치할 때
// 모든 열거형 케이스를 포함한다면
// default를 작성할 필요가 없습니다
switch day {
case .mon, .tue, .wed, .thu:
    print("평일입니다")
case Weekday.fri:
    print("불금 파티!!")
case .sat, .sun:
    print("신나는 주말!!")
}


원시값(Raw value)

C 언어의 enum처럼 정수값을 가질 수도 있습니다. rawValue를 사용하면 됩니다. 

case별로 각각 다른 값을 가져야합니다.

enum Fruit: Int {
    case apple = 0
    case grape = 1
    case peach
    
    // mango와 apple의 원시값이 같으므로 
    // mango 케이스의 원시값을 0으로 정의할 수 없습니다
//    case mango = 0
}

print("Fruit.peach.rawValue == \(Fruit.peach.rawValue)")
// Fruit.peach.rawValue == 2


정수 타입 뿐만 아니라 Hashable 프로토콜을 따르는 모든 타입이 원시값의 타입으로 지정될 수 있습니다.

enum School: String {
    case elementary = "초등"
    case middle = "중등"
    case high = "고등"
    case university
}

print("School.middle.rawValue == \(School.middle.rawValue)")
// School.middle.rawValue == 중등

// 열거형의 원시값 타입이 String일 때, 원시값이 지정되지 않았다면
// case의 이름을 원시값으로 사용합니다
print("School.university.rawValue == \(School.university.rawValue)")
// School.middle.rawValue == university


원시값을 통한 초기화

rawValue를 통해 초기화 할 수 있습니다. rawValuecase에 해당하지 않을 수 있으므로 rawValue를 통해 초기화 한 인스턴스는 옵셔널 타입입니다.

// rawValue를 통해 초기화 한 열거형 값은 옵셔널 타입이므로 Fruit 타입이 아닙니다
//let apple: Fruit = Fruit(rawValue: 0)
let apple: Fruit? = Fruit(rawValue: 0)

// if let 구문을 사용하면 rawValue에 해당하는 케이스를 곧바로 사용할 수 있습니다
if let orange: Fruit = Fruit(rawValue: 5) {
    print("rawValue 5에 해당하는 케이스는 \(orange)입니다")
} else {
    print("rawValue 5에 해당하는 케이스가 없습니다")
} // rawValue 5에 해당하는 케이스가 없습니다


메서드

스위프트의 열거형에는 메서드도 추가할 수 있습니다.

enum Month {
    case dec, jan, feb
    case mar, apr, may
    case jun, jul, aug
    case sep, oct, nov
    
    func printMessage() {
        switch self {
        case .mar, .apr, .may:
            print("따스한 봄~")
        case .jun, .jul, .aug:
            print("여름 더워요~")
        case .sep, .oct, .nov:
            print("가을은 독서의 계절!")
        case .dec, .jan, .feb:
            print("추운 겨울입니다")
        }
    }
}

Month.mar.printMessage()


관련문서

The Swift Programming Language - Enumerations





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓ 블로거에게 공감은 큰 힘이 됩니다 ↓↓↓ 

저작자 표시 비영리 변경 금지
신고

'Swift > 기본문법' 카테고리의 다른 글

클로저 - Closure  (0) 2017.06.22
클래스, 구조체, 열거형 비교  (0) 2017.06.19
열거형 - Enumerations  (0) 2017.06.15
클래스  (0) 2017.06.12
구조체  (2) 2017.06.08
옵셔널  (0) 2017.06.05
Posted by yagom


오늘의 주제

Objective-C의 상수와 스위프트의 상수


안녕하세요 야곰입니다.

Objective-C를 쓰다가 스위프트로 넘어왔을 때 고민되었던 부분 중의 하나인 스위프트의 상수에 관해 이야기해 보려 합니다.


혼자 프로젝트를 진행하다 보면 상수의 필요성을 많이 느낄 수 없을지 모르지만, 누군가 협업을 하게 된다면, 혹은 미래 또는 과거의 나와 협업(?)을 하게 된다면 상수의 필요성을 많이 느끼게 됩니다. 바꾸면 안 되는 데이터를 실수로 바꿔서 난감했던 경험이 없나요? 혹시 그런 적이 있다면 상수의 필요성에 대해서는 많이 공감하실 것으로 생각됩니다.


* 오해가 생길 소지의 표현들이 있어서 처음 발행 이후 조금 수정하였습니다. 좋은 의견 주신 과니님 고맙습니다 :)


사라진 const


사실 저는 Objective-C에서 특별한 경우가 아니면 const를 많이 사용하지 않았습니다(반성).


그런데 스위프트에서는 전역이든 지역이든 데이터를 저장할 공간(변수 또는 상수)에는 var 또는 let을 사용하여 변수인지 상수인지 명확히 명시해 주어야 하므로 상수에 대한 고민을 많이 하게 되었습니다.


사실 지역상수가 필요한 경우에 const 키워드를 쓰는 귀찮음 때문에 상수를 많이 사용하지 않았는데 스위프트에서는 var 또는 let을 선택해야 하는 시간이 조금 걸렸지만, 지금은 큰 시간 들일 필요 없이 자연스럽게 상수를 많이 사용하고 있습니다. 또, 혹시라도 상수로 사용해야 하는 경우임에도 변수로 선언하고 사용한다면 Xcode에서 변수 대신 상수를 사용하는 게 어떻냐는 경고를 보여줍니다. 




[Xcode의 경고]


지역상수


지역상수를 사용하는 경우에는 사실 Objective-C와 크게 다를 바 없이 사용할 수 있습니다. 상수의 이름을 지어주는 명명법도 크게 다를 바 없습니다. 

상수로 사용할 변수 앞에 const를 붙여 쓴 것처럼 let을 사용하여 상수를 선언하여 사용하면 됩니다.



// Objective-C
const NSInteger someConstant = 100;


// Swift
let someConstant: Int = 100



전역상수


전역상수를 사용할 때 조금 더 생각해보아야 할 것들이 있습니다. 저는 처음 스위프트를 사용할 때 별생각 없이 Objective-C에서 사용하던 것과 같은 명명법으로 전역상수를 사용했습니다.


// Objective-C NSInteger const  YGSomeGlobalConstant = 100;


// Swift
let YGSomeGlobalConstant: Int = 100


그런데 Objective-C에서 'YG'와 같이 접두어(prefix)를 붙이는 것은 Objective-C에는 네임스페이스(name space)가 없기 때문인데, 스위프트에는 이 단점을 극복했다는 것에 대한 생각이 문득 스쳤습니다.


Objective-C에는 네임스페이스가 없어서 전역변수를 선언하고 사용할 때 꽤 골치가 아팠습니다. 귀찮기도 아주 귀찮았죠. 이름도 매우 길어지기만 했습니다. 열거형(enum)은 정수밖에 지원하지 않기 때문에 다른 타입의 값들은 관련된 상수끼리 묶어 쓰기도 어렵기도 했지요.


// Objective-C의 상수들... // 네임스페이스가 없기 때문에 // 연관된 상수들을 접두어를 사용하여 표현합니다 // 요일 상수들 NSString *const YGWeekMonday = @"MON"; NSString *const YGWeekTuesday = @"TUE"; NSString *const YGWeekWednesday = @"WED"; NSString *const YGWeekThursday = @"THU"; NSString *const YGWeekFriday = @"FRI"; NSString *const YGWeekSaturday = @"SAT"; NSString *const YGWeekSunday = @"SUN"; // 네트워킹 관련 상수들 NSTimeInterval const YGNetworkingTimeoutInterval = 10.0f; NSUInteger const YGNetworkingMaxRetryCount = 3; NSString *const YGNetworkingBaseURLString = @"https://abc.com";


정말 보기만 해도 정신이 없습니다. 또, 실수로 복사 붙여넣기를 하다가 중복된 값을 넣었다면 컴파일 오류가 발생하지 않기 때문에 실수를 찾아내기도 매우 어려워집니다.


스위프트에서는 이런 전역 상수들을 조금 더 멋진 방법으로 표현해 볼 수 있습니다. 타입 내부에 다른 타입을 정의하는 방법으로 네임스페이스를 사용할 수 있습니다. 더군다나 네임스페이스 덕분에 접두어는 더 이상 스위프트에서 사용하지 않습니다.


// Week라는 구조체 타입 내부에
// 여러 타입 상수를 선언
struct Week {
    static let mon: String = "MON"
    static let tue: String = "TUE"
    static let wed: String = "WED"
    static let thu: String = "THU"
    static let fri: String = "FRI"
    static let sat: String = "SAT"
    static let sun: String = "SUN"
}

// 실제 사용시 Week.mon // "MON" Week.sat // "SAT"


처음에 이렇게 선언해 보았습니다. 그런데 만약 복사 붙여넣기를 하다가 실수로 중복된 값을 넣는다면...? 가령 "SUN"을 넣어야 하는데 "SAT"를 넣어버렸다면? 이때는 중복 값이 들어있는지 확인할 수 없습니다. 물론 의도적으로 다른 이름의 상수에 같은 값을 넣을 수도 있지만 그렇지 않은 경우에는 낭패입니다.


그래서 이렇게 개선해 봅니다.


// 열거형의 연관 값(associated value)을 사용하여
// 상수처럼 사용
enum Week: String {
    case mon = "MON"
    case tue = "TUE"
    case wed = "WED"
    case thu = "THU"
    case fri = "FRI"
    case sat = "SAT"
    case sun = "SUN"
}

// 실제 사용시 Week.mon.rawValue // "MON" Week.sat.rawValue // "SAT"



이렇게 사용하면 열거형 내부의 연관 값이 중복되는 경우에 컴파일오류가 발생하게 됩니다. 그래서 미리 실수를 발견하기도 좋습니다.


또, 위의 Objective-C로 선언했던 네트워킹 관련 상수를 스위프트에서 선언한다면 이렇게 바꿔볼 수 있을 것 같습니다.


// Objective-C NSTimeInterval const YGNetworkingTimeoutInterval = 10.0f; NSUInteger const YGNetworkingMaxRetryCount = 3; NSString *const YGNetworkingBaseURLString = @"https://abc.com";
// 사용 YGNetworkingTimeoutInterval // 10.0


// Swift
struct Networking {
    static let timeoutInterval: TimeInterval = 10.0
    static let maxRetryCount: Int = 3
    static let baseURL: URL? = URL(string: "https://abc.com")
}

// 사용

Networking.timeoutInterval // 10.0


이처럼 꼭 열거형의 연관 값을 사용하지 않고 용도에 맞게 구조체의 타입 상수(static let)로 사용해도 좋습니다. 


상수뿐만 아니라 전역변수, 전역함수(메서드) 등에도 충분히 응용할 수 있습니다.


또한 구조체 내부에 다른 타입(구조체, 클래스, 열거형) 등등 몇 단계를 걸쳐 내부 타입을 정의할 수 있기 때문 연관된 값을 타입의 타입의 타입까지 여러 번에 걸쳐 정의도 가능합니다.



struct CalendarItem {
    typealias Year = Int
    typealias Day = Int
    
    enum Week: String {
        case mon = "MON", tue = "TUE" //...
    }
    
    enum Month: Int {
        case jan = 1, feb, mar //...
    }
    
    static let startYear: Int = 1970
    static let startMonth: CalendarItem.Month = .jan
    
    struct Date {
        var day: Day = 1
        var weekDay: CalendarItem.Week = .mon
        var month: CalendarItem.Month = .jan
        var year: Year = CalendarItem.startYear
    }
}

var userBirthday: CalendarItem.Date userBirthday = CalendarItem.Date.init(day: 10, weekDay: .tue, month: .mar, year: 2017)



마치며


같은 Cocoa 플랫폼 위에서 코드를 작성하는데도 불구하고 역시나 언어의 특성을 살려 새로이 구조를 설계하기는 쉽지 않습니다 하핳


무언가 두서없이 써내려간 느낌입니다만, 잘 이해가 가지 않거나 궁금한 점이 있다면 댓글 남겨주세요 :D





by yagom

facebook : http://www.facebook.com/yagomSoft

facebook group : https://www.facebook.com/groups/yagom/


p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


저작자 표시 비영리 변경 금지
신고
Posted by yagom

오늘의 주제

1. 계산기 기능 넣기
2. 메모장 화면 구성 바꾸기



쉰 한 번째 시간입니다.^^

지난 번에 만들어 놓은 계산기 아직 잘 갖고 계신가요?ㅎㅎㅎ
이제 계산기 로직을 완성해 볼 차례입니다.

아............. 지금 제가 글을 쓰고 있는 이 시간은 아직 훈련소에 가기 전이지만, 전 지금 훈련소에서 뒹굴고 있겠군요 ㅋㅋㅋㅋㅋㅋㅋㅋ

뭐, 응원의 한마디...는 볼 수 없겠지만 무탈히 돌아오도록 기도해주세요 ㅋㅋㅋㅋㅋ

2일 전인데 한달이라도 막상 가려니까 싱숭생숭 하네요 ㅋㅋㅋ

아마 들어가기 전까지도 계속 블로그 포스팅 예약을 하다 갈거 같은..ㅋㅋㅋㅋㅋㅋㅋㅋ

뭐 여튼 사설은 각설하고 시작해 봅니다~~~~~~~~~~~~~


# 계산기 기능 완성하기

일단, 지난번에 구현파일에 만들어 주었던 enum을 헤더로 옮겨옵니다. 거기에 FUNC_INVALID도 추가해줬어요 ㅎ

그리고 아래 interface에 enum 변수 하나를 만들어 주었구요~

enum이 뭔지 잘 모르겠다 하시는 분들은
2012/05/24 - [C] - C <20>. enum 

을 참고해 주세요 ㅎㅎㅎ


자, 이제 다시 구현파일로 넘어와서~

일단, 변수 초기화를 따로 메소드로 빼주었습니다. 왜냐면 2번 이상은 사용할 것 같거든요 ㅎㅎㅎ C버튼 눌렀을 때랑, 처음 viewDidLoad되었을 때. 생각난김에 메소드로 빼주고 viewDidLoad에서 호출도 해 줍니다.


자, 그리고 화면에 숫자를 출력해 줄만한 메소드도 하나 따로 빼줍니다 ㅎㅎㅎ


자, 그리고 이제 계산을 해 줄 메소드를 하나 만들어 줍니다. 아마도 = 버튼을 눌렀을 때 요녀석이 실행이 되겠죠?ㅎㅎㅎ
(현재 로직은 약간 틀린 부분이 있습니다만, 아래쪽에서 조금 수정을 해 줄거예요. 일단 요렇게 작성해 주세요..ㅎㅎㅎ)


자, 그리고 숫자 버튼을 눌렀을 때 동작할 메소드를 채워넣어 줍니다.


자, 그리고 기능키를 눌렀을 때 어떻게 동작할지를 버튼과 연결된 메소드에 채워넣어 줍니다 ㅎㅎ
switch문이 아직도 헷갈리는 분들은
2011/12/14 - [C] - C <7>. 조건문(2) switch 
참고 해 주시면 좋을 것 같네요 ㅎㅎ 


자, 그리고 나서 실행 해 봅니다. command + R
어때요 ㅎㅎㅎ 잘 동작하나요?
이것저것 해보다 보면 뭔가 약간 안맞는게 있습니다...ㅎㅎㅎ
네......그렇죠 ㅎㅎㅎ
2 + 3 하고 = 을 누르면 5가 나옵니다.
그리고 또다시 = 을 누르면 8이 나와야 하는데 7이 나올거예요... 흐음... 로직에 문제가 있다!!!!!!!!!!!! (제가 새벽에 정신이 혼미한 상태로 하다보니...)ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

그래서 수정해 줬습니다.
헤더파일에 와서 새로운 flag 변수를 하나 만들어 주었구요~


구현파일에 와서 약간의 조건을 추가해 줍니다. 기존에 변수에 저장하던 값들도 살짝 바꿔줬구요.


그리고 계산부분의 변수들도 살짝 바꿔줬습니다 ㅎㅎ



자, 그리고 다시 실행!!!!!!

어떠세요? 잘 동작하나요?

제가 계산기를 잘 안써봐서 로직을 생각해 보려고 한참 쑈를 했었더랬죠... 계산기 한 번만 켜서 해보면 되는것을...ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

여튼 뭐 이렇게 초간단 계산기가 완성되었습니다~!

가로 모드로 바꾸면 공학용 계산기가 나오게도 해보고 싶었으나... 시간이 없는 관계로(낼모레 입소... 'ㅁ') 메모장으로 넘어가 볼게요 ㅋㅋㅋ



# 메모장 화면구성 변경

지난번에 메모장 화면도 조금 만들어 놨었는데요, 살짝만 바꾸도록 합니다 ㅎㅎ


다들 그림만 보고 이해는 하셨으리라 믿습니다 ㅎㅎㅎ

자, 이제 본격적으로 메모장 구현은?

다음 포스팅에......ㅋㅋㅋ



by yagom

facebook : http://fb.yagom.net

twitter : http://twitter.yagom.net ( @yagomsoft )

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 손가락 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 






저작자 표시 비영리 변경 금지
신고
Posted by yagom

오늘의 주제

1. 테이블 뷰에 파싱결과 뿌리기


서른 일곱 번째 시간입니다.^^

지난 번에는 웹에 자료를 요청하고 JSON으로 결과를 받아 파싱하는 과정까지 해 보았습니다.
잘 실행 되셨나요?
계속해서 코드의 양이 늘어나고 어려워 지고 있습니다 +_+
코드의 양도 많고 해야 할 것도, 처리해 줘야 할 것들도 많기 때문에 코드에 일일히 설명을 자세히 달기가 더 어려워지고 있습니다 ㅠ_ㅠ

여러분께서 부족한 부분은 질문을 주셔서 채워주셔야 합니다~!

그럼 오늘 또 차근차근 스텝을 밟아 나가 볼까요?ㅎ

렛츠고~~~~~~~~~


# 테이블뷰에 결과 띄워주기

자, 파싱된 결과를 활용해 주어야 하기 때문에 적절히 딕셔너리와 배열 포인터를 헤더에 선언해 줍니다.


변수를 만들어 줬으면 초기화와 마무리는 꼭 해주어야 하는거 잊지 않으셨죠?ㅎ


그리고 조금 더 편하게 읽을 수 있도록 enum 하나를 만들어 주었습니다.
enum에 대해 잘 모르시겠다구요?
2012/05/24 - [C] - C <20>. enum 요녀석을 참고해 주세요 ㅎ


그리고 이제 본격적으로 코딩에 들어갑니다~
지난 번에 요청을 해서 결과를 딕셔너리로 받아왔죠?
그녀석을 이제 적절히 포인터 변수에 넣어주고, 우리가 정말로 필요로 하는 item 녀석들을 따로 보관해 주기 위해서 Mutable Array를 만들어 줍니다.
우리가 웹에 요청하였을 때 반환되어 오는 데이터들에 대해 궁금하시다면 http://dna.daum.net/apis/search/book 에서 자세히 확인해 보세요 ㅎ


그리고 재검색을 할 때에는 지난 자료들은 필요가 없어졌으니 다시 초기화 해줄 필요가 있어서 초기화 메소드를 따로 만들어 주었습니다.
그래서 다시 검색을 하고자 할 때 초기화 메소드를 먼저 호출해 주고 시작하게 했습니다.


또한 우리는 한꺼번에 모든 검색결과를 보여줄 수 없으니 일부분만 검색 결과를 받아오게 됩니다. 그런데 남은 검색결과가 더 있다면 테이블의 맨 아래 셀을 눌렀을 때 데이터를 더 불러오도록 하려고 매번 검색 후에 이것이 검색이 끝났는지 체크를 합니다. 그 메소드를 구현해 주었구요.
본격적으로 테이블 데이터소스 코드를 넣어줍니다.
간략한 설명이 코드와 함께 주석으로 있으므로 참고하시구요...
데이터 소스 메소드들의 리턴값(반환값)들로 테이블이 움직인다고 해도 과언이 아닙니다. 동작을 잘 파악해 보도록 하세요.
참고로 return ... 이 호출되게 되면 그 메소드는 반환값을 전달한 후 더이상 진행되지 않고 끝나버립니다.
이해가 되지 않는 부분이 있다면 5번 더 코드를 해석해 보시고 더 생각해 보세요. 그리고 정 모르겠으면 그 때 댓글 주세요 ㅎ 스스로 연구해 봐야 실력이 팍팍 늘어요 ㅎ



이제 거의 다 왔습니다 ㅎ
데이터소스의 마지막 메소드를 이렇게 채워줍니다.
바로 각각의 셀(테이블의 칸칸)을 만들어 주는 메소드입니다.
지난 번에 복사해온 코드에서 약간 변경이 되었으니 처음부터 하나하나 잘 코딩해 보세요.
여기서도 마찬가지로 retrun 이라는 키워드가 나오면 반환값을 주고 메소드는 종료되어버립니다.
왜 중간에 뜬금없이 마지막 셀을 체크하는 조건문이 나왔는지 잘 생각해 보세요.


자, 이렇게 필수 코딩은 마쳤구요, 마지막으로 아까 위에서 만들어준 초기화 메소드로 처음 초기화와 마무리를 세줄에서 한 줄로 다시 간략화 해줬습니다. ㅎ 이것이 메소드의 힘이죠? >_<ㅋ


실행하고 검색해 보았습니다.
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
아 근데 왜 이따위로 나오죠?ㅋㅋㅋ
저도 잘 모르겠습니다 +_+
일단 대충 뭔가 맞는거 같긴 한데 왜 이렇게 나오는지는 저도 몰라서 급 패닉상태에 빠졌습니다.
이번 포스팅은 제가 다 해보고 포스팅 하는게 아니라 저도 해보면서 포스팅 하는거라 이런 결과가 나왔네요 =_=ㅋㅋㅋ
다음 오픈 API도 처음 써보는거라..ㅋㅋㅋ
여하튼 뭐 이런식으로 나왔습니다!!ㅋ


다음번에는 책의 대표이미지를 웹에서 불러와서 셀에 넣어주는 과정을 해 볼게요 ㅎ

다음 포스팅도 기다려 주실거죠? +_+ㅋ

아... XML은 언제하지..ㅋㅋㅋㅋㅋㅋ 곰방할게용~


by yagom

twitter : @yagomsoft

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 추천 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 




저작자 표시 비영리 변경 금지
신고
Posted by yagom

C <20>. enum

C 2012.05.24 12:30

오늘의 주제

1. enum


벌써 스무 번째 시간입니다.^^

지난 번에 연결리스트에 대해 알아보았는데요 ㅎ 어려우셨죠?
요번에는 잠시 쉬어갈 겸 간단한 녀석 하나 들고 왔습니다~
이런 녀석도 있구나~
알고 가시면 될 듯 합니다.

자 그럼 상쾌한 기분으로 출발 해 볼까요?
고고씽~~~~~~~~~~~~




# enum

지난 번에 전처리자를 이야기 하면서 enum에 대하여 스치듯이 이야기 해 드린 것 같은데요 그때 소개해 드리지 못해 이번에 소개해 드리려 합니다.

enum은 상수 세트를 선언 해 줄 수 있습니다.

주로 어떤 상수 Flag를 지정해 줄 때 사용하게 되는데요, 그게 무슨 뜻이냐 하면 

내가 프로그램 안에서의 약속을 

상태1 == 0
상태2 == 1
상태3 == 2

으로 표현 간단히 해 주고 싶을 때 사용하게 됩니다.

뭐, 일단 알아두시고 나중에 프로그램을 짤 때 아! 이거 써먹으면 편하겠다! 라는 생각이 들 때가 올거예요 ㅎ 

언제 한 번 사용 해볼 때가 있으면 저도 다시 소개 해 드릴게요 ㅎ

오늘은 간단한 코드만 하나 내려놓고 갑니다~^^*


실행 해 보세요~

아까 말씀드렸다시피 enum으로는 상수형 정수만 표현이 가능합니다.

enum안에서 다음번의 순서에 있는 녀석에 특별히 숫자를 대입해 주지 않는다면, 이전 숫자에 +1 이 되어 들어갑니다.

직접 실행해서 확인해 보시는 방법이 가장 빠르겠네용 ㅎ

그럼 저는 이만~!

다음엔 뭘 가지고 나타나 볼까요 ㅎㅎ


by yagom

twitter : @yagomsoft

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 추천 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 



저작자 표시 비영리 변경 금지
신고

'C' 카테고리의 다른 글

C <20>. enum  (4) 2012.05.24
C <18>. 연결리스트 (Linked list) - 자료구조(1)  (0) 2012.05.21
C <17>. 동적할당  (2) 2012.05.18
C <16>. 구조체  (2) 2012.05.16
C <15>. 전처리자  (0) 2012.05.14
C <14>. 배열  (4) 2012.05.11
Posted by yagom

C <15>. 전처리자

C 2012.05.14 12:30

오늘의 주제

1. #define 
2. #ifdef 



열 다섯번째 시간입니다.^^

지난 번에는 배열에 대해 알아보았는데, 흥미로우셨나요?
배열은 두고두고 계속 사용하게 되니까 잘 알아두셔야 합니다~
게다가 배열과 포인터는 뗄 수 없는 관계이므로 꼭 기억해 두세요 ㅎ

이번엔 전처리자에 대해 알아봅니다.
스따뚜~~~~~~~~~~~~

그 전에 추천 한 방 어떠세요?ㅎ


# 전처리자

전처리자는 전처리 명령을 수행하는 녀석입니다.

전처리 명령은 '#'으로 시작하게 됩니다. 

우리가 흔히 볼 수 있는 전처리 명령에는 #include가 있겠죠?

이 전처리 명령은 컴파일이 시작되기 전에 처리가 되게 됩니다.

그래서 이름이 전처리 명령이죠..^^

이 전처리 명령을 수행하는 전처리기는 C언어의 문법을 알지 못합니다.

어쨋든 이 전처리 명령은 우리가 잘만 활용을 하면 유용하게 사용할 수 있습니다^^

일단 처음에 소개할 녀석은

#define 이라는 녀석입니다.

간단한 예제로 시작해 볼게요~




#define 이라는 녀석은

define... 말 그대로 정의 해 주는 녀석입니다.

이녀석은 이거다!!! 이렇게요 ㅎ

선언 방법은

#define 이녀석 이거

입니다.

위의 그림을 보시면 MAX(a, b) 라는 녀석은 (a>=b ? a :b ) 라고 알아먹어라.

라는 이야기가 되지요.

위의 뜻이 이해가 안가신다구요? 3항연산자를 모르신다구요? 안돼요 ㅠㅠ
2012/01/28 - [C] - C <8>. 조건문(3) 3항 연산자

ㅋㅋ 여튼 define 해줄때 뿐만 아니라 모든 전처리 명령에서는 뒤에 세미콜론 (;)을 붙이지 않습니다.

위의 예제를 실행해 봅시다.


이런 결과가 나오게 되네요~

#define 이라는 녀석 조금은 감이 오시나요?ㅎ

다음에는 char 형을 파라메터로 넣어 봅시다.

이렇듯이 define하여 '매크로화' 된 녀석의 파라메터로 들어가는 값은 어떤 형식이든지 상관이 없습니다. 왜냐면 이 녀석은 C의 문법을 모르기 때문이지요.
그만큼 편리하지만 그만큼 무서운 녀석입니다.
잘못된 인자(파라메터)를 받고서도 무작정 실행 해 버리기 때문에 warning이나 error가 발생하지 않기 때문에 나중에 프로그램에 문제가 생겼을 때 그 원인을 찾기가 힘들어 집니다...
물론 위의 예제는 에러나 워닝의 요소는 아닙니다..^^;

자, 다음에 소개드릴 녀석은 #ifdef 라는 녀석입니다.

말 그대로 '만약 이녀석이 define 되어 있다면...' 이런 뜻입니다.

 #ifdef 이녀석

이런 표현이 되겠지요?

우리가 if 를 쓸 때 else 라는 녀석이 따라왔지요. 여기서도 마찬가지 입니다~

#else가 따라옵니다 ㅎ

거기에 덧붙여 #ifdef를 끝마친다는 의미의 #endif도 추가적으로 따라옵니다.


위의 그림에서는 MODE_DEBUG가 #define 이 되어있기 때문에 #ifdef안의 문장이 실행이 됩니다.

만약 MODE_DEBUG가 #define되어 있지 않다면 어떻게 되는지 봅시다.


요로코롬 #else 에 속해있는 녀석이 실행이 되겠지요..^^

이 #ifdef 같이 되어있는 녀석은 if와는 다른점이 컴파일 되기도 전에 해당사항이 없다면 컴파일 되지 않게 된다는 점입니다.

즉, 프로그램 안에 영영 속하지 않게 된다는 뜻이 겠지요~

그 다음에 살펴볼 녀석은

#undef 라는 녀석입니다.

말 그대로 define되어 있던 녀석을 해제하는 녀석입니다.

예제를 통해 볼까요?


#define으로 정의되어 있던 SUM(a, b)라는 녀석을 define 해제시키고 새로 define한 예제입니다. 지난 define값이 없어지고 새로 define 되었지요..^^

이 외에도 ifdef말고도 

#if

#ifelse

등을 쓸 수도 있습니다.

한 번 시도해 보세요~^^

그러나 이 전처리자의 무서움은 C문법을 알고있지 않다는 점에 있습니다.

함부로 사용하게 되면 복잡한 프로그램에서는 피를 보는 결말을 보게되지요..^^;

그러므로 적절히 사용하는 것이 좋습니다.

이 전처리 명령을 대체할 수 있는 방법들이 몇 가지 있습니다.

enum을 사용해도 좋고, const변수를 사요해도 좋습니다.

물론 꼭 define을 사용해야 하는 경우도 생기지만 말입니다~


위의 그림을 보고 코드를 이해해 보세요..^^

구글링을 해 보셔도 좋습니다~

전처리 명령은 잘만 사용하면 효과적인 프로그래밍에 많은 도움이 됩니다.

꼭 기억해 두세요~^^

오늘은 여기 까~~~~~~~~지~~~~~~~~~

by yagom

twitter : @yagomsoft

p.s 제 포스팅을 RSS 피드로 받아보실 수 있습니다.

RSS Feed 받기   


↓↓↓저 열심히 썼는데 추천 한방 꾹 눌러주고 가시는 건 어떨까요? 로그인이 필요 없습니다. ^~^ 고맙습니다~ ↓↓↓ 



저작자 표시 비영리 변경 금지
신고

'C' 카테고리의 다른 글

C <17>. 동적할당  (2) 2012.05.18
C <16>. 구조체  (2) 2012.05.16
C <15>. 전처리자  (0) 2012.05.14
C <14>. 배열  (4) 2012.05.11
C <13>. 변수의 범위  (0) 2012.04.05
C <12>. 함수  (4) 2012.04.02
Posted by yagom


티스토리 툴바