절차 파라미터

Procedural parameter

컴퓨팅에서 절차 파라미터는 절차 자체인 절차파라미터입니다.

이 개념은 프로그래머가 라이브러리 프로시저의 특정 단계를 그 프로시저의 코드를 이해하거나 수정할 필요 없이 임의로 복잡한 방법으로 수정할 수 있도록 하기 때문에 매우 강력하고 다용도 프로그래밍 도구입니다.

이 도구는 특히 파스칼과 C현대 GNU 방언과 같은 로컬 함수 정의를 지원하는 언어에서 효과적이고 편리합니다.기능 폐쇄를 사용할 수 있는 경우에는 더욱 그렇습니다.객체 지향 프로그래밍 언어의 객체에는 동일한 기능(및 그 이상)이 제공되지만 비용이 상당히 많이 듭니다.

절차 파라미터는 퍼스트 클래스 함수 및 익명 함수의 개념과 어느 정도 관련되어 있지만 그것들과는 다릅니다.이 두 가지 개념은 함수의 사용 방식보다는 함수의 정의 방식과 더 관련이 있습니다.

기본 개념

이 기능을 제공하는 대부분의 언어에서 서브루틴 P의 프로시저 파라미터 f는 통상적인 프로시저인 것처럼 P의 본문 내에서 호출할 수 있습니다.

순서 P(f): f(6,3)* f(2,1)를 반환한다.

서브루틴 P를 호출할 때는 P가 파라미터 f를 사용하는 방법과 호환되는 정의된 함수를 1개 지정해야 합니다.예를 들면,

프로시저 플러스(x, y): 반환 x + y

그런 다음 P(플러스)를 호출하면 결과는 플러스(6,3) * 플러스(2,1) = (6 + 3)*(2 + 1) = 27이 됩니다.다른 한편으로, 우리가 만약

순서 quot(u, v): u/v를 반환

그러면 콜 P(6,3)*contract(2,1)=(6/3)*(2/1)=4를 반환합니다.마지막으로,

procedure evil(z) z + 100을 반환합니다.

P()는 그다지 의미가 없고, 에러로서 플래그가 붙을 가능성이 있습니다.

구문 상세

