2012-02-15 2 views
0

예기치 않은 결과가 반환되고 있습니다. 때로는 그들이 옳다. 때로는 완전히 이상합니다. 누구든지 무엇이 잘못되었는지 말할 수 있습니까?배열 길이 계산 이상

#include <stdio.h> 
int len(int[]); 

int main (int argc, const char * argv[]) 
{ 
    int a[]={1,2,3,4,5,6,7,8}; 
    int* i = a; 
    printf("length is %d",(len(i))); 
    return 0; 
} 

int len(int* a){ 
    int count = 0; 
    for (; *a!='\0'; a++) { 
     count++; 
    } 
    return count; 
} 
+2

예 - 당신이하려는 것은 본질적으로 결함이 있습니다. C에서 배열 길이를 셀 수는 없습니다. 실제 배열이 있다면'#define ARRLEN (arr) (sizeof (arr)/sizeof (* arr))'을 사용할 수 있지만 포인터에는 사용할 수 없습니다. 따라서 함수에 전달 된 배열에서. –

답변

3

C 문자열 (배열 char)과 다른 배열 사이에는 혼란 스럽다고 생각됩니다. C 문자열은 null 문자 ('\0')로 끝나지만 모든 배열 (심지어 char 배열)이이 방법으로 종료되지 않는 규칙입니다.

일반적으로 배열의 길이를 어딘가에 저장하거나 배열 끝에 센티널 값을 사용하는 것이 일반적입니다. 이 값은 배열 내부에 나오지 않는 값이어야합니다. 예를 들어, 문자열에 '\0' 또는 양의 정수 배열에 -1이 있어야합니다.

size_t length = sizeof(a)/sizeof(a[0]); 

그래서 당신은 할 수 :

int a[] = {1,2,3,4,5,6,7,8}; 
size_t length = sizeof(a)/sizeof(a[0]); 

// In this case, sizeof(a[0]) 
// is the same as sizeof(int), because it's an int array. 

당신이 a이 int 배열 (그리고있는 int 배열이 아닌 포인터), 당신이 사용할 수있는 것을 알고있는 경우 또한

, 그러나 당신은 할 수 없습니다 :

int *a = malloc(sizeof(int) * 10); 
size_t length = sizeof(a)/sizeof(a[0]); // WRONG! 

마지막 예제는 컴파일되지만 대답은 잘못 될 것입니다. 배열의 크기보다는 배열에 대한 포인터의 크기를 얻습니다.

sizeof을 사용하여 함수에 전달 된 배열의 크기를 읽을 수도 없습니다. 컴파일러가 함수 인수의 배열을 첫 번째 요소의 포인터로 변환하기 때문에 함수 len(int *a) 또는 len(int a[]) - a이 포인터가 될지 여부는 중요하지 않습니다.

+0

길이에 대해 'int'? \ * shudder \ * (그리고 이것을'size_t'로 고치면 sizeof (int)를 sizeof (a [0])로 변경하는 것도 고려해보십시오.) –

+0

@ChrisLutz 죄송합니다. 계산식이 무엇인지 명확하게하기 위해'a [0]'대신'int'를 사용했습니다. 그러나 대신 단어로 표현해야한다고 생각합니다. 업데이트 된 :) –

7

거기에 넣지 않으면 배열 끝에 0이 없습니다! 문자열을 사용하여 정의 된 리터럴 char 배열은 참으로 센티널 값을 가지지 만 특별한 것은 아닙니다. 다른 배열에는 해당 사항이 없습니다.

당신이 쓰려고하는 함수는 C의 일반 배열에 쓸 수 없습니다. 메모리 할당 자의 (문서화되지 않은 플랫폼에 특정한) 내부 구조를 사용하지 않고 동적 배열의 크기를 결정할 방법이 없습니다. 응용 프로그램에서이 작업을 수행하는 것이 중요하다면 명시 적으로 모든 배열 끝에 0을 추가 할 수있는 경우에만 수행 할 수 있습니다.

1

그런 배열 수는 계산할 수 없습니다. 문자열 만이 null로 끝납니다. 이를 안정적으로 작동 시키려면 배열에 '\ 0'을 포함하는 요소를 추가해야합니다. 그러나 '\ 0'때문에 실제 길이가 1보다 길지는 않을 것임을 고려해야합니다.

1

문자열과 달리 일반 배열은 null 바이트 0x00으로 종료되지 않습니다. 문자열이 이것을 사용하는 이유는 배열에 길이 개념이 없기 때문입니다. 배열은 연속적인 메모리 조각 일뿐입니다. 배열의 길이를 추적하는 것은 당신에게 달려 있습니다.