프로시저와 함수

프로시저와 함수가 왜 필요한가?

 

프로그램을 작성할 때 어떤 특정 업무(비즈니스 로직)를 코드로 구현합니다. 이러한 코드가 한 부분에서만 필요한 것이 아니고 여러 부분에서 필요하다면 아래와 같이 코드를 구현 할 것입니다.

 

소스 A

 Statement1;

 Statement2;

 StateMent3;

 

소스 B

 Statement1;

 Statement2;

 StateMent3;

 

 

  이렇게 작성하면 어떠한 단점이 생길까요? (좋은 프로그램 작성 방법에서 어는 부분이 위반될까요?) 

 

   , 먼저 소스 코드 부분이  길어집니다. 또 하나는 수정이 생기는 경우 각각 수정을 하기 때문에 유지 보수 면에서

  공수가 많이 듭니다. 그래서 자주 사용하는 공통의 코드부분을 모듈화 하는데 이를 루틴 또는 서브루틴 이라고 부릅니다.

 

 프로시저와 함수의 차이점

 

  루틴은 반환 값(리턴)이 있는 루틴과 반환 값이 없는 루틴으로 분리되는데 델파이에서는 전자를 Function(함수),

  후자를 Procedure(프로시저)라고 부릅니다. 선언 시에 이 규칙이 지켜지지 않을 경우 컴파일 오류가 발생합니다.

  참고로 C, C++, 자바의 경우는 Function, Void Function 이라고 부릅니다.

 

 프로시저와 함수 선언 및 코드구현방법

   

  선언(Definetion)은 컴파일러에게 루틴이름 매개변수의 정보 등을 알려주는 작업입니다. 이후에 설명과 예제는 델파이를

  기준로 작성하였으니 참고하십시오. 즉 루틴의 선언 및 구현방법은 프로그래밍 언어에 따라 차이가 있습니다.

 

  또한 델파이 프로그램 구조와 프로젝트를 구성하는 파일들을 먼저 살펴보아야 합니다. 데브기어 동영상 강의를 참조하시면      도움이 될 것입니다. 단 교육 이전의 분들은 여기서는 프로젝트 구조와 파일들은 교육에서 설명합니다.

 

l  선언방법

 

Procedure 프로시저 이름(매개변수이름:매개변수타입, 매개변수이름:매개변수타입..);

 

Function 함수이름(매개변수이름:매개변수타입, 매개변수이름:매개변수타입….):리턴타입

 

 

함수와 프로시저는 0개 이상의 매개변수 목록을 가진다. 여러 개의 매개변수 사용 시 세미콜론(;) 으로 구분하고 같은 자료형 사용 시 쉼표로 구분합니다. 매개변수는 뒤 부분에서 자세히 설명하도록 하겠습니다.

 

델파이 소스인 유니트 파일에서 프로시저와 함수를 선언해 보도록 하겠습니다. 이러한 선언은 어느 곳에 해야 할까요?

  선언은 Interface부분과 Implementation 부분에 선언하실 수 있습니다. Interface 부분은 자기 유니트의 선언 아래 부분은

  물론 외부 유니트에서도 컴파일 하기 전에 바인딩 하여(uses하여) 사용 할 수 있는 영역입니다. 주로 전역변수, 서브루틴들을    선언하는 곳입니다.

 

   Implementation은 원래 인터페이스 선언된 루틴들을 구현하는 곳인데 이 영역에도 함수나 프로시저를 선언할 수 있습니다.       단 여기에 선언된 루틴들은 자기 유니트 선언 이후 부분에서만 사용할 수 있고 외부에서도 사용 할 수 없습니다.

 

  루틴을 선언만하고 컴파일 하시면 다음과 같은 오류 메시지가 표시될 것입니다.

 

   E2065: Unsatisfied forward or external declaration: '%s' (Delphi)

 

  이 오류는 루틴이 선언만 되어 있고 구현부분이 없다는 의미입니다.

 

   이제 루틴을 implementation에 구현해 보도록 하겠습니다.

 

procedure 프로시저이름(매개변수이름: 매개변수타입, 매개변수이름: 매개변수타입, …);

{ 선언부 : 구현부에서 사용할 변수,상수,타입 지정 }

begin

{ 구현부 }

end;

 

function 함수이름(매개변수이름:매개변수타입, 매개변수이름:매개변수타입…): 반환값타입;

{ 선언부 }

begin

{ 구현부 }

Result := 반환값;

