달력

12

« 2024/12 »

  • 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
2010. 5. 31. 21:44

[17일차]Objective-C 2.0에서 추가된 기능 Objective-C2010. 5. 31. 21:44

Protocal의 옵션 지정이 가능
=> 1.0까지 에서는 Protocol의 모든 메서드를 구현하지 않으면 Warning : 실행은 가능
=> 2.0에서는 @required와 @optional을 지정해서 필수적으로 구현할것과 선택적으로 구현이 가능하도록 지정가능
    defalult는 required
   

dev-c : objective-c 1.0 기반
x-code : objective-c 2.0 기반
cocoa

2. for 구문의 변경
1) for의 (    )안에서 변수 생성이 가능(지역변수)

2) for(변수명 in 배열명)  <= nsdictionary 의 경우 key값을 리턴
=>배열의 모든 멤버가 순차적으로 변수에 하나씩 대입이 됩니다.
   이 기능을 고속 열거라고 합니다.
=>단 변수에 대입되는 멤버는 오브젝트 이어야 합니다.
    value 타입또는 일반 C 배열은 안됩니다.
=> enumerator를 반환할 수 있는 컬렉션 만이 배열명에 올 수 있습니다. 
    ex. nsarray 는 Object를 리턴

//가장 느림
NSArray * ar = 생성 ;
    int i ;
    for(i=0;i<[ar count];i++)
   {
       NSLog(@"%@",[ar ObjectAtIndex:i]);
   }

// 가장빠름, 코딩양이 많음.
NSEnumerator * it ;
    it = [ar getEnumerator];
    NSString * str;
    While((str=[it nextObject])!=nil)
    {
        NSLog(@"%@",str);
    }

//코딩양도 적고 빠름. enumerator형태로 변환되어 실행
NSString * str
    for(str in ar)
        NSLog(@"%@",str);
======================================================================
ex) for ~ in 예제
#import <foundation/foundation.h>
int main()
{
   NSAutorelease * pool = [[NSAutoreleasePool alloc]init];
   NSArray* monthName = [NSArray arrayWithObjects:@"Janurary",@"Feburary",nil];
   // NSArray 는 get Enumerator을 소유
   for(NSString * temp in monthName)
       NSLog(@"%@",temp);
   [Pool drain];
   return 0;
}
======================================================================
*잘못된 예
int ar[3]={1,2,3};
for(int n in ar)
    // n 은 Object가 아님, int 계열에는 get Enumerator가 없음.
    NSLog(@"%i",n);
======================================================================

* Property가 추가
=> 모든 멤버변수의 setter와 getter 문제 해결
예약어
@property : setter 와 getter의 선언
@synthesize : setter 와 getter의 구현

======================================================================
@interface Test:NSObject
{
    int a;
}
-(void)setA:(int)n;
-(int)a;
// 위의 두 선언은 @property int a; 로 완전히 대체
// 멤버변수와 메소드가 동일한 이름을 가져도 문제가 없다.
@property(setter=setting:)int k;
@end
======================================================================
@implementation Test
-(void)setA:(int)n
// 여기부터
{
   a=n;
}
-(int)a
{
   return a;
}
// 여기까지 => synthesize a; 로 대체
-(void)setting :(int)x
{
   k=x;
   NSLog(@"K가 초기화");
}
@end

Teste *obj = [Test new];
   [obj setk:10]; <=setter 구문을 그대로 사용가능

복사옵션지정 (property에 적용)
assign : 대입
retain : retain 메서드 호출
copy : 얕은 복사
=> NSArray * ar; 얕은 복사 문제발생 가능성 높음 // objective-c는 참조형 배열

    NSString * str ; 얕은 복사 문제 발생가능성이 적음



:
Posted by 에너지발전소
2010. 5. 28. 21:32

[16일차]에러처리 Objective-C2010. 5. 28. 21:32

1. 에러 처리

에러가 발생하면 메서드나 함수의 리턴 값 형태로 에러의 발생을 리턴합니다.

파일 처리에는 이러한 에러 처리를 위한 객체를 대입하도록 되어 있습니다.

이 경우 에러 처리에 관련된 오브젝트를 대입하면 에러가 발생해도 프로그램이 중단되지 않고 적절한 메시지를 출력하도록 프로그램을 만들 수 있습니다.


2. 타이머

일정한 주기를 가지고 또는 일정 시간을 delay 한 후 실행해야 하는 프로그램이나 메서드가 있다면 이 때는 타이머 오브젝트를 이용할 수 있습니다.

이 클래스는 NSTimer.h에 정의되어 있습니다.



3. 스레드(Thread)

NSThread 클래스가 스레드 기능을 제공하며 NSThread.h 파일에 정의와 구현되어 있습니다.

실제 main 함수도 스레드로 동작합니다.
모든 Objective-c프로그램 1개 이상의 스레드 소유.
기본적으로 main도 하나의 main 스레드로 생성해서 실행

현재 스레드가 수행 중인지 아닌지 확인하는 메서드는 아래와 같습니다.

 

+(BOOL)isMultiThreaded

멀티 스레드인지 아닌 지 확인해주는 메서드. 과거 한번이라도 수행이 되었는지 확인

+(NSThread *)currentThread

현재 스레드를 나타내는 인스턴스 리턴

+(NSThread *)mainThread

현재의 main 스레드를 나타내는 인스턴스 리턴
---------------------------------------------------------------
#import <Foundation/Foundation.h>
int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    NSThread * thread;
    thread = [NSThread currentThread];
    if(thread !=nil)
     NSLog(@"현재 스레드가 동작중입니다");
    else
     NSLog(@"현재 스레드가 동작중이지 않습니다.");
    
    if(thread == [NSThread mainThread])
     NSLog(@"이 스레드는 main스레드 입니다.");
    else
     NSLog(@"이 스레드는 main스레드가 아닙니다");
    
    if([NSThread isMultiThreaded] == YES)
     NSLog(@"현재 프로그램은 멀티 스레드 환경입니다.");
    else
     NSLog(@"현재 프로그램은 멀티 스레드 환경이 아닙니다.");        
    
    [pool drain];
    system("pause");
    return 0;
}

---------------------------------------------------------------

스레드 생성하기

-(id) initWithTarget:(id)스레드 수행 주체 selector:@selector(스레드로 수행할 메서드:) object:인수로 넘겨줄 오브젝트-스레드함수에게 넘겨줄 매개변수];

 

스레드 수행 메서드

-(void)메서드명:(id)argument

{        

    작업 내용

}

-스레드 시작
[스레드객체 Start];

-스레드 중지
+(void)exit // 현재 실행중인 스레드 중지
-(void)cancel // 호출하는 인스턴스 스레드가 중지

ex)스레드로 메서드 수행
---------------------------------------------------------------
#import <Foundation/Foundation.h>
#import <stdlib.h>
@interface ThreadTest:NSObject
{
    NSThread *thread;
}     
-(void)setThread; // 스레드 생성하고 시작
-(void)Print:(id)argument; // 스레드가 수행할 메서드
@end

@implementation ThreadTest
-(void)setThread
{
//  -(id) initWithTarget:(id)스레드 수행 주체 selector:@selector(스레드로 수행할 메서드:) object:인수로 넘겨줄 오브젝트-스레드함수에게 넘겨줄 매개변수];
    thread = [[NSThread alloc] initWithTarget:self selector:@selector(Print:) object:nil];
               // 생성                                시작
    [thread start];
}
-(void)Print:(id)argument
// 비선점
{        
    NSLog(@"Hello World");               
}
@end

int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    ThreadTest *Obj = [[ThreadTest alloc]init]; // 현재 스레드 생성 안됨
    if([NSThread isMultiThreaded] == YES)
     NSLog(@"현재 프로그램은 멀티 스레드 환경입니다.");
    else
     NSLog(@"현재 프로그램은 멀티 스레드 환경이 아닙니다.");
     [Obj setThread];
     if([NSThread isMultiThreaded] == YES)
     NSLog(@"현재 프로그램은 멀티 스레드 환경입니다.");
     else
     NSLog(@"현재 프로그램은 멀티 스레드 환경이 아닙니다.");
    [pool drain];   
    system("pause");    
    return 0;
}
---------------------------------------------------------------

//* 두개의 스레드 수행
---------------------------------------------------------------
#import <Foundation/Foundation.h>
#import <stdlib.h>
@interface ThreadTest:NSObject
{
    NSThread *thread1;
    NSThread *thread2;
}     
-(void)setThread;
-(void)Print:(id)argument;
@end

