programing

C를 사용하여 어레이 반환

goodsources 2022. 12. 19. 21:28
반응형

C를 사용하여 어레이 반환

저는 C에 비교적 익숙하지 않기 때문에 어레이 처리 방법에 대한 도움이 필요합니다.자바 프로그래밍에서 온 저는 이렇게 말하는 것에 익숙합니다.int [] method()어레이를 반환하기 위해 사용합니다.그러나 C에서는 어레이를 반환할 때 포인터를 사용해야 한다는 것을 알게 되었습니다.저는 초보 프로그래머로서 많은 포럼을 살펴보았는데도 전혀 이해할 수 없습니다.

기본적으로 C에 char 배열을 반환하는 메서드를 작성하려고 합니다.메서드(return Array)에 어레이를 제공합니다.이전 배열에서 새 배열을 만들고 포인터를 반환합니다.이것을 기동하는 방법이나, 포인터가 어레이로부터 송신되었을 때에 읽어내는 방법에 대해서, 도움이 필요합니다.이에 대해 설명해 주시면 감사하겠습니다.

어레이 반환 함수에 대해 제안된 코드 형식

char *returnArray(char array []){
 char returned [10];
 //methods to pull values from array, interpret them, and then create new array
 return &(returned[0]); //is this correct?
} 

함수의 호출자

int main(){
 int i=0;
 char array []={1,0,0,0,0,1,1};
 char arrayCount=0;
 char* returnedArray = returnArray(&arrayCount); ///is this correct?
 for (i=0; i<10;i++)
  printf(%d, ",", returnedArray[i]);  //is this correctly formatted?
}

현재 C 컴파일러가 동작하지 않기 때문에 아직 테스트하지 않았습니다만, 이것을 확인하고 싶습니다.

C의 함수에서 어레이를 반환할 수 없습니다.또, 다음의 조작도 실행할 수 없습니다(해 두어서는 안 됩니다).

char *returnArray(char array []){
 char returned [10];
 //methods to pull values from array, interpret them, and then create new array
 return &(returned[0]); //is this correct?
} 

returned는 자동 저장 기간으로 생성되며 선언 범위를 벗어나면(즉, 함수가 돌아오면) 참조가 비활성화됩니다.

함수 내부에서 메모리를 동적으로 할당하거나 발신자가 제공한 사전 할당 버퍼를 채워야 합니다.

옵션 1:

기능내의 메모리를 동적으로 할당합니다(할당 해제의 원인이 되는 메모리).ret)

char *foo(int count) {
    char *ret = malloc(count);
    if(!ret)
        return NULL;

    for(int i = 0; i < count; ++i) 
        ret[i] = i;

    return ret;
}

이렇게 불러주세요.

int main() {
    char *p = foo(10);
    if(p) {
        // do stuff with p
        free(p);
    }

    return 0;
}

옵션 2:

발신자에 의해 제공된 사전 할당된 버퍼를 채웁니다(예: 할당).buf함수로 넘어갑니다.)

void foo(char *buf, int count) {
    for(int i = 0; i < count; ++i)
        buf[i] = i;
}

이렇게 불러주세요.

int main() {
    char arr[10] = {0};
    foo(arr, 10);
    // No need to deallocate because we allocated 
    // arr with automatic storage duration.
    // If we had dynamically allocated it
    // (i.e. malloc or some variant) then we 
    // would need to call free(arr)
}

C의 어레이 처리는 Java와 크게 다르므로 그에 따라 생각을 조정해야 합니다.C의 어레이는 퍼스트 클래스 객체가 아닙니다(즉, 어레이 표현은 대부분의 컨텍스트에서 어레이의 "어레이니스"를 유지하지 않습니다).C에서 N-element 배열 타입의 식T"는 암묵적으로 "type"의 표현으로 변환됩니다.T". 단, 어레이 식이 피연산자일 경우sizeof또는 단항&연산자 또는 선언에서 다른 배열을 초기화하기 위해 배열 식이 문자열 리터럴인 경우.

이는 특히 배열 식을 함수에 전달하여 배열 유형으로 수신할 수 없음을 의미합니다. 함수는 실제로 포인터 유형을 수신합니다.

void foo(char *a, size_t asize)
{
  // do something with a
}

int bar(void)
{
  char str[6] = "Hello";
  foo(str, sizeof str);
}