end;

 

  위에서 매개변수이름과 타입들은 생략할 수 있습니다. 이를 Short type 라고 합니다. 단 소스의 가독성이나 디버깅 시에

  불편하기 때문에 대부분의 개발자들을 기술합니다. 매개변수이름, 타입이 불일치 시에는 컴파일 오류가 발생합니다.

 

 매개변수란(Parameter) 무엇이고 왜 필요한가?

 

  퇴직금을 계산하는 루틴을 작성한다고 가정해 보겠습니다. 퇴직금은 해당 사원의 급여에 근속연수를 곱한다고 정하겠습니다.

  그럼 루틴을 수행하기 위해 어떠한 정보가 최소한 필요합니까? 네 해당직원의 입사일자, 급여정보가 필요합니다.

  또는 그 직원의 해당 정보를 읽을 수 있는 사원코드가 필요합니다. 이를 해당 루틴의 매개변수라고 부릅니다.

 

  즉 매개변수는  변수의 특별한 한 종류로서프로시저, 함수등과 같은 서브루틴의 인풋으로 제공되는 여러 데이터 중

  하나를 가리키기 위해 사용됩니다. 여기서 서브루틴의 인풋으로 제공되는 여러 데이터들을 전달인자(argument) 라고 부른다.

 

  보통 매개변수의 목록은 서브루틴의 정의 부분에 포함되며, 매번 서브루틴이 호출될 때 마다 해당 호출에서 사용된

  전달인자들을 각각에 해당하는 매개변수에 대입시켜 줍니다.

 

 매개변수의 전달방식

 

  함수 호출 시 인자 전달 방법에는 Call-by-value(값에 의한 호출) Call-by-reference(참조에 의한 호출)이 있다 먼저

  이 둘을  비교하며 설명한 후, 델파이의 인자 전달 방식에 대해서도 설명하겠습니다.

 

l  Call-By-Value (값에 의한 호출)

 

l  Call-By-Reference (참조에 의한 호출)

 

 

 델파이에서의 호출방법

 

l  Call By Value

 

 

Function Add(x,y:integer):integer

 

 

l  Call By Const

 

 

Procedure ShowMessage(const Msg:string)

 

 

l  Call By Reference

 

procedure TForm28.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

begin

 

end;

 

l  Out 매개변수

 

 

Function Test(out sum:integer):integer;

 

 

 

 매개변수 디폴트 값 지정방법

 

  매개변수 선언 시 기본값 지정이 가능합니다. 맨 뒤의 매개변수부터 연속적으로 기본값 지정 가능

 

procedure StrDef(AStr: string = '');

 

procedure StrsDef(AStr1: string = 'a'; AStr2: string = 'b');

 

procedure IntDef(ANum: Integer = 0);

 

procedure IntsDef(ANum1: Integer; ANum2: Integer = 0);

 

procedure IntsDef(ANum1, ANum2: Integer = 0); // 오류발생

 

 

 

 프로시저, 함수 호출 방법

 

<선언>

procedure Helloworld;

 

<코딩>

 

procedure Helloworld;

begin

  ShowMessage(‘안녕하세요’);

end;

 

<호출>

Helloworld;

 

 

 

 함수호출 규칙(Calling Convention)

 

  함수 호출 규칙(calling convention)은 피호출자 함수를 호출하는 과정에서 매개변수를 전달하는 순서 및 매개변수가 사용한      메모리 관리방법 등에 관한 규칙입니다.

 

  루틴을 선언할 때 호출 규칙을 지정할 수 있습니다. 델파이에는 아래와 같은 호출 규칙이 있습니다. 선언하지 않으면

  디폴트인 Regiser 방식으로 호출됩니다.

 

지시어

 

매개변수 전달 순서

 

Clean_Up

 

레지스트리에 매개변수 전달 여부

 

register 

 

Undefined 

 

Undefined

 

Yes

 

pascal

 

Undefined

 

Undefined

 

No

 

cdecl

 

Left-to-Right

 

Caller

 

No

 

stdcall

 

Right-to-Left

 

Routine

 

No

 

safecall

 

Right-to-Left

 

Routine

 

No

 

 

 

  Inline 루틴은 무엇이며 왜 필요한가

 

  아래의 그림은 일반 프로시저나 함수가 호출되는 방법을 표시해 놓은 것 입니다. 함수나 프로시저를 호출 하면 해당

  루틴이 있는 곳으로 점프하여 루틴의 구현 부분을 수행하고 다시 호출 부분으로 돌아와서 다음 문장을 수행하는 것이

  일반적인 호출 방법입니다. 그러한 이 루틴을 자주 호출하는 경우라면 이러한 작업을 반복하기 때문에 프로그램의

  실행 속도가 지연 될 것입니다.

 

인라인함수.png

 

  그래서 루틴을 선언할 때 inline 지시어를 사용하여 선언하면 호출 부분에 코드 부분을 삽입하여 다음과 같이 실행하는

  방법입니다.

 

인라인함수2.png

 

  이렇게 호출하면 루틴 부분으로 이동하여 실행하는 것보다 실행 속도를 빠르게 할 수 있습니다. 루틴 사이즈가 큰 경우는

   inline 함수를 사용하면 전체적으로 프로그램 사이즈가 커지기 때문에 결론적으로 inline 함수는 짧으면서 자주 사용되는

  프로시저, 함수에 사용됩니다.

 

 

 오버로드(overload) 함수

 

      델파이에서는 같은 유니트에 같은 이름의 변수나 루틴들은 선언 할 수가 없습니다. 프로시저, 함수 종류가 다른 경우에도

      같은 이름을 사용하지 못합니다.

 

