IT TIP

배열, 고정 크기 배열 및 배열의 ​​기본 주소를 함수 매개 변수로 전달하는 것의 차이점

itqueen 2021. 1. 6. 20:37
반응형

배열, 고정 크기 배열 및 배열의 ​​기본 주소를 함수 매개 변수로 전달하는 것의 차이점


알려진 또는 알려지지 않은 크기의 배열을 함수 매개 변수로 전달하려는 경우 사용할 구문에 대해 혼란스러워합니다.

목적을 위해 이러한 변형이 있다고 가정합니다.

void func1(char* str) {
    //print str
}

void func2(char str[]) {
    //print str
}

void func3(char str[10]) {
    //print str
}

이들 각각을 사용하는 장점과 단점은 무엇입니까?


이러한 모든 변형은 동일합니다. C를 사용하면 대체 철자를 사용할 수 있지만 배열 크기로 명시 적으로 주석이 추가 된 마지막 변형도 일반 포인터로 감소합니다.

즉, 마지막 구현에서도 모든 크기 의 배열로 함수를 호출 할 수 있습니다.

void func3(char str[10]) { }

func("test"); // Works.
func("let's try something longer"); // Not a single f*ck given.

말할 필요도없이 이것을 사용해서는 안됩니다 . 사용자에게 잘못된 보안 감각을 줄 수 있습니다 ( "오,이 함수는 길이 10의 배열 만 허용하므로 길이를 직접 확인할 필요가 없습니다").

헨릭 말했듯이, 올바른 방법 C ++로는 사용하는 것입니다 std::string, std::string&또는 std::string const&(개체를 수정할 필요가 있는지 여부에 따라, 당신은 복사 할 여부).


C ++에서 배열의 길이가 컴파일 타임에 알려진 경우 (예 : 문자열 리터럴을 전달한 경우) 실제로 크기를 얻을 수 있습니다.

template<unsigned int N>
void func(const char(&str)[N])
{
    // Whatever...
}

int main()
{
    func("test"); // Works, N is 5
}

C ++에서는 void func4(const std::string& str).


이들은 모두 기능적으로 동일합니다. C의 함수에 배열을 전달하면 배열이 암시 적으로 배열의 첫 번째 요소에 대한 포인터로 변환됩니다. 따라서이 세 가지 함수는 동일한 출력 (즉,에 대한 포인터의 크기)을 인쇄합니다 char.

void func1(char* str) {
    printf("sizeof str: %zu\n", sizeof str);
}

void func2(char str[]) {
    printf("sizeof str: %zu\n", sizeof str);
}

void func3(char str[10]) {
    printf("sizeof str: %zu\n", sizeof str);
}

이 변환은 배열의 첫 번째 차원에만 적용됩니다. A는 char[42][13]A를 변환됩니다 char (*)[13], 하지char ** .

void func4(char (*str_array)[13]) {
    printf("sizeof str_array: %zu\n"
           "sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}

char (*)[13] is the type of str_array. It's how you write "a pointer to an array of 13 chars". This could have also been written as void func4(char str_array[42][13]) { ... }, though the 42 is functionally meaningless as you can see by experimenting, passing arrays of different sizes into func4.

In C99 and C11 (but not C89 or C++), you can pass a pointer to an array of varying size into a function, by passing it's size along with it, and including the size identifier in the [square brackets]. For example:

void func5(size_t size, char (*str_array)[size]) {
    printf("sizeof str_array: %zu\n"
           "sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}

This declares a pointer to an array of size chars. Note that you must dereference the pointer before you can access the array. In the example above, sizeof str_array[0] evaluates to the size of the array, not the size of the first element. As an example, to access the 11th element, use (*str_array)[11] or str_array[0][11].


In a one dimensional array they are all treated the same by the compiler. However for a two or more dimensional array, (e.g. myArray[10][10]), it is useful as it can be used to determine the row/column length of an array.


To add-on, describing in points.

1) As everyone told it is same.

2) Arrays are decayed into pointers when they are passed in the function arguments.

3) Fundamental problem could be finding the size of a array in the function. For that we can use macro like.

   #define noOfElements(v) sizeof(v)/sizeof(0[v])

   int arr[100]
   myfunction ( arr, noOfElements(arr))

either 0[v] or v[0] can be used in the macro, where the first is used to avoid user defined data type passed in to noOfElements.

Hope this helps.


In C, the first two definitions are equivalent.The third one is essentially same but it gives an idea about the size of the array.

If printing str is your intent, then you can safely use any of them.Essentially all three of the functions are passed a parameter of type char*,just what printf() needs to print a string.And lest you don't know, despite what it may seem, all parameter passing in C is done in pass-by-value mode.

Edit: Seems like I'll have to be very rigorous in my choice of words on SO henceforth.Well,in the third case it gives no idea about the size of the array to the function to which it is passed as eventually it is reduced to type char* just as in the first two cases.I meant to say it kinda tells the human reading it that the array's size is 10.Also,it is not wrong/illegal in C.But for the program,doing it is as good as useless.It gives no idea whatsoever about the array size to the function it is passed to.Mr.Downvoter, thanks for pointing out that casual attitude and negligence is not tolerated on SO.

ReferenceURL : https://stackoverflow.com/questions/16144535/difference-between-passing-array-fixed-sized-array-and-base-address-of-array-as

반응형