함수 인수의 배열 길이
이는 어레이 길이를 C로 계산하는 데 잘 알려진 코드입니다.
sizeof(array)/sizeof(type)
하지만 함수에 인수로 전달된 배열의 길이를 찾을 수 없습니다.
#include <stdio.h>
int length(const char* array[]) {
return sizeof(array)/sizeof(char*);
}
int main() {
const char* friends[] = { "John", "Jack", "Jim" };
printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}
배열을 값으로 함수 인수에 상수 포인터로 복사하고 이를 참조하면 해결할 수 있지만 이 선언은 유효하지 않습니다.
int length(const char**& array);
만, 입니까?main
음음음같 뭇매하다
int main(int argc, char** argv);
인수에서 알수 수 있다면 """에 .main
.
sizeof
는 원래 어레이에 적용할 경우에만 어레이 길이를 검색합니다.
int a[5]; //real array. NOT a pointer
sizeof(a); // :)
그러나 배열이 포인터로 소멸할 때까지 sizeof는 배열의 크기가 아닌 포인터의 크기를 제공합니다.
int a[5];
int * p = a;
sizeof(p); // :(
이미 현명하게 지적한 바와 같이 main은 어레이의 길이를 인수(argc)네, 이것은 필수가 아닌 용장성이 없습니다.(argv는 null 포인터에 의해 쉽게 종료되기 때문에 약간 재이용됩니다만, 저는 이 문제를 해결합니다.)
왜 이런 일이 일어나는지에 대한 몇 가지 추론이 있다.C 어레이의 길이도 알 수 있도록 하려면 어떻게 해야 할까요?
첫 번째 아이디어는 배열이 함수에 전달될 때 포인터로 분해되지 않고 유형 시스템에서 배열 길이를 계속 유지하는 것입니다.단점은 어레이의 길이마다 다른 함수를 사용할 필요가 있다는 것입니다.(Pascal이 이것을 실시해, 이것이 C에 「손실」한 이유 중 하나라고 생각하는 사람도 있습니다.)
두 번째 아이디어는 어레이 옆에 배열 길이를 저장하는 것입니다. 이는 현대의 다른 프로그래밍 언어처럼 다음과 같습니다.
a -> [5];[0,0,0,0,0]
은 눈에 보이지 않는 있을 뿐이다.struct
c c c c c c c c c. 그러한 은, 어떤 의 문제에는 입니다.
struct {
size_t length;
int * elements;
}
생각할 수 있는 또 다른 것은 (Pascal과 같이) 길이를 저장하는 대신 C의 문자열이 Null로 종단되는 방법입니다.한도를 걱정하지 않고 길이를 저장하려면 상상할 수 없을 정도로 비싼 4바이트가 필요합니다(적어도 그 당시에는).어레이도 이와 같이 null로 종료할 수 있는지 궁금할 수 있습니다.그렇다면 어레이에 null을 저장할 수 있는 방법은 무엇일까요?
전달되면 어레이가 포인터로 감쇠합니다.
C FAQ의 섹션 6.4에서는 이를 매우 잘 다루고 있으며 K&R 레퍼런스 등을 제공하고 있습니다.
이와는 별도로 함수가 포인터에 할당된 메모리의 크기를 알 수 있다고 상상해 보십시오.길이가 다를 수 있는 다른 입력 배열로 함수를 2회 이상 호출할 수 있습니다.따라서 그 길이는 어떻게든 비밀 숨김 변수로 전달되어야 합니다.되어 있는 합니다.malloc
이치노이것은, 본문의 표시나 이유가 아니고, 컴파일러가 링크 하는 것입니다).
비하인드 슬라이스 오브젝트 등이 없으면 어떻게 동작할지 상상하기 어렵습니까?
은 Symbian을 .AllocSize()
.malloc()
1에서 포인터 가 발생합니다
불가능하다고 믿고 싶진 않겠지만, 정말 그럴 수 없어요.함수에 전달되는 길이의 유일한 방법은 사용자가 직접 길이를 추적하여 별도의 명시적 매개 변수로 전달하는 것입니다.
이것은 오래된 질문이며, OP는 C++와 C를 그의 의도/예시로 혼합한 것 같습니다.C에서는 배열을 함수에 전달하면 포인터로 감쇠합니다.따라서 어레이 크기를 저장하는 함수에서 두 번째 인수를 사용하는 것 외에는 어레이 크기를 전달할 방법이 없습니다.
void func(int A[])
// should be instead: void func(int * A, const size_t elemCountInA)
다차원 어레이를 사용하는 경우처럼 이 기능이 필요하지 않은 경우는 거의 없습니다.
void func(int A[3][whatever here]) // That's almost as if read "int* A[3]"
함수 시그니처에 배열 표기를 사용하는 것은 기능에 필요한 요소의 수를 알 수 있기 때문에 개발자에게도 유용합니다.예를 들어 다음과 같습니다.
void vec_add(float out[3], float in0[3], float in1[3])
는 이것보다 이해하기 쉽습니다(다만, 두 기능 모두 함수의 4번째 요소에 접근하는 것을 막을 수는 없습니다).
void vec_add(float * out, float * in0, float * in1)
C++ 를 사용하는 경우는, 실제로 어레이의 사이즈를 캡쳐 해, 기대하는 것을 얻을 수 있습니다.
template <size_t N>
void vec_add(float (&out)[N], float (&in0)[N], float (&in1)[N])
{
for (size_t i = 0; i < N; i++)
out[i] = in0[i] + in1[i];
}
이 경우 컴파일러는 2D 벡터를 가진 4D 벡터를 추가하지 않도록 보장합니다(C에서는 함수의 인수로 각 차원의 치수를 전달하지 않으면 불가능합니다).vec_add 함수의 인스턴스는 벡터에 사용되는 차원 수만큼 존재합니다.
@Will에서 설명한 바와 같이 파라미터 전달 중에 감쇠가 발생합니다.이 문제를 회피하는 한 가지 방법은 요소의 수를 전달하는 것입니다.여기에 추가하기 위해,_countof()
매크로가 도움이 됩니다.그것은 지금까지와 같은 기능을 합니다.
가장 좋은 예는 다음과 같습니다.
감사합니다 #정의 사이즈 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}
int arsize(int st1[]) {
int i = 0;
for (i; !(st1[i] & (1 << 30)); i++);
return i;
}
이것으로 충분합니다. :)
크기: sizeof(array)/sizeof(int)를 가진 배열(type int)의 길이
첫째, 실제 어레이 선언이 범위 내에 있을 때 요소 수를 계산하는 데 더 나은 사용 방법은 다음과 같습니다.
sizeof array / sizeof array[0]
이렇게 하면 유형 이름이 반복되지 않습니다. 물론 선언에서 변경되어 잘못된 길이 계산이 발생할 수 있습니다.이것은 반복하지 않는 전형적인 경우입니다.
둘째, 부차적인 점으로 주의해 주십시오.sizeof
는 함수가 아니기 때문에 위의 식은 인수 주위에 괄호를 둘 필요가 없습니다.sizeof
.
셋째, C는 레퍼런스가 없기 때문에 당신의 사용법은&
안 통할 거야
적절한 C솔루션은 길이를 넘기는 것에 동의합니다(C솔루션은size_t
type)을 별도의 인수로 사용하여sizeof
인수가 「실제」배열인 경우, 콜이 발신되고 있는 장소.
에 의해 반환된 메모리로 작업하는 경우가 많습니다. malloc()
이 경우 크기를 계산할 수 있는 "진정한" 어레이가 없기 때문에 요소 수를 사용하도록 함수를 설계하는 것이 더 유연합니다.
int main()에 대해서:
준준에 according according according 에 따르면,argv
는 NULL 종단 배열(NULL 종단 문자열에 대한 포인터)을 가리킵니다.(5.1.2.2.1:1).
그것은,argv = (char **){ argv[0], ..., argv[argc - 1], 0 };
.
따라서 크기 계산은 의 간단한 수정인 함수에 의해 이루어진다.strlen()
.
argc
''를 위해 argv
O(1)
일반 어레이 입력에는 count-until-NULL 메서드가 작동하지 않습니다.크기를 두 번째 인수로 수동으로 지정해야 합니다.
언급URL : https://stackoverflow.com/questions/8269048/length-of-array-in-function-argument
'programing' 카테고리의 다른 글
간단한 Linux 디바이스 드라이버 작성 방법 (0) | 2022.08.31 |
---|---|
재사용 가능한 컴포넌트가 있는 라우터 뷰에서는 Vue 전환이 기능하지 않음 (0) | 2022.08.31 |
vuex 스토어가 업데이트되어도 Nuxtjs 페이지가 업데이트되지 않음 (0) | 2022.08.30 |
Android 개발에 적합한 ORM 도구가 있습니까? (0) | 2022.08.30 |
새 파일에 쓸 때 전체 경로 자동 생성 (0) | 2022.08.30 |