6 장데이터타입
데이터타입과타입정보
타입구성자
타입동등성
, 타입검사
타입변환
다형성
소개
실세
계
•타입은추상화를지원함
프로
그래
밍언
어프
로그
래밍
언어
구현
유한
추상
화구
체적
표현
Progra
mm
ing L
angua
ges
2
자연
수
실수
int
dat
a
double
dat
a
sizeof(int)
바이
트크
기의
이진
수
sizeof(double)
바이
트크
기의
이진
수
추상
화표
현
2의보
수
IEEE
754
명시적인타입결정
•프로그래밍언어가정적인타입검사를
지원해야할지는여전히논란거리임
유연
성신
뢰성
(보안
성)
여전
히논
란거
리
Progra
mm
ing L
angua
ges
3
타입
없는
언어
엄격
하게
타입
검사
하는
언어
정적타입검사를하는이유
1.수행효율
: 실행시간에타입검사할필요없음
2.번역효율
: 분리컴파일이가능함
3.작성용이성
(코딩효율
): 컴파일시간에타입에러판별
4.보안성과신뢰성
: 수행오류를줄임
5.:
Progra
mm
ing L
angua
ges
4
5.판독성
: 문서화에좋음
6.모호성제거
: 다중적재된이름문제해결
7.설계도구
: 정적인타입검사
8.인터페이스일관성과정확성
: 추상데이터타입이지원
됨
데이터타입의정의
•정의
1–값들의집합
예) Ja
va의데이터타입
int는다음집합을뜻함
Vint= { x
| x
∈ Z
, -2,
147,
483,
648
≤ x
≤ 2
,147
,483
,647
}
•정의
2
Progra
mm
ing L
angua
ges
5
•정의
2–값들의집합과그에상응하는연산자들의집합
예) Ja
va의데이터타입
int는다음집합을뜻함
Vint= { x
| x
∈ Z
, -2,
147,
483,
648
≤ x
≤ 2
,147
,483
,647
}
그리고다음의연산자들의집합을뜻함
F int= { +
, -, *
, … }
•연산자는적절한
“피연산자
”에적용되어야함
타입검사와타입추론
•타입검사
–연산자
(또는서브프로그램
)과피연산자
(또는
매개변수
) 간의타입일관성을결정하는과정
•타입추론
Progra
mm
ing L
angua
ges
6
•타입추론
–표현식에타입을부착하는과정
•타입검사와타입추론은서로의존관계
임
타입구성
•타입구성자
–기반타입들은매개변수없는타입구성자들임
–파생타입들은매개변수들을가지는타입구성자
들기
반타
입(원
시타
입)
파생
타입
arra
y, s
truc
ture
s,타
입구
성자
Progra
mm
ing L
angua
ges
7
•타입선언
–타입에이름을붙임
C의예
)typedef int int10[10];
(원시
타입
)int, d
ouble,
…
arra
y, s
truc
ture
s,…
타입
구성
자
타입
구성
자들
타입시스템
•타입동등성알고리즘
–두개의타입을비교하여서로같은지를결정
함
•타입시스템
Progra
mm
ing L
angua
ges
8
•타입시스템
–타입구성방법
–타입동등성알고리즘
–타입추론과타입검사규칙
언어의타입검사
•엄격결정언어
–번역시간에모든타입에러를찾아냄
(예:
Ada)
•해이타입결정언어
Progra
mm
ing L
angua
ges
9
•해이타입결정언어
–번역시간에타입에러들을찾아내지만
, 몇몇
빠진구석을허용함
(예: C
, C++)
•타입결여언어
–정적인타입시스템이없는언어
안전한프로그램
•타입검사가잘되어있는모든프로그램
은안전하지만
, 그역은성립하지않음
실행
가능
한프
로그
램
합법
적인
프로
그램
(안전
한프
로그
램)
불안
전데이
터를
오염
시키
는에
러를
포함
Progra
mm
ing L
angua
ges
10
(안전
한프
로그
램)
타입
검사
가잘
된프
로그
램
불안
전프
로그
램
단순타입
•단순타입
–원자타입
–다른타입구조를포함하고있지않은타입
•단순타입분류 Pr
ogra
mm
ing L
angua
ges
11
단순
타입
미리
정의
된단
순타
입들
사용
자에
의해
정의
된순
서를
가지
는타
입
열거
타입
부분
범위
타입
정의
된연
산자
들:
•후
행자
•선
행자
•비
교
순서타입들의예
•C 에서의열거타입
enum Color { Red, Green, Blue };
•Ada 에서의열거타입
type Color_Type is (Red, Green, Blue);
Progra
mm
ing L
angua
ges
12
•M
L 에서의열거타입
datatype Color_Type = Red | Green | Blue;
•Ja
va 는열거타입이없음
•Ada 에서의부분범위타입
type Digit_Type is range 0..9;
단순타입에대한몇가지노트
•비교연산자를가지는타입들이라고전부
순서타입은아님
예) Ada 의부동소수점숫자들의부분범위
type Unit_Interval is range 0.0..1.0;
•대부분의단순타입들은하드웨어에의해
Progra
mm
ing L
angua
ges
13
•대부분의단순타입들은하드웨어에의해
직접적으로구현됨
(하드웨어효율성이중
요함
)예
) Ja
va의정수나누기는소수점부분을절사함
으로써구현됨
(x / y) * y + x % y
≡ x
음수
일수
있음
타입구성자
Set
Set
U =
S ⅹ
T집
합구
성
•타입들은값들의집합으로간주할수있고
, 타입구성은집합구성으로간주할수있
음
Progra
mm
ing L
angua
ges
14
Set
S, T
Set
U =
S ⅹ
T집
합구
성
Type
S, T
Type
struct U
{S
…;
T …;
};
타입
구성
데카르트곱
(Car
tesian
Pro
duc
t)
•데카르트곱은쌍
(pai
r)들의집합으로
U ⅹ
V =
{ (u,
v) | u∈
U a
nd v
∈ V
}
p1과
p2의투사함수
(pro
ject
ion
func
tions
)들을가짐
:p
: U ⅹ
V →
U
Progra
mm
ing L
angua
ges
15
p1:
U ⅹ
V →
Up
1((u,
v)) =
up
2: U ⅹ
V →
Vp
2((u,
v)) =
v
•데카르트곱들에상응하는타입구성자들
: 레코드
(구조
) 구성자들
예: C의구조체타입
structIntReal
// IntReal= intⅹ ⅹⅹⅹ
double
{
inti;
double r;
};
Progra
mm
ing L
angua
ges
16
structIntRealx = {1, 2.5};
// x = (1, 2.5) ∈ ∈∈∈
IntReal
x.i
// p1(x)
x.r
// p2(x)
요소
선택
자연
산(구
조체
멤버
연산
)
예: M
L의튜플타입
(2, #"a", 3.14)
(* 타입이
타입이
타입이
타입이
int* char * real 인 인인인튜플튜플튜플튜플
*)
#1
#2
#3
요소
선택
자
Progra
mm
ing L
angua
ges
17
#3 (2, #"a", 3.14) = 3.14
노트
) 객체지향언어에서는
, 레코드타입이클래스로확장
되었음
합집합
•합집합의종류
–비구별합집합
: 일반적인집합연산
–구별합집합
: 구별자
(태그
) 가추가됨
•예
: C 에서의합집합
–비구별합집합
: 집합그자체
Progra
mm
ing L
angua
ges
18
–비구별합집합
: 집합그자체
–구별합집합
: 구조체
(struc
t)안에유니언
(uni
on)
union IntOrReal
{ int i;
double r;
};
enum
Disc {IsInt,IsReal};
struct
IntOrReal
{ enum
Disc which;
union
{ int
i;
double r;
} val;
};
좀더안전한합집합
•Ada의가변레코드
–구별자
(discr
imin
ant)와값
이동시에배정되어야함
•M
L의데이터타입
–열거자가데이터필드를가질
수있음
–case표현식을이용한패턴매
칭
type
Disc
is
(IsInt,
IsReal);
datatypeIntOrReal=
Progra
mm
ing L
angua
ges
19
type
Disc
is
(IsInt,
IsReal);
type
IntOrReal
(which:
Disc)
is
record
case
which
is
when
IsInt
=>
i:integer;
when
IsReal
=>
r:float;
end
case;
end
record;
...
x:
IntOrReal
:=
(IsReal,2.3);
datatypeIntOrReal=
IsIntofint|
IsRealofreal;
...
funprintIntOrRealx=
casexof
IsInt(i)
=>
printInt
i
|
IsReal(r)
=>printReal
r;
합집합에대한노트
•객체지향언어에서는
, 합집합은상속으로바뀜
•C++에서의익명합집합
–C++ 에서는태그이름이없는익명합집합을지원함
Progra
mm
ing L
angua
ges
20
enum
Disc {IsInt,IsReal};
struct
IntOrReal
// C++ only
{ enum
Disc which;
union
{ int
i;
double r;
}; // no member name here
};
부분집합
•일반적으로부분집합은하위타입에의해지원됨
•Ada에서는
, 하위타입과부분범위타입은다름
–하위타입
subtypeIntDigit_Type is integer
range 0..9;
–새로운타입
(이미존재하는타입의부분범위
)
Progra
mm
ing L
angua
ges
21
–새로운타입
(이미존재하는타입의부분범위
)typeDigit_Type is range 0..9;
–가변레코드타입의가변부분을고정시킴
subtypeIRInt is IntOrReal(IsInt);
subtypeIRReal is IntOrReal(IsReal);
•객체지향언어에서는
, 상속은서브타입메커니즘
임
배열들과함수들
•다음의함수를보자
f: U
→ V
만일
U 가순서타입이면
, f 는배열
:U
: 인덱스타입
Progra
mm
ing L
angua
ges
22
U: 인덱스타입
V: 요소타입
f(i)
∈ V
whi
ch i ∈
U
•배열크기문제
–배열의크기는배열의일부일수도있고아닐
수도있음
배열의예
: C/C
++
•배열의크기는배열의일부가아님
–배열패러미터들을보낼때
, 배열의크기도별도의패러미터로
보냄 int array_max (int a[], int size);
–형식인자리스트에서배열표현은포인터임
C
C++
:
Progra
mm
ing L
angua
ges
23
•C 와
C++ 배열선언의작은차이
:–
C 에서배열의크기가리터럴이나상수식도가능하며
, C99와그
이후버전은배열의크기를동적으로설정할수있음
–C++ 에서
, 배열의크기에서배열의크기가리터럴이나상수식도
가능 const int Size = 5;
int x[Size]; /* ok
in C, ok in C++ */
int x[Size*Size]; /* ok
in C, ok in C++ */
C99의가변길이배열
(VLA
) -중요
1.in
t m
ain(
)2.
{3.
int n
= 5
;4.
int a[
n];
4.in
t a[
n];
5.}
•C++에선템플릿라이브러리가강력하므
로필요없음
Progra
mm
ing L
angua
ges
24
배열의예
: Jav
a, A
da
•Ja
va 에서는
,–배열의크기는배열의일부
–배열이동적으로할당가능
함
•Ada 에서의무제한배열
–동적으로크기가정해지는
배열
–배열의크기는변수가선언
될때결정됨
Progra
mm
ing L
angua
ges
25
//
apart
of
Figure
6.3
...
int
[]
x=
new
int[u]
;
//
Dynamic
array
allocation
for
(int
i=
0;
i<
x.length;
i++)
x[i]
=i;
...
typeIntToIntis
array(INTEGERrange<>)
ofINTEGER;
...
declare
x:IntToInt(1..size);
begin
foriinx'rangeloop
x(i):=i;
다차원배열
•다차원배열지원
–다차원배열은배열들의배열로시뮬레이션됨
(C,
C++, J
ava)
–어떤언어들은별도의다차원배열을지원함
(Ada,
FO
RTRAN
): Ada에서는
, x(i,j)
≠ x(i)(j)
Progra
mm
ing L
angua
ges
26
FORT
RAN
): Ada
, x(i,j)
≠ x(i)(j)
•다차원배열의메모리할당
–행
-우선형태
: 배열의배열을선언하는일반적형태
–열
-우선형태
: FO
RTRAN
123
456
행-우
선:
135
246
열-우
선:
다차원배열을보내는방법
•차원값을보내는방법
–배열의크기가배열의일부라면
, 문제없음
–배열의크기가배열의일부가아니라면
, 배열
의크기도같이보내져야함
) C/C
++
2
Progra
mm
ing L
angua
ges
27
•예
) C/C
++ 에서
2차원배열을보내야할
때는
3가지경우를생각할수있음
–2차원의크기를다미리아는경우
–1차원의크기를같이보내야하는경우
–2차원의크기를모두보내야하는경우
2차원의크기를미리알고있음
(중요
)
#include <iostream>
using namespace std;
const int R = 3, C = 3;
int sum(int a[R][C])
{int sum = 0;
for (int i = 0; i < R; ++i)
Progra
mm
ing L
angua
ges
28
for (int i = 0; i < R; ++i)
for (int j = 0; j < C; ++j)
sum += a[i][j];
return sum;
} main()
{int a[R][C] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "1+2+..+9 = " << sum(a) << endl;
}
1차원의크기를패스하는경우
(중요
)
#include <iostream>
using namespace std;
const int R = 3, C = 3;
int sum(int a[][C], int row)
{int sum = 0;
for (int i = 0; i < row; ++i)
Progra
mm
ing L
angua
ges
29
for (int i = 0; i < row; ++i)
for (int j = 0; j < C; ++j)
sum += a[i][j];
return sum;
} main()
{int a[R][C] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "1+2+..+9 = " << sum(a, R) << endl;
}
각각의차원들을패스하는경우
(중요
)
#include <iostream>
using namespace std;
int sum(int a[], int row, int col)
{int sum = 0;
for (int i = 0; i < row; ++i)
for (int j = 0; j < col; ++j)
sum += a[i*col+j];
Progra
mm
ing L
angua
ges
30
sum += a[i*col+j];
return sum;
} const int R = 3, C = 3;
main()
{int a[R][C] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
cout << "1+2+..+9 = " << sum(&(a[0][0]), R, C) << endl;
}
2차원배열에대한노트
(중요
)
•동일함과차이점
(형식인자리스트에서
)–상수
Nint a[N] ≡ int a[] ≡ int *a
–상수
M 과
Nint a[M][N] ≡ int a[][N] ≡ int (*a)[N]
Progra
mm
ing L
angua
ges
31
int a[M][N] ≡ int a[][N] ≡ int (*a)[N]
–주의할것
int a[][N] ≠ int **a
•C/C
++ 에서의선언
–선언이사용방법을의미함
int *a[N];
int (*a)[N];
함수타입
•함수타입은포인터로간주될수있음
•언어의예
–C는함수타입변수를지원함
: 역참조는함수타입변수에대해
암시적으로지원됨
(중요
)typedef int (*IntFunction)(int);
int square(int x) { return x*x; }
Progra
mm
ing L
angua
ges
32
int square(int x) { return x*x; }
IntFunction
f = square;
int evaluate(IntFunction
g, int value)
{ return g(value); }
–Ada9
5 도함수타입변수지원함
–Sm
alltal
k 와
Java
같은순수객체지향언어들은함수변수가없
음•왜냐면객체가함수를포함하고있으므로
, 객체변수로충분함
–C++ : 함수포인터
, 멤버함수포인터
, 함수객체
포인터
(참조
) 타입
•포인터
(참조
) 타입구성자들
–이에상응하는집합구성자들은없음
–특정타입을가리키는모든주소들의집합
–쓰레기수집기가사용되는경우
, 포인터는암시적
임(Jav
a, M
L, S
chem
e 등등
)
Progra
mm
ing L
angua
ges
33
임(Jav
a, M
L, S
chem
e 등등
)•포인터에대한노트
–일부의경우
(특히
C++), 참조와포인터가구별됨
•참조는역참조만가능한상수포인터
double r = 2.3, &s = r;
–C 와
C++ 에서
, 배열은상수포인터
int a[] = {1,2,3,4,5};
a[2] ≡ *(a + 2)
≡ 2[a] // Wow!
순환타입
(Rec
ursive
Typ
es)
•순환타입
–선언에서자신을사용하는
타입
–순환타입에서포인터는유
용함
struct CharList
{ char data;
struct CharList
next;
}; /* illegal! */
union
CharList
{enum
{nothing
}empty;
struct
{char
data;
Progra
mm
ing L
angua
ges
34
•순환타입의크기문제
–어떤언어에서는데이터타
입의크기를번역시간에
다알아야함
{char
data;
union
CharList
next;
}charListNode;
};
/*
still,
illegal!
*/
struct
CharListNode
{char
data;
struct
CharListNode*
next;
};
typedef
struct
CharListNode*
CharList;
/* Now, legal */
데이터타입과환경
완전히동적인환경
순환
타입
전통
적환
경(스
택&
힙)
포인
터로
구현
되는
순환
Progra
mm
ing L
angua
ges
35
순환
타입
일반
적함
수타
입
함수
형언
어
포인
터로
구현
되는
순환
타입
과함
수타
입
알골
스타
일의
언어
C의타입구조
Progra
mm
ing L
angua
ges
36
Java의타입구조
Progra
mm
ing L
angua
ges
37
Ada의단순화된타입구조
Progra
mm
ing L
angua
ges
38
타입동등성
(Typ
e Eq
uiva
lenc
e)
•구조적동치
(Struc
tura
l Eq
uiva
lenc
e)–두개의타입은같은구조를가지면동일함
–같은구조란
, 같은타입생성자와같은요소
타입을의미함
(Nam
e Eq
uiva
lenc
e)
Progra
mm
ing L
angua
ges
39
•이름동치
(Nam
e Eq
uiva
lenc
e)–두개의타입은같은이름을가지면같다고봄
•선언동치
(Dec
lara
tion
Equi
vale
nce)
–같은이름에서파생된타입은같다고봄
복잡하게만드는요소들
•배열크기
–배열타입들의크기는배열타입의일부로간주될수있음
–만일그렇다면
, 배열패러미터의타입검사는문제의소지가있음
•레코드타입의필드명
–다음의두구조체
RecA와
RecB는구조적으로같으나
(char
ⅹ
int), 필드명때문에실제로는다름
Progra
mm
ing L
angua
ges
40
struct RecA
{ char x;
int y;
};
struct RecB
{ char a;
int b;
};
언어예
: Ada
•Ada
–완전히이름동치방식임
•변수
a 와
b 는
a, b: array (1..10) of integer;
타입동치가아님
, 그이유는위의선언이다음과같이
해석되기때문임
Progra
mm
ing L
angua
ges
41
해석되기때문임
a: array (1..10) of integer;
b: array (1..10) of integer;
–새로운타입과서브타입은서로다름
•새로운타입
type Age is new integer;
•서브타입
: 원래의타입과호환가능
subtype Age is integer;
언어예
: C
•구조체와유니언에대해
서는이름동치
•다른경우는
, 구조적동치
•‘typedef’ 은새로운타입
을맨드는게아니라
, 별
struct
A{char
x;
int
y;
};
struct
B{char
x;
int
y;
};
struct
A = C
≠ struct
B
P = R ≠ R
S = T
Age = int
F = G
Progra
mm
ing L
angua
ges
42
을맨드는게아니라
, 별명을만듬
•배열크기는배열타입의
일부가아님
};
typedef
struct
AC;
typedef
C*
P;
typedef
struct
B*
Q;
typedef
struct
A*
R;
typedef
int
S[10];
typedef
int
T[5];
typedef
int
Age;
typedef
int
(*F)(int);
typedef
Age
(*G)(Age);
언어예
: 다른것들
•파스칼
(Pas
cal)
–새로운타입생성자는새로운타입을만듬
–존재하는타입이름을위한새로운타입이름은동등함
•자바
(Jav
a)–
‘typedef’ 구성물이없음
Progra
mm
ing L
angua
ges
43
–‘typedef’ 구성물이없음
–클래스와인터페이스선언은새로운타입이름을만듬
–상속체계를가지고있음
(서브타입
)–배열에대해구조적인동치를제공함
•M
L–
‘datatype’ 은새로운타입을만듬
–‘type’ 구성물은존재하는타입에대한별명임
타입검사
•타입검사의종류
–동적타입검사
–정적타입검사
•약하게타입을검사하는언어들
Progra
mm
ing L
angua
ges
44
•약하게타입을검사하는언어들
•엄격하게타입을검사하는언어들
: 모든타입에러
는실행시간이전에다잡힘
노트
) 어떤언어들은동적인또는정적인타
입검사가사용될지그렇지않을지를일부
러지정하지않고놔두기도함
타입검사의예
•C/C
++
–정적인타입검사
–엄격한타입검사는아님
: 타입변환가능
•Sc
hem
e
Progra
mm
ing L
angua
ges
45
•Sc
hem
e–동적인타입검사그러나엄격함
–미리정의된타입테스트함수들
: number?, s
ymbol?,
…
•Ada
–엄격한타입검사
–배열의한계검사는실행시간에함
: 예외발생
타입검사와타입추론
•타입추론
–주어진표현식의일부에서그표현식의타입을추
론하는과정
•타입검사와타입추론
–타입검사규칙과타입추론규칙은서로얽혀있
Progra
mm
ing L
angua
ges
46
–타입검사규칙과타입추론규칙은서로얽혀있
음e 1
+ e
2
–타입검사규칙은타입동등성알고리즘과긴밀히
연결된타입추론규칙인셈임
–명시적인선언은타입검사에도움이되지만
, 프로그래머에게의무적인건아님
전체
표현
식의
타입
에러
를검
사하
기위
해서
는,
그표
현식
의일
부에
서타
입을
추론
해야
함
타입호환성
(Typ
e Com
patibili
ty)
•타입의옳고그름에대한기준을완화함
배정호환성
(ass
ignm
ent co
mpa
tibili
ty)을위해서
타입
동등
성타
입호
환성
e1+ e2
e1
와e2
는동
등한
타입
이어
야함
e1
와e2
는호
환가
능한
타입
이어
야함
Progra
mm
ing L
angua
ges
47
배정호환성
(ass
ignm
ent co
mpa
tibili
ty)을위해서
는, 정보보존이중요한요구조건임
•언어의예
–Ada:
부분범위타입은원래의기본타입과호환
가능함
–C, J
ava:
수치적인타입들은호환가능함
암시적인타입들
•암시적타입들
–객체들의타입이명시적으로선언되지는않으나
, 암시적으로추
론되는경우
•예제들
–C: 변수와함수들의타입이암시적으로
int (K
&R 버전의경우
)x; /* 암시적으로
암시적으로
암시적으로
암시적으로
int */
Progra
mm
ing L
angua
ges
48
x; /*
int */
f(int x) { return x + 1; } /* int 반환
반환반환
반환
*/
–Pa
scal
: 상수는그리터럴값에서암시적으로타입지정됨
const PI = 3.14159; (* 암시적으로
암시적으로
암시적으로
암시적으로
real *)
•노트–대부분의언어에서리터럴은암시적으로타입지정됨
–만일부분범위타입이허용된다면
, 리터럴은여러타입들을가질
수있음
: 0은
integer이면서만일다음과같은선언이있다면
Digit_Type일수도있음
type Digit_Type is range 0..9;
겹치는타입
(Ove
rlap
pin
g T
ypes
)•값들은겹치는타입을통해여러개의타입으로지정될수있음
–두개의
타입들이같은값들을공유하는경우
•C 언어
,
–어떤언어에서는실행시간타입검사가적용됨
-128
~ -
1
0 ~ 1
27 12
8 ~ 2
55
char
unsigned
char
Progra
mm
ing L
angua
ges
49
–어떤언어에서는실행시간타입검사가적용됨
•Ada에서는
, CONSTRAINT_ERROR가발생할수있음
.subtype SubDigit
is integer range 0..9;
subtyep
NegDigit
is integer range –9..-1;
x: SubDigit;
y: NegDigit;
...
x := y
–겹치는타입을가지는값들은코드를단순화하는데도움이됨
–C 언어에서
, 0
은정수거나포인터타입일수있음
공유되는연산자
(Sha
red O
per
ators
)
•공유되는연산자란다중적재되는연산자를의미함
•공유되는연산자를구별하려면
?–인자
(Arg
umen
t)의타입
•Ja
va에서만일피연산자의크기가정수보다작으면정수연산자가
선택됨
(C/C
++도마찬가지
)
Progra
mm
ing L
angua
ges
50
short x = 2;
x = x + x; // 에러
에러에러
에러?! � ���에러임
에러임
에러임
에러임
x = (short) x + x; // 맞음
맞음맞음
맞음
–반환값의타입
(C++나
Java에선안됨
)•
Ada 의예
function "+"(x,y: Digit_Type) return Digit_Type
is ...
a: Digit_Type
:= 5+7;
C/C
++ 두가지예제
#1
#in
clud
e <io
stre
am>
usin
g n
ames
pace
std
;in
t m
ain(
){
unsigne
d in
t x
= 1
0;un
signe
d in
t x
= 1
0;if
(x <
-1)
cout
<< "작다
\n"
;el
se c
out
<< "크다
\n"
;re
turn
0;
}
Progra
mm
ing L
angua
ges
51
C/C
++ 두가지예제
#2
#in
clud
e <io
stre
am>
usin
g n
ames
pace
std
;in
t m
ain(
){
char
x =
'A';
char
x =
'A';
cout
<< x
<< e
ndl;
cout
<< x
+1
<< e
ndl;
cout
<< x
++ <
< e
ndl;
retu
rn 0
;}
Progra
mm
ing L
angua
ges
52
타입변환
(Typ
e Conv
ersion)
•타입변환의분류
–표현법에따라
•암시적변환
(강압
; co
erci
on)
•명시적변환
(캐스팅
)
–타입의크기에따라
•C 의예
int
x = 3;
x = 2.3 + x / 2; int 승
진pro
motion
(wid
enin
g)
Progra
mm
ing L
angua
ges
53
–타입의크기에따라
•확장변환
•축소변환
–데이터의손
실이생길수있음
double
(wid
enin
g)
int
double
배정
변환
assignm
ent
conv
ersion
(nar
row
ing)
타입변환의노트
•명시적변환의장점
–타입변환이정확히문서화됨
–번역기가다중적재해결을더쉽게함
double max(int, double); // max #1
double max(double, int); // max #2
Progra
mm
ing L
angua
ges
54
double max(double, int); // max #2
...
max(2, 3); // calls what?
max(2, (double)3); // calls max #1
•구조캐스팅
–구조타입의크기가동일해야함
–번역기는단순히메모리를재해석할뿐
포괄적
(Gen
eric
)포인터
(임의의포인터
)
•포괄적포인터는아무거나가리킬수있음
–익명포인터
(void*
in C
)
char *
int *
변환
1
변환
2
void *
Progra
mm
ing L
angua
ges
55
–C에서는양쪽변환이암시적으로가능함
–C++에선변환
1은암시적일수있으나
, 변환
2는명시적이어야함
int *
...
변환
2
변환을위한라이브러리함수
•Ada 의경우
–문자타입의어트리뷰트함수
character'pos('a') --returns 97
character'val(97) --returns 'a'
Java
Progra
mm
ing L
angua
ges
56
•Ja
va 의경우
–In
teger
클래스의변환함수들
String s = Integer.toString(12345);
int i = Integer.parseInt("54321");
엄격한타입검사의틈새
•엄격한타입검사에서비구별집합구현은
틈새가있음
•예
) C++에서내부적으로부울값
true에
대해어떤정수값을사용하는지검사하는
Progra
mm
ing L
angua
ges
57
대해어떤정수값을사용하는지검사하는
경우 u
nion
{ char c;
bool b;
} x;
x.b = true;
cout << static_cast<int>(x.c) << endl;
다형적인타입검사
•기존의타입검사
선언
들타
입정
보를
모음
이름
-타입
Progra
mm
ing L
angua
ges
58
•H
indle
y-M
ilner
타입검사
이름
의사
용타
입정
보추
론
이름
-가장
일반
적인
타입
(주된
타입
)
기존의타입검사기
1.구문트리
(Syn
tax
Tree
)2.노드를타입값으로지정
3.타입검사
(내부적인변
환은허용
)
a[i] + i
+int
Progra
mm
ing L
angua
ges
59
[]
i
ai
int
int
int[]
int
Hin
dle
y-M
ilner
타입추론
a[i] + i
+int
1.구문트리
(Syn
tax
Tree
)2.타입변수배정
3.타입제한사항수집
4.가장일반적인타입판별
Progra
mm
ing L
angua
ges
60
[]
i
ai
β
αβ
γ
= int
= γ[]
= int
= int
= int[]
타입추론에대한노트
•H
indle
y-M
ilner
타입추론의경우
–모든타입변수들은같은타입값으로구체화
되어야한다
(구체화
)–두개의타입변수들은이름을사용하는용례
Progra
mm
ing L
angua
ges
61
–두개의타입변수들은이름을사용하는용례
에따라단일화되어야한다
(단일화
)
단일화
(Uni
ficat
ion)
•단일화
(Uni
ficat
ion)
–두개의타입이단일화될수있는지를검사
•단순한단일화알고리즘이포함하는세가지경우
–타입변수는어떤것이든임의의타입표현과단일화
–임의의두개의타입상수
(int나
char
)는서로동일해야만단일화됨
–임의의두개의타입구성
(배열이나구조체같은타입구성자
)은서로
Progra
mm
ing L
angua
ges
62
–임의의두개의타입구성
(배열이나구조체같은타입구성자
)은서로
동일한타입구성자가적용된것이고그구성요소타입들전부가단일
화될때만단일화
U: t
ype
expre
ssio
n ×
type
expre
ssio
n →
boole
anU
(v, e
) = tru
eU
(c1,
c 2) =
tru
e if
c 1= c
2
false
oth
erw
ise
U(c
1(e 1
1,…,e
1n),
c 2(e
21,…
,e2m
))
= U
(e11
,e21
) an
d …
and
U(e
1n,e
2n)
if c 1
= c
2an
d n
= m
false
oth
erw
ise
다형적타입검사
•H
indle
y-M
ilner
타입시스템에서는다형적타입
검사를구현했음
•다형성
: 하나의이름이동시에하나이상의타입을
가지는것
(중요
!)–
ad h
oc
poly
morp
hism
(ove
rloa
din
g; 다중적재
)
Progra
mm
ing L
angua
ges
63
–ad
hoc
poly
morp
hism
(ove
rloa
din
g; 다중적재
)–
para
met
ric
poly
morp
hism
(H
indle
y-M
ilner
; 템플릿
)•
implic
it p
aram
etric
poly
morp
hism
(암시적매개변수다형성
)•
explic
it p
aram
etric
poly
morp
hism
(명시적매개변수다형성
)
–pur
e poly
morp
hism
(su
bty
pe
poly
morp
hism
; 상속및
가상함수
)
다형성의장점
•단형적인함수
(in C
)int max(int x, int y)
{ return x > y ? x : y; }
–문제
1: max는
int타입에만사용가능
.–문제
2: int타입이
>연산자를가지고있어야함
Progra
mm
ing L
angua
ges
64
–문제
2: int타입이
>연산자를가지고있어야함
int max(int x, int y, int(*gt)(int,int))
{ return gt(x,y) ? x : y; }
–위와같이해도문제
1 은해결되지않음
.•다형성을가진함수
(ML 의예
)fun max(x,y,gt) = if gt(x,y) then x else y;
–x, y의타입과
gt는지정되지않았음에주목
더복잡한예
fun max(x,y,gt) = if gt(x,y) then x else y;
if
xy
gt
def
ine
max
γα
βδ(*)(α,β,γ)
δ
= ε(*)(α,β)
= δ(*)(α,β,ε(*)(α,β))
= α
= α
Progra
mm
ing L
angua
ges
65
call
x
gt
x
y
y
αβ
αβ
γ
= ε(*)(α,β)
= ε(*)(α,β)
ε
= δ(*)(α,β,ε(*)(α,β))
= α
= bool
= bool(*)(α,α)
= bool(*)(α,α)
= α(*)(α,α,bool(*)(α,α))
max의
가장
일반
적인
타입
(주된
타입
)
타입
변수
α 가
여전
이주
된타
입내
에도
존재
하므
로,
여전
히다
형적
임!
다형적타입을구현하는방법
•확장
(Exp
ansion)
–서로다른타입에대해코드의새로운복사본을생성
–코드크기가커지는문제
•박싱
(Box
ing; 책에선
‘상자
’로번역
; 중요
!) 및태깅
(Tag
gin
g)
Progra
mm
ing L
angua
ges
66
(Tag
gin
g)
–모든데이터종류마다태그를붙임
(즉, 스칼라데이터인지아니
면구조적데이터인지
…)
–태깅과역참조의오버헤드가있음
Scalar25
Scalar3.5
Scalar25
Struct
다형적데이터타입은어떤가
?
•다형적데이터타입을구성하기위해서는
, 타입
변수가있어야함
→ 명시적다형성
!•
C에서다음처럼가정하면
typedefstructStackNode
{ ?? data;
node
데이
터의
타입
이선
언되
야함
타입
를지
정하
는변
수메
커니
즘이
있어
야함
Progra
mm
ing L
angua
ges
67
{ ?? data;
structStackNode*next;
} *Stack;
•In
ML,
datatype'a Stack= EmptyStack
| Stackof 'a * ('a Stack)
valx = Stack(3,EmptyStack);
메커
니즘
이있
어야
함
타입
구성
자
데이
터구
성자
타입
은순
환적
으로
정의
가가
능함
C++ 의명시적다형성
(중요
!)
•템플릿구조
template <typename T>
struct StackNode
{ T data;
StackNode<T> * next;
};
•템플릿함수
template <typename T>
T top (Stack<T> s)
{ return
s.theStack->data;
}
Progra
mm
ing L
angua
ges
68
};
template <typename T>
struct Stack
{ StackNode<T> *
theStack;
};
}
•템플릿사용
Stack<int> s;
s.theStack = new
StackNode<int>;
s.theStack->data = 3;
s.theStack->next = 0;
int t = top(s);
// t is now 3
템플릿에대한노트
(중요
!)
•템플릿함수를사용할때
, 타입패러미터
는기술할필요없음
•템플릿구조의변수를사용할때에는
, 타입패러미터를기술해야함
Progra
mm
ing L
angua
ges
69
입패러미터를기술해야함
템플릿함수
max
•M
L 에서는다음과같은다형성함수가있
었음
fun max(x,y,gt) = if gt(x,y) then x else y;
•이런함수는
C++에서다음과같이정의됨
Progra
mm
ing L
angua
ges
70
template <typename T>
T max (T x, T y, bool (*gt)(T,T))
{ return gt(x,y) ? x : y ;
} bool gti (int x, int y)
{ return x > y; }
int larger = max(2,3,gti); // larger is now 3
다른템플릿함수
max
•다음의
max는타입
T가
> 연산자가있다고가정함
template <typename T>
T max (T x, T y)
{ return x > y ? x : y ;
} int larger_i = max(2,3); // OK
Progra
mm
ing L
angua
ges
71
int larger_i = max(2,3); // OK
double larger_d = max(3.1,2.9); // OK
Stack<int> s, t, u;
u = max(s,t);
// 에러
에러에러
에러! Stack 타입에
타입에
타입에
타입에대해서
대해서
대해서
대해서
> 가 가가가정의되어
정의되어
정의되어
정의되어있지
있지있지
있지않음
않음않음
않음
•이러한형태의다형성을암시적
(또는묵시적
) 제약매개
변수다형성이라함
Ada 의제니릭패키지
(포괄적패키지
)•패키지스펙
generic
type T is private;
package Stacks is
type StackNode;
type Stack is access
StackNode;
type StackNode is
•패키지바디
package body Stacks is
function top( s: Stack )
return T
is
begin
return s.data;
end top;
end Stacks;
Progra
mm
ing L
angua
ges
72
type StackNode is
record
data: T;
next: Stack;
end record;
function top( s: Stack )
return T
;
end Stacks;
end Stacks;
•패키지사용
package IntStacks
is new Stacks(integer);
use IntStacks;
s: Stack := new StackNode;
t: integer;
...
s.data := 3;
s.next := null;
t := top(s); --
t is now 3
Ada의제네릭함수
(포괄적함수
)
•함수스펙
generic
type T
is private;
with function gt(x,y:T)
return boolean;
function max (x,y:T) return T;
•함수사용
with max; --
import
...
function maxint is new
max(integer,">");
i: integer;
...
i := maxint(1,2);
Progra
mm
ing L
angua
ges
73
•함수몸체
function max (x,y:T) return T
is
begin
if gt(x,y) then return x;
else return y;
end if;
end max;
i := maxint(1,2);
명시
적제
약매
개변
수다
형성