@implementation ThreadTest
-(void)setThread
{
    thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(Print:) object:nil];
    thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(Disp:) object:nil];
    [thread1 start];
    [thread2 start];
}
-(void)Print:(id)argument
{
         int i;                         
         for(i=0; i<10; i++)                
         {
                  NSLog(@"Hello World");
                  Sleep(1000);
         } 
         NSLog(@"Print 메서드 수행 종료");     
}
-(void)Disp:(id)argument
{
         int i;                         
         for(i=0; i<10; i++)                
         {
                  NSLog(@"Hi Objective-C");
                  Sleep(1000);                 
         } 
          NSLog(@"Disp 메서드 수행 종료");      
}
@end

int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    ThreadTest *Obj = [[ThreadTest alloc]init];
    [Obj setThread];
    [pool drain];
    system("pause");
    return 0;
}
---------------------------------------------------------------

멀티스레드의 자원공유문제에러 => Mutex 에러 // Syncronize 하지 않아서 발생
                              // (Mutual Exclusion - 상호배제에러)

#import <Foundation/Foundation.h>
#import <stdlib.h>
@interface ThreadTest:NSObject
{
    NSThread *thread1;
    NSThread *thread2;
    int share;
}     
-(void)setThread;
-(void)Print:(id)argument;
@end

@implementation ThreadTest
-(void)setThread
{
    thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(Print:) object:nil];
    thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(Disp:) object:nil];
    [thread1 start];
    [thread2 start];
    share = 0;
}
-(void)Print:(id)argument
{
         int i;                                        
          for(i=0; i<10; i++)                
          {                
                  share --;
                  Sleep(100);
                  NSLog(@"감소 시킨 share 값: %i:", share);
          }       
}
-(void)Disp:(id)argument
{
         int i;
       
         for(i=0; i<10; i++)                
         {
                  share ++;
                  Sleep(100);
                  NSLog(@"증가 시킨 share 값: %i:", share);
         }         
}
@end

int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    ThreadTest *Obj = [[ThreadTest alloc]init];
    [Obj setThread];
    [pool drain];
    system("pause");
    return 0;
}
---------------------------------------------------------------

:
Posted by 에너지발전소
2010. 5. 27. 21:03

[15일차]일반 오브젝트 아카이브 Objective-C2010. 5. 27. 21:03

1. 일반 오브젝트 아카이브

일반 오브젝트를 아카이브 할 때는 NSCoding 프로토콜에 정의되어 있는 encodeWithCoder: initWithCoder: 메서드를 정의하면 됩니다.

 

메서드의 원형

-(void)encodeWithCoder:(NSCoder *)encoder

이 메서드의 안에서 encoder가 아카이브 할 실제 멤버들을 직접 인코딩하면 됩니다.

 

-(id) initWithCoder:(NSCoder *)decoder

이 메서드의 안에서 decoder가 언아카이브 할 실제 멤버들을 직접 디코딩하면 됩니다.




2. NSData를 이용한 아카이브

여러 개의 데이터를 아카이브 해야 하는 경우 NSData를 이용해서 이러한 작업을 수행할 수 있습니다.

이 때는 NSData를 이용해서 미리 영역을 설정한 후 이를 아카이브 클래스의 오브젝트에 연결한 후 이들을 아카이브 해나가면 됩니다.

------------------------------------------------------------
//Achive

#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSKeyedArchiver.h>
#import <Foundation/NSCoder.h>
#import <Foundation/NSData.h>
@interface Test : NSObject<NSCoding>
{
  NSString * str;
  int n;
  float f;
}
-(void)setStr:(NSString *)msg;
-(NSString *)str;
-(void)setN:(int)temp;
-(int)n;  
-(void)setF:(float)temp;
-(float)f;                    
@end

@implementation Test
-(void)setStr:(NSString *)msg
{
  str = [NSString stringWithString:msg];
}
-(NSString *)str
{ return str; }
-(void)setN:(int)temp
{ n = temp; }
-(int)n
{ return n;}
-(void)setF:(float)temp
{ f = temp; }
-(float)f
{return f; }

-(void) encodeWithCoder:(NSCoder *)encoder
{
        [encoder encodeObject:str forKey:@"TestSrt"];
        [encoder encodeInt:n forKey:@"TestN"];
        [encoder encodeFloat:f forKey:@"TestF"];       
}

-(id) initWithCoder:(NSCoder *)decoder
{
    str =  [decoder decodeObjectForKey:@"TestSrt"];
     n =   [decoder decodeIntForKey:@"TestN"];
     f =   [decoder decodeFloatForKey:@"TestF"];       
}
@end

int main ()
{
 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 Test *Obj1 = [ [ Test alloc] init];
 Test *Obj2 = [ [ Test alloc] init];
 NSMutableData *dataArea; //nsData로 선언하면 Data변경이 안됨
 NSKeyedArchiver *archiver;
 
 [Obj1 setStr:@"Hello World"];
 [Obj1 setN: 111];
 [Obj1 setF: 11.1];
 
 [Obj2 setStr:@"Objective-C"];
 [Obj2 setN: 222];
 [Obj2 setF: 22.2];
 
 dataArea = [NSMutableData data]; // "data"는 생성자 , mutable 에서만 호출가능
 archiver = [[ NSKeyedArchiver alloc] initForWritingWithMutableData: dataArea];
 [archiver encodeObject:Obj1 forKey: @"Obj1"];
 [archiver encodeObject:Obj2 forKey: @"Obj2"];
 [archiver finishEncoding];
 
 if (( [ dataArea writeToFile:@"myArchive" atomically:YES ] ) == NO)
  NSLog(@"아카이빙 실패");
 
 [Obj1 release];
 [Obj2 release];
 [pool drain];
 system("pause");
    return 0;
}
------------------------------------------------------------
------------------------------------------------------------
//UnAchive
#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSKeyedArchiver.h>
#import <Foundation/NSCoder.h>
#import <Foundation/NSData.h>
@interface Test : NSObject<NSCoding>
{
  NSString * str;
  int n;
  float f;
}
-(void)setStr:(NSString *)msg;
-(NSString *)str;
-(void)setN:(int)temp;
-(int)n;  
-(void)setF:(float)temp;
-(float)f;                    
@end

@implementation Test
-(void)setStr:(NSString *)msg
{
  str = [NSString stringWithString:msg];
}
-(NSString *)str
{ return str; }
-(void)setN:(int)temp
{ n = temp; }
-(int)n
{ return n;}
-(void)setF:(float)temp
{ f = temp; }
-(float)f
{return f; }

-(void) encodeWithCoder:(NSCoder *)encoder
{
        [encoder encodeObject:str forKey:@"TestSrt"];
        [encoder encodeInt:n forKey:@"TestN"];
        [encoder encodeFloat:f forKey:@"TestF"];       
}

-(id) initWithCoder:(NSCoder *)decoder
{
    str =  [decoder decodeObjectForKey:@"TestSrt"];
     n =   [decoder decodeIntForKey:@"TestN"];
     f =   [decoder decodeFloatForKey:@"TestF"];       
}
@end

 

int main ()
{
   
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSData    *dataArea;
 NSKeyedUnarchiver *unarchiver;
 Test *Obj1, *Obj2;
 dataArea = [NSData dataWithContentsOfFile: @"myArchive"];
 if (dataArea == nil)
    {
  NSLog(@"읽어 오기 실패");
  return 0;
 }
 
 unarchiver = [[ NSKeyedUnarchiver alloc] initForReadingWithData: dataArea];
 Obj1 = [unarchiver decodeObjectForKey: @"Obj1"];
    Obj2 = [unarchiver decodeObjectForKey: @"Obj2"];
 
 [unarchiver finishDecoding];
 NSLog(@"Obj1의 데이터");
    NSLog(@"==============");
 NSLog(@"\n%@\n%i\n%g", [Obj1 str], [Obj1 n], [Obj1 f]);
    NSLog(@"==============");
 NSLog(@"Obj2의 데이터");
    NSLog(@"==============");
 NSLog(@"\n%@\n%i\n%g", [Obj2 str], [Obj2 n], [Obj2 f]);
    [unarchiver release];
    [pool drain];
 system("pause");
    return 0;   
}
------------------------------------------------------------
ex>archive를 이용한 오브젝트의 복사(깊은 복사)
#import <Foundation/Foundation.h>
int main ()
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 NSData    *data;
 NSMutableArray  *ar1 = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"], [NSMutableString stringWithString:@"2"],[NSMutableString stringWithString:@"3"],nil];
 NSMutableArray  *ar2;
 NSMutableString  *str;
 int i;
 data = [NSKeyedArchiver archivedDataWithRootObject: ar1];
 ar2 = [NSKeyedUnarchiver unarchiveObjectWithData: data];
 str = [ar1 objectAtIndex: 0];
 [str appendString: @"1"]; 
 NSLog(@"ar1: ");
 NSLog(@"=================");
 for(i=0; i<[ar1 count]; i++ )
  NSLog(@"%@", [ar1 objectAtIndex:i]);
 NSLog(@"=================");
 NSLog(@"ar2: ");
 NSLog(@"=================");
 for(i=0; i<[ar2 count]; i++ )
  NSLog(@"%@", [ar2 objectAtIndex:i]); 
    [pool drain];
    system("pause");
    return 0;
}
------------------------------------------------------------


