1)
아래는 파이썬 함수 summation
입니다. 큐브 / 사각형 / .., 유사한 작업 의 합계를 수행 할 수 있습니다.
def identity(k): return k def cube(k): return pow(k, 3) def square(k): return pow(k,2) def summation(n, term): if n == 0: return 0 else: return term(n) + summation(n-1, term) def sum_cubes(n): return summation(n, cube) if __name__ == "__main__": sum = sum_cubes(4) print(sum) """ In C, We can implement the same using function pointers. Goal is, to perform similar operations(Sum of ..) using single function summation()"""
2)
C에서 정렬 API 아래 고려
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
여기에서 qsort
는 모든 유형의 데이터 , 디렉토리 / 문자열 / …에있는 float / 파일 이름 배열
질문 :
일반 함수를 정의하는 방법?
summation
는 일반 함수입니까?
또는
qsort
는 일반 함수입니까?
또는
두 가지 예, 일반 기능 이 잘못된 용어입니까?
참고 : 동기 부여 용어 qsort
또는 내가 디자인 한 정렬 기능
댓글
li>
Answer
일반에는 몇 가지 의미가 있습니다.
비공식적 정의
“generic”은 공통 속성을 공유하지만 어떤면에서는 덜 구체적인 일상 언어로 사용됩니다.
이 관점에서 qsort()
를 일반적인 것으로 간주 할 수 있습니다.이 함수의 코드 QSORT 알고리즘을 사용하여 비교 함수를 정의 할 수있는 고정 크기 데이터 구조를 정렬 할 수 있습니다.
하나의 매개 변수가있는 모든 함수를 사용하여 얻은 용어를 요약하는 summation()
함수에도 동일하게 적용됩니다.
형식 정의
C ++ 또는 Java와 같은 프로그래밍 언어는 일반 프로그래밍을 허용합니다. 템플릿 또는 제네릭 사용 :
C ++ 14 표준의 정의 : 템플릿은 클래스 또는 함수 패밀리 또는 유형 패밀리에 대한 별칭을 정의합니다.
원칙은 클래스 또는 함수의 구현을 유형별로 매개 변수화 할 수 있다는 것입니다.
이보다 공식적인 관점에 따르면 qsort()
은 일반 함수가 아닙니다. 구현시 컴파일시 유형을 결정할 필요가 없으며 해당 동작은 유형에 독립적입니다. 필요한 것은 정렬되는 요소의 크기이며이 크기는 런타임에 처리되는 일반적인 인수입니다.
Python과 같이 정적으로 입력되지 않은 언어 의 경우 . 구현 및 동작이 유형에 따라 다르기 때문에 일반적이지 않다고 생각합니다.이 함수는 단지 더 높은 순서의 함수이며 term
인수는 유형에 따라이 함수의 동작을 변경하는 기능을 사용하지 않습니다.
일반 함수의 설명을 위해 C ++ 표준 함수 std::sort()
를 살펴볼 수 있습니다. a> : 구현은 인수의 유형에 따라 다릅니다 (선택적으로 결정된 유형의 인수가있는 비교 함수). C ++ 템플릿의 기능을 사용하여 제네릭 함수 구현에 필요한 연산자 / 멤버 함수 / 특성 / 반복자가있는 조건에서 모든 유형의 컨테이너를 정렬 할 수 있습니다.
동적 유형 언어에 일반 기능이있을 수 있습니까?
동적 유형 언어에는 정적으로 형식화 된 언어보다 덜 일반적인 코드.
예를 들어, 동적 유형의 객체 컨테이너가있는 경우 컨테이너에있는 두 요소의 조합을 비교할 수있는 한 qsort 함수는 일반적으로 컨테이너를 정렬 할 수 있습니다.
그러나 이러한 유연한 환경에서도 일반적인 유형 종속 프로그래밍이 도움이 될 수 있습니다. 일반적인 사용 사례는 multimethods입니다. 여기서 동작이나 코드는 인수의 유형 또는 유형의 조합 (예 : 서로 다른 두 모양 사이의 교차점 결정)에 따라 달라집니다. 추가 정보는 다음을 참조하십시오.
댓글
- 확실하지 않습니다. Generics 를 비교하는 이유 (주로 자바에서 타입 캐스팅을 피하는 데 사용 & 일반 함수 정의로 다형성 수행에 도움이 되나요?
- @overexchange Java는 일반 메소드를 포함한 일반 프로그래밍도 제공한다고 생각합니다. ( 사양 또는 튜토리얼 참조). 그럼에도 불구하고 ‘ 당신의 의견을 다루기 위해 정의 부분을 약간 편집했습니다.
- Python의 Generic 패키지는 일반 함수와 관련이 없습니다. 같은 형용사를 공유한다는 점을 제외하면
- @Killian if 일반 프로그래밍 은 구체적이고 효율적인 알고리즘에서 추상화하는 아이디어에 관한 것입니다. 다른 데이터 표현과 결합 할 수있는 일반 알고리즘을 얻으려면 해당 패키지의 다중 메소드가 있어야한다고 생각합니다. ‘ 그렇게 생각하지 않습니까?
Answer
일반 함수는 컴파일 타임에 일반적으로 하나 이상의 함수 인수 유형을 취합니다. 즉, 컴파일러는 특정 위치에서 사용되는 유형을 찾아 함수에서 사용되는 위치에 정확히이 유형을 적용합니다. 예 : 함수에 +
연산자와 함께 사용되는 일반 인수가있는 경우 유형에 적절한 메서드가 있어야합니다. 문자열 / 배열의 경우 이것은 많은 경우 연결이고 for 및 integer / float 덧셈입니다. 컴파일러는 올바른 작업 적용을 감지 할 수 있습니다. C 루틴은 그런 의미에서 일반적이지 않습니다. 컴파일러가 유형을 감지하고 올바른 크기를 사용하지 않고 일부 크기 정보를 적용하는 것은 프로그래머이기 때문입니다.
예 : 일부 가상 언어
func add(p1,p2) { return p1+p2 } print add("a", "b") // yields "ab" print add(1, 2) // yields 3
여기서 컴파일러는 두 개의 문자열이 적용된 첫 번째 경우를 감지하고 내부적으로 다음과 같이 확장합니다.
func add(p1:string, p2:string)
+
를 연결로 처리하고 두 번째 경우에는 제공된대로 확장합니다.
func add(p1:int, p2:int)
정수 매개 변수입니다. 일반적인 의미는 컴파일러가 컴파일 시간 동안 개별 코드를 생성한다는 것을 의미합니다. 예를 들어 Python은 유형이 지정되지 않았으며 런타임 중에 그런 종류의 대체를 수행합니다. 의미 : Python은 모든 것이 일반적이기 때문에 일반 함수가 없습니다.
코멘트
- 아이디어를 얻지 못했습니다. +는 일반 함수, C ++의 구문을 의미합니까?
- 함수 인수를받는 함수는 더 높은 순서입니다. 함수 Python / JavaScript 세계에서 s. C에서도 함수 포인터가 필요합니다.
- 위의 편집 내용을 참조하세요.
- 그러면
summation
는 어떤 함수인지, 고차 기능? 그 이상은 없나요? - 일반이 무엇인지에 대한 많은 정의가 있습니다. 예를 들어 Stroustrup은이를 ” 유형을 매개 변수로 사용하는 프로그래밍 “로 정의합니다. 위키 백과 참조는 ‘ 차라리 en.wikipedia.org/wiki/Generic_programming
Answer
C ++의 관점에서 시작한 다음 C로 작업하겠습니다.
C, C ++, Java 등과 같은 정적으로 유형이 지정된 언어에서 “일반”함수를 사용하면 다양한 유형에 대한 자리 표시자를 사용하여 함수 작업을 한 번 지정할 수 있습니다. 서로 다른 호출간에 (즉, qsort
및 bsearch
와 같은 함수는 확실히 일반 함수가 아닙니다 . 이상적으로는 컴파일러가이 일반 함수에 대한 호출을 자동으로 감지하고 필요에 따라 실제 코드를 생성하기를 원합니다.
C ++는 템플릿 을 제공하여 1 쉽게 만듭니다.
template <typename T> T summation( T *values, size_t numValues ) { T result = 0; for ( size_t i = 0; i < numValues; i++ ) result += values[i]; return result; }
T
는 모든 유형 2 에 대한 자리 표시 자이므로
int ivals[] = {1,2,3,4,5,6,7,8,9}; double dvals[] = {1,2,3,4,5,6,7,8,9}; int sumi = summation( ivals, 10 ); double sumd = summation( dvals, 10 );
코드가 컴파일되면 컴파일러는 summation
에 대한 두 번의 호출을보고 인수 유형을 추론 합니다. 각 유형에 대해 함수의 새 인스턴스를 생성 하여 고유 한 이름을 부여합니다.
int summation_i( int *values, size_t numValues ) // actual compilers will generate { // more complex "mangled" names int result = 0; // than this ... } double summation_d( double *values, size_t numValues ) { double result = 0; ... }
그런 다음 코드를 생성합니다. summation_i
의 결과는 sumi
에 할당되고 summation_d
는
.
C는 템플릿 기능과 유사한 기능을 제공하지 않습니다. 전통적으로 우리는 매크로를 사용하거나 void *
모든 곳에서 유형 인식 작업을 다른 함수에 위임합니다.
다음은 매크로 기반 솔루션의 나쁜 예입니다.
#include <stdio.h> #define SUMMATION_DEF(t) \ t summation_##t( t *values, size_t numValues ) \ { \ t result = 0; \ for ( size_t i = 0; i < numValues; i++ ) \ result += values[i]; \ return result; \ } #define SUMMATION(t,x,s) summation_##t(x, s) SUMMATION_DEF(int) SUMMATION_DEF(double) int main( void ) { int ivals[] = {1, 2, 3, 4, 5}; double dvals[] = {1, 2, 3, 4, 5}; int sumi = SUMMATION(int, ivals, 5); double sumd = SUMMATION(double, dvals, 5); printf( "sumi = %d\n", sumi ); printf( "sumd = %f\n", sumd ); return 0; }
SUMMATION_DEF
는 매크로 매개 변수 t
를 유형 자리 표시 자로 사용하여 함수 작업을 지정한다는 점에서 템플릿과 대략 유사합니다. 또한 t
–##
는 토큰 붙여 넣기 연산자이며 전처리 기는 t
함수 이름에 해당 값을 추가합니다 3 .
C ++와 다른 점은 매크로가 단순한 텍스트 대체라는 사실입니다. 트리거하지 않습니다. 컴파일러 부분의 특수 작업. 실제 함수 인스턴스는 SUMMATION
매크로 호출을 기반으로 자동 생성되지 않습니다. 원하는 함수를 명시 적으로 생성해야합니다 (따라서 SUMMATION_DEF(int)
및 SUMMATION_DEF(double)
이전 main
). 또한 summation_xxx
를 호출 할 때 SUMMATION
매크로를 통해 올바른 함수가 호출되도록 매크로 인수 목록의 일부로 유형을 전달해야합니다. 정말 고통 스럽습니다.
The C 2011 표준은 _Generic
키워드를 추가하여 그 점에서 삶을 좀 더 쉽게 만들 수 있습니다.
#include <stdio.h> #define SUMMATION_DEF(t) \ t summation_##t( t *values, size_t numValues ) \ { \ t result = 0; \ for ( size_t i = 0; i < numValues; i++ ) \ result += values[i]; \ return result; \ } #define SUMMATION(x,s) _Generic((x), \ int * : summation_int, \ double * : summation_double \ )(x, s) SUMMATION_DEF(int) SUMMATION_DEF(double) int main( void ) { int ivals[] = {1, 2, 3, 4, 5}; double dvals[] = {1, 2, 3, 4, 5}; int sumi = SUMMATION(ivals, 5); double sumd = SUMMATION(dvals, 5); printf( "sumi = %d\n", sumi ); printf( "sumd = %f\n", sumd ); return 0; }
_Generic
키워드를 사용하면 유형 을 기반으로 표현식을 평가할 수 있습니다. 따라서 iv id =에 대한 첫 번째 인수의 유형 이 “ab6b2923ab”>
는int *
이고, 우리는summation_int
라고 부릅니다. ,summation_double
라고합니다. 이렇게하면 매크로 인수에 유형 이름을 지정할 필요가 없습니다.
여러분이 본 것처럼 다른 접근 방식은 void *
를 사용하고 유형 인식 작업을 다른 함수에 위임하는 것입니다. 위에서 말했듯이 ” 각 유형에 대해 각 비교 함수를 수동으로 구현해야하기 때문에 실제로 “일반적인”프로그래밍이 아닙니다. 한 번만 코딩하여 끝낼 수는 없습니다. 그리고 void *
를 사용하면 기본적으로 형식 안전을 창 밖으로 다가오는 트래픽으로 던집니다.
그리고 누구도 불평하기 전에 – 아니오, 이러한 합산 함수는 산술 오버플로를 확인하거나 처리하지 않습니다. 그것은 다른 날의 주제입니다.
- “쉬움”에 대한 충분히 느슨한 정의용. 템플릿을 지원하는 데 사용되는 메타 프로그래밍 언어는 Turing-complete이므로 * 정말 놀라운 * 작업을 수행 할 수 있으며 이해하기 불가능합니다.
- 모든 유형의 정의가 충분히 느슨한 경우. 어떤 유형을 사용하든
+=
연산자를 지원해야합니다. 그렇지 않으면 컴파일러가 소리를 지 릅니다. - 이 코드는 이름에 공백이 있으므로
unsigned int
또는long double
와 같은 유형에서 해제됩니다 . 나는 그 문제에 대한 해결책을 즉시 알지 못하며이 대답에 충분한 시간을 보냈다.
일반 함수 ” 당신이 이해하지 못한다고 ‘ 읽었습니까? 코드를 작성하는 대신 게시하면 도움이 될 것입니다.