400 likes | 560 Views
처음으로 배우는 C 프로그래밍. 제 5 부 추가적인 화제들 제 12 장 부가 특성. 제 1 절 부가기능. typedef 선언문 이미 존재하는 C 자료형 이름을 다른 이름으로 사용할 수 있게 한다 . typedef float REAL; REAL val; float val; 같은 의미를 갖는다. 제 1 절 부가기능. typedef 의 확장
E N D
처음으로 배우는 C 프로그래밍 제5부 추가적인 화제들 제 12 장 부가 특성
제 1 절 부가기능 • typedef 선언문 • 이미 존재하는 C 자료형 이름을 다른 이름으로 사용할 수 있게 한다. • typedef float REAL; • REAL val; • float val; 같은 의미를 갖는다.
제 1 절 부가기능 typedef의 확장 는 와 같다. • typedef struct { • char name[100]; • int id_num; • }EMP_REC; • EMP_REC employee[74]; • struct { • char name[100]; • int id_num; • } employee[75];
제 1 절 부가기능 • enum 명세자 • 사용자가 정의한 값의 목록인 나열 자료형(enumeration data type)이다. • enum color { red, green, blue}; • color 라는 나열 자료형은 red, green, blue라는 값을 갖는다. • 내부적으로 나열 자료형에 나열된 값들은 0에서부터 시작하여 양의 정수로 순서적으로 치환된다. 예) enum color a, b, c; a = red; b = a; if (c==yellow) printf("\nThe color is yellow");
제 1 절 부가기능 프로그램 12-1 #include <stdio.h> void main(void) { enum color red, green, yellow; enum color crayon = red; /* crayon을 color 형으로 선언하고 red값으로 초기화함 */ printf("\f2 nThe color is %d", crayon); printf("Enter in a value: "); scanf("%d", &crayon); if (crayon == red) printf("The crayon is red. "); else if (crayon == green) printf("The crayon is green. "); else if (crayon == yellow) printf("The crayon is yellow. "); else printf("The crayon is not defined. "); }
제 1 절 부가기능 • 컴파일러에 의해 나열 자료형 값에 대한 정수는 나열 자료형이 생성될 때 특정 정수 값을 할당함으로써 변경될 수 있다. • enum color {red, green = 7, yellow}; • red는 정수 0으로 치환되지만, green과 yellow는 각각 정수 7과 8로 치환된다. • 표준 C 자료형에 적용 가능한 유효범위 규칙(scope rule)이 나열 자료형에도 적용된다. • 나열 자료형에서 사용자가 정의한 자료 값과 정수는 일대일로 대응되므로 cast 연산자를 사용하여 강제로 정수를 사용자 정의 자료 값으로 혹은 사용자 정의 자료 값을 동일한 정수로 변환시킬 수 있다.
제 1 절 부가기능 • 캐스트(casts)표 12-1 산술 연산자의 변환 규칙 규칙 1: 모든 문자와 short 정수 피연산자는 항상 정수로 변환된다. 모든 부동소수점 피연산자는 배정밀도 수로 변환된다. 규칙 2: 하나의 피연산자가 배정밀도 수이면 다른 피연산자는 배정밀도 수로 변환되며 수식의 결과도 배정밀도 수이다. 규칙 3: 하나의 피연산자가 long 형 정수이면 다른 피연산자는 long형 정수로 변환되며 수식의 결과도 long 형 정수이다. 규칙 4: 하나의 피연산자가 부호 없는 정수이면 다른 피연산자는 부호 없는 정수로 변환되며 이 수식의 결과는 부호 없는 정수이다. 규칙 5: 두 피연산자가 int 형이면 변환이 일어나지 않으며 이 수식의 결 과는 정수이다. 이들 규칙은 단계적으로 적용된다.
제 1 절 부가기능 • 자동 형 변환 a = b * d - e % f; • a, b : 정수형(int) • e : short 정수형 • f : long 정수형 • b : 부동 소수점 변수 • 강제 형 변환 • 값을 다른 형으로 변환하기 위한 연산자는 캐스트(cast) 연산자이다. (int)(a * b) • 주의 • a,b는 배정밀도 변수(int)a * b
제 1 절 부가기능 • 조건 수식(conditional expression) • 형태 : expression1 ? expression2 : expression3 • 수식 expression1의 값이 0이 아니면, 즉 참(true)이면 수식 expression2의 값이 구해지고, 그렇지 않으면 수식 expression3의 값이 구해진다. if (hours > 40) rate = 0.045; else rate = 0.02; rate = (hours > 40) ? 0.045 : 0.02;
제 1 절 부가기능 • goto 문 • 프로그램의 실행 제어를 아무 조건 없이 다른 곳으로 넘길 수 있다. if (denom == 0.0) goto err; else result = num / denom; err: printf("Error - Attempted Division by Zero");
제 1 절 부가기능 goto 문의 부적절한 사용 예 if (a == 100) goto first; else x = 20; goto sec; first: x= 50; sec: y= 10; • if (a == 100) • x = 50; • else • x = 20; • y = 10;
제 2 절 비트별 연산자(bitwise operator) • C 언어는 문자, 정수 상수 및 변수의 개개 비트를 조작할 수 있는 기능을 제공한다. • 비트 조작을 실행하기 위해 사용된 연산자를 비트 연산자(bit operator)라 한다.
제 2 절 비트별 연산자(bitwise operator) • AND연산자 (AND operator) • AND 연산자는 두 피연산자간의 비트별 AND 비교를 수행한다. 각 비트별 비교 결과는 비교되어질 두 비트가 1인 경우 1이고 그 이외의 경우는 모두 0이다. 1 0 1 1 0 0 1 1 & 1 1 0 1 0 1 0 1 ----------------- 1 0 0 1 0 0 0 1
제 2 절 비트별 연산자(bitwise operator) • 실행 결과 => 325 ANDed with 263 is 221 #include <stdio.h> void main(void) { int op1 = 0325, op2 = 0263; printf("%o ANDed with %o is %o",op1,op2,op1&op2); }
제 2 절 비트별 연산자(bitwise operator) • AND 연산은 임의의 피연산자로부터 선택된 비트를 제거하거나 혹은 마스킹(masking)하는데 유용하게 사용된다. • op2에 있는 비트 0은 op1에 대응되는 비트를 마스크(mask) 시키고, op2에 있는 비트 1는 op1에 대응되는 비트를 여과시킨다(filtering). • 변수 op2를 마스크라고 한다. op1= x x x x x x x x op2= 0 0 0 0 1 1 1 1 ----------------- 0 0 0 0 x x x x
제 2 절 비트별 연산자(bitwise operator) • 포함 OR 연산자 (inclusive OR operator) • 서로 비교되어질 두 비트들 중 하나라도 1이면 포함 OR 비교의 결과는 1이며, 그렇지 않으면 0이다. 1 0 1 1 0 0 1 1 | 1 1 0 1 0 1 0 1 ----------------- 1 1 1 1 0 1 1 1
제 2 절 비트별 연산자(bitwise operator) • 실행 결과 => 325 ORed with 263 is 367 #include <stdio.h> void main(void) { int op1 = 0325, op2 = 0263; printf("%o ORed with %o is %o",op1,op2,op1|op2); }
제 2 절 비트별 연산자(bitwise operator) • 포함 OR 연산은 선택된 비트를 1로 만들거나 혹은 변하지 않는 비트로 전달하기 위해 사용된다. • op2에 있는 비트 1은 항상 대응되는 결과 비트를 1로 만들고, 비트 0에 대해서는 대응되는 결과 비트를 변하지 않는 op1 비트로 만든다. op1 = x x x x x x x x op2 = 1 1 1 1 0 0 0 0 --------------------- 결과 = 1 1 1 1 x x x x
제 2 절 비트별 연산자(bitwise operator) • 배타 OR 연산자 (exclusive OR operator) • 비교될 두 비트가 서로 다르면 비교 결과는 1이고 그렇지 않으면 그 결과는 0이다. 1 0 1 1 0 0 1 1 ^ 1 1 0 1 0 1 0 1 ----------------- 0 1 1 0 0 1 1 0
제 2 절 비트별 연산자(bitwise operator) • 배타 OR 연산은 변수에 있는 개개 비트의 반대 값 혹은 보수를 취하기 위해 사용될 수 있다. • op2에 있는 1에 의해 원래 비트 값이 보수로 변했고, op2에 있는 0은 원래 비트 값을 그대로 유지한다. op1 = x x x x x x x x op2 = 0 1 0 1 0 1 0 1 --------------------- 결과 = x x x x x x x x
제 2 절 비트별 연산자(bitwise operator) • 보수 연산자 (complement operator) • 보수 연산자 ~는 단항 연산자로 피연산자에 있는 비트 1을 0으로, 비트 0을 1로 바꾼다. • 변수 op1이 이진수로 11001010이면 ~op1은 00110101이다. • 보수 연산자는 피연산자의 임의의 비트를 모두 0으로 만들기 위해 사용될 수 있다. • 예를 들어, op1 = op1 & ~07; (간단하게 op1 &= ~07;)은 op1의 마지막 세 비트 값 모두를 0으로 만든다.
제 2 절 비트별 연산자(bitwise operator) • 서로 다른 크기의 자료 항목 • 비트 연산자 &, |, ^이 서로 다른 크기의 피연산자를 사용하는 경우 길이가 짧은 피연산자의 길이를 증가 시킨다. 그림 12-4 16비트 부호 없는 자료를 32비트 자료로 확장
제 2 절 비트별 연산자(bitwise operator) 그림 12-4 16비트 부호 있는 자료를 32비트 자료로 확장
제 2 절 비트별 연산자(bitwise operator) • 이동 연산자(Shift Operator) • 좌측 이동 연산자(<<)는 피연산자에 있는 비트를 주어진 수만큼 좌측으로 이동시킨다. • 부호 없는 정수에 대해 좌측 이동은 2를 곱한 것과 같다. 그림 12-6 좌측이동 예
제 2 절 비트별 연산자(bitwise operator) • 우측 이동 연산자(>>)는 피연산자에 있는 비트를 주어진 수만큼 우측으로 이동시킨다. 그림 12-7a 부호 없는 수의 우측 이동 예
제 2 절 비트별 연산자(bitwise operator) 그림 12-7b 음수의 산술 우측 이동 예
제 2 절 비트별 연산자(bitwise operator) 그림 12-7c 양수의 산술 우측 이동 예
제 2 절 비트별 연산자(bitwise operator) • 산술 우측 이동에서 우측으로 한번 이동은 2로 나눈 것과 같다. • 논리 이동(logical shift) • 부호 있는 수에 대해 우측 이동 시 빈 비트를 부호 비트로 채우는 대신 빈 비트를 0으로 채우는 경우
제 3 절 매크로 • 동치 관계가 하나 이상의 값, 연산자 혹은 변수로 구성되는 경우 기호명을 매크로(macro)라고 부르고, 기호명 대신에 문장으로 치환하는 것을 매크로 확장(macro expansion) 혹은 매크로 치환(macro substitution)이라 한다. • #define 전처리기가 상수와 연산자를 기호명(symbolic name)과 같게 하기 위해 사용된다. 예) #define SALESTAX 0.05 예)#define FORMAT “The answer is %f” printf(FORMAT, 15.2); • #define 문은 직접적 문장 치환이외에도 인자를 사용하는 동치 문을 정의할 수 있다. 예) #define SQUARE(x) x * x • y = SQUARE(num);와 같은 문장은 전처리기에 의해 y = num * num;으로치환된다.
val = (num1+num2)*(num1+num2) val = SQUARE(num1 + num2); val = num1 + num2 * num1 + num2; 제 3 절 매크로 • 매크로 사용의 주의 #define SQUARE(x) x * x #define SQUARE(x) (x) * (x)
제 4 절 명령 행 인자(command line argument) • 이 장에서 우리는 프로그램이 처음 실행될 때 main() 함수에 인자를 전달하고 저장하는 방법을 설명한다. • 인자는 main() 함수를 포함하여 임의의 함수에 전달될 수 있다.
제 4 절 명령 행 인자(command line argument) • 실행 파일이 showad.exe라면 명령 행 C>showad는 showad.exe라는 프로그램을 실행시킨다. 그림 12-8 showad 프로그램 실행
제 4 절 명령 행 인자(command line argument) • 세 개의 문자열 인자 three blind mice를 main() 함수에 직접적으로 전달하기를 원한다고 가정해 보자. C>showad three blind mice 그림 12-9 메모리에 저장된 명령 행
제 4 절 명령 행 인자(command line argument) • 함수 인자와 같이 main() 함수에 전달된 인자는 함수 정의 시에 선언되어 있어야 한다. • main() 함수에 전달될 인자를 저장하기 위해 두 개의 항목, 즉 수와 배열이 요구된다. • 수는 정수이며, 일반적으로 argc(argument counter의 약어)라는 이름을 갖는다. 배열은 문자열을 저장하기 위한 일차원 배열이며, 일반적으로 argv(argument values의 약어)라는 이름을 갖는다.
제 4 절 명령 행 인자(command line argument) • main() 함수에 전달된 정수, argc는 명령 행의 입력된 항목의 개수를 의미한다. 그림 12-11 argv 배열에 저장된 명령 행의 입력 항목
제 4 절 명령 행 인자(command line argument) 프로그램 12-4 #include <stdio.h> void main(int argc, char *argv[]) { int I; printf("\f2 nThe number of items on the command line is %d", argc); for (i=0; I < argc; I++) { printf("The address stored in argv[%d] is %p”, I, argv[i]); printf("The character pointed to is %c", *argv[i]); } }
제 4 절 명령 행 인자(command line argument) • 프로그램 12-4의 실행 C>showad three blind mice 실행 결과는 다음과 같다. The number of items on the command line is 4 The address stored in argv[0] is FFDA The character pointed to is s The address stored in argv[1] is FFEB The character pointed to is t The address stored in argv[2] is FFF1 The character pointed to is b The address stored in argv[3] is FFF7 The character pointed to is m
제 4 절 명령 행 인자(command line argument) 그림 12-12 메모리에 저장된 명령 행
제 4 절 명령 행 인자(command line argument) 프로그램 12-5 /* 명령 행 인자를 출력하는 프로그램 */ #include <stdio.h> void main(int argc, char *argv[]) { int I; printf("\f2 nThe following arguments were passed to main(): "); for (i=1; I < argc; I++) printf("%s ", argv[i]); printf(""); }
제 4 절 명령 행 인자(command line argument) 프로그램 12-6 /* 명령 행 인자를 수치 자료로 출력하는 프로그램 */ #include <stdio.h> void main(int argc, char *argv[]) { int I; int value; int sum = 0; printf("\f2 nThe following numerical data of the arguments passed to main(): "); for (i=1; I < argc; I++) { value = atoi(argv[i]); sum += value; printf("%d ", value); } printf("\f2 nThe sum of the numerical data is %d", sum); }