programing

C에서 어레이 크기를 확인하는 방법

sourcetip 2022. 8. 8. 22:56
반응형

C에서 어레이 크기를 확인하는 방법

C에서 어레이 크기를 확인하는 방법

즉, 어레이에 포함할 수 있는 요소의 수는?

이그제큐티브 요약:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

완전한 답변:

바이트 하려면 , 「」를 합니다.sizeof★★★★★★★★★★★★★★★★★★:

int a[17];
size_t n = sizeof(a);

내 컴퓨터에서는 ints의 길이가 4바이트이므로 n은 68입니다.

어레이 내의 요소 수를 결정하려면 어레이의 총 크기를 어레이 요소의 크기로 나눕니다.다음과 같은 유형으로 이 작업을 수행할 수 있습니다.

int a[17];
size_t n = sizeof(a) / sizeof(int);

/ 4을 맞혀야 하는데, 만약 '아까보다'(68 / 4 = 17)의 ,a만약 당신이 그것을 바꾸는 것을 잊었다면 당신은 끔찍한 버그를 갖게 될 것이다.sizeof(int)뿐만 아니라.

바람직한 는 '제수'입니다.sizeof(a[0])에 상당하는 「」를 참조해 주세요.sizeof(*a)을 사용법

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

또 다른 장점은 매크로에서 어레이 이름을 쉽게 파라미터화하고 다음을 얻을 수 있다는 것입니다.

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

sizeof파라미터로 수신되지 않은 어레이를 취급하는 경우에는 way가 올바른 방법입니다.함수에 파라미터로 전송된 배열은 포인터로 처리되므로sizeof는 어레이가 아닌 포인터의 크기를 반환합니다.

