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 또는 내가 디자인 한 정렬 기능

댓글

  • 일반 함수 ” 당신이 이해하지 못한다고 ‘ 읽었습니까? 코드를 작성하는 대신 게시하면 도움이 될 것입니다.

  • 함수가 제약없이 특정 유형에 대한 지식없이 모든 유형에 대해 작동하는 일반적인 유형의 유형 이론 용어는 파라 메트릭 다형성 . 식별 기능은 이러한 방식으로 일반적입니다.
  • 일부 언어 (예 : Java)에서는 ” 일반 함수 “가 특정 기술 정의. 그러나 Python에서는 그렇지 않으므로 ” 일반 함수 “에는 잘 정의 된 의미가 없습니다. ” 유효하지 않은 용어 “가 아니라 용어를 사용할 때 문맥을 알고 있어야합니다.

li>

  • @AndresF. Javascrpt는 또한이 일반 함수 용어를 많이 사용합니다. html 요소를 처리하는 함수가있을 수 있기 때문입니다 (예 : 주어진 html 요소의 모든 하위 항목 삭제)
  • 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 등과 같은 정적으로 유형이 지정된 언어에서 “일반”함수를 사용하면 다양한 유형에 대한 자리 표시자를 사용하여 함수 작업을 한 번 지정할 수 있습니다. 서로 다른 호출간에 (즉, qsortbsearch와 같은 함수는 확실히 일반 함수가 아닙니다 . 이상적으로는 컴파일러가이 일반 함수에 대한 호출을 자동으로 감지하고 필요에 따라 실제 코드를 생성하기를 원합니다.

    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 *를 사용하면 기본적으로 형식 안전을 창 밖으로 다가오는 트래픽으로 던집니다.

    그리고 누구도 불평하기 전에 – 아니오, 이러한 합산 함수는 산술 오버플로를 확인하거나 처리하지 않습니다. 그것은 다른 날의 주제입니다.


    1. “쉬움”에 대한 충분히 느슨한 정의용. 템플릿을 지원하는 데 사용되는 메타 프로그래밍 언어는 Turing-complete이므로 * 정말 놀라운 * 작업을 수행 할 수 있으며 이해하기 불가능합니다.
    2. 모든 유형의 정의가 충분히 느슨한 경우. 어떤 유형을 사용하든 += 연산자를 지원해야합니다. 그렇지 않으면 컴파일러가 소리를 지 릅니다.
    3. 이 코드는 이름에 공백이 있으므로 unsigned int 또는 long double와 같은 유형에서 해제됩니다 . 나는 그 문제에 대한 해결책을 즉시 알지 못하며이 대답에 충분한 시간을 보냈다.

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다