** 예외처리

1. 예외처리를 위한 예약어

@try: Exceptions이 던져질 수 있는 block을 정의합니다.

@throw Exception object를 던진다.

@catch() @try bolck안에서 던져진 exception catch한다.

@finally @try block에서 Exceptions가 던져지던 아니던 수행되어질 block code를 정의한다.

모두 NSException.h에 정의되어 있습니다.


2. NSAssert (메서드 안에서 작성)
특정 조건을 만족하지 않는 경우 NSInternalInconsistencyException예외를 발생시켜 프로그램을 강제로 중단시키는 매크로함수

사용방법
NSAssert(만족해야 하는 조건, 출력할 문장);
         ==> 조건을 만족하지 않으면 Excception 발생시킨후 출력내용 출력

 

:
Posted by 에너지발전소
2010. 5. 26. 20:28

[14일차]객체의 복사 Objective-C2010. 5. 26. 20:28

* 얕은복사
int *p = (int *)malloc(4);
int *q = p;
*p = 10;
printf("%d",*p);
printf("%d",*q);
*p =20;
printf("%d",*q);


* 깊은복사
int*p=(int *)malloc(4);
*p=10;
int *q = (int*) malloc(4);
*q=*p;
printf("%d",*p);
printf("%d",*q);
*p=20;
printf("%d",*q);

ex)copy와 mutablecopy는 얕은복사
#import <foundation/NSObject.h>
#import <foundation/NSArray.h>
#import <foundation/NSString.h>
#import <foundation/NSAutorelease.h>
int main()
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    NSMutalbeArray * ar1 = [NSMutalbeArray arrayWithObjects:[NSMutableString:@"1"],[NSMutableString:@"2", [NSMutableString:@"3"],nil];
NSMutableArray *ar2;
NSMutalbeString *str;
int i;
NSLog(@"ar 1의 요소");
NSLog(@"--------");
for(i=0; i<[ar1 count];i++)
    NSLog(@"%d",[ar1 objectAtIndex: i]);
    ar2=[ar1 mutableCopy]; 
    str=[ar1 objectAtIndex:0];
    [str app;endString:@"1"];
    NSLog(@"---------");
    NSLog(@"ar2의 요소");
    NSLog(@"---------");
    for(i=0;i[ar2 count];i++)
        NSLog(@"%@",[ar2 objectAtIndex:i]);

[ar1 release];
[ar2release];
[pool drain];
system("pause");
return 0;
}

3. Copy의 구현
=>NSObject 클래스의 NSCopying프로토볼이 선언
=>NSObject 클래스에는 실제구현되어 있지 않음
   이 메서드는 내부적으로
  -(id)copyWithZone:(NSZone *)
                             //heap에 관련된 클래스0
                                메모리할당시 allocwinthzone: nose객체를 이용하면 비슷한 경험이 생김

따라서 copy메서드를 사용하고자 하는 경우 위의 메서드를 출현
:
Posted by 에너지발전소
2010. 5. 25. 21:19

[13일차]파일처리 Objective-C2010. 5. 25. 21:19


4. 디렉토리 작업

NSFileManager에는 디렉토리를 다루는 메서드를 제공합니다.

 

-(NSString *)currentDirectoryPath

현재 디렉토리 경로 NSString으로 반환

 

-(BOOL)changeCurrentDirectoryPath: (NSString *)path

path로 현재 디렉토리를 변경

 

-(BOOL) copyPath:(NSString *)from toPath:to handler:handler

from으로부터 to로 디렉토리 구조를 복사

 

-(BOOL)createDirectoryAtPath: (NSString *)path attributes:(NSDictionary *) attr

path를 생성하고 attr에 속성을 저장

 

-(BOOL)fileExistsAtPath: (NSString *)path isDirectory:(BOOL *)flag

path가 디렉토리인지 여부를 flag에 저장                // 변수대입

 

-(NSArray *)directoryContentsAtPath:(NSString *)path

path의 내용을 배열로 리턴

 

-(BOOL)removeFileAtPath:(NSString *)path handler:handler

path 디렉토리를 삭제

 

-(BOOL) movePath:(NSString *)from toPath: (NSString *)to handler:handler

디렉토리 이름 변경                                  // to 존재하면 에러


5. 디렉토리 내용 열거

- (NSDirectoryEnumerator *)enumeratorAtPath:(NSString *)path
            // nextObject     allObjects : 전체를 NSArray타입으로 리턴
path
에 지정된 디렉토리내의 모든 서브 디렉토리와 파일목록을 가져 옵니다.
==> 하위디렉토리까지 전부조사

- (NSArray *)directoryContentsAtPath:(NSString *)path

path에 존재하는 파일 목록을 배열로 리턴
==> 파일명만 배열로 리턴 - 서브디렉토리 확인하지 않음

- (NSDictionary *)fileAttributesAtPath:(NSString *)path traverseLink:(BOOL)flag
path
에 지정된 파일 또는 디렉토리의 속성을 가지고 옵니다.

flag YES로 지정하면 심볼릭 링크된 파일의 원본 파일의 정보를 가져오며, NO일 경우에는 링크된 파일의 정보를 가지고 옵니다.

:
Posted by 에너지발전소

C 언어의 개요

1. C언어의 역사

C언어는 1972년 벨 연구소의 Dennis Ritchie에 의해 만들어졌습니다.

Dennis Ritchie UNIX 운영체제의 개발을 맡고 있었는데 운영체제는 그 특성상 하드웨어를 직접 제어할 수 있어야 했습니다.

또한 당시의 컴퓨터 환경이 지금과는 달라 CPU의 속도나 메모리의 용량이 충분하지 않았기 때문에 프로그램의 크기는 작아야 했고 속도는 빨라야 했습니다.

이런 모든 요구를 만족시킬 수 있는 유일한 언어는 어셈블리밖에 없었습니다.

그러나 어셈블리는 특정 기계에 종속적이며 이식성이 없기 때문에 여러 플랫폼에 사용하는 것이 목적인 UNIX와는 잘 어울리지 않았습니다.

그래서 Dennis Ritchie는 기존의 언어를 사용하지 않고 어셈블리의 강력한 기능과 고급언어의 이식성을 동시에 갖춘 새로운 언어를 직접 만들었습니다.

물론 Dennis Ritchie 혼자서 C언어를 다 만든 것은 아니며 과거 언어들의 장점을 정리해서 만든 것입니다.

C언어의 뿌리는 ALGOL언어이며 Dennis Ritchie는 동료인 켄 톰슨(Ken Thompson)이 만든 B언어를 개량하여 C언어를 만들었습니다.

C언어의 계보를 그려 보면 다음과 같습니다.

이 언어에 C라는 이름을 붙인 이유는 B보다 한 단계 더 발전했다는 의미로 B다음의 알파벳인 C를 사용한 것입니다.

C언어는 간결하면서도 강력한 프로그램을 작성하기에 적합하여 오늘날 가장 대중적인 프로그래밍 언어로 사용되고 있습니다.

차후에 C 언어는 C++ 로 발전하게 되는데 이때는 D언어라 하지 않고 C언어에서 하나 증가하는 연산자로 사용하는 C++라는 이름으로 불리게 됩니다.

이러한 시기 중간에 80년대 초에는 Brad Cox SmallTalk의 객체 지향 적인 개념과 C의 강력함을 동시에 사용하는 언어인 Objective – C를 설계하게 됩니다.

이를 기반으로 1988 NeXT Software(Steve Jobs)가 라이센스를 넘겨받아 새로운 개뱔 환경과 라이브러리를 개발합니다.

이를 다시 1996년에 애플이 이 회사를 인수하여 차세대 운영체제 개발에 이용하기로 하고 이러한 개발환경을 Cocoa라고 명명하게 됩니다.