의 콜 중foo식 , 。str 「」에서 됩니다.char [6]로로 합니다.char * 첫 는 '''입니다foochar *achar a[6]sizeof strsizeof연산자는 포인터 유형으로 변환되지 않으므로 배열(6)의 바이트 수를 얻을 수 있습니다.

정말 관심이 있다면 데니스 리치의 'C 언어 개발'을 읽고 이 치료법이 어디서 왔는지 이해할 수 있다.

결과적으로 함수는 어레이 유형을 반환할 수 없습니다. 어레이 표현식도 할당 대상이 될 수 없기 때문에 문제가 없습니다.

가장 안전한 방법은 발신자가 어레이를 정의하고 어레이에 쓰는 함수에 주소와 크기를 전달하는 것입니다.

void returnArray(const char *srcArray, size_t srcSize, char *dstArray, char dstSize)
{
  ...
  dstArray[i] = some_value_derived_from(srcArray[i]);
  ...
}

int main(void)
{
  char src[] = "This is a test";
  char dst[sizeof src];
  ...
  returnArray(src, sizeof src, dst, sizeof dst);
  ...
}

또 다른 방법은 배열을 동적으로 할당하고 포인터와 크기를 반환하는 것입니다.

char *returnArray(const char *srcArray, size_t srcSize, size_t *dstSize)
{
  char *dstArray = malloc(srcSize);
  if (dstArray)
  {
    *dstSize = srcSize;
    ...
  }
  return dstArray;
}

int main(void)
{
  char src[] = "This is a test";
  char *dst;
  size_t dstSize;

  dst = returnArray(src, sizeof src, &dstSize);
  ...
  free(dst);
  ...
}

이 는, 「 」, 「 」, 「 」, 「 」의을 집니다.free이이라라

:dst에는 '일부러'에 간단한 포인터는 '일단' 포인터입니다.char 의 .char 연산자 C를 할 수 있습니다[]배열 유형 또는 포인터 유형의 식에 대한 설명(둘 다)src[i] ★★★★★★★★★★★★★★★★★」dst[i]합니다.i (''만''('', ''),src

N 요소 배열에 대한 포인터를 선언할 수 있습니다.T비슷한 걸 할 수 있어요

char (*returnArray(const char *srcArr, size_t srcSize))[SOME_SIZE]
{
  char (*dstArr)[SOME_SIZE] = malloc(sizeof *dstArr);
  if (dstArr)
  {
    ...
    (*dstArr)[i] = ...;
    ...
  }
  return dstArr;
}

int main(void)
{
  char src[] = "This is a test";
  char (*dst)[SOME_SIZE];
  ...
  dst = returnArray(src, sizeof src);
  ...
  printf("%c", (*dst)[j]);
  ...
}

상기의 몇 가지 결점이 있습니다.의 C에서는 「」, 「C」가 기대됩니다.SOME_SIZE컴파일 시간 상수가 됩니다. 즉, 함수는 하나의 배열 크기에서만 작동합니다.둘째, 첨자를 적용하기 전에 포인터의 참조를 해제해야 합니다.이치노어레이에 대한 포인터는 다차원 어레이를 다룰 때 더 효과적입니다.

이것이 주어진 문제에 대한 최선의 해결책이나 바람직한 해결책이라고 말하는 것이 아닙니다.그러나 함수는 구조물을 반환할 수 있다는 것을 기억하면 도움이 될 수 있습니다.함수는 어레이를 반환할 수 없지만 어레이를 구조체로 감싸서 반환함으로써 어레이를 반송할 수 있습니다.이것은 고정 길이 어레이에 유효합니다.

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

    typedef
    struct 
    {
        char v[10];
    } CHAR_ARRAY;



    CHAR_ARRAY returnArray(CHAR_ARRAY array_in, int size)
    {
        CHAR_ARRAY returned;

        /*
        . . . methods to pull values from array, interpret them, and then create new array
        */

        for (int i = 0;  i < size; i++ )
            returned.v[i] = array_in.v[i] + 1;

        return returned; // Works!
    } 




    int main(int argc, char * argv[])
    {
        CHAR_ARRAY array = {1,0,0,0,0,1,1};

        char arrayCount = 7;

        CHAR_ARRAY returnedArray = returnArray(array, arrayCount); 

        for (int i = 0; i < arrayCount; i++)
            printf("%d, ", returnedArray.v[i]);  //is this correctly formatted?

        getchar();
        return 0;
    }

이 기술의 장점과 단점에 대한 의견을 구합니다.나는 그렇게 하려고 애쓰지 않았다.

여기서 보고되는 다른 응답과 마찬가지로 (malloc() 호출을 통해) 힙 메모리를 사용하여 실행할 수 있지만, 항상 메모리를 관리해야 합니다(함수를 호출할 때마다 free() 함수를 사용합니다).스태틱 어레이에서도 실행할 수 있습니다.

char* returnArrayPointer() 
{
static char array[SIZE];

// do something in your array here

return array; 
}

메모리 관리에 신경 쓰지 않고 사용할 수 있습니다.

int main() 
{
char* myArray = returnArrayPointer();
/* use your array here */
/* don't worry to free memory here */
}

이 예에서는 어레이 정의에서 static 키워드를 사용하여 application-long 어레이 라이프 타임을 설정해야 반환문 후에 파기되지 않습니다.물론 이렇게 하면 애플리케이션 수명 전체에 걸쳐 메모리 내의 SIZE 바이트를 차지하므로 크기를 적절하게 조정하십시오.

이 맛있는 악마의 구현은 어떻습니까?

array.

#define IMPORT_ARRAY(TYPE)    \
    \
struct TYPE##Array {    \
    TYPE* contents;    \
    size_t size;    \
};    \
    \
struct TYPE##Array new_##TYPE##Array() {    \
    struct TYPE##Array a;    \
    a.contents = NULL;    \
    a.size = 0;    \
    return a;    \
}    \
    \
void array_add(struct TYPE##Array* o, TYPE value) {    \
    TYPE* a = malloc((o->size + 1) * sizeof(TYPE));    \
    TYPE i;    \
    for(i = 0; i < o->size; ++i) {    \
        a[i] = o->contents[i];    \
    }    \
    ++(o->size);    \
    a[o->size - 1] = value;    \
    free(o->contents);    \
    o->contents = a;    \
}    \
void array_destroy(struct TYPE##Array* o) {    \
    free(o->contents);    \
}    \
TYPE* array_begin(struct TYPE##Array* o) {    \
    return o->contents;    \
}    \
TYPE* array_end(struct TYPE##Array* o) {    \
    return o->contents + o->size;    \
}

메인

#include <stdlib.h>
#include "array.h"

IMPORT_ARRAY(int);

struct intArray return_an_array() {
    struct intArray a;
    a = new_intArray();
    array_add(&a, 1);
    array_add(&a, 2);
    array_add(&a, 3);
    return a;
}

int main() {
    struct intArray a;
    int* it;
    int* begin;
    int* end;
    a = return_an_array();
    begin = array_begin(&a);
    end = array_end(&a);
    for(it = begin; it != end; ++it) {
        printf("%d ", *it);
    }
    array_destroy(&a);
    getchar();
    return 0;
}

이 경우 스택에 어레이를 만들고 있으며 기능 범위를 벗어나면 어레이가 할당 해제됩니다.대신 동적으로 할당된 어레이를 만들고 포인터를 반환하십시오.

char * returnArray(char *arr, int size) {
    char *new_arr = malloc(sizeof(char) * size);
    for(int i = 0; i < size; ++i) {
        new_arr[i] = arr[i];
    }
    return new_arr;
}

int main() {

    char arr[7]= {1,0,0,0,0,1,1};
    char *new_arr = returnArray(arr, 7);

    // don't forget to free the memory after you're done with the array
    free(new_arr);

}

메서드는 실패가 심한 로컬스택 변수를 반환합니다.배열을 반환하려면 함수 외부에 배열을 만들고 주소별로 함수에 전달한 다음 수정하거나 힙에 배열을 만들어 해당 변수를 반환합니다.둘 다 동작합니다만, 첫 번째는, 올바르게 동작하기 위해서 동적 메모리 할당이 필요 없습니다.

void returnArray(int size, char *retArray)
{
  // work directly with retArray or memcpy into it from elsewhere like
  // memcpy(retArray, localArray, size); 
}

#define ARRAY_SIZE 20

int main(void)
{
  char foo[ARRAY_SIZE];
  returnArray(ARRAY_SIZE, foo);
}

다음과 같은 코드를 사용할 수 있습니다.

char *MyFunction(some arguments...)
{
    char *pointer = malloc(size for the new array);
    if (!pointer)
        An error occurred, abort or do something about the error.
    return pointer; // Return address of memory to the caller.
}

이렇게 하면 나중에 주소를 free로 전달하여 메모리를 해방할 수 있습니다.

다른 선택사항이 있습니다.루틴에서 기존 구조의 일부인 어레이(또는 어레이의 일부)로 포인터를 반환할 수 있습니다.호출자가 어레이를 전달할 수 있으며 루틴은 새 어레이에 공간을 할당하지 않고 어레이에 쓰기만 합니다.

언급URL : https://stackoverflow.com/questions/11656532/returning-an-array-using-c

반응형