이 기능을 가진 일부 프로그래밍 언어에서는 각 절차 파라미터 f(인수의 수 및 유형, 결과 유형(있는 경우)을 포함한 완전한 유형 선언을 허용하거나 요구할 수 있습니다.예를 들어, C 프로그래밍 언어에서 위의 예는 다음과 같이 쓸 수 있습니다.

인트 P(인트 (*f)(인트 a, 인트 b)) {     돌아가다 f(6,3) * f(2,1); } 

원칙적으로 P가 호출되었을 인수로 전달되는 실제 함수 actf는 프로시저 파라미터 f의 선언된 유형과 타입 호환성이 있어야 합니다.이것은 보통 actf와 f가 같은 유형의 결과를 반환하고, 같은 수의 인수를 가져야 하며, 대응하는 인수가 같은 유형을 가져야 함을 의미합니다.단, 위의 더하기 따옴표 예에서 보듯이 인수 이름이 같을 필요는 없습니다.그러나 일부 프로그래밍 언어는 이 점에서 더 제한적이거나 더 자유로울 수 있습니다.

범위 설정

절차 매개 변수를 허용하는 언어에서는 일반적으로 절차 매개 변수가 기본 범위에서 실행되도록 범위 지정 규칙이 정의됩니다.보다 정확하게는 함수 actfP에 인수로서 전달되고, 절차 파라미터 f;가 P의 본체 내부에서 호출된다고 가정합니다.actf가 실행되는 동안 정의 [example needed]환경을 확인합니다.

이러한 범위 지정 규칙의 실장은 간단하지 않습니다.마지막으로 actf가 실행될 때까지 그 환경변수가 존재하는 활성화 레코드는 임의로 스택 내에 깊이 있어도 된다.이것은 이른바 하향식 문제 입니다.

예: 일반 삽입 정렬

절차 파라미터의 개념은 예를 통해 가장 잘 설명된다.일반적인 어플리케이션은 삽입 정렬 알고리즘의 다음과 같은 일반적인 실장입니다.이 알고리즘에는 2개의 정수 파라미터 a, b와 2개의 절차 파라미터 prec, swap이 필요합니다.

절차 isort(a, b, prec, swap): 정수 i, j; i ← a; i i bji; j > a  prec(j, j-1); j ← j-1; i ← i+1;

이 절차를 사용하여 임의의 유형배열 x의 요소 x[a] ~ x[b]를 사용자 지정 순서로 정렬할 수 있습니다.prec 파라미터와 swap 파라미터클라이언트에 의해 정의된2개의 함수여야 합니다.둘 다 a와 b 사이에2개정수 r, s를 사용합니다.prec 함수는 x[r]에 저장된 데이터가 클라이언트에 의해 정의된 순서대로 x[s]에 저장된 데이터보다 선행되어야 하는 경우에만 true를 반환해야 합니다.스왑 함수는 x[r]와 x[s]의 내용을 교환하고 결과를 반환하지 않습니다.

prec swap 기능을 적절하게 선택함으로써 동일한 isort 절차를 사용하여 모든 데이터 유형의 어레이를 재정렬할 수 있으며, 모든 미디어에 저장되며 개별 어레이 요소에 대한 인덱스 액세스를 제공하는 모든 데이터 구조로 편성됩니다.(단, 대규모 어레이의 경우 삽입 정렬보다 훨씬 효율적인 정렬 알고리즘이 있습니다.)

부동 소수점 번호 정렬

예를 들어 isort(1, 20, zprec, zswap)를 호출함으로써 20개의 부동소수점 번호 z[1]~z[20]의 배열 z를 순서대로 정렬할 수 있습니다.여기서 zpreczswap 함수는 다음과 같이 정의됩니다.

절차 zprec(r, s): 반환(z[r] < z[s]; 절차 zswap(r, s): 플로트 t; t ← z[r]; z[r]← z[s]; z[s]← t

행렬 행 정렬

다른 예로, M은 행이 10개이고 열이 20개인 정수 행렬이며 지수는 1부터 시작합니다.다음 코드는 모든 짝수 값이 모든 홀수 값 앞에 오도록 각 행의 요소를 재배치합니다.

integer i procedure eoprec(r, s): 반환(M[i, r] mod 2) < (M[i, s] mod 2); 프로시저 eoswap(r, s): 정수 t; t ← M[i,r] ← M[i,s]; M[i,s] ← t1에서 i(iort까지이다.

eopreceoswap의 효과는 행 번호i에 따라 다르지만 isort 절차에서는 알 필요가 없습니다.

벡터 정렬 절차

다음 예제에서는 isort를 사용하여 요소 v[0]에서 v[n-1]까지의 정수 n 및 정수 벡터v를 사용하여 세 번째 파라미터 incr이 각각 true인지 false인지에 따라 오름차순 또는 내림차순으로 정렬하는 프로시저 벡소트를 정의합니다.

프로시저 vecsort(n, v, incr): 프로시저 vprec(r, s): incr이면 v[r] < v[s]를 반환하고, 그렇지 않으면 v[r] > v[s]를 반환합니다. 프로시저 vswap(r, s): 정수 t; tv[r] ← v[s]; v[s] ← v[0, s]; recort, s]

vecsort에 전달된 파라미터 incr에 따라 효과가 달라지는 함수 vprec을 얻기 위해 중첩된 함수 정의를 사용합니다.표준 C와 같이 중첩된 함수 정의를 허용하지 않는 언어에서 이 효과를 얻으려면 다소 복잡하거나 스레드 안전하지 않은 코드가 필요합니다.


예: 두 시퀀스를 병합

다음은 절차 매개변수를 사용하여 추상 데이터 구조를 구체적인 구현과 독립적으로 처리하는 예를 보여 줍니다.문제는 2개의 정렬된 레코드 시퀀스를 1개의 정렬된 시퀀스로 결합하는 것입니다.여기서 클라이언트는 레코드의 특성과 순서 기준을 선택할 수 있습니다.다음의 실장에서는, 각 레코드가 메모리주소에 의해서 참조될 수 있는 것만으로, 유효한 레코드의 주소가 아닌 「늘주소」가 존재하는 것을 전제로 하고 있습니다.클라이언트는 각 시퀀스에서 첫 번째 레코드의 주소 A, B를 제공해야 하며 나중에 설명하도록 함수의 prec, next append를 제공해야 합니다.

절차 merge (A, B, prec, nextA, appendA, nextB, appendB): 주소 ini, fin, t ini ← λ; fin ← λ반면 A b 또는 B ≠ = a경우 또는 (A ≠ B prec와 prec B ≠ b b b b b b b)nini

function prec은 각 시퀀스에서1개씩 2개의 레코드의 주소 r, s를 가져와 출력 시퀀스에서 첫 번째 레코드가 다른 레코드보다 먼저 와야 할 경우 true를 반환해야 합니다.함수 nextA는 첫 번째 시퀀스에서 레코드 주소를 가져와 같은 시퀀스로 다음 레코드의 주소를 반환해야 합니다.없을 경우 δ를 반환해야 합니다.함수 appendA는 시퀀스A의 첫 번째 레코드를 출력 시퀀스에 추가해야 합니다.인수는 추가할 레코드의 주소 A 및 출력 목록의 마지막 레코드의 주소 핀(또는 목록이 아직 비어 있는 경우 λ)입니다.절차 부록 A는 출력 목록의 최종 요소의 업데이트된 주소를 반환해야 합니다.다음 B 및 추가 B 절차는 다른 입력 시퀀스와 유사합니다.

링크 목록 병합

범용 머지 순서를 설명하기 위해서, 주소 R, S 의 노드로부터 시작하는, 2 개의 간단한 링크 리스트를 머지 하는 코드를 다음에 나타냅니다.여기에서는 각 레코드 x 에 정수 필드 x 가 포함되어 있다고 가정합니다.INFO 및 주소 필드 x.[NEXT]는 다음 노드를 가리킵니다.여기서 각 리스트의 정보 필드가 오름차순으로 표시됩니다.입력 목록은 병합에 의해 해체되고 해당 노드가 출력 목록을 작성하는 데 사용됩니다.

프로시저 listmerge(R, S): 프로시저 prec(r, s): return r.정보 < s.INFO 프로시저 next(x):x를 반환합니다.NEXT procedure append(x, fin)         if fin ≠ Λ then fin.다음x x.다음 ← λ 반환 x 병합(R, S, 사전, 다음, 추가, 다음, 추가)

벡터 병합

다음 코드는 시퀀스의 실제 표현으로부터 일반 병합 절차의 독립성을 보여 줍니다.부동소수점 숫자의 U[0]~U[m-1] 및 V[0]~V[n-1]의 2개의 일반 배열 요소를 내림차순으로 병합합니다.입력 배열은 변경되지 않고 병합된 값의 시퀀스는 세 번째 벡터 W[0] ~ W[m+n-1]에 저장됩니다.C 프로그래밍 언어에서와 같이 표현식 "&V"는 변수 V의 주소를 나타내고, "*p"는 주소가 p 값인 변수를 나타내고, "&(X[i])"는 배열 X 및 정수 i에 대해 "&(X[0] + i"와 동등하다고 가정합니다.

절차 arraymerge(U, m, V, n, W):절차 prec(r, s):반환(*r)>(80)절차 nextU()):x)&(U[m−1]) 다음 Λ 다른 반환) 돌아오+1절차 nextV()):x)&만약 지느러미)Λ 다음← 및 fin(V[n−1]) 다음 Λ 다른 반환)+1절차 append(x, fin),(W[0])(*fi하고 있다.nx←(*x)return fin + 1 m = 0이면 U ← 0이면 V ← Ω 반환 병합(U, V, prec, nextU, append, nextV, append)

예:확정적분

일정 간격에 걸쳐 통합

다음 절차에서는 실선의 소정 간격 [a, b]에 걸쳐 소정의 실값 함수 f의 대략적 _ (x) dx를 계산합니다.사용되는 수치 방법은 주어진 n개의 스텝 를 갖는 사다리꼴 규칙입니다.실수는 부동소수점 숫자로 근사됩니다.

절차 Intg(f, a, b, n): float t, x, s; 정수 i가 b = a이면 0 x ← a; sf(a) / 2를 반환합니다. i는 1~n-1경우 t ← i/(n+1); x ← a + t * b; s + f(x) s ← f(b) / 2 f(b)

디스크를 통한 통합

여기서 x c 및 R(\ 으로 디스크D(\ 특정 함수(\ g를 2개의 인수로 통합하는 문제를 검토합니다.이 문제는 변수의 변경에 의해 2개의 중첩된 단일 변수 적분으로 줄일 수 있습니다.

다음 코드는 우측 수식을 구현합니다.

절차 DiskIntg(g, xc, yc, R, n): 절차 gpolar(t): float x, y xxc + z * cos(t) y ← yc + z * sin(t) 반환 g(x, y) 정수 m ← round(n*z/R) 반환 z * Intg(극성, 0, n) 반환

이 코드는 2가지 레벨의 통합 절차 Intg를 사용합니다.외부 수준(마지막 줄)은 Intg를 사용하여0 ~ R z 의 적분을 계산합니다.내부 수준( 줄에서 마지막 줄)은 r y적분으로 합니다 중심( c, c), { z { z를 사용하여 원을 그립니다.

역사

절차 매개변수는 전자계산기 시대 이전에 수학자 Alonzo Church에 의해 그의 람다 미적분 모델의 일부로 발명되었습니다.

ALGOL 60에 의해 프로그래밍 언어 기능으로서의 절차 파라미터가 도입되었습니다.실제로 ALGOL 60에는 프로시저 파라미터의 사용을 단순화할 수 있는 강력한 "이름에 의한 콜" 파라미터 전달 메커니즘이 있습니다.Jensen's Device를 참조하십시오.

절차 매개변수는 LISP 프로그래밍 언어의 필수적인 특징이었으며, 함수 폐쇄 또는 funarg의 개념도 도입했습니다.C 프로그래밍 언어를 사용하면 함수 포인터를 파라미터로 전달할 수 있으며, 이는 동일한 목적을 달성하며 이벤트 구동 프로그래밍 및 오류 핸들러로 자주 사용됩니다.단, 네스트된 함수 정의를 사용할 수 있는 최신 C 컴파일러는 몇 개뿐이므로 다른 용도는 비교적 드뭅니다.절차 매개 변수는 중첩된 절차 정의와 함께 파스칼에서도 제공되었지만 표준 파스칼은 별도의 컴파일을 허용하지 않았기 때문에 이 언어에서도 이 기능은 거의 사용되지 않았습니다.

「 」를 참조해 주세요.