사용법 자체는 C++와 유사합니다. (main 함수가 특정 클래스에 속하지 않음)

이 언어가 IPhone SDK의 모태가 됩니다.

C#이나 Java C++와 이 Objective-C를 개량한 객체지향언어입니다.

따라서 현재 사용되는 대부분의 언어는 C언어에 모태를 두고 있습니다.

C언어를 잘 하게 되면 다른 언어를 잘 할 수 있는 이유이며 언어를 공부할 때 C언어를 가장 먼저 공부하는 이유이기도 합니다.


 

2. C언어의 특징

① 문법이 간결하며 예약어가 적고 제공하는 연산자가 다양하기 때문에 짧은 명령으로 많은 일을 할 수 있습니다.

② 효율성이 좋아 대규모의 프로그램을 만들 수 있습니다.

제작된 프로그램의 크기가 작고 속도도 빠릅니다.

③ 운영체제 개발을 목적으로 만든 언어이므로 하위 수준 프로그래밍이 가능하며 어셈블리 수준의 하드웨어 제어를 할 수 있습니다.

④ 모든 분야에 활용할 수 있을 정도로 범용적입니다.

사무 처리, 과학 기술, 상업용 등 거의 대부분의 응용 프로그램을 개발할 수 있습니다.

⑤ 성능을 위해 불필요한 에러 처리를 하지 않습니다.

타입의 불일치나 배열 경계 점검 등은 프로그래머가 직접 해야 하므로 개발자는 항상 이 점을 주의해야 합니다.

⑥ 이식성이 좋습니다.

대부분의 플랫폼에서 C/C++ 언어를 사용할 수 있으므로 재 컴파일만 하면 타 운영체제에서 실행되는 프로그램을 쉽게 만들 수 있습니다.

C언어가 발표되기 전의 언어들은 각각 장단점이 있어서 특정 분야에서 독점적인 지위를 가지는 고유한 영역을 확보하고 있었습니다.

Pascal이나 Basic은 교육용 언어로 분류되었고 COBOL은 상업용 소프트웨어 작성에 효율적이었으며 FORTRAN은 과학 기술용 언어로 주로 사용되었습니다.

또한 LISP는 인공 지능 구현에 적합했으며 어셈블리는 시스템 프로그래밍을 위한 최적의 언어였습니다.

C언어는 거의 모든 분야에 광범위하게 사용되게 됩니다.

C 언어는 원래 목적이었던 UNIX제작은 물론이거니와 Microsoft사의Windows NT와 같은 운영체제를 만들 때도 사용되며 빠른 속도를 요하는 게임프로그래밍에서도 C언어 내부에 어셈블리언어를 삽입시켜 제작하게 됩니다.

이러한 강력한 특징 때문에 모든 프로그래머들이 처음 프로그래밍을 접할 때 C언어부터 배우게 됩니다.

하지만 이러한 많은 장점에도 불구하고 C언어에도 치명적인 단점은 존재합니다.

C언어는 플랫폼(하드웨어나 운영체제)에 종속적입니다.

특정 개발 환경하에서 만든 프로그램은 그 개발환경과 동일하거나 유사한 경우에만 실행이 됩니다.

이러한 이유는 C언어는 미리 컴파일을 한 후 오브젝트 프로그램(기계어와 유사)을 만들고 이를 기반으로 실행 프로그램을 만들기 때문입니다.

또한 C언어는 웹에는 취약한 기반입니다. - C언어가 나올 때는 Web이 없었습니다.

이러한 단점을 해결하기 위해 등장한 것이 Java와 닷넷입니다.

이러한 언어들은 중간코드까지만 만들고 두고 Java Virtual Machine이나 닷넷 프레임워크가 실행하게 됩니다.


 

3. C 언어 수행과정

프로그램을 작성한다는 것은 사용하는 언어의 문법에 맞게 명령들을 작성하는 것을 의미합니다.

언어의 문법에 맞게 명령들을 기술한 파일을 원시 파일(Source File)이라고 하며 원문 그대로 소스(Source)파일 이라고도 부릅니다.

소스는 고급 언어로 작성되어 있기 때문에 컴퓨터가 바로 이해할 수 없으며 따라서 실행할 수도 없습니다.

컴퓨터는 오로지 이진수로 된 기계어밖에 이해하지 못합니다.

그래서 소스를 컴퓨터가 이해할 수 있는 기계어 코드로 번역해야 하는데 이 동작을 컴파일(Compile)이라고 합니다.

컴파일이란 소스에 작성된 명령들을 컴퓨터 언어인 기계어로 번역하는 작업이며 컴파일을 해주는 프로그램을 컴파일러(Compiler)라고 부릅니다.

컴파일러는 소스 파일에 작성된 고급 언어 명령을 해석하여 기계어 코드로 바꾸고 그 결과를 목적 파일(Object File)에 써 넣게 됩니다.

따라서 컴파일러는 소스 파일을 목적 파일로 바꾸는 시스템 프로그램입니다.

목적 파일은 소스의 명령들을 번역한 기계어 코드를 가진 파일이되 이 파일도 곧바로 실행할 수 없습니다.

왜냐하면 프로그램은 기계어 코드 외에도 운영체제가 요구하는 코드를 추가로 가져야 하기 때문입니다.

목적 파일을 실행 파일로 바꾸기 위해서는 이 실행 파일이 운영체제의 요건에 맞도록 형태를 조금 바꾸고 스타트업(StartUp)이라는 추가 코드를 가져야 합니다.

목적 파일에 이런 처리를 하여 실행 파일로 만드는 동작을 링크(Link)라고 하며 링크를 해 주는 프로그램을 링커(Linker)라고 부릅니다.

하나의 프로그램이 작성되는 과정은 다음과 같이 그릴 수 있습니다.

Source File

à

Object File

à

Excute File

소스 파일은 컴파일러에 의해 컴파일되어 목적 파일이 되며 목적 파일은 링커에 의해 링크되어 최종적으로 실행 가능한 실행 파일이 됩니다.

소스 파일을 번역하여 곧바로 실행 파일을 만들지 않고 목적 파일이라는 중간 과정을 거치는 이유는 여러 개의 소스를 합쳐 하나의 실행 파일을 만들어낼 수 있어야 하기 때문입니다.

하나의 소스에 필요한 모든 명령을 다 기술할 수 없으므로 소스를 여러 개 작성하고 이것을 모두 연결하면 완전한 실행 파일이 나오게 됩니다.


A.c

à

A.obj

 

 

Linking

à

Excute

 

 

B.c

à

B.obj

 

 

 

 

C.c

à

C.obj

 

 

 

 

A.c를 컴파일하여 A.obj를 만들고 B.c, C.c는 각각 B.obj, C.obj를 만듭니다.

각 목적 파일은 소스 파일의 명령을 번역한 기계어 코드를 가지고 있을 것입니다.

이렇게 개별 소스를 컴파일해서 만들어진 세 개의 목적 파일을 연결하면 하나의 실행 파일이 되며 링크 단계에서 이미 만들어진 라이브러리도 결합되게 됩니다.

이런 식으로 소스를 여러 개 작성해서 최종적으로 링크하는 방식을 분할 컴파일이라고 하는데 여러 사람이 같이 작업하거나 기능별로 모듈을 개발할 때 일반적으로 사용하는 방법입니다.

하나의 실행 파일을 만들려면 편집기로 명령들을 기술하여 소스를 만들고 이 소스를 컴파일하여 목적 파일로 만든 후 다시 링크 과정을 거쳐야 합니다.

아직도 일부 Linux, Unix 환경에서는 이 방법대로 개발하기도 합니다.

최근의 개발툴들은 자체에 편집기, 컴파일러, 링커를 모두 내장하고 있기 때문에 한번에 소스를 실행 파일로 바꿀 수 있습니다.

뿐만 아니라 디버거, 프로파일러, 리소스 편집기 등 개발에 필요한 편의 기능까지 같이 제공하는데 이런 환경을 통합 개발 환경(IDE, Integrated Development Environment)이라고 부릅니다.

이러한 IDE로 가장 유명한 것이 Visual Studio 입니다.

개발 환경 내에서 편집, 개발, 디버깅, 최적화까지 다 할 수 있기 때문에 무척 편리하며 생산성 향상에 크게 기여하고 있습니다.

컴파일러란 소스 파일을 목적 파일로 변환하는 프로그램을 의미하는데 요즘은 통합 개발 환경이 워낙 일반화되었기 때문에 개발 환경 자체를 컴파일러라고 부르기도 합니다.

