제 7 장 자 료 형

Preview:

DESCRIPTION

제 7 장 자 료 형. 7.1 자료형과 형 선언 7.2 단순형 7.3 열거형 7.4 배열 7.5 연상 배열 7.6 레코드 7.7 포인터 자료형 7.8 자료형의 변환 7.9 자료형의 동치. 자 료 형. 7.1 자료형과 형 선언. 자료형. 객체들의 집합과 생성 , 작성 , 소멸 , 수정 , 분해등의 연산들의 집합. 자료형 시스템. 새로운 자료형을 제공 , 변수를 어느 한정된 자료형으로 선언해 주는 설비. 자 료 형. 자료형 범주. 내장 자료형. 사용자 정의 자료형. - PowerPoint PPT Presentation

Citation preview

제 7 장 자 료 형

7.1 자료형과 형 선언7.2 단순형7.3 열거형7.4 배열7.5 연상 배열7.6 레코드7.7 포인터 자료형7.8 자료형의 변환7.9 자료형의 동치

자료형

7.1 자료형과 형 선언

객체들의 집합과 생성 , 작성 , 소멸 , 수정 , 분해등의 연산들의 집합

자 료 형

자료형 시스템

새로운 자료형을 제공 , 변수를 어느 한정된 자료형으로 선언해 주는 설비

기본 자료형

자 료 형

Fortran 77 C Java Ada

INTEGERREAL

LOGICALCHARACTER

DOUBLECOMPLEX

intshortlongfloat

doublechar

intshortbytelongfloat

doublechar

boolean

integerfloat

booleancharacternatural

durationpriority

자료형 범주

내장 자료형사용자 정의 자료형

변수 자료형 선언

정적 자료형 검사명세부를 구현부과 분리프로그램 신뢰성 증가프로그램 판독성 증가

자료형 쟁점 사항

자료형 정보의 바인딩 시점 : 번역 시간 또는 실행 시간강 자료형 (strongly type) : 자료형에 관한 모든 특성들이

컴파일 시간에 확정

자료의 적법성과 동치 관계

자료형의 매개 변수와 매개 변수의 평가 시점

자 료 형

자료형 영역스칼라 형 (scalar type)

상수 값들로 구성 되어 있는 자료형: 정수, 실수, 문자, 논리

구조형 (structured type)

상수 값이 아닌 자료들의 집합: 배열, 레코드

자 료 형

CData Type

기본형 합성형( 파생형 )

산술형무치형

인터페이스

정수적형

signed, unsignedshort

intlong

void

배열포인터 (*)

구조체 (struct)공용체 (union)열거형 (enum)

실수형

char

정수형 문자형 floatdouble

C++Data Type

기본형 합성형( 파생형 )

산술형 무치형인터페이스

정수형 bool

signed, unsignedshort

intlong

floatdouble

논리형

void

배열포인터 (*)

구조체 (struct)공용체 (union)클래스 (class)열거형 (enum)

실수형 문자형

char

JAVAData Type

기본형 참조형

숫자 문자 논리형 배열 클래스 인터페이스

정수형

char

실수

boolean

byteshort

intlong

floatdouble

열거형

enum

자바 5.0 부터 적용되었음

C#Data Type

기본형 참조형

내장기본형 사용자정의형

열거형

구조체 enum

포인터 클래스 배열

정수형 논리형 문자형실수형

sbytebyteshortushortintuintlongulong

bool charfloatdoubledecimal

struct

인터페이스

수치형 (Number)

7.2 단순형

기본 자료형 : 실수 , 정수기계 의존적 빠른 속도 , 호환성 문제

자 료 형

Ada의 시도실수 : 유효자리수 , 범위 , 실수 사이 증분치 선언 가능

type COEF is digits 10 range -1.0… 1.0;- 10 자리의 유효 숫자

type COEF is delta 0.01 range 0.0… 100.0; - 10001 의 숫자 (0.0, 0.01.0.02, .., (00.0)

혼합형 연산 해결피 연산자와 연산 결과에 대한 자료형 표로 제공+ integer real double

integerreal

double

integer real** double***real** real double*double*** double* double

* : ( 실수형 -> 배정도형 ) 후 연산** : ( 정수형 -> 실수형 ) 후 연산*** : ** , * 변환 후 연산

* : ( 실수형 -> 배정도형 ) 후 연산** : ( 정수형 -> 실수형 ) 후 연산*** : ** , * 변환 후 연산

연산 결과의 자료형 미리 결정하여 해당 연산 수행피 연산자가 연산 결과의 자료형과 다르면 결과형으로 변환하여 연산

FOTRAN

P = Q + I/J 전자의 경우 P = Q + REAL (I/J) 후자의 경우 P = Q + REAL (I) / REAL (J)

자 료 형

논리형 (Boolean)값의 영역이 두개의 객체 ( 참과 거짓 ) 로 구성

논리형 연산andornotimpequiv

예 ) ALGOL 60 : true, false ( 수와 혼합 연산 금지 ) PASCAL, Ada : 열거형 false < true PL/I : 수와 혼합 연산 가능 187 + TRUE

