프로시저와 함수

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

 

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

 

소스 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 14399
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13033
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 15541
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 21075
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 22305
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 17950
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 38238
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 173751
614 2020년 5월 GM 업데이트 - 여러분의 비즈니스에 길을 열어주세요! 관리자 2020.05.26 315
613 델파이 안드로이드 개발을 위해 OpenJDK 채택 file 김원경 2020.05.25 888
612 엠바카데로 오픈 소스 프로젝트 관리자 2020.05.25 699
611 [10.4 시드니 신기능] 겟잇 패키지 매니저(GetIt Package Manager) 개선 험프리 2020.05.21 593
610 [10.4 시드니 신기능] 컨트롤 개별 VCL 스타일 적용(Per-Control Style) 적용 험프리 2020.05.19 918
609 [10.4 시드니 신기능] 새로운 VCL TEdgeBrowser 컴포넌트 험프리 2020.05.18 22880
608 [고객 사례- 솔루션, 델파이] Beyond Compare - 데이터, 시스템 비교/병합/관리 프로그램 관리자 2020.05.14 741
607 [고객 사례- 솔루션, 델파이] AlignMix - 시각화된 세일즈 관리 도구 관리자 2020.05.12 364
606 [발표자료] 20200429 델파이 Push 메시지 전송 시스템 구현 방법 with 구글 Firebase [3] file 관리자 2020.05.04 1020
605 헬스케어 분야에서의 델파이 - 코로나에 맞서며 file 김원경 2020.04.29 604
604 [고객 사례- 의료, 델파이] COVID-19 격리 대상자 상태 관리 앱 관리자 2020.04.28 643
603 이 달의 기술자료 - 2020년 05월 file 험프리 2020.04.24 349
602 [사례 소개] 데브기어 마이그레이션 유상 컨설팅 사례 험프리 2020.04.22 529
601 델파이용 벡터 컨테이너 file 김원경 2020.04.14 752
600 [프로그래밍 애피타이저] 개발이 처음이거나 비 전공자 분들을 위한 가장 첫 번째 STEP! 관리자 2020.04.13 2449
599 [프로그래밍 애피타이저] 10장 트랜잭션의 정의 file 김원경 2020.04.09 436
598 [프로그래밍 애피타이저] 9장 저장프로시저와 트리거 file 김원경 2020.04.09 582
597 [프로그래밍 애피타이저] 8장 SQL 정의와문법 file 김원경 2020.04.09 658
596 [프로그래밍 애피타이저] 7장 데이터베이스 개념과 용어정의 file 김원경 2020.04.09 749
595 [고객 사례- POS, 주문, 델파이, 모바일] 마리스코스 - 레스토랑 주문 관리&전송 앱 관리자 2020.04.08 607