저는 C 프로그래밍 언어에 비교적 익숙하지 않습니다. 다른 유형의 데이터를 매개 변수로 받아 들일 수있는 함수를 만드는 방법을 알아 내려고하고 있습니다. 이 함수는 문자 또는 정수 배열의 요소 수를 계산하여 반환합니다. 이 작업을 수행 할 두 가지 기능이 이미 있지만 두 작업에 하나의 기능을 사용하고 싶습니다. C에서이 작업을 수행 할 수있는 방법이 있습니까?다른 데이터 형식의 매개 변수를 받아들이는 C 함수 만들기
미리 감사드립니다.
저는 C 프로그래밍 언어에 비교적 익숙하지 않습니다. 다른 유형의 데이터를 매개 변수로 받아 들일 수있는 함수를 만드는 방법을 알아 내려고하고 있습니다. 이 함수는 문자 또는 정수 배열의 요소 수를 계산하여 반환합니다. 이 작업을 수행 할 두 가지 기능이 이미 있지만 두 작업에 하나의 기능을 사용하고 싶습니다. C에서이 작업을 수행 할 수있는 방법이 있습니까?다른 데이터 형식의 매개 변수를 받아들이는 C 함수 만들기
미리 감사드립니다.
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
함수 인수를 void *
형식으로 지정해야합니다. 이렇게하면 여러 유형의 데이터를 전달하고 원하는 형식으로 데이터를 캐스팅 할 수 있습니다. 그러나 void*
이 가리키는 형식을 정확하게 '추측'할 수있는 보장 된 방법이 없기 때문에 조심해야합니다.
, 당신은 전화 기능 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;
}
C11에'_Generic'이 있습니다. – jxh
는 자,이 두 가지 기능을 가정 해 보자는 sizeof_char_array
및 sizeof_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으로 나누기 예외가 발생합니다.
엄격히 말하면 : -P, OP는 포인터가 보유하는 데이터 유형에 따라 하나의 함수에서 두 개의 다른 함수를 호출하려고합니다. –
그래서 나는 일종의 추론 시스템을 원한다고 생각합니다. 이거 내 생각. –
@Aniket : 배열의 길이를 함수에 전달한 후에 배열의 길이를 추론 할 수 없기 때문에 그건별로 이해가되지 않습니다. 배열의 길이는 함수에 전달되어야합니다 (추론이 센티널 값을 통해 수행되지 않는 한). – jxh
답변은 간단합니다. 이 작업을 수행하려면 함수가 필요합니다. 이 코드 조각을 사용해보십시오.
#define len(array) sizeof(array)/sizeof(array[0])
그게 전부입니다.
int 크기는 무엇입니까? –
배열의 크기는? 명확하지 않은 것으로 보아 이것을 분명히하겠습니다. – Nobilis
만약 그가 배열의 크기를 알고 있다면 그 배열을 자동으로 추론하고 배열의 길이를 계산하기 위해 적절한 함수를 호출하는 것과 같은 super 함수를 사용해야할까요? :-) –