의 크기가 피연산자 배열의 크기를 어떻게 알 수 있습니까?
이것은 바보 같은 질문일 수도 있지만 배열의 요소 양을 전달하지 않을 때 연산자의 크기가 배열 피연산자의 크기를 어떻게 알 수 있습니까?어레이의 전체 요소를 반환하는 것이 아니라 바이트 단위의 크기를 반환한다는 것은 알고 있지만, 어레이가 언제 종료되는지는 여전히 알아야 합니다.이게 어떻게 작동하는지 궁금할 뿐입니다.
sizeof
컴파일 시 해석되며 컴파일러는 배열이 어떻게 선언되었는지(따라서 얼마나 많은 공간을 차지하는지) 알고 있습니다.호출sizeof
동적으로 변환된 배열에서는 배열의 끝점이 지정되지 않았기 때문에 원하는 작업을 수행하지 않을 가능성이 높습니다.
이 문제를 이해하는 데 어려움을 겪는 근본적인 문제는 많은 사람들이 그러하듯이 배열과 포인터를 혼동하기 때문일 수 있습니다.하지만 배열은 포인터가 아닙니다. Adouble da[10]
는 10열의 입니다.double
, 한푼도double*
할 때 알 수 . 평가를 요청하면, 은 이 를 할 에게 sizeof(da)
가 안다고 해서 가 는 입니다 입니다 는 가 .sizeof(double)
?
배열의 문제는 많은 맥락에서 (함수로 전달될 때와 같이) 첫 번째 요소에 대한 포인터로 자동으로 붕괴된다는 것입니다.그러나 배열은 배열이고 포인터는 포인터입니다.
한가지 경우를 제외하고는sizeof
컴파일 타임에 할 수 있습니다.컴파일 시, 컴파일러는 개체의 전체 유형을 추적합니다. [편집: 어쨌든 개체의 유형에 대해 알고 있는 모든 것 - 크기를 포함하지 않는 유형이 완전하지 않으면 사용을 시도합니다.sizeof
실패할 것입니다] 및sizeof
기본적으로 컴파일러에서 해당 정보의 한 부분을 컴파일되는 코드로 "변환"하여 결과 코드에서 본질적으로 상수가 됩니다.
는 는 과 과 는 입니다.sizeof
는 1VLA(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
'programing' 카테고리의 다른 글
자바스크립트 이벤트에 Ajax vs Json을 언제 사용할 것인가요? (0) | 2023.09.12 |
---|---|
AWS RDS 세션 대 Global sql mode Setting 값 (0) | 2023.09.12 |
MariaDB MySQL 최적화 (0) | 2023.09.07 |
도커 파일에서 변수를 정의하는 방법은? (0) | 2023.09.07 |
jQuery UI 없이 자동 완성 (0) | 2023.09.07 |