자 료 형

문자형

60년대 중반 문자열 자료 요구FOTRAN, ALGOL 60 수치 중심

PL/I : 다양한 문자 처리 기능 제공

DCL A CHAR(10); -> A 길이 10 인 문자열 DCL B CHAR(80) VARYING; -> B 최대 길이 80 인 문자열 DCL C PIC ‘AAXX99’;

자 료 형

PL/I 에서의 문자열 연산( |, INDEX, LENGTH, SUBSTR, TRANSLATE, VERIFY)

PL/I 에서의 문자열 처리 예

DCL A CHAR(15) , (B , C , D) CHAR (20) VARYING ;

연결 연산A = 'WHAT,' | '?' | 'ME' | '?' | 'WORRY?'; A 에 ‘WHAT,?ME?WORRY?' 저장

길이 연산LENGTH(A) 길이 15 반환

자 료 형

부분 문자열 연산 (SUBSTR은 l-value, r-value 존재 )

SUBSTR(A, 7, 2) 'ME' 반환SUBSTR(A, 7, 2) = 'US' A 에 'WHAT,?US?WORRY?' 저장

INDEX(A, B) : A에서 문자열 B의 시작위치 반환 (없으면 0)

자 료 형

VERIFY(A, B) :A에 있으나 B에는 없는 첫 문자 위치 반환VERIFY(GSTRING , ‘ABCDEFGHIJKLMNOPQRSTYVWXYZ')

영문자 아닌 위치 반환

TRANSLATE(A , B , C) :

A에서 C에 있는 모든 문자를 찾아 대응되는 B의 문자로 변환 TRANSLATE(A , '-' , '?')

A를 'WHAT,-ME-WORRY-’ 로 변환

자 료 형

public class CheckString { public static void main(String[] args) { String str1 = " 안녕하세요 ! 자바 공부를 열심히 합시다 ."; String str2 = "hello world!"; System.out.println(" 문자열 : " + str1); System.out.println(" 문자열의 길이 : " + str1.length()); System.out.println("8 번째 문자 : " + str1.charAt(7)); System.out.print(" 인덱스 14 에서 17 까지의 substring : "); System.out.println(str1.substring(14,17 )); System.out.println(" 문자 ' 공 ' 의 인덱스 : " + str1.indexOf(' 공 ')); System.out.print("substring \" 자바 \" 의 시작 인덱스 : "); System.out.println(str1.indexOf(" 자바 ")); System.out.println("\n 문자열 : " + str2); System.out.println(" 문자열을 대문자로 : " + str2.toUpperCase()); }}

Pascal (PL/I 의 문자열 처리 기능 제거 고비용 )char 자료형만 존재문자열 : 문자형 1차원 배열

문자열에 대한 함수 없음

ord(c), chr(x) 함수 제공

Snobol 문자열

1964 년 Farber, Griswold, Polonsky

기계 독립적 (Machine independent)

자 료 형

문자열 연산 사용 예제

연결 연산 - 공백

Y = 'UP’

X = 'HURRY’

Z = XY 문자 연결 연산 ('HURRYUP')

널 문자 배경

X =

자 료 형

패턴 매칭 (Pattern matching) ① [ label ] subject pattern [ : goto ]

/* 레이블은 첫열 시작 */AXIOM = 'SNOBOL IS A NIFTY LANGUAGE'AXIOM 'NIFTY' : S(FOUND) F(NOTFOUND) ‘NIFTY’ 를 발견하면 레이블 FOUND 로 제어 이동

② [label] subject pattern = object [ : goto] /* 삽입 , 소거 , 변경 가능 */

예 ) LOOP AXIOM 'SNOBOL’ = 'APL’ :S(LOOP)

모든 ‘ SNOBOL’ 을 ‘APL’ 로 변환하는 문장LOOP AXIOM ' ' = : S(LOOP) AXIOM 에서 모든 공백을 제거

자 료 형

택일 패턴

PAT= ‘RED’ | ’GREEN’ 변수 PAT 에 ‘RED’ 와 ‘GREEN’ 배정

예 ) SMAPLE = ‘ONE SHOULD NOT EAT GREEN APPLES’

SAMPLE PAT : S(LABEL)

‘GREEN’ 이 매칭되어 LABEL 로 분기

자 료 형

택일과 연결 연산

FANCY = (‘R’ | ‘B’) (’EDS’ | ‘ED’) 패턴으로 사용되는 경우 (REDS, RED, BEDS, BED)

순서로 검사

조건 배정문 (conditional assignment)

SAMPLE FANCY.ITEM : S(FOUND) F(NOTFOUND) 성공시 찾은 문자열이 변수 ITEM 에 ( 이 경우 , REDS, RED, BEDS, BED 중 하나 배정 )

자 료 형

열거 자료형 (enumerated data type)

7.3 열거형

사용되는 자료 집합을 리스트 형태로 정의

자 료 형

동등 관계 , 순서 관계 , 배정 연산 허용프로그래밍 언어의 능력 향상

예 ) PASCAL

type months = (Jan, Feb, Mar, Apr, May, Jun, Jul,Agu, Sep, Oct, Nov, Dec);

