IT

배열 변수의 크기가 main에서와 동일하지 않은 이유는 무엇입니까?

lottoking 2020. 8. 19. 18:51
반응형

배열 변수의 크기가 main에서와 동일하지 않은 이유는 무엇입니까?


매개 변수로 전송되는 배열의 크기가 main 내에서와 동일하지 않은 이유는 무엇입니까?

#include <stdio.h>

void PrintSize(int p_someArray[10]);

int main () {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* As expected, 40 */
    PrintSize(myArray);/* Prints 4, not 40 */
}

void PrintSize(int p_someArray[10]){
    printf("%d\n", sizeof(p_someArray));
}

배열 유형은 함수에 즉시 암시 적으로 포인터 유형으로 변환됩니다.

그래서,

void PrintSize(int p_someArray[10]) {
    printf("%zu\n", sizeof(p_someArray));
}

void PrintSize(int *p_someArray) {
    printf("%zu\n", sizeof(p_someArray));
}

동등합니다. 그래서 당신이 얻는 것은sizeof(int*)


포인터이기 때문에 배열의 크기를 함수에 두 번째 매개 변수로 전달하는 것이 일반적인 구현입니다.


배열은 함수 변수로 배열은 첫번째 요소에 대한 포인터로 붕괴됩니다. 또한 sizeof는 사용하지 않고 사용할 때 평가하지 않고 사용하지 않고 사용할 때 사용할 변수가 실제로 사용되지 않은 값이 아닌 유형 크기를 작성하는 것이 좋습니다.

#include <stdio.h>

void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );

int main ()
{
    int myArray[10];
    printf ( "%d\n", sizeof myArray ); /* as expected 40 */
    printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
    PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
    PrintSize2 ( 0 ); /* prints 40, someArray unused */
}

void PrintSize1 ( int someArray[][10] )
{
    printf ( "%d\n", sizeof someArray[0] );
}

void PrintSize2 ( int someArray[10] )
{
    printf ( "%d\n", sizeof ( int[10] ) );
}

따라서 배열의 길이를 두 번째 매개 변수로 전달해야합니다. 둘 다 상수 크기의 배열을 선언하고 나중에 해당 배열을 함수에 전달하는 코드를 사용하는 배열 길이 상수가 코드의 여러 위치에 배열되는 고통 스럽습니다.

구조를위한 K & R :

#define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) 

이제 다음과 같이 할 수 있습니다.

int a[10];
...
myfunction(a, N_ELEMENTS(a));

배열은 매개 변수로 전달 될 때 포인터로 붕괴되기 때문입니다. C ++에서 "배열"을 참조로 전달 하고이 문제를 해결할 수 있습니다. 크기가 다른 배열을 사용할 수 있습니다.

 // 10 is superfluous here! You can pass an array of different size!
void PrintSize(int p_someArray[10]);

당신이 실제로 행동은 C 언어에서 큰 사마귀입니다. 배열 매개 변수를 사용하는 함수를 선언 할 때마다 컴파일러는 사용자를 무시하고 다음 변수를 포인터로 변경합니다. 선언 선언 모두 첫 번째 선언 선언합니다.

void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)

a는 네 가지 경우 모두 int에 대한 포인터입니다. func에 배열을 전달하면 즉시 첫 번째 요소에 대한 포인터로 붕괴됩니다. (64 비트 시스템에서 64 비트 포인터는 32 비트 int의 두 배이므로 sizeof 비율은 2를 반환합니다.)

이 규칙의 유일한 목적은 집계 값을 함수 인수로 전달하는 것을 지원하지 않는 기록 컴파일러와의 역 호환성을 유지하는 것입니다.

이것은 배열을 함수에 전달할 수 없다는 것을 의미하지 않습니다. 배열을 구조체에 임베딩하여이 사마귀를 피할 수 있습니다 (기본적으로 C ++ 11의 std :: array 목적).

struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0]));  /* prints 5 */
}

또는 포인터를 배열에 전달하여 :

void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints 5 */
}

배열 크기가 컴파일 타임 상수가 아닌 경우 C99 가변 길이 배열에 포인터-배열 기술을 사용할 수 있습니다.

void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints n */
}

C ++에서는 이러한 목적을 위해 참조로 배열을 전달할 수 있습니다.

void foo(int (&array)[10])
{
    std::cout << sizeof(array) << "\n";
}

C 언어에서는 알 수없는 배열의 크기를 결정하는 방법이 없으므로 수량은 첫 번째 요소에 대한 포인터와 함께 전달되어야합니다.


함수에 배열을 전달할 수 없습니다.

정말로 크기를 인쇄하고 싶다면 배열에 포인터를 전달할 수 있지만 함수의 배열 크기도 정의해야하므로 일반적이지 않습니다.

#include <stdio.h>

void PrintSize(int (*p_anArray)[10]);

int main(void) {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* as expected 40 */
    PrintSize(&myArray);/* prints 40 */
}

void PrintSize(int (*p_anArray)[10]){
    printf("%d\n", (int) sizeof(*p_anArray));
}

동작은 의도적으로 설계된 것입니다.

함수 매개 변수 선언의 동일한 구문은 지역 변수 정의와는 완전히 다른 것을 의미합니다.

그 이유는 다른 답변에 설명되어 있습니다.


C 언어에서는 배열을 함수에 인수로 전달하면 자동으로 포인터로 변환되고, 다른 함수에서 전달되는 배열은 참조에 의한 호출로 알려져 있습니다. 이것이 호출 된 함수가 함수의 첫 번째 요소를 가리키는 포인터 만받는 이유입니다.

fun (int a [])는 fun (int * a)와 비슷합니다.

따라서 배열의 크기를 인쇄하면 첫 번째 요소의 크기가 인쇄됩니다.


'C'프로그래밍 언어에서 'sizeof ()'는 연산자이고 그는 객체의 크기를 바이트 단위로 반환합니다. 'sizeof ()'연산자의 인수는 왼쪽 값 유형 (정수, 부동 숫자, 구조체, 배열)이어야합니다. 따라서 배열의 크기를 바이트 단위로 알고 싶다면 매우 간단하게 할 수 있습니다 .'sizeof () '연산자를 사용하고 그의 인수에는 배열 이름을 사용하면됩니다.

#include <stdio.h>

main(){

 int n[10];
 printf("Size of n is: %d \n", sizeof(n)); 

}

32 비트 시스템의 출력은 다음과 같습니다 : Size of n is : 40.Because on 32 system is 4bytes. 64x on 8bytes.이 경우 하나의 배열에 10 개의 정수가 선언되어 있으므로 결과는 '10 * sizeof ( int) '.

몇 가지 팁 :

이와 같이 선언 된 배열이있는 경우 'int n [] = {1, 2, 3, ... 155 ..};'. 그래서 우리는이 배열에 얼마나 많은 요소가 저장되었는지 알고 싶습니다. 이 알고리즘을 사용하십시오.

sizeof (배열 _ 이름) / sizeof (배열 _ 유형)

코드 : #include

본관(){

int n[] = { 1, 2, 3, 44, 6, 7 };
printf("Number of elements: %d \n", sizeof(n) / sizeof(int));
return 0;

}


배열의 크기는 느슨합니다. 대부분의 경우 배열은 메모리에 대한 포인터입니다. 선언의 크기는 배열에 할당 할 메모리의 양만 컴파일러에 알려줍니다. 유형과 관련이 없으므로 sizeof ()는 계속 진행할 필요가 없습니다.

참고 URL : https://stackoverflow.com/questions/1975128/why-isnt-the-size-of-an-array-parameter-the-same-as-within-main

반응형