programing

함수 인수의 배열 길이

randomtip 2022. 8. 30. 22:07
반응형

함수 인수의 배열 길이

이는 어레이 길이를 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]

은 눈에 보이지 않는 있을 뿐이다.structc 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_ttype)을 별도의 인수로 사용하여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 ''를 위해 argvO(1)

일반 어레이 입력에는 count-until-NULL 메서드가 작동하지 않습니다.크기를 두 번째 인수로 수동으로 지정해야 합니다.

언급URL : https://stackoverflow.com/questions/8269048/length-of-array-in-function-argument

반응형