var x, y, z : months; x := Jan; y := Jun; if x = y then z := Nov else z := Dec;

자 료 형

순서 관련 연산

Pred (Jun) = May Pred (Jan) = undefined Succ (Jun) = Jul Succ (Dec) = undefined

순서 관련 연산자

Pred (x) : x 이전에 정의된 값 Succ(x) : x 다음에 정의된 값

자 료 형

예 ) Ada

type month is (Jan, Feb, Mar, Apr, May, Jun, Jul,Agu, Sep, Oct, Nov, Dec);

type is (Jun, Jul, Aug); x : months; y : summermonths;

Ada : 다중 정의 허용PASCAL : 다중 정의 불허용다중 정의 : 동일한 상수를 두 열거형의 리터럴 값 사용

자 료 형

자 료 형

구조 자료형 (structured data types)

7.4 배열

여러 자료를 묶여 하나의 단위로 처리하는 자료형

Array - homogeneous data 모임

Record - heterogeneous data 모임

자 료 형

배열 (Array)

이름 , 차원 , 원소형 , 첨자 집합의 형과 범위로 구성첨자

일반적으로 연속적인 정수형 집합참고 ) Pascal : 스칼라 형 사용 ( 실수형 불가 )각 차원 : 하한 (lb)≤ 상한 (ub) 크기 (ub-lb+1)인텍스의 예

Fortran, PL/I, Ada : A(5, 3, 7)Algol60, Algol68, Pascal : A[5,3,7]

/* 함수 호출과 구별 */

배열 첨자의 범위첨자 범위의 하한값

– Java : 0 - Fortran 77, Fortran 90 : 1

첨자 범위 바인딩 기억 장소 할당

장점

정적 배열 정적 정적 효율성

고정 스택 - 동적 배열

정적 실행시간중 기억 장소 공간의 효율성

스택 - 동적 배열 동적 동적 고정 후 변경 불가유연성

힙 - 동적 배열 동적 동적 변경 가능유연성

– C, C++ : static 선언하면 정적 : function 에서 선언하면 고정스택 동적배열

: new 와 delete 사용하면 힙 - 동적배열 - JAVA : 모든 배열은 힙 - 동적배열 .

: 또한 ArrayList List = new ArrayList();※ 힙 - 동적배열 ( 고정 힙 - 동적배열과 힙 - 동적배열로 구분하기로

함 )

자 료 형

배열 첨자의 경계값배열에서 상한 / 하한값 표현예 ) Fortran : 상수 Alogol : 정수 수식 Pascal : 상수 ( 크기가 다른 형이면 다른 자료형 )

type asize 10 = array[1..10] of integer;asize 20 = array[1..20] of integer;

asize 10, asize 20 은 다른 형으로 인식

Pascal에서 크기가 다른 배열들을 매개 변수로 전달시 . 최대 크기의 배열을 사용 (비효율적 )

자 료 형

Fotran

DIMENSION A(100), B(10, 10) A(100) => 1 차원 (100 개 ), A(1), A(2), ..., A(100) B(10, 10) => 2 차원 (100 개 ), B(1,1), B(2,1),… B(10, 10)

배열 첨자에 비 상수 사용 경우 ( 형식 매개 변수 사용 시 )

SUBROUTINE SORT(A, N) DOMENSION (A(N))

Pascal ( 배열의 첨자에 상수명 사용 )

const numberofdays = 30; var day : array[1.. numberofdays] of real; 고정 크기의 배열 , 판독성 , 유지보수 편리성 제공

자 료 형

Ada( 동적 배열 허용 )

type SEQUENCE is array(INTEGER range <>) of FLOAT type SEQREF is access SEQUENCE; P : SEQREF; . . . P := new SEQUENCE(M .. N);

동적 배열 (dynamic array) 허용 언어 Ada, PL/I, Algol60, Simula 등 Heap 에 할당 후 포인터에 배정

배열 저장 순서 ( A(1:2, 1:3) 에 대해 ) 행 우선 (row major) : 대부분 언어 => A(1,1), A(1,2), A(1,3), A(2,1), A(2,2), A(2,3) 열 우선 (column major) : Fortran => A(1,1), A(2,1), A(1,2), A(2,2), A(1,3), A(2,3)

자 료 형

배열 명세표 (descriptor)

배열의 정보 저장 테이블( 배열 이름 , 원소형 , 길이 , 시작 주소 , 차원소 , 각 차원 상 /하한값 )명세표 사용 예

one location

A

1

real

α

-2

2

real A(-2:2)

배열명

첨자 상한

원소형원소 길이

차원수시작주소

첨자 하한

13.

3.4

5.5

21.

14.3

α

α+1

α+2α+3α+4

A(-2)A(-1)

A(0)A(1)A(2)

one location

B

2

integer

β

0

2

integer B(0:2,1:2)

배열명

첨자 상한

원소형원소 길이

차원수시작주소

첨자 하한

13

3

5

21

14

β

β+1

β+2β+3β+4

B(0,1)B(0,2)

B(1,1)B(1,2)B(2,1)

12