UNIX 환경에서는 .obj가 아니고 .o 파일이 생성될 것입니다.


 

4. C 컴파일러의 종류

C/C++ 컴파일러에는 많은 종류가 있습니다.

컴파일러가 생성해 내는 기계어는 특정 CPU와 운영체제에서만 동작하기 때문에 컴파일러는 본질적으로 플랫폼에 종속적입니다.

매킨토시용 컴파일러로 인텔 계열 CPU에서 동작하는 프로그램을 작성할 수 없으며 도스용 컴파일러로 Windows용 프로그램을 작성할 수 없습니다.

운영체제 별로 C/C++ 컴파일러를 분류해 보면 다음과 같습니다.

운영체제

컴파일러

도스용

터보 C, 볼랜드 C++, MS C

Windows

Visual C++, 볼랜드 C

유닉스용

gcc

Gcc + Mingw

Dev C++

최근에는 WindowsTurbo C도 등장했습니다.

같은 컴파일러라도 버전에 따라 기능과 사용 방법, 지원하는 문법 수준이 다르므로 사용할 컴파일러를 선택하는 것은 아주 어려운 일입니다.

현재 가장 많이 사용되는 컴파일러는 마이크로소프트사의 Visual C++입니다.

Windows 전용 컴파일러이므로 Windows용 프로그램을 가장 잘 생성하며 작업 환경이 편리합니다.

코드를 자동으로 생성해 주는 위저드 기능과 MSDN이라는 방대한 도움말, 프로젝트 관리 기능 등 개발자를 위한 많은 지원들이 포함되어 있습니다.

Visual C++ Windows 전용의 컴파일러이기 때문에 도스에 대한 지원이 없습니다.

대신 도스와 비슷한 콘솔 환경을 지원하는데 콘솔에서는 기본적인 입출력만 해 볼 수 있으며 도스에 비해 화면 제어 능력이 취약합니다.

Visual C++(Visual C++)은 마이크로소프트사에서 만든 C/C++ 컴파일러입니다.

1992 4월에 첫 버전인 1.0이 발표되었으며 꾸준한 버전업을 거쳐 2009년 현재 Visual 스튜디오 2008까지 발표되었으며 조만간 Visual C++ 2010도 발표될 예정입니다.

Visual C++은 단순한 C/C++ 컴파일러가 아니라 여러 가지 다양한 프로젝트를 만들 수 있는 종합 개발 툴입니다.

Visual C++ 2008을 설치한 경우에는 마이크로소프트사의 홈페이지에 접속해서 자신의 Visual C++ 2008 언어에 맞는 서비스 팩을 같이 설치하는 것이 좋습니다.

서비스 팩을 설치하지 않으면 컴파일이나 링크가 되지 않는 경우가 발생할 수 도 있습니다.


 

5. 첫번째 실습 예제

Microsoft VC++2008을 실행합니다.

메뉴에서 파일 -> 새로 만들기 -> 프로젝트 항목을 선택하여 새로 프로젝트를 만듭니다.

왼쪽 화면에서 Win32를 선택하고 오른쪽 화면에서 Win32 콘솔 응용 프로그램을 지정하고 이름 란에 프로젝트 이름을 입력합니다.

그리고 다음 화면에서 추가 옵션에서 빈 프로젝트 란에 체크하고 마침을 누릅니다.

그리고 오른쪽 화면의 솔루션 탐색기에서 소스파일을 선택하고 마우스 오른쪽을 클릭해서 [추가] – [새 항목]을 선택합니다.

그리고 오른쪽의 화면에서 C++ 파일을 선택하고 파일 이름란에 파일명을 입력합니다.

이 때 주의할 점은 순수 C파일을 만들 때는 확장자를 .c로 해주어야 한다는 것입니다.

확장자를 입력하지 않으면 cpp가 붙게 되어 C++ 파일이 됩니다.

다음으로 소스 편집 창에 아래와 같은 코드를 입력합니다.

C언어는 영어 대소문자를 구별하므로 정확하게 입력하도록 합시다.

1-1 실습예제

#include <stdio.h>

int main()

{

    printf("안녕하세요반갑습니다. \n");

        system("pause");

    return 0;

}

위의 코드에서 들여쓰기나 줄 바꿈은 큰 의미가 없으므로 정확하게 들여쓰거나 줄바꿈을 할 필요는 없습니다.

작성한 프로젝트를 Compile(Bulid 메뉴에서 Compile을 선택하거나 Ctrl + F7)하여 Source 파일을 Compile하고 난 후 Bulid(Bulid 메뉴에서 Bulid 를 선택하거나 F7)를 수행한 후 Excute(Bulid 메뉴에서 Excute 를 선택하거나 Ctrl + F5)를 수행하여 실행 시켜봅시다.

만약 에러가 없다면 console 화면에 안녕하세요 반갑습니다라는 메시지를 화면 상에 출력 시켜 주게 될 것입니다.

프로그램을 작성하다 보면 컴파일이 제대로 되지 않을 수도 있는데 이럴 때 컴파일러는 다음 두 방법으로 사용자의 실수를 지적해 줍니다.

 에러(Error): 문법상 명백하게 잘못된 점이 있어서 번역을 할 수 없는 경우 에러 메시지를 출력하고 컴파일을 하지 않게 됩니다.

가장 흔한 경우는 오타가 있고 형식이 맞지 않다든가 반드시 필요한 지정이 빠진 경우 등이 에러로 처리됩니다.

에러가 있는 상태로는 컴파일을 계속할 수 없으므로 반드시 수정해야 합니다.

경고(Warning): 좀 이상한 문장이기는 하지만 컴파일에 큰 문제가 없는 경우 경고를 해주는 것입니다.

경고의 내용은 무시해도 되지만 만일 사용자의 실수가 있어서 나오게 되는 경우라면 수정을 해주는 것이 좋습니다.

 

만일 에러가 발생했다면 디버그 모드를 실행해 볼 수 있습니다.

디버그 모드 실행은 코드를 한 줄씩 실행하면서 어디가 잘못되었는지 알아내는 방법입니다.

값이 애매한 경우나 어디서 잘못 되었는지 모르는 경우 디버그 모드를 이용하면 버그를 쉽게 찾을 수가 있습니다.

이 때 소스 코드는 디버그용으로 컴파일된 것이어야 합니다.

메뉴에서 [Build] – [Start Debug] – [Go]를 선택해서 디버그로 실행하면 됩니다.

F5를 단축키를 이용할 수도 있습니다.

F10, F11을 이용해서 코드를 한 줄씩 실행시켜볼 수 있으며 현재 실행하고 있는 줄을 표시해서 보여주게 됩니다.


 

gcc 컴파일러를 이용한 소스 작성 및 실행

gcc는 통합 개발환경이 아닙니다.

따라서 문서 편집 기능이 없습니다.

윈도우에서 사용한다면 먼저 메모장을 이용해서 파일을 작성합니다.

파일 명 뒤에 확장자를 .c로 해서 저장합니다.

[시작] – [실행] – [cmd]를 쳐서 콘솔 창으로 이동합니다.

cd 명령을 이용해서 gcc가 있는 디렉토리로 이동합니다.

그런 다음 gcc 소스 파일 경로 및 이름.c –o 실행 파일 경로 및 파일명.exe

로 컴파일합니다.

실행은 콘솔 창에서 실행 파일의 경로 및 파일 명을 입력하면 됩니다.

 

1. 메모장에 아래와 같이 작성해서 C:\Test.c로 저장

#include <stdio.h>

int main()

{

         printf("Hello World");

}

 

2. [시작] – [실행] – [cmd]

 

3. 실행 창에서 아래 와 같이 입력

C:\gcc\Bin>gcc c:\test.c -o c:\test.exe

C:\gcc\Bin>c:\test

Hello World


 

6. C 프로그램의 구조

1) 전처리부(Preprocessor)

- 먼저 컴파일 되는 부분

 

2) 전역 변수 선언부

- 전역 자료 형이나 변수를 선언하는 부분

 

3) 사용자정의함수 선언부

- 사용자가 직접 만들어 사용하는 함수를 선언하는 부분

 

4) 메인 함수부

- 기본적으로 존재해야 하는 함수

 

하지만 이 구조가 꼭 지켜져야 하는 것은 아닙니다.

main() 함수는 꼭 있어야 하지만 때론 전역변수 선언부나 사용자정의 함수부분은 존재하지 않을 수도 있습니다.

 

1-2 실습예제

#include <stdio.h>

int a;

void hello( )