예를 들어 선언 부분에서 정수형 Add 함수 외에 실수형 Add를 선언하려면 오류가 발생합니다. 만일 Add_int, Add_real

이런식으로 다른 이름으로 각각 선언한다면 호출 시점에 각각의 매개변수의 타입을 체크하여 각각 호출하여야 하는 번거로울 뿐만 아니라 유지 보수 시에 문자 연결하는 Add가 필요한 경우 Add_str 함수를 추가하고 구현함은 물론 호출 부분을 또 수정하셔야 합니다. 이러한 문제를 오버로드 함수를 통해 해결해 보도록 하겠습니다

 

      오버로드란 같은 이름의 함수를 여러 개 정의하고, 매개변수의 유형과 개수를 다르게 하여 다양한 유형의 호출에 응답하게

      하는 방법입니다

 

l  오버로드 함수 선언 

 

function Divide(x,y:integer):integer; overload;
function Divide(x,y:real):extended; overload;

참고: C++자바는 OVERLOAD라는 개념은 동일하나 overload 지시어를 사용하지 않고 선언합니다.

 

 

l 오버로드 함수 호출

 

procedure TForm1.Button7Click(Sender: TObject);

begin

 

  Button7.Caption := IntToStr(Divide(12,4));

 

end;

 

procedure TForm1.Button7Click(Sender: TObject);

begin

 

  Button7.Caption := FloatTostr(Divide(12.0,4.0));

 

end;

 

    첫 번째 호출은 정수형 Divide가 호출되고 두 번째 호출은 실수형 Divide가 호출됩니다

 

    다른 언어나 다른 프로그램에서 공통의 루틴들을 사용할 수 있는 방법은 교육 과정(DLL 작성과 호출)에서

    다루도록 하겠습니다

 

    다운로드 : 6장 프로시저와 함수.pdf

 

 

 


프로그래밍을 제대로 공부해보고 싶다면, 다음 순서로 진행하시는 것을 권장합니다.

 

  1. 프로그래밍 애피타이저 시리즈
  2. [동영상] 데브기어 델파이 기초 시리즈
  3. [오프라인 강의] 델파이/C++빌더 기초 강화
  4. [오프라인 강의] 델파이/C++빌더 윈도우 프로그래밍

 

 

 

 

 

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 7243
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 7080
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 9460
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 14496
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 16250
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 12043
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 31083
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 166958
1201 [프로그래밍 애피타이저] 8장 SQL 정의와문법 file 김원경 2020.04.09 451
1200 [프로그래밍 애피타이저] 7장 데이터베이스 개념과 용어정의 file 김원경 2020.04.09 630
1199 [고객 사례- POS, 주문, 델파이, 모바일] 마리스코스 - 레스토랑 주문 관리&전송 앱 관리자 2020.04.08 468
1198 IBLite 라이브러리 및 라이선스 배포하기 관리자 2020.04.08 219
1197 C++로 UI를 손쉽게 개발해봅시다! 관리자 2020.04.07 911
» [프로그래밍 애피타이저] 6장 프로시저와 함수 file 김원경 2020.04.07 724
1195 [프로그래밍 애피타이저] 5장 메모리의 구조 file 김원경 2020.04.07 502
1194 [프로그래밍 애피타이저] 4장 데이터타입 file 김원경 2020.04.07 257
1193 [프로그래밍 애피타이저] 3장 변수와 상수 file 김원경 2020.04.07 307
1192 [프로그래밍 애피타이저] 2장 컴파일,링크 및 운영체제(Operating System) file 김원경 2020.04.06 333
1191 [프로그래밍 애피타이저] 1장. 컴퓨터프로그램이란 ? file 김원경 2020.04.06 426
1190 2020 년 3 월 GM 업데이트 file 김원경 2020.03.30 601
1189 프로그래밍 언어 인기도 측정의 문제점 file 김원경 2020.03.27 409
1188 이 달의 기술자료 - 2020년 04월 험프리 2020.03.27 236
1187 파이어몽키를 사용하여 멀티 플랫폼/아키텍처 용 소프트웨어 개발 file 김원경 2020.03.25 472
1186 [고객 사례- 의료, 델파이] COVID-19 - 검사 결과 실시간 확인 앱 관리자 2020.03.25 638
1185 [고객사례-솔루션, 델파이] 비디오 오피스(VideoOffice) - 화상회의 솔루션 관리자 2020.03.25 449
1184 [고객사례-사물인터넷, 앱, 델파이] 로봇청소기 제어 앱 '니토 툴리오' 관리자 2020.03.24 251
1183 RAD Studio 10.3.3 안드로이드 앱에서 센서 컴포넌트 사용시 링크 오류 해결방법 김원경 2020.03.18 260
1182 [델파이 안드로이드 64비트 오류 수정] TInAppPurchase 컴포넌트 수정 file 김원경 2020.03.18 252