첨자 하한첨자 상한

25β+5 B(2,2)

자 료 형

배열 저장 위치 ( 행우선시 )

base : 배열 시작 주소 , s : 원소 크기 1) 1 차원 A(lb1:ub1) 에 대해 loc(A(i)) = base + (i - lb1) * s

= base - lb1 * s + i * s2) 2 차원 A(lb1:ub1, lb2:ub2) 에 대해

loc(B(i, j)) = base+(i-lb1)*(ub2-lb2+1)*s = base-s*lb1*(ub2-lb2_1)-s*lb2

+ j*s + i*s *(ub2-lb2+1)

Pascal배열 첨자 : 실수형 제외한 스칼라형 (정수형 , 열거형 )

var temperature : array[months] of real ; i : months; . . . temperature :=(15.5, 12, 10.4, 29, 45, 65.5, 78, 84,

82, 61, 42, 22.5) ; temperature[May] := 25.5; for i :=Jan to Dec do x := x + temperature[i];

자 료 형

Algol 68[1 : 3] ref [ ] real w

=> 실수형 배열을 가리키는 3 원소 배열

[1: a] real x[1: b] real y[1: c] real z

[1: a] real x[1: b] real y[1: c] real z

w[1] :=xw[2] :=yw[3] :=z

w[1] :=xw[2] :=yw[3] :=z

W

1 a

b

c

x

y

z

< 선언문 > < 배정문 >

< 결과 >

- 이 경우 , W[2][3] <=> y[3]

자 료 형

배열 부분 선택 (w(1:3, 1:5) 에 대해 )slice - 배열의 연속된 일부분slice 표기 예 PL/I : w(3,*), w(*,5) Algol68 : w[3, ], w[ ,5], w[3,5] = w[ ,5][3] APL : w[3; ], w[ ;5] Algol68 : w[3,2:4] = w[3,2], w[3,3], w[3,4

배열 연산Fortran, Algol60 배열 원소에 대한 연산만 가능APL, PL/I, Alogol68 배열 배정 연산

(A<-B, A=B, A:=B)

DCL A(10,10), B(10) 배열 복사 (B = A(i , *))

예 ) PL/I

자 료 형

배열 초기화 (Ada)

type MAT is array(INTEGER range 1 .. 2, INTEGER range 1 .. 2) of INTEGER ;

A : MAT :=((10, 20), (30, 40)) ;A : MAT := (1 => (1 => 1, others => 0), 2 => (2 => 1, others => 0));

자 료 형

배열 자료형 고려 사항

배열 이름과 배열 원소에 대한 구문원소값에 대하여 어떤 자료형이 사용되는가 ?첨자로 어떤 자료형을 사용할 수 있는가 ?배열 크기의 바인딩 시간 ?배열 이름에 대한 주소 결정이 얼마나 복잡하게 되어 있는가?

어떤 형태의 slicing 을 제공하는가 ?배열을 초기화 시키기 위한 어떤 종류의 문장이 허용 되는가?

배열에 대한 내장된 연산은 어떤 종류가 허용되는가 ?

7.5 연상 배열연상 배열 (associative array)

키 값들에 의해서 접근되는 순서를 갖지 않은 데이터 집합체 사용자 - 정의 키들이 배열에 함께 저장

설계시 고려사항원소의 참조형 식과 연상 배열 크기의 바인딩 시간

%salaries = ( “Hong”=>1200000, “Won”=> 2000000, “Kim” => 1500000, “Lee” => 2500000) ;

$salaries = { “Won” } => 2000000 ;

delete $salaries { “Lee”} ;

@salaries = ( ) ;

%salaries = ( “Hong”=>1200000, “Won”=> 2000000, “Kim” => 1500000, “Lee” => 2500000) ;

$salaries = { “Won” } => 2000000 ;

delete $salaries { “Lee”} ;

@salaries = ( ) ;

자 료 형

7.6 레코드- 이질형 요소들의 모임인 자료형

예 ) Pascaltype stock = record name : array[1 .. 30] of char ; price : array[1 .. 365] of real ; dividend : real ; volume : array[1 .. 365] of integer ; exchange : (nyse, amex, nasdaq) end;var newstock, ibm : stock; • stock : 5 개 필드로 구성된 레코드형

• 필드 ① price, volumn : 숫자형 배열 ② name : 문자형 배열 ③ dividend : 실수형 ④ exchange : 열거형 (nyse, amex, nasdaq)• newstock, ibm : 레코드형 (stock) 변수

• stock : 5 개 필드로 구성된 레코드형• 필드 ① price, volumn : 숫자형 배열 ② name : 문자형 배열 ③ dividend : 실수형 ④ exchange : 열거형 (nyse, amex, nasdaq)• newstock, ibm : 레코드형 (stock) 변수

자 료 형

필드 참조 방식

① 필드 ( 변수명 ) name(ibm), price(ibm)[25], dividend(ibm),

volumn(ibm)[25], exchange(ibm)② 변수명 . 필드 (Pascal, Ada) ibm.name, ibm.price[25], ibm.dividend,