따라서 내부 기능에서는 이 방법이 작동하지 않습니다.항상 '''를 해 주세요.size_t size이치

테스트:

#include <stdio.h>
#include <stdlib.h>

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

출력(64비트 Linux OS의 경우):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

출력(32비트 Windows OS):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1

할 가 있다sizeof는 포인터로 축소된 배열 값을 처리할 때 도움이 되지 않습니다.배열의 시작을 가리켜도 컴파일러에게는 해당 배열의 단일 요소에 대한 포인터와 같습니다.포인터는 포인터를 초기화하는 데 사용된 어레이에 대한 다른 정보를 "기억"하지 않습니다.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

하지 말 .sizeof(사용할 수 있는 경우에도) 요소의 수 또는 바이트 단위로 배열의 두 가지 다른 크기 중 하나를 가져옵니다.이것들은 여기서 보여드리는 마지막 두 가지 경우입니다.두 가지 크기 각각에 대해 아래에 표시된 매크로를 사용하여 더 안전하게 만들 수 있습니다.그 이유는 유지 관리자에게 좋겠고 이색 그 이유는 코드의 의도를 유지관리자에게 명확히 하기 위해서입니다가 분명한 것 의도하는 것이다.sizeof(ptr)부터에서sizeof(arr)언뜻(이 방식 드러나진 않지만 써 놓)니에서 벌레들이 모두가 코드 읽기 위해 분명하다.언뜻 보면(이렇게 써있지는 않지만)코드를 읽는 모든 사람이 버그를 알 수 있습니다.


TL;DR:

#define ARRAY_SIZE(arr)     (sizeof(arr) / sizeof((arr)[0]) + must_be_array(arr))

#define ARRAY_SSIZE(arr)    ((ptrdiff_t)ARRAY_SIZE(arr))

#define ARRAY_BYTES(arr)    (sizeof(arr) + must_be_array(arr))

#define ARRAY_SBYTES(arr)   ((ssize_t)ARRAY_BYTES(arr))

must_be_array(arr)(아래에서 정의) 버그가 있는 IS가 필요합니다(2020년 4월 현재).

#define is_same_type(a, b)  __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)       (!is_same_type((arr), &(arr)[0]))
#define must_be(e)          (                                           \
        0 * (int)sizeof(                                                \
                struct {                                                \
                        static_assert(e);                               \
                        char ISO_C_forbids_a_struct_with_no_members__;  \
                }                                                       \
        )                                                               \
)
#define must_be_array(arr)  must_be(is_array(arr))

이 토픽에 관한 중요한 버그가 있습니다.https://lkml.org/lkml/2015/9/3/428

저는 Linus가 제공하는 해결책에 동의하지 않습니다. 즉, 함수의 파라미터에 배열 표기법을 사용하지 않는 것입니다.

포인터가 배열로 사용되고 있다는 문서로서 배열 표기를 좋아합니다.그러나 이는 버그 코드를 작성할 수 없도록 오류 방지 솔루션을 적용해야 한다는 것을 의미합니다.

어레이에는 다음 3가지 사이즈가 있습니다.

  • 배열 요소의 크기
  • 배열의 요소 수
  • 어레이가 메모리에서 사용하는 바이트 크기

배열 요소의 크기

첫 번째는 매우 간단합니다.배열이든 포인터든 같은 방법으로 처리되기 때문에 상관없습니다.

사용 예:

void foo(ptrdiff_t nmemb, int arr[static nmemb])
{
        qsort(arr, nmemb, sizeof(arr[0]), cmp);
}

qsort()그 세번째 인수로 이 값을 높여야 합니다는 이 값을 세 번째 인수로 필요로 합니다.


질문의 주제인 다른 두 가지 크기에 대해서는 어레이를 다루고 있는지 확인하고 그렇지 않으면 컴파일을 중단해야 합니다. 포인터를 취급하면 잘못된 값이 나오기 때문입니다.컴파일이 깨지면 어레이가 아니라 포인터로 처리했음을 쉽게 알 수 있으며 포인터 뒤에 어레이 크기를 저장하는 변수 또는 매크로로 코드를 작성해야 합니다.


배열의 요소 수

이것은 가장, 대답은 별로 전형적인 매크로이것은가장 일반적인 것으로, 많은 답변이 전형적인 매크로를 제공하고 있습니다로 보실 수 있도록 흔하다.ARRAY_SIZE:

#define ARRAY_SIZE(arr)     (sizeof(arr) / sizeof((arr)[0]))

는의 결과가의 결과인 것이다.ARRAY_SIZE일반적으로부호 있는함께 사용됩니다 변수와 유형의 일반적으로 형식의 부호 있는 변수를 사용합니다.ptrdiff_t, 이 매크로의 사인된 변형을 정의하기:, 이 매크로의 부호 있는 배리언트를 정의하는 것이 좋습니다 좋다.

#define ARRAY_SSIZE(arr)    ((ptrdiff_t)ARRAY_SIZE(arr))

이상 2대이상의 어레이와 Arrays.PTRDIFF_MAX회원들은 매크로의 이 서명된 버전에 대해 유효하지 않값을 주고자 했지만, C17을 읽는 것으로부터::그런 6.5.6.9, 배열 이미 불 장난을 하고 있고 있다.멤버는 이 서명된 버전의 매크로에 유효하지 않은 값을 제공하지만 C17::6.5.6.9로읽으면 이미 이와 같은어레이가fire로재생되고 있습니다.오직 오직.ARRAY_SIZE ★★★★★★★★★★★★★★★★★」size_t그런 일들의 경우에 사용되어야 합니다.그런 경우에는 사용해야 합니다.

GCC 8 등의 최신 버전의 컴파일러에서는 이 매크로를 포인터에 적용하면 경고가 표시되므로 이 매크로가 안전합니다(오래된 컴파일러를 사용하여 안전하게 할 수 있는 다른 방법이 있습니다.

전체 배열의 크기(바이트 단위)를 각 요소의 크기로 나누는 방식으로 작동합니다.

사용 예:

void foo(ptrdiff_t nmemb)
{
        char buf[nmemb];

        fgets(buf, ARRAY_SIZE(buf), stdin);
}

void bar(ptrdiff_t nmemb)
{
        int arr[nmemb];

        for (ptrdiff_t i = 0; i < ARRAY_SSIZE(arr); i++)
                arr[i] = i;
}

이러한 함수가 어레이를 사용하지 않고 파라미터로 취득하면 이전 코드가 컴파일되지 않기 때문에 버그(최근 컴파일러 버전이 사용되고 있거나 다른 트릭이 사용되고 있는 것을 고려하면)가 발생하지 않으므로 매크로 호출을 값으로 대체해야 합니다.

void foo(ptrdiff_t nmemb, char buf[nmemb])
{

        fgets(buf, nmemb, stdin);
}

void bar(ptrdiff_t nmemb, int arr[nmemb])
{

        for (ptrdiff_t i = 0; i < nmemb; i++)
                arr[i] = i;
}

어레이가 메모리에서 사용하는 바이트 크기

ARRAY_SIZE이전 케이스에 대한 해결책으로 일반적으로 사용되지만, 이 케이스는 그다지 흔하지 않아서인지 안전하게 작성되는 경우는 거의 없습니다.

인 방법은 ""를 사용하는 입니다.sizeof(arr)문제: 이전 것과 같습니다.배열 대신 포인터가 있으면 프로그램이 미쳐버립니다.

이 문제의 해결 방법에는 이전과 같은 매크로를 사용하는 것이 포함됩니다(포인터에 적용하면 컴파일이 중단됩니다).

#define ARRAY_BYTES(arr)        (sizeof((arr)[0]) * ARRAY_SIZE(arr))

는 ARARY_BYTS를 .ssize_t,이 좋습니다.예를 들어, 부호 있는 배리언트를 정의하는 것이 좋습니다

#define ARRAY_SBYTES(arr)       ((ssize_t)ARRAY_BYTES(arr))

. 즉, 대로 되돌리는 것이다.이것에 의해, 다음의 구분이 해제됩니다.ARRAY_SIZE 후에는 1개의 .sizeof(arr)단, 의 안전성이 향상되었습니다.ARRAY_SIZE★★★★★★ 。

사용 예:

void foo(ptrdiff_t nmemb)
{
        int arr[nmemb];

        memset(arr, 0, ARRAY_BYTES(arr));
}

memset()이 노래의 주인공입니다.

이전과 같이 어레이가 파라미터(포인터)로 수신되면 컴파일되지 않으므로 매크로 호출을 값으로 대체해야 합니다.

void foo(ptrdiff_t nmemb, int arr[nmemb])
{

        memset(arr, 0, sizeof(arr[0]) * nmemb);
}

업데이트(23/apr/2020): 버그가 있습니다.

오늘 GCC의 새로운 경고는 매크로가 시스템헤더가 아닌 헤더에 정의되어 있는 경우에만 기능한다는 것을 알게 되었습니다.하는 경우(통상은 「」를 참조해 주세요)./usr/local/include/ ★★★★★★★★★★★★★★★★★」/usr/include/ ) ( ) (#include <foo.h>컴파일러는 경고를 표시하지 않습니다(GCC 9.3.0을 사용해 보았습니다).

, 이렇게 '우리'가 있어요.#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) C2X가 필요합니다.static_assert()및 일부 GCC 확장: 식에서의 문장과 선언, __builtin_types_compatible_p:

#include <assert.h>


#define is_same_type(a, b)      __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)           (!is_same_type((arr), &(arr)[0]))
#define Static_assert_array(arr) static_assert(is_array(arr))

#define ARRAY_SIZE(arr)         (                                       \
{                                                                       \
        Static_assert_array(arr);                                       \
        sizeof(arr) / sizeof((arr)[0]);                                 \
}                                                                       \
)

, 이제ARRAY_SIZE()완전히 안전하기 때문에 모든 파생상품이 안전할 것입니다.


는 "libbsd"를 제공합니다.__arraycount():

Libbsd는 매크로를 제공합니다.__arraycount()는, 괄호 쌍이 없기 때문에 안전하지 않습니다만, 이러한 괄호를 스스로 추가할 수 있기 때문에, 헤더에 분할을 쓸 필요도 없습니다(이미 존재하는 코드를 복제하는 이유는 무엇입니까?).이 매크로는 시스템 헤더에 정의되어 있기 때문에 사용할 경우 위의 매크로를 사용해야 합니다.

#inlcude <assert.h>
#include <stddef.h>
#include <sys/cdefs.h>
#include <sys/types.h>


#define is_same_type(a, b)      __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)           (!is_same_type((arr), &(arr)[0]))
#define Static_assert_array(arr) static_assert(is_array(arr))

#define ARRAY_SIZE(arr)         (                                       \
{                                                                       \
        Static_assert_array(arr);                                       \
        __arraycount((arr));                                            \
}                                                                       \
)

#define ARRAY_SSIZE(arr)        ((ptrdiff_t)ARRAY_SIZE(arr))
#define ARRAY_BYTES(arr)        (sizeof((arr)[0]) * ARRAY_SIZE(arr))
#define ARRAY_SBYTES(arr)       ((ssize_t)ARRAY_BYTES(arr))

「」가 제공되고 있습니다.nitems()시스템에 따라서는 둘 다 제공됩니다.시스템을 체크하고, 가지고 있는 것을 사용해 주세요.또, 휴대성과 서포트를 위해서 프리프로세서의 조건을 몇개인가 사용할 수도 있습니다.


업데이트: 파일 범위에서 매크로 사용 허용:

도 ★★★★★★★★★★★★★★★★★.({})cccc 、 gcc 、 gcc 、 gcc 、 gcc 、 gcc 、 gcc 、 gcc 、 gcc 。수이 내부에 .sizeof(struct {})ㄴㄴㄴ데, ㄴ데를 됩니다0★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★(int)반환되는 함수를 시뮬레이트하는 것이 좋습니다.(int)0(이 경우 필수는 아니지만 다른 용도로 재사용할 수 있습니다).

「 」의 정의, 「 」ARRAY_BYTES()조금 단순화할 수 있습니다.

#include <assert.h>
#include <stddef.h>
#include <sys/cdefs.h>
#include <sys/types.h>


#define is_same_type(a, b)     __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr)          (!is_same_type((arr), &(arr)[0]))
#define must_be(e)             (                                        \
        0 * (int)sizeof(                                                \
                struct {                                                \
                        static_assert(e);                               \
                        char ISO_C_forbids_a_struct_with_no_members__;  \
                }                                                       \
        )                                                               \
)
#define must_be_array(arr)      must_be(is_array(arr))

#define ARRAY_SIZE(arr)         (__arraycount((arr)) + must_be_array(arr))
#define ARRAY_SSIZE(arr)        ((ptrdiff_t)ARRAY_SIZE(arr))
#define ARRAY_BYTES(arr)        (sizeof(arr) + must_be_array(arr))
#define ARRAY_SBYTES(arr)       ((ssize_t)ARRAY_BYTES(arr))

주의:

이 코드에서는 다음과 같은 확장이 사용되며, 이러한 확장은 완전히 필요하며, 이러한 확장은 안전을 확보하기 위해 반드시 필요합니다.컴파일러에 이러한 기능이 없거나 유사한 기능이 없으면 이 수준의 안전성을 얻을 수 없습니다.

또, 이하의 C2X 기능을 사용하고 있습니다.그러나 오래된 표준을 사용함으로써 이러한 부재는 몇 가지 더러운 속임수를 사용하여 극복할 수 있습니다(예:C코드의 ":-!!"는 무엇입니까? (C11에도 있습니다)static_assert()(비유, 비유, 비유)

sizeof"꼼수"는 제가 아는 가장 좋은 방법인데, 하나는 작지만 (이것이) 괄호 사용에 있어서 중요한 변화입니다.

알 수 의 Wikipedia는 입니다.sizeof함수가 아니라 연산자입니다.따라서 인수가 유형 이름이 아닌 한 인수 주위에 괄호를 둘 필요가 없습니다.이것은 주장을 캐스트 표현처럼 보이게 하고 괄호도 사용하기 때문에 기억하기 쉽습니다.

그래서: 다음이 있는 경우:

int myArray[10];

다음과 같은 코드로 요소의 수를 찾을 수 있습니다.

size_t n = sizeof myArray / sizeof *myArray;

괄호 안에 있는 대안보다 훨씬 쉽게 읽을 수 있습니다.또한 색인화보다 더 간결하기 때문에 나눗셈 오른쪽 부분에 별표를 사용하는 것이 좋습니다.

물론 이것도 모두 컴파일 타임이기 때문에 프로그램의 퍼포먼스에 영향을 주는 분할에 대해서는 걱정할 필요가 없습니다.그러니 이 양식을 아무데나 사용하세요.

사용하시는 좋습니다.sizeof어떤 타입이 아닌 실제 오브젝트가 있는 경우 오류나 잘못된 타입을 말할 염려가 없어집니다.

예를 들어, 일부 데이터를 바이트 스트림으로 출력하는 함수가 있다고 가정합니다. 예를 들어, 네트워크를 통해 출력하는 경우입니다. 함수를 '함수'라고 불러볼까요send()송신하는 오브젝트에 대한 포인터와 오브젝트내의 바이트수를 인수로 합니다.츠키다

void send(const void *object, size_t size);

그런 다음 정수를 전송해야 합니다.그래서 다음과 같이 코드화합니다.

int foo = 4711;
send(&foo, sizeof (int));

그럼 이번에는 '의 발을 을 '자신의 발을 쏘는 방법'의 foo 다른 않으면 깨집니다.한쪽이 변경되고 다른 한쪽이 변경되지 않으면 코드가 깨집니다.따라서 항상 다음과 같이 하십시오.

send(&foo, sizeof foo);

이제 넌 보호받았어물론 변수 이름을 복제하지만, 변경 시 컴파일러가 탐지할 수 있는 방법이 깨질 가능성이 높습니다.

int size = (&arr)[1] - arr;

자세한 내용은 이 링크를 참조하십시오.

「」ARRAYELEMENTCOUNT(x)모든 사람이 평가를 잘못 사용하고 있다는 것입니다.실제로는 '어레이' 타입의 표현은 할 수 없기 때문에 이것은 단지 민감한 문제일 뿐입니다.

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))

ARRAYELEMENTCOUNT(p + 1);

실제 평가:

(sizeof (p + 1) / sizeof (p + 1[0]));

반면에.

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])

ARRAYELEMENTCOUNT(p + 1);

올바른 평가:

(sizeof (p + 1) / sizeof (p + 1)[0]);

이는 어레이의 크기와는 그다지 관계가 없습니다.C 프리프로세서가 제대로 동작하지 않는 것으로부터, 많은 에러가 발생하고 있는 것을 알게 되었습니다.매크로 파라미터는 항상 랩합니다.의 식은 관여하지 않습니다.


을 사용하다★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 말씀드린 바와 같이 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」p + 1포인터 타입이 되어 전체 매크로가 무효가 됩니다(포인터 파라미터가 있는 함수의 매크로를 사용하려고 했을 때와 같음).

결국, 이 특별한 경우, 결점은 별로 중요하지 않습니다(따라서 모두의 시간을 낭비하고 있을 뿐입니다). 왜냐하면 '어레이' 타입의 표현이 없기 때문입니다.하지만 프로세서의 평가 하위 항목에 대한 요점은 매우 중요하다고 생각합니다.

sizeof 연산자는 사용할 수 있지만 포인터의 참조를 사용하기 때문에 함수에서는 작동하지 않습니다.배열 길이를 찾기 위해 다음을 수행할 수 있습니다.

len = sizeof(arr)/sizeof(arr[0])

원래 여기에 있는 코드: 배열 내의 요소 수를 찾는 C 프로그램

어레이 크기(C):

int a[10];
size_t size_of_array = sizeof(a);      // Size of array a
int n = sizeof (a) / sizeof (a[0]);    // Number of elements in array a
size_t size_of_element = sizeof(a[0]); // Size of each element in array a                                          
                                       // Size of each element = size of type

"자신의 발을 쏘는 교묘한 방법을 도입했다"

네이티브 어레이는 크기를 저장하지 않습니다.따라서 배열의 길이를 별도의 변수/정수에 저장하고 배열을 통과할 때마다 전달하는 것이 좋습니다. 즉, 다음과 같습니다.

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

네이티브 어레이는 항상 피해야 합니다(그렇지 않은 한, 주의를 기울이십시오).C++ 를 쓰는 경우는, STL 의 「벡터」컨테이너를 사용합니다.「어레이와 비교하면, 거의 같은 퍼포먼스를 실현해, 훨씬 편리합니다.」

// vector is a template, the <int> means it is a vector of ints
vector<int> numbers;  

// push_back() puts a new value at the end (or back) of the vector
for (int i = 0; i < 10; i++)
    numbers.push_back(i);

// Determine the size of the array
cout << numbers.size();

참조: http://www.cplusplus.com/reference/stl/vector/

다차원 어레이의 경우 조금 더 복잡합니다.종종 사람들은 명시적인 매크로 상수를 정의한다.

#define g_rgDialogRows   2
#define g_rgDialogCols   7

static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
{
    { " ",  " ",    " ",    " 494", " 210", " Generic Sample Dialog", " " },
    { " 1", " 330", " 174", " 88",  " ",    " OK",        " " },
};

그러나 이러한 상수는 컴파일 시 다음과 같은 크기로도 평가할 수 있습니다.

#define rows_of_array(name)       \
    (sizeof(name   ) / sizeof(name[0][0]) / columns_of_array(name))
#define columns_of_array(name)    \
    (sizeof(name[0]) / sizeof(name[0][0]))

static char* g_rgDialog[][7] = { /* ... */ };

assert(   rows_of_array(g_rgDialog) == 2);
assert(columns_of_array(g_rgDialog) == 7);

이 코드는 C 및 C++로 동작합니다.2차원 이상의 어레이의 경우

sizeof(name[0][0][0])
sizeof(name[0][0][0][0])

etc, ad ininitum.

sizeof(array) / sizeof(array[0])

어레이의 데이터 유형을 알고 있는 경우 다음과 같은 방법을 사용할 수 있습니다.

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};

int noofele = sizeof(arr)/sizeof(int);

또는 어레이의 데이터 유형을 모르는 경우 다음과 같은 방법을 사용할 수 있습니다.

noofele = sizeof(arr)/sizeof(arr[0]);

주의: 이 기능은 어레이가 실행 시(malloc 등)에 정의되어 있지 않고 어레이가 함수로 전달되지 않은 경우에만 작동합니다.경우든, 「」는,arr

보다 우아한 솔루션은

size_t size = sizeof(a) / sizeof(*a);

★★sizeof메모리 내의 어레이가 사용하는 바이트 수를 반환합니다.이를 '수'로 .sizeof배열의 변수 유형입니다. '우리'라고 합시다.int array[10];컴퓨터의 변수 유형 정수가 32비트(또는 4바이트)인 경우 어레이 크기를 가져오려면 다음을 수행해야 합니다.

int array[10];
int sizeOfArray = sizeof(array)/sizeof(int);
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))

가장 간단한 답변:

#include <stdio.h>

int main(void) {

    int a[] = {2,3,4,5,4,5,6,78,9,91,435,4,5,76,7,34};//for Example only
    int size;

    size = sizeof(a)/sizeof(a[0]);//Method

    printf ("size = %d",size);
    return 0;
}

어레이를 전달하려면 어레이의 크기를 나타내는 정수와 어레이에 대한 포인터를 저장하는 구조를 구현하는 것이 좋습니다.그리고 나서 당신은 당신의 기능에 그것을 전달할 수 있습니다.해당 포인터에 배열 변수 값(첫 번째 요소에 대한 포인터)을 할당하기만 하면 됩니다. 됩니다.Array.arr[i] i번째 원소를 Array.size이치

당신을 위해 코드를 포함했습니다.별로 유용하지는 않지만 더 많은 기능으로 확장할 수 있습니다.단, 솔직히 이런 것들이 당신이 원하는 것이라면 당신은 C 사용을 중지하고 이러한 기능들이 내장된 다른 언어를 사용해야 합니다.

/* Absolutely no one should use this...
   By the time you're done implementing it you'll wish you just passed around
   an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and 
   cut out the array in main by using the stdlib memory allocation methods,
   but it will work much slower since it will store your array on the heap */

#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h 
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
   int age;
   char name[20];
} MyType;
typedef struct MyTypeArray
{
   int size;
   MyType *arr;
} MyTypeArray;

MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */

/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
   MyType d;
   d.age = age;
   strcpy(d.name, name);
   return d;
}

MyTypeArray new_MyTypeArray(int size, MyType *first)
{
   MyTypeArray d;
   d.size = size;
   d.arr = first;
   return d;
}
/* End MyTypeArray.c */


void print_MyType_names(MyTypeArray d)
{
   int i;
   for (i = 0; i < d.size; i++)
   {
      printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
   }
}

int main()
{
   /* First create an array on the stack to store our elements in.
      Note we could create an empty array with a size instead and
      set the elements later. */
   MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
   /* Now create a "MyTypeArray" which will use the array we just
      created internally. Really it will just store the value of the pointer
      "arr". Here we are manually setting the size. You can use the sizeof
      trick here instead if you're sure it will work with your compiler. */
   MyTypeArray array = new_MyTypeArray(2, arr);
   /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
   print_MyType_names(array);
   return 0;
}

.&과 같습니다츠키다

#include<stdio.h>
#include<stdlib.h>
int main(){

    int a[10];

    int *p; 

    printf("%p\n", (void *)a); 
    printf("%p\n", (void *)(&a+1));
    printf("---- diff----\n");
    printf("%zu\n", sizeof(a[0]));
    printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));


    return 0;
};

다음은 샘플 출력입니다.

1549216672
1549216712
---- diff----
4
The size of array a is 10

가장 좋은 방법은 이 정보를 다음과 같은 구조로 저장하는 것입니다.

typedef struct {
     int *array;
     int elements;
} list_s;

생성, 파괴, 평등 확인 등 필요한 모든 기능을 구현합니다.매개 변수로 전달하기가 더 쉽습니다.

사전 정의된 배열의 경우:

 int a[]={1,2,3,4,5,6};

배열 내 요소 수 계산:

 element _count =sizeof(a) / sizeof(a[0]);

주의: 이것은 M이 지적한 정의되지 않은 동작을 제공할 수 있습니다.댓글에 M.

int a[10];
int size = (*(&a+1)-a) ;

상세한 것에 대하여는, 여기를 참조해 주세요.

이미 제공된 답변 외에, 다음을 사용하여 특별한 사례를 지적하고 싶습니다.

sizeof(a) / sizeof (a[0])

ifa의 배열 중 하나입니다.char,unsigned char ★★★★★★★★★★★★★★★★★」signed char 쓸 요.sizeof 두 번sizeof이러한 1로 귀결됩니다.1.

C18,6.5.3.4/4에서 인용:

타입, 타입, 또는 (또는 한정판) 가지는 오퍼랜드에 적용하면, 결과는 「」입니다.

thus따는sizeof(a) / sizeof (a[0]) 동등하다NUMBER OF ARRAY ELEMENTS / 1a는 타입의 입니다.char,unsigned char ★★★★★★★★★★★★★★★★★」signed char. ~1 ~1까지 나누다

이 경우 생략하여 다음 작업을 수행할 수 있습니다.

sizeof(a)

예를 들어 다음과 같습니다.

char a[10];
size_t length = sizeof(a);

증명이 필요한 경우 GodBolt에 대한 링크가 있습니다.


그럼에도 불구하고 유형이 현저하게 변화할 경우(이러한 경우는 드물지만) 사업부는 안전을 유지한다.

언급URL : https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c

반응형