{

        printf("안녕하세요\n");

        a = 2;

        printf("이예제는%d번째예제입니다\n",a);

}

int main( )

{

        hello();

        system("pause");

        return 0;

}

 


 

7. C 언어의 구성요소

1)키워드(Keyword)

C언어 차제가 의미를 미리 정해 놓은 단어들이며 예약어(Reserved word)입니다.

C언어가 이미 사용하고 있는 단어들이므로 다른 목적으로 사용할 수 없습니다.

키워드와 똑같은 이름의 변수나 함수를 만들 수 없습니다.

만약 키워드와 같은 이름의 변수를 사용하면 컴파일러는 이것을 변수로 인식하지 않고 키워드로 인식하므로 변수나 함수의 역할을 할 수 없을 것입니다.

C언어의 키워드에는 아래와 같은 것들이 있습니다.

 

auto, case, cdecl, const, char, continue, default, do, double, else, enum,

extern, float, for, goto, if, int, long, register, return, short, signed,

sizeof, static, struct, switch, typedef, union, unsigned, void, volatile,

while, asm, class, delete, friend, inline, mutable, new, operator, private,

protected, public, template, this, virtual, explicit, ....

 

일반적으로 Visual C++에서는 파란색 글씨로 보이게 됩니다.

 

2) 사용자정의 명칭(Identifier)

사용자정의 명칭은 사용자가 직접 만들어서 사용하는 것입니다.

변수나 함수는 다른 것들과 구분되어야 하므로 영역 내에서는 자기만의 고유한 이름을 가져야 합니다.

만약 두 변수가 동일한 영역에서 같은 이름을 가진다면 컴파일러가 이 변수들을 구분하지 못하므로 제대로 컴파일되지 않을 것이다.

폴더 안에 속한 파일 이름들이 다르듯이 C언어에서도 사용자 정의 명칭은 동일한 영역에서 중복해서 사용할 수 가 없습니다.

사용자 정의 명칭은 사용자가 직접 정의하는 것이므로 이름을 자유롭게 붙일 수 있습니다.

입력하기 편리하도록 적당한 길이의 명칭을 작성하는 것이 좋고 최대한 의미를 기억하기 쉽도록 만드는 것이 좋습니다.

사용자정의명칭은 자유롭게 정의할 수 있으나 몇 가지 제약사항이 따릅니다.

① 키워드는 쓸 수 없습니다.

키워드는 C언어 자체가 이미 사용하고 있는 단어이기 때문에 명칭으로 사용해서는 안됩니다.

② 알파벳, 숫자, _ 로 구성됩니다.

그 외의 특수한 문자들이나 중간에 공백은 사용할 수 없습니다.

③ 첫 문자는 알파벳이나 _ 만 올 수 있습니다.

숫자는 사용자정의명칭의 중간에는 나올 수 있지만 숫자로 시작할 수는 없습니다.

C언어는 대소문자를 구분합니다.

대문자로 정의한 경우와 소문자로 정의한 경우는 전혀 다른 정의가 됩니다.

3)상수(Constant)

고정된 값을 가지는 것을 말합니다.

5, 10.7, ‘A’, “abc” 처럼 처음부터 고정된 값을 말합니다.

5는 정수상수이며 10.7은 실수상수, ‘A’는 문자상수, “abc”는 문자열 상수입니다.

 

4)연산자(Operator)

계산을 지시하는 기호들을 연산자라고 합니다.

+, -, *, / 같은 사칙 연산자들도 있고 이외에도 관계, 대입, 논리 연산자 등 다양한 연산자가 있습니다.

또한 C 언어만의 고유한 포인터 연산자, 삼항 연산자 등 도 있습니다.

 

5)구두점(Punctuator)

C언어에서 구성 요소를 구분하여 좀 더 분명한 의미를 가지도록 하는 구두점이 있습니다.

쉼표, 따옴표, 괄호, 세미콜론 등이 구두점으로 사용됩니다.

모든 명령의 마지막에는 세미콜론이 와야 합니다.

이 사실은 매우 중요합니다.

처음 C프로그램을 작성하는 분들은 세미콜론에 주의해야 합니다.

 

6)공백 문자(White Space)

스페이스와 탭, 개행(줄 바꿈)코드 등이 공백입니다.

공백 문자는 눈에 보이지 않지만 구성 요소들을 구분하는 아주 중요한 역할을 합니다.

 

7)주석(Comment)

설명을 위해 삽입되는 문자나 문장을 말합니다.

주석은 프로그램을 읽는 사람이 의미를 쉽게 파악할 수 있도록 설명을 붙여 놓는 것입니다.

어려운 부분이거나 보충설명이 필요한 부분 등에 대해서는 주석으로 설명을 달아 놓을 수 있습니다.

여러 줄의 주석은 /*로 시작해서 */로 끝나고 한 줄 주석을 쓰고 싶을 때는 //를 사용합니다.

주석은 컴파일러가 번역하지 않으므로 한글과 영문 모두 가능합니다.

프로그램을 작성할 경우에는 주석을 삽입하여 다른 사람이 알아보기 쉽게 하고 차후에 자신이 자신의 프로그램을 수정하는 경우에도 사용할 수 있으므로 습관화 하는게 좋습니다.

주석은 이외에도 에러가 발생한 경우 특정부분을 주석 처리하여 에러를 찾는데도 이용하기도 합니다.

 


 

다음이 주석을 활용한 예제입니다.

1-3 실습예제

/*

두개의문장을출력하는예제

*/

#include <stdio.h>

int main()

{

        printf("안녕하세요\n");

        printf("반갑습니다\n");

        //\n 은줄을바꿔주는제어문자입니다.

        system("pause");

        return 0;

}

 


 

8. 프로그램 작성 규칙

1) C언어는 대소문자를 구분하므로 키워드나 명칭 등을 작성할 때 대소문자 구분에 유의해야 합니다.

변수를 선언할 때는 Score로 선언해 놓고 쓸 때는 score로 쓰면 이 변수는 선언되지 않은 것으로 취급됩니다.

또한 main Main으로 써도 안되며 예약어들도 대소문자에 맞게 써야 한다.

INT num; 이라고 쓰면 안됩니다.

C의 예약어들은 모두 소문자입니다.

 

2) C 프로그램은 항상 main 함수로 시작합니다.

C는 함수 위주의 언어이며 필요한 함수를 자유롭게 만들어 쓸 수 있는데 함수 중에 반드시 있어야 하는 함수가 바로 main 함수입니다.

main은 프로그램의 시작점이 되며 이름이 고정되어 있습니다.

컴파일러는 main에서부터 실행을 시작합니다.

하나의 프로젝트에 반드시 하나의 main()만 존재해야 합니다.

 

3) 모든 문장은 세미콜론으로 끝이 나는데 세미콜론은 자연어의 마침표에 해당합니다.

컴파일러는 세미콜론을 기준으로 어디서 어디까지가 한 문장인지를 구분하므로 모든 명령 끝에 반드시 세미콜론을 달아 주도록 해야 합니다.

 

4) C언어는 프리 포맷(Free Format)을 지원합니다.

문법에만 맞으면 한 줄에 붙여 쓸 수도 있고 여러 줄에 나누어 쓸 수도 있습니다.

조금 여백을 주기 위해 괜히 한 줄을 비워 둘 수도 있으며 들여쓰기나 공백의 개수도 편한 대로 작성할 수 있습니다.

 

연습문제) 자기 자신의 이름을 출력하는 프로그램을 작성하시오.

#include <stdio.h>

int main()

{

         printf("박 문석\n");

         system("pause");

         return 0;

}


:
Posted by 에너지발전소
2010. 5. 24. 20:52

[12일차]Protocol Objective-C2010. 5. 24. 20:52


6. 프로토콜의 정합성 여부확인
* 재정의하면 안되는 메서드
+(BOOL)conformsToProtocol:@protocol(프로토콜이름)
                                         ==>대신에 프로토콜클래스 객체를 이용해도 됨
-(BOOL)conformsToProtocol:@protocol(프로토콜이름)
:호출하는 인스턴스나 클래스가 프로토콜이름에 기재된 프로토콜을 인증하고 있으면 YES 아니면 NO를 리턴
:프로토콜 클래스 객체 얻기
Protocol * 변수명 = @protocol(프로토콜이름)


앞쪽의 프로토콜과 클래스 구현부
    <ProtocolToString>    =>Test<ProtocolToString>