ibm.volumn[25], ibm.exchange③ 필드 of 변수명 (Algol68) name of ibm, price[25] of ibm

자 료 형

역사

Cobol 시작 (structure)PL/I

Pascal(record) -> 가변부 (variant part) 추가레코드 초기화 (Algol W, Algol 68, Ada)

var ibm, csc : stock; ibm :=make-stock('IBM', 0 .. 0, 5.25, 0 .. 0, nyse ) ; csc :=make-stock('Computer Science Corp.',

0 .. 0, 0, 0 .. 0, nyse);

With 문 (Pascal)변수명을 생략하는 필드 지정 구문

newstock.name :="dec";newstock.dividend :=36;newstock.exchange :=amex;

newstock.name :="dec";newstock.dividend :=36;newstock.exchange :=amex;

with newstock do begin name :="dec"; dividend :=36; exchange :=amex; end;

with newstock do begin name :="dec"; dividend :=36; exchange :=amex; end;

자 료 형

Ada 의 레코드 사용 예Adatype FLIGHT;

type LISTOFFLIGHTS is access FLIGHT;type FLIGHT is

record FLIGHTNO : INTEGER range

0..100; SOURCE : STRING; DESTINATION : STRING; RETURNFLIGHT : LISTOFFLIGHTS;

end record; X, Y : LISTOFFLIGHTS; . . .

X.RETURNFLIGHTS := Y;

• X.RETURNFLIGHTS : FLIGHT 형을 가리키는 포인터 ( 여기서는 Y 를 가리킴 )• 사용 X.RETURNFLIGHTS.FLIGHTNO X.RETURNFLIGHTS.SOURCE

• X.RETURNFLIGHTS : FLIGHT 형을 가리키는 포인터 ( 여기서는 Y 를 가리킴 )• 사용 X.RETURNFLIGHTS.FLIGHTNO X.RETURNFLIGHTS.SOURCE

자 료 형

가변부 (variant part)- 판별자를 이용한 필드들의 택일 변환 기술

Ada, Pascal- 가변부 : case 문 사용

Pascal 예type listptr =↑listnode ;type listnode = record link : listptr ; case tag : boolean of

false : (data : char); true : (downlink : listptr)

endvar p, q : listptr

Pascal 과 같은 가변부의 사용은 심각한 오류 발생 유도 ( 판별자값만 바뀌고 내용이 변화되지 않은 상태에서 접근하는 경우 )

• 판별자 tag 값에 따라 필드 결정 1) tag = false 이면 data 필드 생성 2) tag = true 이면 downlink 필드 생성

• 다음 문장 가능 p↑.tag := true; p↑.downlink := q; p↑.tag := false; writeln(p↑.data)

• 판별자 tag 값에 따라 필드 결정 1) tag = false 이면 data 필드 생성 2) tag = true 이면 downlink 필드 생성

• 다음 문장 가능 p↑.tag := true; p↑.downlink := q; p↑.tag := false; writeln(p↑.data)

포인터와 포인터 변수

7.7 포인터 자료형

포인터 - 객체에 대한 참조

자 료 형

포인터 변수 - 객체를 참조하기 위한 주소를 값으로 취하는 식별자

필요성실행 시간까지 크기 ( 개수 ) 를 알수 없는 자료( 동적 기억 장소 할당 )다중 관계 (multiple relationship)

자 료 형

문제점다수의 포인터가 동일 객체 지시 => 이명

포인트 되지 않은 객체 존재 => 현수 참조

포인터 변수 : x-value( 객체를 가리킴 ) l-value

Dangling reference - Pascal, PL/I 발생 가능 Algol 68 발생 불가

자 료 형

예 ) Pascal ( 예외 - forward reference)

type nodeptr = ↑node;node = record

number : real;next : nodeptr

end

var x, y : nodeptr; x, y : nodeptr 형의 포인터 변수 ...

new(x); new(x) : node 형의 객체 생성 (x 의 배정 )...

dispose(x) dispose(x) : x 에 배정된 객체 소멸

• x : node 형 객체를 가리키는 포인터 변수 x↑: node 형 객체 x↑.number : x 가 가리키는 객체의 실수부분 x↑.next : x 가 가리키는 객체의 포인터 부분• 연산 - 배정연산 , 동등연산 , 역참조 (dereference)• 포인터 상수 - nil• 수명 (life time) - 생성 (new()) 부터 소멸 (dispose()) 까지

• x : node 형 객체를 가리키는 포인터 변수 x↑: node 형 객체 x↑.number : x 가 가리키는 객체의 실수부분 x↑.next : x 가 가리키는 객체의 포인터 부분• 연산 - 배정연산 , 동등연산 , 역참조 (dereference)• 포인터 상수 - nil• 수명 (life time) - 생성 (new()) 부터 소멸 (dispose()) 까지

자 료 형

예 ) Ada type NODE type NODEPTR is access NODE type NODE is record

NUMBER : REAL;NEXT : NODEPTR;end record;

객체 생성 및 값 배정 (Pascal 과 Ada 비교 )

var P, Q : NODEPTR ; ...new(P) ;P↑. NUMBER := 3 . 54;P↑. NEXT := nil;

