programing

배열을 반환하기 위한 C 함수 선언

prostudy 2022. 6. 6. 10:34
반응형

배열을 반환하기 위한 C 함수 선언

어레이를 반환하는 함수를 만들려면 어떻게 해야 합니까?이거 먹어봤어

const int WIDTH=11;
const int HEIGHT=11;

int main() {
  char A[WIDTH][HEIGHT];
  A=rand_grid(WIDTH,HEIGHT);
  return 0;
}

// Initializes a random board.
char[][] rand_grid(int i, int k) {
  char* A[i][k];
  for(j=0;j<i;++j) {
    for(l=0;l<k;++l) {
      A[j][l]=ran(10);
    }
  }
  return A;
}

// Returns a random number from the set {0,...,9}.
int ran(int i) {
  srand((unsigned int) time(0));
  return(rand()%10);
}

몇 가지 짚고 넘어가야 할 것이 있습니다.

우선 다음과 같이 어레이 개체를 할당할 수 없습니다.

char A[WIDTH][HEIGHT];  
A=rand_grid(WIDTH,HEIGHT);

어레이 유형의 개체는 수정할 수 없습니다.

둘째, C의 함수는 어레이 유형을 반환할 수 없습니다.단, 다음과 같이 포인터를 어레이에 반환할 수 있습니다.

char (*foo(int width))[HEIGHT]
{
  /**
   * dynamically allocate memory for a widthxHEIGHT array of char
   */
  char (*newArr)[HEIGHT] = malloc(sizeof *newArr * width);
  /**
   * initialize array contents here
   */
  return newArr;
}

이 구문은 약간 혼란스럽습니다.

       foo                                   -- foo
       foo(int width)                        -- is a function
                                             -- taking an int parameter
      *foo(int width)                        -- returning a pointer
     (*foo(int width))[HEIGHT]               -- to a HEIGHT-element array
char (*foo(int width))[HEIGHT]               -- of char

C89의 경우 위 스니펫의 HEIGHT는 컴파일 시간 상수 적분식(매크로, 숫자 리터럴 또는 매크로 및/또는 숫자 리터럴로 구성된 산술식)이어야 합니다.그것이 C99에도 해당되는지 확실하지 않습니다.

투고해 주신 스니펫에 근거해, 이미 할당한 어레이를 가져와, 그 컨텐츠를 초기화합니다.대부분의 컨텍스트에서 어레이 유형의 식은 기본 유형에 대한 포인터로 암묵적으로 변환됩니다.IOW, T의 N 요소 배열을 함수에 전달하면 함수가 실제로 수신하는 것은 T에 대한 포인터입니다.

void foo (T *p) {...}
...
T arr[N];
foo(arr);

2-D 어레이의 경우 조금 더 추합니다.

void foo (T (*p)[M]) {...}
...
T arr[N][M];
foo(arr);

이는 또한 컴파일 시 M을 알고 있어야 함수의 유용성을 제한할 수 있습니다.원하는 것은 임의의 크기의 2차원 배열에 대응할 수 있는 기능입니다.이 작업을 수행하는 가장 좋은 방법은 포인터를 배열에 전달하는 대신 배열의 첫 번째 요소 주소를 전달하고 행과 열의 수를 별도의 매개 변수로 전달하는 것입니다.

void foo(T *base, size_t rows, size_t cols) {...}
...
T arr[N][M];
foo (&arr[0][0], N, M);

따라서 rand_grid 함수는 다음과 같습니다.

void rand_grid(char *base, size_t rows, size_t cols)
{
  size_t i, j;
  for (i = 0; i < rows; i++)
  {
    for (j = 0; j < cols; j++)
    {
      /**
       * Since base is a simple char *, we must index it
       * as though it points to a 1-d array.  This works if
       * base points to the first element of a 2-d array,
       * since multi-dimensional arrays are contiguous.  
       */
      base[i*cols+j] = initial_value();
    }
  }
}

int main(void)
{
  char A[WIDTH][HEIGHT];
  rand_grid(&A[0][0], WIDTH, HEIGHT);
  ...
}

  1. 은 「 」라고 해도.&A[0][0] ★★★★★★★★★★★★★★★★★」A동일한 값(A의 기본 주소)을 산출하며, 두 식의 유형이 다릅니다.를 가리키는 단순한 됩니다.char * 배열에 2d 문자 ('2d 문자')는 'char' ('char')로 평가됩니다.char (*)[HEIGHT]

그럴수는 없어요.포인터를 매개 변수로 배열에 전달하여 함수에서 수정하도록 할 수도 있고 함수 자체가 데이터를 할당하여 포인터를 반환할 수도 있습니다.

당신의 경우

void rand_grid(char A[WIDTH][HEIGHT]) {
    A[0][0] = 'A'; // or whatever you intend to do
}

main() {
    char A[WIDTH][HEIGHT];
    rand_grid(A);
}

편집: 카페가 지적한 바와 같이 실제로 반환할 수 있는 것은struct물론 제정신인 C프로그래머는 그렇게 하지 않을 겁니다

스택 할당("")은 반환할 수 없습니다.auto") 원시(값) 유형 이외의 변수 및struct그런 것 같아요.그 외의 타입의 경우는, 다음의 방법으로, 히프에서 메모리를 할당할 필요가 있습니다.malloc()또는 (크기) 어레이를 랩하여struct.

고정 사이즈 어레이를 사용하고 있는 경우는, 이 어레이를 모델화할 수 있습니다.structstructure-return을 사용합니다.

#define WIDTH  11
#define HEIGHT 11

typedef struct {
  unsigned char cell[WIDTH * HEIGHT];
} Board;

Board board_new(void)
{
  Board b;
  size_t i;

  for(i = 0; i < sizeof b.cell / sizeof *b.cell; i++)
    b.cell[i] = rand() & 255;
  return b;
}

이는 정상이며 명시적 포인터를 사용하는 다른 방법보다 비용이 많이 들지 않습니다.

void board_init(Board *b);

앞의 structure-return 케이스는 (컴파일러에 의해) 후자로 다시 쓰여질 수 있기 때문입니다.이를 반환값 최적화라고 합니다.

이렇게 하려면 어레이 A를 정적 상태로 만들 수 있습니다. 이렇게 하면 A의 스토리지가 기능 범위에 따라 결정되지 않으므로 실제로 어레이를 반환할 수 있습니다(물론 포인터 형식으로).

그러나 이는 달성하고자 하는 것을 달성하기 위한 좋은 방법은 아닙니다.어레이를 기능을 위해 넘겨주세요.rand_grid그게 바로 주소별 패스(pass by address)의 의미입니다.

함수에서 배열을 반환하는 모든 방법에는 약점과 강점이 있습니다.

스트럭으로 감싸면 메모리 할당 및 개방에 따른 오버헤드를 피할 수 있을 뿐만 아니라 개방에 대한 기억도 피할 수 있습니다.이러한 문제는 malloc, calloc 및 realloc을 사용하는 솔루션에서 발생합니다.한편, 구조내에서 래핑 하려면 , 어레이의 최대 사이즈를 알 필요가 있어, 대규모 어레이의 메모리나 실행 시간이 낭비됩니다(예를 들면, 파일을 메모리에 로드해, 카피에 의해서 기능간에 파일 컨텐츠를 건네주는 것).

언급URL : https://stackoverflow.com/questions/1453410/declaring-a-c-function-to-return-an-array

반응형