Upload
fala
View
50
Download
2
Embed Size (px)
DESCRIPTION
처음으로 배우는 C 프로그래밍. 제 5 부 추가적인 화제들 제 12 장 부가 특성. 제 1 절 부가기능. typedef 선언문 이미 존재하는 C 자료형 이름을 다른 이름으로 사용할 수 있게 한다 . typedef float REAL; REAL val; float val; 같은 의미를 갖는다. 제 1 절 부가기능. typedef 의 확장 - PowerPoint PPT Presentation
Citation preview
처음으로 배우는 C 프로그래밍
제 5 부 추가적인 화제들
제 12 장 부가 특성
2
제 1 절 부가기능• typedef 선언문
• 이미 존재하는 C 자료형 이름을 다른 이름으로 사용할 수 있게 한다 .
– typedef float REAL;
• REAL val;
• float val;
같은 의미를 갖는다 .
3
typedef 의 확장
는
와 같다 .
struct {
char name[100];
int id_num;
} employee[75];
typedef struct {char name[10
0];int id_num;
}EMP_REC;EMP_REC employee[74];
제 1 절 부가기능
4
• 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 절 부가기능
5
프로그램 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 절 부가기능
6
제 1 절 부가기능• 컴파일러에 의해 나열 자료형 값에 대한 정수는 나열 자료형이
생성될 때 특정 정수 값을 할당함으로써 변경될 수 있다 .– enum color {red, green = 7, yellow};– red 는 정수 0 으로 치환되지만 , green 과 yellow 는 각각 정수 7 과 8
로 치환된다 .
• 표준 C 자료형에 적용 가능한 유효범위 규칙 (scope rule) 이 나열 자료형에도 적용된다 .
• 나열 자료형에서 사용자가 정의한 자료 값과 정수는 일대일로 대응되므로 cast 연산자를 사용하여 강제로 정수를 사용자 정의 자료 값으로 혹은 사용자 정의 자료 값을 동일한 정수로 변환시킬 수 있다 .
7
제 1 절 부가기능• 캐 스 트 (casts)
표 표 12-1 12-1 산술 연산자의 변환 규칙산술 연산자의 변환 규칙
규칙 규칙 1: 1: 모든 문자와 모든 문자와 short short 정수 피연산자는 항상 정수로 변환된다정수 피연산자는 항상 정수로 변환된다 . . 모든 모든 부동소수점 피연산자는 배정밀도 수로 변환된다부동소수점 피연산자는 배정밀도 수로 변환된다 ..규칙 규칙 2: 2: 하나의 피연산자가 배정밀도 수이면 다른 피연산자는 하나의 피연산자가 배정밀도 수이면 다른 피연산자는 배정밀도 배정밀도 수로 변환되며 수식의 결과도 배정밀도 수이다수로 변환되며 수식의 결과도 배정밀도 수이다 ..규칙 규칙 3: 3: 하나의 피연산자가 하나의 피연산자가 long long 형 정수이면 다른 피연산자는 형 정수이면 다른 피연산자는 longlong형 형 정수로 변환되며 수식의 결과도 정수로 변환되며 수식의 결과도 long long 형 정수이다형 정수이다 ..규칙 규칙 4: 4: 하나의 피연산자가 부호 없는 정수이면 다른 피연산자는 하나의 피연산자가 부호 없는 정수이면 다른 피연산자는 부호 부호 없는 정수로 변환되며 이 수식의 결과는 부호 없는 정수이다없는 정수로 변환되며 이 수식의 결과는 부호 없는 정수이다..규칙 규칙 5: 5: 두 피연산자가 두 피연산자가 int int 형이면 변환이 일어나지 않으며 이 형이면 변환이 일어나지 않으며 이 수식의 결수식의 결 과는 정수이다과는 정수이다 . .
이들 규칙은 단계적으로 적용된다이들 규칙은 단계적으로 적용된다 ..
8
제 1 절 부가기능• 자동 형 변환
a = b * d - e % f;• a, b : 정수형 (int)• e : short 정수형• f : long 정수형• b : 부동 소수점 변수
• 강제 형 변환– 값을 다른 형으로 변환하기 위한 연산자는 캐스트 (cast)
연산자이다 .(int)(a * b)
• 주의– a,b 는 배정밀도 변수
(int)a * b
9
제 1 절 부가기능• 조건 수식 (conditional expression)
– 형태 : expression1 ? expression2 : expression3– 수식 expression1 의 값이 0 이 아니면 , 즉 참 (true) 이면 수식 expres
sion2 의 값이 구해지고 , 그렇지 않으면 수식 expression3 의 값이 구해진다 .
if (hours > 40) rate = 0.045; else rate = 0.02;
rate = (hours > 40) ? 0.045 : 0.02;
10
goto 문프로그램의 실행 제어를 아무 조건 없이 다른 곳으로 넘길 수 있다 .
if (denom == 0.0)goto err;
elseresult = num / denom;
err:printf("Error - Attempted Division by Zero");
제 1 절 부가기능
11
제 1 절 부가기능
if (a == 100)goto first;
else x = 20;goto sec;
first: x= 50;sec: y= 10;
if (a == 100)x = 50;
elsex = 20;
y = 10;
goto 문의 부적절한 사용 예
12
• C 언어는 문자 , 정수 상수 및 변수의 개개 비트를 조작할 수 있는 기능을 제공한다 .
• 비 트 조 작 을 실 행 하 기 위 해 사 용 된 연 산 자 를 비 트 연 산 자 (bit operator) 라 한다 .
연산자 설명& 비트별 AND 연산| 비트별 포함 OR 연산^ 비트별 배타 OR 연산~ 비트별 1 의 보수 연산<< 좌측 이동 연산>> 우측 이동 연산
표 12-2 비트 연산자
제 2 절 비트별 연산자 (bitwise operator)
13
• 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)
14
• 실행 결과 => 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)
15
• 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)
16
• 포함 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)
17
• 실행 결과 => 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)
18
• 포함 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)
19
• 배타 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)
20
• 배타 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)
21
• 보수 연산자 (complement operator)• 보수 연산자 ~ 는 단항 연산자로 피연산자에 있는 비트 1 을 0 으로 ,
비트 0 을 1 로 바꾼다 .• 변수 op1 이 이진수로 11001010 이면 ~op1 은 00110101 이다 .• 보수 연산자는 피연산자의 임의의 비트를 모두 0 으로 만들기 위해
사용될 수 있다 .– 예를 들어 , op1 = op1 & ~07; ( 간단하게 op1 &= ~07;) 은 op1 의
마지막 세 비트 값 모두를 0 으로 만든다 .
제 2 절 비트별 연산자 (bitwise operator)
22
• 서로 다른 크기의 자료 항목• 비트 연산자 &, |, ^ 이 서로 다른 크기의 피연산자를 사용하는 경우
길이가 짧은 피연산자의 길이를 증가 시킨다 .
16 비트
X 는 0 혹은 0 임XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
원래 16 비트16 개의 0 비트
32 비트
그림 12-4 16 비트 부호 없는 자료를 32 비트 자료로 확장
제 2 절 비트별 연산자 (bitwise operator)
23
16 비트
X 는 0 혹은 0 임0XXXXXXXXXXXXXXX
0XXXXXXXXXXXXXXX0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
원래 16 비트16 개의 0 비트
32 비트
부호 비트
16 비트
X 는 0 혹은 0 임1XXXXXXXXXXXXXXX
1XXXXXXXXXXXXXXX1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
원래 16 비트16 개의 1 비트
32 비트
부호 비트
그림 12-4 16 비트 부호 있는 자료를 32 비트 자료로 확장
제 2 절 비트별 연산자 (bitwise operator)
24
• 이동 연산자 (Shift Operator)– 좌측 이동 연산자 (<<) 는 피연산자에 있는 비트를 주어진 수만큼 좌측으로
이동시킨다 .– 부호 없는 정수에 대해 좌측 이동은 2 를 곱한 것과 같다 .
1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 1
1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0
각 비트를 명시된 수 만큼 좌측 이동
좌측이동시 발생한 빈공간을 0 으로 채움
그림 12-6 좌측이동 예
제 2 절 비트별 연산자 (bitwise operator)
25
– 우측 이동 연산자 (>>) 는 피연산자에 있는 비트를 주어진 수만큼 우측으로 이동시킨다 .
1 1 1 1 1 0 0 0 1 0 1 0 1 0 1 1
0 0 0 1 1 1 1 1 0 0 0 1 0 1 0 1
각 비트를 명시된 수 만큼 우측 이동
우측이동시 발생한 빈공간을 0 으로 채움
그림 12-7a 부호 없는 수의 우측 이동 예
제 2 절 비트별 연산자 (bitwise operator)
26
1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 1
1 1 1 1 0 0 0 1 0 0 0 1 0 1 0 1
각 비트를 명시된 수 만큼 우측 이동
우측이동시 발생한 빈공간을 1 로 채움
그림 12-7b 음수의 산술 우측 이동 예
제 2 절 비트별 연산자 (bitwise operator)
27
0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1
각 비트를 명시된 수 만큼 우측 이동
우측이동시 발생한 빈공간을 1 로 채움
그림 12-7c 양수의 산술 우측 이동 예
제 2 절 비트별 연산자 (bitwise operator)
28
• 산술 우측 이동에서 우측으로 한번 이동은 2 로 나눈 것과 같다 .
• 논리 이동 (logical shift) – 부호 있는 수에 대해 우측 이동 시 빈 비트를 부호 비트로 채우는 대신
빈 비트를 0 으로 채우는 경우
제 2 절 비트별 연산자 (bitwise operator)
29
• 동치 관계가 하나 이상의 값 , 연산자 혹은 변수로 구성되는 경우 기호명을 매크로 (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;
으로치환된다 .
제 3 절 매크로
30
• 매크로 사용의 주의
#define SQUARE(x) x * x
val = SQUARE(num1 + num2);
val = (num1+num2)*(num1+num2)
val = num1 + num2 * num1 + num2;
#define SQUARE(x) (x) * (x)#define SQUARE(x) (x) * (x)
제 3 절 매크로
31
• 이 장에서 우리는 프로그램이 처음 실행될 때 main() 함수에 인자를 전달하고 저장하는 방법을 설명한다 .
• 인자는 main() 함수를 포함하여 임의의 함수에 전달될 수 있다 .
제 4 절 명령 행 인자 (command line argument)
32
• 실행 파일이 showad.exe 라면 명령 행 C>showad 는 showad.exe라는 프로그램을 실행시킨다 .
C> showad 인자 없이 main() 에서시작하는 프로그램을실행
실행 파일 showad
main(){
}
그림 12-8 showad 프로그램 실행
제 4 절 명령 행 인자 (command line argument)
33
• 세 개 의 문 자 열 인 자 three blind mice 를 main() 함 수 에 직접적으로 전달하기를 원한다고 가정해 보자 .
C>showad three blind mice
s h o w a d \0 t h r e e \0 b l I n d \0 m i c e \0
그림 12-9 메모리에 저장된 명령 행
제 4 절 명령 행 인자 (command line argument)
34
• 함수 인자와 같이 main() 함수에 전달된 인자는 함수 정의 시에 선언되어 있어야 한다 .
• main() 함수에 전달될 인자를 저장하기 위해 두 개의 항목 , 즉 수와 배열이 요구된다 .– 수는 정수이며 , 일반적으로 argc(argument counter 의 약어 ) 라는
이름을 갖는다 . 배열은 문자열을 저장하기 위한 일차원 배열이며 , 일반적으로 argv(argument values 의 약어 ) 라는 이름을 갖는다 .
제 4 절 명령 행 인자 (command line argument)
35
• main() 함수에 전달된 정수 , argc 는 명령 행의 입력된 항목의 개수를 의미한다 .
•
s h o w a d \0 t h r e e \0 b l i n d \0 m i c e \0
Argv 배열은주소를 포함
s 의 주소
t의 주소
b의 주소
m 의 주소
그림 12-11 argv 배열에 저장된 명령 행의 입력 항목
제 4 절 명령 행 인자 (command line argument)
36
프로그램 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)
37
• 프로그램 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)
38
s h o w a d \0 t h r e e \0 b l I n d \0 m i c e \0
Argv 배열은주소를 포함
s 의 주소= FFDAt의 주소= FFEBb 의 주소= FFF1m 의 주소= FFF7
메모리주소 FFDA FFEB FFF1 FFF7
그림 12-12 메모리에 저장된 명령 행
제 4 절 명령 행 인자 (command line argument)
39
프로그램 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)
40
프로그램 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);
}
제 4 절 명령 행 인자 (command line argument)