var P, Q : NODEPTR ; ...new(P) ;P↑. NUMBER := 3 . 54;P↑. NEXT := nil;

var P, Q : NODEPTR : new NODE(3.54, nil);var P, Q : NODEPTR : new NODE(3.54, nil);

자 료 형

필드 접근과 복사 (Ada 에서의 field 지정 )

Pascal 과 Ada 의 포인터 변수

P.NEXT := Q.NEXT; P.NUMBER := Q.NUMBER;

P.NEXT := Q.NEXT; P.NUMBER := Q.NUMBER; P.all := Q.all;P.all := Q.all;

언 어Pascal

포인터 배정p := q p↑:= q↑

값 배정 필드 지정p↑.필드명

Ada p := q p.all := q.all p.필드명 p := new( 자료형 )[ := 초기값 ];

생성new(p);

자 료 형

EUCLID- 매개변수화 선언 : 실행중 판별자 값이 변함으로써 발생되는 오류 제거

var x : listnode(true)var y :listnode(false)var z : listnode(any)

• x 는 tag 값이 true y 는 tag 값이 false z 은 tag 값이 true 와 false z := y; 가능• tag 초기화 후 배정 불가능

• x 는 tag 값이 true y 는 tag 값이 false z 은 tag 값이 true 와 false z := y; 가능• tag 초기화 후 배정 불가능

위의 예제에서 z := y 는 가능 , y := z 불가 해결법

case discreminating w = z on tag of true => x := w; end false => y := w; endend case

Ada : 매개 변수화 선언에 any 허용 안됨

C 와 C++ 의 포인터

int *ptr;

int a,b;

. . .

ptr = &b;

a = *ptr;

ptr.

.

a

b

참조형C++ 은 참조형이라 불리는 포인터형 제공주로 함수 정의에서 형식 매개 변수를 위해서 사용묵시적으로 항상 역참조 되는 상수 포인터참조형 변수는 상수 정의시 주소값으로 초기화

다른 변수를 참조하도록 변경될 수 없다 .묵시적 역참조는 참조 변수의 주소값에 배정을 허용하지 않는다 .

int result = 0 ;int &ref_result = result ;. . . ref_result = 100;

int result = 0 ;int &ref_result = result ;. . . ref_result = 100;

Java안전성 향상을 위해 포인터 제거

C++ 포인터와 Java 참조 변수 의 차이

C++ - 메모리 주소 참조Java - 클래스 인스턴스 참조

Pointer.c#include "stdio.h"

int main(){

int* s;int* t;int s1 = 10;int t1 = 20;

s = &s1; // 변수 s 초기화t = &t1; // 변수 t 초기화printf("s1 의 주소 : %d\n", &s1);printf("s1 의 값 : %d\n", s1);

printf("t1 의 주소 : %d\n", &t1);printf("t1 의 값 : %d\n", t1);

printf("s 의 값 = s1 의 주소 : %d\n", s);printf("s 가 가르키는 값 = s1 의 값 : %d\n", *s);printf("s 의 주소 : %d\n", &s);printf("s 가 가르키고 있는 주소 = s1 의 주소 : %d\n", *&s); //s 의 값

return 0;}

Pointer.c (C/C++ 포인터의 차이점 )#include <stdio.h>

void main(){int value=100;int *pointer=&value;int &refer=value; // 에러

*pointer=20;

printf("value=%d\n", value);printf("*pointer=%d\n", *pointer);printf("pointer=%#010x\n", pointer);printf("refer=%d\n", refer); // 에러

printf("\n");

refer=30; // 에러

printf("value=%d\n", value);printf("*pointer=%d\n", *pointer);printf("pointer=%#010x\n", pointer);printf("refer=%d\n", refer); // 에러

}

PointerRefer.cpp (C/C++ 포인터의 차이점 )#include <iostream.h>

void main(){int value=100;int *pointer=&value;int &refer=value;

*pointer=20;

cout << "value=" << value << endl;cout << “&value=" << &value << endl;cout << "*pointer=" << *pointer << endl;cout << "pointer=" << pointer << endl;cout << "refer=" << refer << endl;cout << “&refer=" << &refer << endl;

cout << endl;

refer=30;

cout << "value=" << value << endl;cout << “&value=" << &value << endl;cout << "*pointer=" << *pointer << endl;cout << "pointer=" << pointer << endl;cout << "refer=" << refer << endl;cout << “&refer=" << &refer << endl;

}

swap1.c#include <stdio.h>

void swap_val(int, int);void swap_ref(int*, int*);

void main(){int x, y;

x=10;y=20;

printf("x=%d , y=%d\n", x, y);printf("address of x : %#010x\n",&x); // 0x0012ff7cprintf("address of y : %#010x\n",&y); // 0x0012ff78

swap_val(x, y);

printf("x=%d , y=%d\n", x, y);

swap_ref(&x, &y);

printf("x=%d , y=%d\n", x, y);}

swap1.c ( 계속 )// call by valuevoid swap_val(int a, int b){

int temp;

