2013-07-16 2 views
5

저는 C 프로그래밍 언어에 비교적 익숙하지 않습니다. 다른 유형의 데이터를 매개 변수로 받아 들일 수있는 함수를 만드는 방법을 알아 내려고하고 있습니다. 이 함수는 문자 또는 정수 배열의 요소 수를 계산하여 반환합니다. 이 작업을 수행 할 두 가지 기능이 이미 있지만 두 작업에 하나의 기능을 사용하고 싶습니다. C에서이 작업을 수행 할 수있는 방법이 있습니까?다른 데이터 형식의 매개 변수를 받아들이는 C 함수 만들기

미리 감사드립니다.

답변

5

C에서 표준 함수 오버로드가 없으며 (템플릿도 있음) "printf-like"함수 (또는 variadic functions)를 조사해 볼 수 있습니다. 어떤 것이라도 유연한 매개 변수 목록을 허용합니다.

가변 크기 정수 배열을 사용하는 함수의 예가 here입니다.

아마도 당신은 다음과 같은 방법으로 사용하는 void iterate(const char* format, ...); 같은 함수 서명을 할 수 :

iterate("char", some_char_array); // for char arrays/strings 

또는

iterate("int", some_int_array); // for integer arrays 

아니 켓 그래도 좋은 지적을합니다, 당신은 어떻게 요소를 센다 정수 배열로? int 배열을 인수로 전달하면 배열의 요소를 계산하는 목적을 무효로하는 크기를 전달해야합니다 (이미 알고있는 것처럼 크기).

크기는 모르지만 배열에 터미네이터 값 (예 : -1)이 있다고 가정합니다.

나는 위와 같은 가정을 염두에두고 필요한 것을 신속하게 해킹했습니다.

#include <stdarg.h> 
#include <stdio.h> 
#include <string.h> 

int iterate(const char* format, ...) 
{ 
    va_list ap; 
    va_start(ap, format); 

    if (strcmp(format, "char") == 0) 
    { 
     char* array = va_arg(ap, char*); 

     return strlen(array); 
    } 
    else if (strcmp(format, "int") == 0) 
    { 
     int j = -1; 
     int* int_array = va_arg(ap, int*); 
     while (int_array[++j] != -1) 
        ;  
     return j; 
    } 
    return 0; 
} 

int main() 
{ 
    printf("%d\n", iterate("char", "abcdef")); 
    int arr[] = {5, 4, 3, 2, 1, 0, -1}; 
    printf("%d\n", iterate("int", arr)); 

    return 0; 
} 

이 인쇄 : 어느 경우

$ ./a.out 
6 
6 
+0

int 크기는 무엇입니까? –

+0

배열의 크기는? 명확하지 않은 것으로 보아 이것을 분명히하겠습니다. – Nobilis

+0

만약 그가 배열의 크기를 알고 있다면 그 배열을 자동으로 추론하고 배열의 길이를 계산하기 위해 적절한 함수를 호출하는 것과 같은 super 함수를 사용해야할까요? :-) –

1

함수 인수를 void * 형식으로 지정해야합니다. 이렇게하면 여러 유형의 데이터를 전달하고 원하는 형식으로 데이터를 캐스팅 할 수 있습니다. 그러나 void*이 가리키는 형식을 정확하게 '추측'할 수있는 보장 된 방법이 없기 때문에 조심해야합니다.

2

, 당신은 전화 기능 C 컴파일러에게 타입 추론 시스템의 일종이 필요합니다. 즉, 당신이 당신의 "슈퍼 기능"에 매개 변수로 보낼 어레이의 유형을 사전에 알아야합니다.

런타임에 데이터 유형을 반영 할 수있는 C에는 "자동 유형 추론"이 없습니다. 더 나아가,이 작업을 수행 할 수있는 자체 런타임 환경을 작성해야 할 수도 있습니다. 이 작업을 수행하는

약간 사소한 hackish 방법 :

#include <stdio.h> 

size_t GetLengthOfArray(size_t sizeOfOneElementInArray, size_t sizeOfTheArrayInBytes) 
{ 
    return sizeOfTheArrayInBytes/sizeOfOneElementInArray; 
} 
int main(int argc, char *argv[]) 
{ 
    char cArr[10] = {'A','B','C','D','E','F','G','H','I','J'}; 
    int iArr[5] = {10,20,30,40,50}; 
    printf("%d is the length of cArr\n%d is the length of iArr",GetLengthOfArray(sizeof(cArr[0]),sizeof(cArr)), 
                   GetLengthOfArray(sizeof(iArr[0]),sizeof(iArr))); 
    return 0; 
} 
+0

C11에'_Generic'이 있습니다. – jxh

2

는 자,이 두 가지 기능을 가정 해 보자는 sizeof_char_arraysizeof_int_array이라고합니다.

#define sizeof_array(X) \ 
    _Generic (*(X), \ 
       char: sizeof_char_array, \ 
       default: sizeof_int_array) (X) 

가 (심지어 테스트하는 C11 구현이없는 : C11에서

, 당신은 비교적 간단한 매크로 당신이 원하는 것을 할 수있게된다 "일반 선택"이라는 새로운 기능이 있습니다 이것에 대항하여주의해야합니다!)

C11 이전에는 정기적으로 명명 된 기능을 사용하여 매크로를 수행하는 경우가있었습니다. 당신은 하나 개의 함수 또는 매크로 인수 힌트에 따라 다른 호출 매크로 정의 할 수 있습니다 : 입력 인수가 진정으로 배열 인 경우

#define sizeof_array(xtype, x) sizeof_ ## xtype ##_array(x) 

int a[] = { 1, 2, 3, 4, -1 }; 
char b[] = "abc"; 

sizeof_array(int, a); /* macro expands to sizeof_int_array(a) */ 
sizeof_array(char, b); /* macro expands to sizeof_char_array(b) */ 

를 직접 크기를 계산하는 매크로를 사용할 수 있습니다

배열의 경우
#define ARRAY_SZ(x) (sizeof(x)/((void *)x == &x ? sizeof(x[0]) : 0)) 

다음 식 사실이다 : 배열의 주소가 첫번째 요소의 어드레스로서 메모리 내의 동일한 위치에있다

(void *)arr == &arr 

때문에.

따라서 매크로는 sizeof(arr)/sizeof(arr[0])을 계산합니다. sizeof 연산자가 인수의 바이트 수를보고하므로 계산 된 표현식은 배열의 요소 수를 나타냅니다. 그러나 센티널을 사용하여 길이를 계산할 경우 ARRAY_SZ 매크로는 센티넬의 배열을 가로 지르는 길이보다 적어도 하나 더 큰 크기가됩니다.

인수가 배열이 아닌 경우 식은 0으로 나누기 예외가 발생합니다.

+0

엄격히 말하면 : -P, OP는 포인터가 보유하는 데이터 유형에 따라 하나의 함수에서 두 개의 다른 함수를 호출하려고합니다. –

+0

그래서 나는 일종의 추론 시스템을 원한다고 생각합니다. 이거 내 생각. –

+0

@Aniket : 배열의 길이를 함수에 전달한 후에 배열의 길이를 추론 할 수 없기 때문에 그건별로 이해가되지 않습니다. 배열의 길이는 함수에 전달되어야합니다 (추론이 센티널 값을 통해 수행되지 않는 한). – jxh

2

답변은 간단합니다. 이 작업을 수행하려면 함수가 필요합니다. 이 코드 조각을 사용해보십시오.

#define len(array) sizeof(array)/sizeof(array[0]) 

그게 전부입니다.

관련 문제