7. 비공식 프로토콜 =>@required (필수), @optional (선택) 로 전향
:
=>NSObject의 카테고리를 생성해서 메서드를 구현해도되고 안해도 되는 형태
=>프로토콜의 인증을 받으려면 프로토콜에 선언되어 있는 모든 메서드를구현


*AutoreleasePool (임시변수 생성시 활용)
1. AutoreleasePool
=>foundation에 속한 클래스읭 인스턴스들은 시스템이 메모리공간을 해제할 수 있도록 AutoreleasePool에 등록이 되어야 합니다.
=>인스턴스들이 release를 호출하지 않아도 pool이 drain을 호출하는 순간 자동적으로 release를 수행
=>AutoreleasePool에 등록하는 방법은 autorelease라는 메서드를 호출하면 됩니다. 현재위치에서 가장 가까운 pool에 등록됨
=>등록을 해도 retainCount에는 변함이 없으며 pool이 drain 될때 retainCount만 1씩 감소

1)생성
NSAutoreleasePool * 변수명 = [[NSAutoreleasePool alloc] init];

2)해제
[변수명 drain];
=>NSAutoreleasePool.h 에 정의 및 구현

* 자동적으로 retainCount가 변하는 경우
=> 강한 참조를 사용하는 collection에 삽입되는 경우 retain을 호출한것과 동일한 효과
=> collection에서 제거되는 경우 release를 호출한것과 동일한 효과
=>Copy메서드를 이용한 복사시에도 retain을 호출하는 효과

ex)retain, alloc, release를 호출하지 않아도 retainCount가 변하는 경우
:
Posted by 에너지발전소
2010. 5. 19. 21:48

[10일차-2]Dictionary Objective-C2010. 5. 19. 21:48

Dictionary
  • Key와 Value로 구성되는 컬렉션
  • Key 값으로 Value를 빠르게 검색합니다.
  • Key와 연결된 Value는 nil 일 수 없습니다.
  • Key는 유일해야하며 일반적으로 NSString 입니다.

1. NSDictionary
+(id)dictionary
+(id)dictionaryWithObject:(id)anObject forKey:(id)aKey
-(id)initWithObjects:(NSArry *)Objects forKeys:(NSArray *)Keys
-(id)initWithObjects:(id *)Objects forKeys:(id*)Keys count:(NSUInteger)count
-(id)initWithObjectsAndKeys:(id)Object,(id)Key,... nil
-(NUInteger)count
-(id)objectForKey:(id)aKey
-(NSArray*)allKeys
-(NSArray*)allValues
-(NSEnumerator *)keyEnumerator
-(NSEnumerator *)objectEnumerator
-(NSArray *)allKeysForObject:(id)anObject

배열을 데이터롤 사용하는 dictionary와 dictionary를 배열로 저장
ex)


2. NSMutableDictionary

  • 삽입과 삭제가 가능한 Dictionary

+(id)DictionaryWithCapacity:size
-(id)initWithCapacity:size
-(void)setObject:(id)anObject forKey:(id)aKey
-(void)removeAllObjects
-(void)removeObjectForKey:key
-(NSArray*)keysSortedByValueUsingSelector:@selector(비교메서드:)

:
Posted by 에너지발전소
2010. 5. 19. 19:10

[10일차]Set 클래스 Objective-C2010. 5. 19. 19:10

Set 클래스
  • 모든 멤버가 순서에 상관없이 저장되고 중복된 데이터는 삽입되지 않는 컬렉션

종류
NSSet
NSMutableSet  // NSSet을 상속
NSCountedSet // NSMutableSet을 상속
                     : 인스턴스와 저장된 개수를 가지고 있는 Set (참조회수 조회시 유용)

1. NSSet 클래스
메서드
+(id)set
// 요소가 포함되지 않는 임시 인스턴스 생성
+(id)setWithObjects:obj1,obj2... ,nil // 중복데이터 배제
// 오브젝트 들을 이용해서 set을 생성
-(id)setWithObjects:obj1,obj2... ,nil // 중복데이터 배제
// 오브젝트 들을 이용해서 set을 초기화
-(id)initWithArray:(NSArray*)array // 중복데이터 배제
-(NSArray *)allObjects; //
-(NSUInteger)count; // 개수를 리턴
-(NSEnumberator *)objectEnumerator; //
--------------------------------------------------------------------------------
#import <foundation/NSSet.h>
#import <foundation/NSString.h>
#import <foundation/NSEnumerator.h>

int main(int argc, const char * argv[])
{
    NSEnumerator * it;
    NSString * element;
    NSSet * setString = [NSSet setWithObjects:@"One",@"Two",@"Three",@"One",nil];

    NSLog(@"setString: ");
    it = [setString objectEnumerator];
    while((element=[it nextObject])!=nil)
    NSLog(@"%@",element);

    NSArray * ar = [NSArray arrayWithObjects:@"One",@"Two",@"Three",@"One",nil];
    setString = [setString initWithArray:ar];
   
    NSLog(@"ar: ");
    it = [ar objectEnumerator];
    while((element = [it nextObject])!=nil)
    NSLog(@"%@",element);
   
    NSLog(@"setString: ");
    it = [setString objectEnumerator];
    while((element =[it nextObject])!=nil)
    NSLog(@"%@",element);
   
    system("pause");
    return 0;
}
--------------------------------------------------------------------------------

2) 멤버의 포함여부와 동일성 여부
-(BOOL)containsObject : obj
-(BOOL)isSubsetOfSet : nsset => nsset에 모든 멤버가 있으면 YES
-(BOOL)intersectsSet : nsset => 공통요소가 있으면 YES
-(BOOL)isEqualToSet : nsset  => 동일한 경우

2. NSMutableSet : 변경가능한 SET
-(id)setWithCapacity:size =>size 만큼 저장할 수 있는 초기 용량으로 새로 생성
-(id)initWithCapacity:size
-(void)addObject:obj
-(void)removeObject:obj
-(void)unionSet:nsset
-(void)minusSet:nsset
-(void)intersectSet:nsset =>공통되지 않은 요소를 제거

3. NSCountSet

  • 중복된 데이터의 경우 count 값을 증가시키는 set
  • obj가 추가된 개수 리턴
:
Posted by 에너지발전소
2010. 5. 18. 21:11

[9일차-2]배열 Objective-C2010. 5. 18. 21:11

배열
1. 배열 객체의 종류
    NSArray : 수정이 불가능한 배열 => 확장과 삽입 삭제등이 불가능
    - 자기가 할당받은 공간을 늘이거나 줄이거나 불가능
    - 인스턴스 변수만 생성가능     
    - 타입이 달라도 생성가능
    NSMutableArray : 수정이 가능한 배열 => 확장이 가능

   전부 NSArray.h에 정의되어 있음

2. NSArray의 생성과 요소접근
   1)생성
      NSArray * 배열명 = [NSArray arrayWithObjects:인스턴스 나열,..... nil];
      -(id)initWithArray:(NSArray*)anArray
   2)C 배열에 복사
      -(void)getObjects:(id*)aBuffer;
   3)요소접근
      [배열명 count]:요소개수 리턴
      [배열이름 objectAtIndex:인덱스]
      [배열이름 indexOfObject:(id)anObject]
       -(id)lastObject

ex)배열의 생성과 접근
--------------------------------------------------------
#import <foundation/foundation.h>
#import <foundation/NSArray.h>
#import <foundation/NSString.h>
#import <foundation/NSValue.h>

int main (int argc, char * argv[])
{
    int i;
    NSNumber * intNumber = [NSNumber numberWithInteger:100];
    NSArray * month = [NSArray arrayWithObjects:@"Janurary",@"Feburary",@"March",@"April",@"May",
                      @"June",@"July",@"August",@"September",@"October",@"November",@"December",intNumber,nil];
                                                                                             // nil은 저장안됨
    NSLog(@"한글         영문");
    NSLog(@"=====        ====");
    for (i = 0;i < [month count]; ++i) // 배열의 요소개수를 리턴
        NSLog(@" %2i월       %@", i+1, [month objectAtIndex:i]);
/*
    for (id T in month)
        NSLog(@"%2i월  %@",i+1,T);
    // 다른 언어의 foreach구문
*/    
    system("pause");
    return 0;
}
/*
for (변수 in 배열)
==> 배열의 모든 요소를 변수에 대입해서 사용
==> dev-C 에서는 인식하지 않음
*/
--------------------------------------------------------
Objective-C에는 기본적으로 다차원 배열이 없음
NSArray를 C스타일의 배열 형태로 변경
--------------------------------------------------------
#import <foundation/NSobject.h>
#import <foundation/NSArray.h>
#import <foundation/NSString.h>