printf("\tswap_val() is called.\n");printf("\taddress of a in swap_val() : %#010x\n",&a);printf("\taddress of b in swap_val() : %#010x\n",&b);

temp=a;a=b;b=temp;

}

// call by referencevoid swap_ref(int *a, int *b){

int temp;

printf("\tswap_ref() is called.\n");printf("\taddress of *a in swap_ref() : %#010x\n",&*a);printf("\taddress of *b in swap_ref() : %#010x\n",&*b);

temp=*a;*a=*b;*b=temp;

}

swap2.c#include <stdio.h>

typedef struct swap{int i;int j;

} swap;

void swap_val(swap);void swap_ref(swap*);

void main(){swap x;

x.i=10;x.j=20;

printf("x.i=%d, x.j=%d\n", x.i, x.j);printf("address of x : %#010x\n", &x); // 0x0012ff78

swap_val(x);

printf("x.i=%d, x.j=%d\n", x.i, x.j);

swap_ref(&x);

printf("x.i=%d, x.j=%d\n", x.i, x.j);}

swap2.c ( 계속 )// call by valuevoid swap_val(swap a){

int temp;

printf("\tswap_val() is called.\n");printf("\taddress of a in swap_val() : %#010x\n",&a);

temp=a.i;a.i=a.j;a.j=temp;

}

// call by referencevoid swap_ref(swap *a){

int temp;

printf("\tswap_ref() is called.\n");printf("\taddress of *a in swap_ref() : %#010x\n",&*a);

temp=a->i;a->i=a->j;a->j=temp;

}

swap1.cpp#include <iostream.h>

class swap{public:

int i;int j;

swap(int, int);};

swap::swap(int arg1, int arg2){i=arg1;j=arg2;

}

void swap_val(swap);void swap_ref(swap*);

void main(){

swap obj(10, 20);

cout << "obj.i=" << obj.i << ", obj.j=" << obj.j << endl;cout << "address of obj : " << &obj << endl; // 0x0012FF74

swap_val(obj);

cout << "obj.i=" << obj.i << ", obj.j=" << obj.j << endl;

swap1.cpp ( 계속 )swap_ref(&obj);

cout << "obj.i=" << obj.i << ", obj.j=" << obj.j << endl;}

// call by valuevoid swap_val(swap a){

int temp;

cout << "\tswap_val() is called." << endl;cout << "\taddress of a in swap_val() :" << &a << endl;

temp=a.i;a.i=a.j;a.j=temp;

}

// call by referencevoid swap_ref(swap *a){

int temp;

cout << "\tswap_ref() is called." << endl;cout << "\taddress of *a in swap_ref() : " << &*a << endl;

temp=a->i;a->i=a->j;a->j=temp;

}

swap2.cpp#include <iostream.h>

class swap{public:

int i;int j;

swap(int, int);};

swap::swap(int arg1, int arg2){i=arg1;j=arg2;

}

void swap_val(swap);void swap_ref(swap&);

void main(){

swap obj(10, 20);

cout << "obj.i=" << obj.i << ", obj.j=" << obj.j << endl;cout << "address of obj : " << &obj << endl; // 0x0012FF74

swap_val(obj);

cout << "obj.i=" << obj.i << ", obj.j=" << obj.j << endl;

swap2.cpp ( 계속 )swap_ref(obj);

cout << "obj.i=" << obj.i << ", obj.j=" << obj.j << endl;}

// call by valuevoid swap_val(swap a){

int temp;

cout << "\tswap_val() is called." << endl;cout << "\taddress of a in swap_val() :" << &a << endl;

temp=a.i;a.i=a.j;a.j=temp;

}

// call by referencevoid swap_ref(swap &a){

int temp;

cout << "\tswap_ref() is called." << endl;cout << "\taddress of &a in swap_ref() : " << &a << endl;

temp=a.i;a.i=a.j;a.j=temp;

}

SwapTest.javaclass Swap{

public int i;public int j;

public Swap(int arg1, int arg2){i=arg1;j=arg2;

}}

public class SwapTest{public static void main(String[] args) {

int x=10, y=20;

System.out.println("x=" + x + ", y=" + y);

swap_val(x, y);

System.out.println("x=" + x + ", y=" + y);

SwapTest.java ( 계속 )Swap obj=new Swap(10, 20);

System.out.println("obj.i=" + obj.i + ", obj.j=" + obj.j);System.out.println("hashcode of obj : "+obj); // Swap@757aef

swap_ref(obj);

System.out.println("obj.i=" + obj.i + ", obj.j=" + obj.j);}

// call by valuepublic static void swap_val(int x, int y){

int temp;

System.out.println("\tswap_val() is called.");

temp=x;x=y;y=temp;

}// call by referencepublic static void swap_ref(Swap obj){

int temp;

System.out.println("\tswap_ref() is called.");System.out.println("\thashcode of obj in swap_ref() : "+obj);temp=obj.i;obj.i=obj.j;obj.j=temp;

}}

자료형 변환 (coercion)- 묵시적 변환 ( 수식 평가나 배정시 발생 )- 명시적 변환 (cast)

7.8 자료형 변환

