programing

의 크기가 피연산자 배열의 크기를 어떻게 알 수 있습니까?

yellowcard 2023. 9. 12. 19:56
반응형

의 크기가 피연산자 배열의 크기를 어떻게 알 수 있습니까?

이것은 바보 같은 질문일 수도 있지만 배열의 요소 양을 전달하지 않을 때 연산자의 크기가 배열 피연산자의 크기를 어떻게 알 수 있습니까?어레이의 전체 요소를 반환하는 것이 아니라 바이트 단위의 크기를 반환한다는 것은 알고 있지만, 어레이가 언제 종료되는지는 여전히 알아야 합니다.이게 어떻게 작동하는지 궁금할 뿐입니다.

sizeof컴파일 시 해석되며 컴파일러는 배열이 어떻게 선언되었는지(따라서 얼마나 많은 공간을 차지하는지) 알고 있습니다.호출sizeof동적으로 변환된 배열에서는 배열의 끝점이 지정되지 않았기 때문에 원하는 작업을 수행하지 않을 가능성이 높습니다.

이 문제를 이해하는 데 어려움을 겪는 근본적인 문제는 많은 사람들이 그러하듯이 배열과 포인터를 혼동하기 때문일 수 있습니다.하지만 배열은 포인터가 아닙니다. Adouble da[10]는 10열의 입니다.double, 한푼도double*할 때 알 수 . 평가를 요청하면, 은 이 를 할 에게 sizeof(da)가 안다고 해서 가 는 입니다 입니다 는 가 .sizeof(double)?

배열의 문제는 많은 맥락에서 (함수로 전달될 때와 같이) 첫 번째 요소에 대한 포인터로 자동으로 붕괴된다는 것입니다.그러나 배열은 배열이고 포인터는 포인터입니다.

한가지 경우를 제외하고는sizeof컴파일 타임에 할 수 있습니다.컴파일 시, 컴파일러는 개체의 전체 유형을 추적합니다. [편집: 어쨌든 개체의 유형에 대해 알고 있는 모든 것 - 크기를 포함하지 않는 유형이 완전하지 않으면 사용을 시도합니다.sizeof실패할 것입니다] 및sizeof기본적으로 컴파일러에서 해당 정보의 한 부분을 컴파일되는 코드로 "변환"하여 결과 코드에서 본질적으로 상수가 됩니다.

는 는 과 과 는 입니다.sizeof1VLA(Variable Length Array)에 적용됩니다.VLA에 적용되면,sizeof피연산자를 평가하고(다른 경우에는 그렇지 않음) VLA의 실제 크기를 만듭니다.이 경우 결과는 상수가 아닙니다.


1. VLA는 C99에서 공식적으로 C의 일부가 되었지만, 일부 컴파일러는 그 이전에 C를 지원했습니다.공식적으로 C++의 일부는 아니지만 일부 컴파일러(예: g++)는 C++의 확장으로 VLA를 포함합니다.

컴파일러는 응용프로그램의 각 유형의 크기를 알고 있으며,sizeof단지 컴파일러에게 당신을 위해 그 값을 만들어 달라고 요청할 뿐입니다.

Sizeof컴파일 타임 연산자입니다. 컴파일러만큼 많은 정보를 가지고 있습니다. (그리고 컴파일러는 배열의 크기를 알고 있습니다.)

그래서 전화를 걸면.sizeof포인터에서 포인터가 가리키는 배열의 크기가 아니라 포인터의 너비를 얻을 수 있습니다.

의 크기는 완전히 정의된 유형에만 적용할 수 있습니다.컴파일러는 컴파일 시간에 크기를 결정하거나(예: intoo[8];와 같은 선언이 있는 경우), 가변 길이 배열의 크기를 추적하기 위해 코드를 추가해야 한다고 결정할 수 있습니다(예: intoo[n+3];와 같은 선언이 있는 경우).

여기서 다른 답변과는 달리, C99의 경우 배열의 길이가 가변적일 수 있기 때문에 ()의 크기는 컴파일 시에 반드시 결정되지는 않습니다.

사용하시는 경우sizeof로컬 변수에서 선언한 원소의 개수를 알 수 있습니다.사용하시는 경우sizeof함수 매개 변수에서는 알지 못합니다. 매개 변수를 배열에 대한 포인터로 취급합니다.sizeof포인터의 크기를 제공합니다.

위키에서 인용한 내용:

연산자의 크기를 특정한 방식으로 구현하는 것은 컴파일러 작성자의 책임입니다.연산자의 크기는 다양한 데이터 유형의 크기를 얻기 위해 기본 메모리 할당 체계의 구현을 고려해야 합니다. 의 크기는 일반적으로 컴파일 시간 연산자이며, 이는 컴파일 동안 의 크기와 연산자가 결과 값으로 대체됨을 의미합니다.이는 C 또는 C++ 컴파일러가 생성한 어셈블리 언어 코드에서 명확하게 나타납니다.이러한 이유로 인해 의 크기는 때때로 함수 호출처럼 보이지만 운영자로서 자격이 있습니다.

연산자의 크기는 모든 원자 데이터 유형의 크기를 '알 수' 있습니다. 구조, 결합 및 배열은 원자 유형을 조립해야만 구성할 수 있기 때문에 어떤 유형의 배열 크기도 쉽게 결정할 수 있습니다.컴파일 시간 동안 기본 산술을 사용하여 복잡한 유형을 결정합니다.

sizeof는 보통 컴파일 타임에 평가됩니다.눈에 띄는 예외는 C99의 가변 길이 배열입니다.

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        int count = atoi(argv[1]);
        int someArray[count];

        printf("The size is %zu bytes\n", sizeof someArray);
    }
    else puts("No");
}

의 크기는 항상 컴파일 시 평가됩니다.멀티패스 컴파일러에서는 심볼 테이블 컴파일러를 생성하는 동안 중간 코드를 생성하기 위해 추가로 선언된 각 심볼의 크기를 결정해야 합니다.따라서 코드의 모든 크기의 참조는 정확한 값을 대체합니다.중간 코드 생성 단계에서 모든 연산자는 오른쪽 중간 코드(ASM/기타 형식)로 변환됩니다.최종적으로 m/c code 생성 단계에서 기계 코드로 변환합니다.

크기와 관련된 동적 할당에 대해 위에서 본 일부 논의는 전혀 문맥에 맞지 않습니다.p가 어떤 데이터 유형의 포인터일 때 크기(*p)를 참조하면 컴파일러는 *p의 데이터 유형을 찾아 그 크기를 대체할 뿐 할당된 블록의 MCB 헤더를 검사하여 할당된 메모리 크기가 무엇인지 확인하지 않습니다.실행 시간이 아닙니다.예를 들어 두 배의 *p; 크기(*p)는 포인터 p에 대한 메모리를 할당하지 않고도 수행할 수 있습니다.그게 어떻게 가능해?

의 크기는 컴파일 타임에 계산됩니다.동적 배열을 생성할 때 다음과 같은 방법으로 동적 배열을 생성하는 이유입니다.

char * array;
int size;
//Get size somehow.
array = malloc(size*(sizeof(char)));

// 컴파일하는 동안 컴파일러는 char의 크기를 확실히 알고 있습니다. 왜냐하면 그것들을 메모리에 맞추어야 하기 때문입니다.이 시점에서 OS는 자신이 할당해야 할 크기를 알고 있습니다.

반면에 가변 길이 배열은 스택생성됩니다.그러나 malloc 할당된 메모리는 힙에 생성됩니다.

언급URL : https://stackoverflow.com/questions/3579361/how-does-sizeof-know-the-size-of-the-operand-array

반응형