int main(int argc, char *argv[])
{

    NSArray * month = [NSArray arrayWithObjects:@"Janurary",@"Feburary",@"March",@"April",@"May",
                      @"June",@"July",@"August",@"September",@"October",@"November",@"December",nil];
                      // month : NSString * []
    NSString** cArray = malloc(sizeOf(NSString *) * [month count]); // NSString * cArray[12];
    //                         NSString * 타입의 메모리 * 12
    int i;
    for(i=0; i<[month count]; ++i)
    {
       cArray[i] = [month objectAtIndex:i];
    }
   
    free(cArray);
    system("pause");
    return 0 ;
}
--------------------------------------------------------
3. NSArray의 기타 메서드

-(BOOL)isEqualToArray:(id)anObject
  : 배열의 요소 개수와 모든 멤버가 동일하면 YES 아니면 No를 리턴

-(id)firstObjectCommonWithArray:(NSArray*)otherArray
  : 일치하는것 찾으면 첫번째 인스턴스 리턴

-(NSArray*)arrayByAddingObject:(id)anObject
  : 인스턴스를 추가해서 만들어진 배열을 리턴

-(NSArray*)arrayByAddingObjectsFromArray:(NSArray*)anArray
  : 배열을 추가해서 만들어진 배열을 리턴

-(NSArray*)sortedArrayUsingSelector:(SEL)comparator // => 메서드 이름
  : comparator에 지정된 메서드를 기준으로 오름차순 정렬하여 리턴
--------------------------------------------------------
#import <foundation/NSObject.h>
#import <foundation/NSArray.h>
#import <foundation/NSString.h>

int main(int argc, char *argv[])
{
    NSArray * ar = [NSArray arrayWithObjects:@"D", @"F", @"E", nil];

    int i;
    for(i=0; i<[ar count]; ++i)
    {
       NSLog(@"%@",[ar objectAtIndex:i]);
    }

    ar = [ar arrayByAddingObject:@"C"];
    for(i=0; i<[ar count]; ++i)
    {
       NSLog(@"%@",[ar objectAtIndex:i]);
    }
   
    NSArray * ar1 = [NSArray arrayWithObjects:@"A", @"X", @"Y", nil];
    ar = [ar arrayByAddingObjectsFromArray:ar1];
    for(i=0; i<[ar count]; ++i)
    {
       NSLog(@"%@",[ar objectAtIndex:i]);
    }

    NSArray *sortedArray = [ar sortedArrayUsingSelector:@selector(compare:)];
    for(i=0; i<[sortedArray count]; ++i)
   
    {
       NSLog(@"%@",[sortedArray objectAtIndex:i]);
    }
    system("pause");
    return 0;
}
--------------------------------------------------------   

4. NSArray에 메시지 전송

  • 배열의 모든 요소가 특정한 메서드를 수행하게 하고자 하는 경우 사용

-(void)makeObjectsPerform:(SEL)aSelector
  ==> 리시버(메서드를 호출하는 인스턴스)의 모든 요소들에게 aSelector를 수행

-(void)makeObjectsPerform:(SEL)aSelector withObject:(id)anObj
                                                                    매개변수가 있음
--------------------------------------------------------   
#import <foundation/NSObject.h>
#import <foundation/NSArray.h>
#import <foundation/NSString.h>

@interface Test:NSObject
{int val;}
-(id)init:(int) v;
-(void)disp;
@end

@implementation Test
-(id)init:(int) v
{
   self = [super init];
   if(self != nil)
      val = v;
   return self;
}
-(void)disp
{
   NSLog(@"val:%d",val);
}
@end

int main(int argc, char *argv[])
{
   Test * Obj[3]; // 반드시 포인터 배열이어야 함
   // Test ** obj = malloc(sizeOf(Test*)*3); ==> 변수 사용가능, 동적할당 시 활용
   Obj[0] = [[Test alloc]init : 10];
   Obj[1] = [[Test alloc]init : 20];
   Obj[2] = [[Test alloc]init : 30];
  
   NSArray * ar = [NSArray arrayWithObjects:Obj count:3]; //C타입에서는 포인터배열명이거나 이중포인터명이어야함.
   [ar makeObjectsPerform:@selector(disp)];

   Test *temp[3]; // Test ** Temp; temp=malloc(sizeOf(Test*)*[ar count]);
   // sorting을 하고 싶으면 어떻게하지? 여기에는 compare이 없다.
   // compare를 재정의해서 사용
   /* -(int)compare:(Test *)obj
   {
      if(self->val < obj->val)
         return NSOrderedAscending;
   }
   */
   [ar getObjects:temp];
   int i;
   for(i=0; i<3; i++)
   [temp[i] disp];
   system("pause");
   return 0;
}
--------------------------------------------------------    
5. NSMutableArray

  • 배열의 요소인 객체를 제거하거나 삽입할 수 있는 메서드가 제공되는 NSArray의 하위 클래스

메서드
-(id)initWithCapacity:(NSUinteger)numItems // 매개변수 개수만큼 생성
-(void)addObject:(id)anObject
  // numItems의 개수를 가진 배열을 생성
-(void)addObjectFromArray:(NSArray*)otherArray
  // anObject를 마지막에 추가
  // 이 인수의 값이 nil이면 안됨
-(void)insertObject:(id)anObject atIndex:(NSUinteger)index
  // index 번째에 anObject추가
-(void)replace ObjectAtIndex:(NSUinteger)index withObject:(id)anObject
  // index 번째에 object를 anObject로 변경
-(void)setArray:(NSArray*)otherArray
  // 기존내용을 삭제하고 otherArray로 변경
-(void)removeAllObjects
  // 모든요소 제거
-(void)removeLastObjects
  // 마지막 요소 제거
-(void)removeObjectAtIndex:(NSUinteger)index
  // index번째 제거
-(void)removeObject:(id)anObject
  // anObject와 동일한 오브젝트 찾아서 제거 (메모리 주소가 같은)

6. 열거자(Enumerator)

  • C언어의 포인터 변수나 C++의 STL의 iterator처럼 컬렉션(데이터의모임)의 멤버들을 순서대로 접근할 수 있도록 제공해주는 개념

C 언어의 iterator
int ar[4];
int * it = ar;  // 배열 타입과 동일한 Data타입을 써야함.
 it++; // 자신의 데이터 타입 만큼 진행

  • C언어의 포인터와 다른점은 데이터타입에 상관없이 사용할 수 있다는 것입니다.
  • 모든 컬렉션의 데이터타입이 id타입이므로 실제 데이터타입을 지정하지 않아도 됩니다.
  • C++에서는 템플릿을 지정하는 경우가 일반적이지만 이 역시 필요없습니다.

사용방법
NSEnumerator * 인스턴스명 = [컬렉션명 objectEnumerator] // 앞에서부터 리턴
                                                         reverseObjectEnumerator //뒤에서부터 리턴
[인스턴스명 nextObject] => 다음 오브젝트로 진행. 다음이 없으면 nil 리턴

ex)Enumerator를 이용한 Mutable Array의 멤버접근 //insert, remove가 가능한 클래스
------------------------------------------------------------------------
#import <foundation/NSObject.h>
#import <foundation/NSArray.h>
#import <foundation/NSValue.h>
#import <foundation/NSEnumerator.h>
// 위의 클래스 호출은 #import <foundation/foundation.h> 로 대체가능

int main(int argc, char * argv[])
{
    NSMutableArray * mAr = [NSMutableArray arrayWithCapacity:10];
    //arrayWithCapacity 는 NSMutableArray에서만 받을 수 있음
    [mAr addObject : [NSNumber numberWithInteger:1]];
    [mAr addObject : [NSNumber numberWithInteger:3]];
    [mAr addObject : [NSNumber numberWithInteger:5]];
   
    NSEnumerator * it;
    NSNumber * obj;
    it = [mAr objectEnumerator];
    // mAr의 시작 바로위를 가리킴 (BOF)
    int i = 1;
    while((obj = [it nextObject])!=nil)
    {
       NSLog(@"%i 번째:%i",i++,[obj intValue]);
       //  NSLog(@"%i 번째:%@",i++,obj);
    }
    NSLog(@"역순으로 접근하기");
    it = [mAr reverseObjectEnumerator];
    i=1;
    while((obj=[it nextObject])!=nil)
    {
       NSLog(@"%i번째:%i",i++,[obj intValue]);
    }
    system("pause");
    return 0;
}
------------------------------------------------------------------------

:
Posted by 에너지발전소