프로그래밍실습 제 24 강
강의 내용 선형처리기를 이용한 조건부 컴파일 #ifdef : 정의되었다면 #ifndef : 정의되지 않았다면 #else의 삽입: #if, #ifdef, #ifndef에 해당 디버깅을 고려한 선행처리기의 사용 typedef 구조체(structure) 구조체를 이용한 변수의 사용 예 이름 없는 구조체 typedef를 이용한 구조체의 사용 (권장) 구조체의 입출력 예 구조체의 배열
#if 다음의 내용이 참이면 #endif 직전까지의 내용이 포함되어 컴파일되고, 선형처리기를 이용한 조건부 컴파일 (i) #if ... endif : 참이라면 #if 다음의 내용이 참이면 #endif 직전까지의 내용이 포함되어 컴파일되고, 거짓이면 제외되어 컴파일 된다. 다음은 그 예이다. #include<stdio.h> #define KOR 1 #define ENG 0 main() { #if KOR //KOR가 참이라면 printf("안녕하세요?\n"); printf("반갑습니다.\n"); #endif #if ENG //ENG가 참이라면 printf("How are you?\n"); } 출력: 안녕하세요? 반갑습니다.
#ifdef 다음의 매크로가 정의되었다면 #endif 직전까지의 내용이 (ii) #ifdef . . . endif: 정의되었다면 #ifdef 다음의 매크로가 정의되었다면 #endif 직전까지의 내용이 포함되고, 정의되지 않았다면 제외된 채 컴파일 된다. 다음은 그 예이다. #include<stdio.h> #define FRA 1 //매크로 FRA가 정의 됨 #define ENG //매크로 ENG가 정의 됨 main() { #ifdef KOR //매크로 KOR가 정의되었다면 printf("안녕하세요?\n"); #endif #ifdef ENG //매크로 ENG가 정의되었다면 printf("How are you?\n"); } 출력: How are you?
#ifndef 다음의 매크로가 정의되어 있지 않다면 #endif 직전까지의 내용이 (iii) #ifndef : 정의되지 않았다면 #ifndef 다음의 매크로가 정의되어 있지 않다면 #endif 직전까지의 내용이 포함되어 컴파일되고, 정의되어 있다면 제외된 채 컴파일 된다. #include<stdio.h> #define N 100 #define BIG 1000 main() { #ifndef N //매크로 N이 정의되지 않았다면 const int N=25; #endif #ifndef SMALL //매크로 SMALL이 정의되지 않았다면 const int SMALL=1; printf("%d %d %d\n",SMALL,N,BIG); } 출력: 1 100 1000
(iv) #else의 삽입: #if, #ifdef, #ifndef와 함께 사용 가능 #include<stdio.h> #define AAA 10 #define BBB 20 main() { #if AAA==10 && BBB<100 printf("AAA=10이고 BBB<100입니다.\n"); #else printf("AAA=%d BBB=%d\n",AAA,BBB); #endif #ifdef CCC printf("CCC는 정의되어 있습니다.\n"); printf("CCC는 정의되어 있지 않습니다.\n"); } 출력: AAA=10이고 BBB<100입니다. CCC는 정의되어 있지 않습니다.
(v) #elif의 삽입: #if에만 해당 #include<stdio.h> #define NUM 2 main() { #if NUM==0 printf("NUM=0입니다.\n"); #elif NUM==1 printf("NUM=1입니다.\n"); #elif NUM==2 printf("NUM=2입니다.\n"); #elif NUM==3 printf("NUM=3입니다.\n"); #else printf("NUM은 0, 1, 2, 3이 아닙니다.\n"); #endif } 출력: NUM=2입니다.
참고: 디버깅을 고려한 선행처리기의 사용 #include<stdio.h> #define DEBUG 1 main() { int a[10], s, i; for(i=0;i<10;i++) a[i]=i*i+3*i-1; if(DEBUG==1) printf("a[%d]=%d\n",i,a[i]); s+=a[i]; printf("i=%d s=%d\n",i,s); printf("합=%d\n",s); } DEBUG가 1이면 상세한 출력이 나오게 되고, 0이면 최종 합 이외의 불필요한 상세 출력이 나오지 않는다.
앞 예의 변형: #include<stdio.h> #define DEBUG 1 main() { int a[10], s, i; for(i=0;i<10;i++) a[i]=i*i+3*i-1; #if DEBUG==1 printf("a[%d]=%d\n",i,a[i]); #endif s+=a[i]; printf("i=%d s=%d\n",i,s); printf("합=%d\n",s); } 앞의 방법과 유사하나 #if ... #endif를 사용하여 실행파일의 크기를 줄일 수 있고 좀 더 빨리 실행되는 효율적인 프로그램이 된다.
typedef #include<stdio.h> typedef short int INT; //새로 정의된 INT형은 short int형과 같음 typedef double REAL; //새로 정의된 REAL형은 double형과 같음 main() { INT a=2,b=3; REAL c=1.2; INT i=5,j=6; REAL d[3]={-3.4,1.5,2.4}; printf("%d %d\n",a,i); printf("%f %f\n",c,d[1]); } 출력: 2 5 1.200000 1.500000
#include<stdio.h> #include<stdlib.h> #define N 2 main() { typedef의 다양한 용법을 알려주는 예: #include<stdio.h> #include<stdlib.h> #define N 2 main() { typedef float fl; //fl형은 float형 typedef int array[N];//array형은 2개의 원소를 갖는 int형 1차원 배열 typedef double *vector; //vector형은 double형 포인터 fl a=2.1f; array b={1,2}; vector c; c=calloc(N,sizeof(double)); c--; printf("%.2f %d %d %d\n",a,b[0],c[1],c[2]); free(c+1); } 출력: 2.10 1 0 0
참고로 앞의 예는 다음과 같이 typedef를 사용하지 않고 작성할 수 있다. (출력은 같다.) #include<stdio.h> #include<stdlib.h> #define N 2 main() { float a=2.1f; int b[2]={1,2}; double *c; c=calloc(N,sizeof(double)); c--; printf("%.2f %d %d %d\n",a,b[0],c[1],c[2]); free(c+1); }
구조체(structure) 구조체는 관계 있는 여러 변수를 하나로 묶는 역할을 하며, 구조체를 사용하기 예: 학생이름과 시험점수 및 등수를 하나로 묶는 경우 struct student{ char *name; int score; int rank; }; student: 구조체의 이름 name, score, rank: 구조체의 원소(멤버) 주의: 구조체의 정의 마지막에 세미콜론(;)이 필요하다.
구조체를 이용하여 변수를 선언하려면 다음과 같이 한다. struct 구조체이름 변수명; 즉, 앞의 예에서 구조체 이름 student를 정의하였으므로 student형 변수들 a, b를 선언하려면 다음과 같이 한다: struct student a, b; 또한 구조체의 원소(멤버) 값에 접근하려면 점(.) 을 사용한다. 즉, a.name a.score a.rank 등을 이용한다.
구조체를 이용한 변수의 사용 예 예: #include<stdio.h> main() { struct student{ // 구조체의 정의(구조체 이름은 student) char *name; int score; int rank; }; struct student a={"하늘이",95,1},b;//구초체를 사용한 student형 // 변수 선언 및 초기화 b.name="꽃님이"; // 치환문을 사용한 구조체의 원소별 초기화 b.score=80; b.rank=2; printf("이름:%s 점수:%d 순위:%d\n이름:%s 점수:%d 순위:%d\n", \ a.name,a.score,a.rank,b.name,b.score,b.rank); }
출력: 이름:하늘이 점수:95 순위:1 이름:꽃님이 점수:80 순위:2 참고: 앞의 예에서 구조체 정의 및 변수 선언 부분을 다음과 같이 바꿀 수 있다. 예: (구조체의 정의와 동시에 변수 선언을 하는 예) struct student{ char *name; int score; int rank; } a={"하늘이",95,1}, b;//구조체 student의 정의와 동시에 변수 선언 // a는 초기화까지도 진행한 상태임
이름 없는 구조체 예: (바람직하지 않음): #include<stdio.h> main() { struct{ // 이름 없는 구조체 char *name; int score; int rank; } a={"하늘이",95,1},b; // 이름 없는 구조체의 변수 선언 b.name="꽃님이"; // 구조체의 원소별 초기화 b.score=80; b.rank=2; printf("이름:%s 점수:%d 순위:%d\n이름:%s 점수:%d 순위:%d\n", \ a.name,a.score,a.rank,b.name,b.score,b.rank); } 주의: 이 경우는 구조체의 정의와 동시에 사용할 변수 선언이 이루어져야만 하고, 나중에 추가로 변수 선언을 할 수 없으므로 바람직하지 않다. 그러나 다음 예와 같이 typedef를 이용하면 이름 없는 구조체도 유용하게 사용될 수 있다.
typedef를 이용한 구조체의 사용 (권장) #include<stdio.h> main() { typedef struct{ char *name; int score; int rank; } student; // typedef를 이용한 구조체 student의 정의 student a={"하늘이",95,1},b; // student형 변수의 선언 및 초기화 b.name="꽃님이"; // 치환문을 사용한 구조체의 원소 초기화 b.score=80; b.rank=2; printf("이름:%s 점수:%d 순위:%d\n이름:%s 점수:%d 순위:%d\n", \ a.name,a.score,a.rank,b.name,b.score,b.rank); }
주의: 1. 다음 예에서 마지막 줄의 struct를 생략할 수 없다. (C의 경우) struct student{ char *name; int score; int rank; }; struct student a, b; // struct를 생략하면 컴파일시 오류 발생 참고로 C++인 경우에는 다음이 가능하다. student a, b; // C++에서는 struct를 생략할 수 있다.
2. 아래 예와 같이 typedef를 사용하여 구조체를 사용하는 경우 마지막 줄 앞에 struct를 붙이면 안 된다. typedef struct{ char *name; int score; int rank; } student; student a, b; 즉 마지막 줄을 다음과 같이 바꾸면 오류가 발생한다. (C뿐 아니라 C++의 경우에도 오류이다.) struct student a, b; //오류
3. 앞의 예에서 typedef struct{ char *name; int score; int rank; } student; 는 다음과 같은 것이다. typedef struct student{
구조체의 입출력 예 #include<stdio.h> typedef struct{ char name[12]; int score; } student; main() { student a; printf("이름과 점수를 입력하십시오: "); scanf("%s %d",a.name,&a.score); // &의 사용 유무 주의 printf("이름:%s 점수:%d\n", a.name,a.score); } 입출력 예: 이름과 점수를 입력하십시오: 홍길동 90 이름:홍길동 점수:90
구조체의 배열 #include<stdio.h> typedef struct{ char *name; int score; int rank; } student; // typedef를 이용한 구조체의 정의 main() { student a[2]; // student형 일차원 배열의 선언 a[0].name="하늘이"; // 구조체의 원소값 입력 a[0].score=95; a[0].rank=1; a[1].name="꽃님이"; a[1].score=80; a[1].rank=2; printf("이름:%s 점수:%d 순위:%d\n이름:%s 점수:%d 순위:%d\n", \ a[0].name,a[0].score,a[0].rank,a[1].name,a[1].score,a[1].rank); }