묵시적 변환- Fortran 등 초기 언어에서 시작 ( 혼합형 연산 )- PL/I : 내장된 모든 자료형에 대한 묵시적 변환 제공

자 료 형

종류축소 변환 (narrowing)- 축소되는 크기로 변환 ( 절단 , 반올림 발생 ) 예 ) 정수형 -> 문자형 , 실수형 -> 정수형

확대 변환 (widening)- 확대되는 크기로 변환 예 ) 문자형 -> 정수형 , 정수형 -> 실수형

스칼라 형 : 형 변환 용이

구조형 , 사용자 정의형 : 거의 불가능

자 료 형

Pascal

var r : real;i: integer; ...i := r; 불가능 • 배정 연산에서 narrowing 불허

( 단 , 부분 영역형에서만 narrowing 허용 )

• i = r 문장에 대해 i := round(r); 또는 i := trunc(r); 으로 표현

• 배정 연산에서 narrowing 불허 ( 단 , 부분 영역형에서만 narrowing 허용 )

• i = r 문장에 대해 i := round(r); 또는 i := trunc(r); 으로 표현

정수에서 실수로 확대 배정 허용 ?정수형의 범위가 실수형의 가수 범위보다 클때

자 료 형

Sample (C 언어 ) #include <stdio.h>

void main(){ int x; int a; float y, z, w1, w2; double w3; char c='A'; float b=10.21; x = 7 / 2; y = (float) 7 / 2; z = 7 / 2; w1 = 7.0 /2; //묵시적 형변환을 통해 float 형에 대입 w2 = (float) (7 / 2); // 정수형 연산 이후에 float 형으로 cast w3 = 7.0 /2 ; a=b; // 묵시적 형변환 printf("x = %d, y = %f, z = %f \n", x, y, z); c++; printf("c = %c\n", c);

printf("w1 = %f\n", w1); printf("w2 = %f\n", w2); printf("w3 = %f\n", w3); printf("a = %d", a);

}

자 료 형

Algol68, Algol-w, Pascal : 주요 공헌 (자료형 )- 사용자 정의 자료형- 강력한 자료형 요구- 문제점 ( 동치 , 적법성 ) 들을 내포

7.9 자료형의 동치

자 료 형

자료형 적법성 (type compatibility)- 객체 형이 특정 문맥에서 정당한지 결정하는 의미적인 규칙

자 료 형

일반적인 규칙① 이름 동치 (name equivalence)

- 함께 선언되거나 또는 동일 식별자 이름으로 선언되면 동일

② 구조 동치 (structural equivalence)- 구성요소가 모든 측면에서 같으면 동일형

* 선언 동치 (declaration equivalence)- 이름 동치에서 함께 선언된 것만을 분리하고자 할 때 사용

예 )type T = array [1 .. 100] of integer;var x, y : array [1 .. 100] of integer; z : array [1 .. 100] of integer; w : T; 규칙 ① : x, y 동치 . w 는 x 나 z 와 다른형

규칙 ② : x, y, z, w 모두 동치

규칙 ① : x, y 동치 . w 는 x 나 z 와 다른형 규칙 ② : x, y, z, w 모두 동치

type T2 = ...;type T1 = T2

예 )

규칙 ① : T1, T2 는 다른 형규칙 ② : T1, T2 는 동치

규칙 ① : T1, T2 는 다른 형규칙 ② : T1, T2 는 동치

type T1 = array[1 . . 100] of real ; T2 = array[1 . . 10, 1 . . 10] of real ;

예 )

규칙 ② : T1 과 T2 는 다른 형 ( 서로 다른 구조임 )

규칙 ② : T1 과 T2 는 다른 형 ( 서로 다른 구조임 )

동치 규칙에 대한 장단점 존재이름 동치 : 단순 명료 , 자료형 이름 정의 강요구조적 동치 : 순서만 다르고 모든 것이 같은

열거형은 동치형 (?)

구조적으로는 같으나 개념이 다른 경우type month = 1 .. 12 ; dozen = 1 .. 12 ; ....

var A : record x , y : real end ;

B : record u , v : real end ;

서로 다른 개념

같은 구조이나 다른 필드 이름

1) Pascal 6000 compiler release 1 : 이름 동치 2) Pascal 6000 compiler release 2 : 구조적 동치 3) Pascal 6000 compiler release 3 : 선언 동치

1) Pascal 6000 compiler release 1 : 이름 동치 2) Pascal 6000 compiler release 2 : 구조적 동치 3) Pascal 6000 compiler release 3 : 선언 동치

선언 동치 (declaration equivalence)함께 선언된 자료형끼리만 동치type stock = record name : array[1 .. 30] of char; dividend : real; price : array[1 .. 365] of real; end;var industrial, utility : stock; transportation : stock;

1) industrial 와 utility : 선언 동치2) industrial, utility 와 transportation : 다른 자료형 3) 구조 동치나 이름 동치 : 세 변수 모두 동치

1) industrial 와 utility : 선언 동치2) industrial, utility 와 transportation : 다른 자료형 3) 구조 동치나 이름 동치 : 세 변수 모두 동치

Recommended