简体   繁体   English

将2D数组从函数返回到主函数

[英]Returning a 2D array from function to main function

I am writting code for Game of Life, and as stipulated for my assigment I am not supposed to use pointers. 我正在编写《生命游戏》的代码,并且按照我的职责规定,我不应该使用指针。

For couting the amount of neightbours each cell, cell in this context is a coordinate on my 2D array, I have written a fucntion which goes through all rows and columns and counts how many ALIVE neighbours each cell has. 为了计算每个像元的高度,在此上下文中,像元是我的2D数组上的坐标,我编写了一个遍历所有行和列并计算每个像元有多少个ALIVE邻居的函数。 Maximum would be 8. 最大值为8。

However I do not know how to return my array which stores the amount neighbouring cells in a 20x20 array. 但是我不知道如何返回我的数组,该数组将20x20数组中相邻单元的数量存储起来。

Below is the entire code. 以下是整个代码。 Observe that some parts are unfinished since I am complementing a template given to me. 请注意,由于我正在补充给我的模板,因此某些部分尚未完成。

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

/* Constants, representation of states */
#define ALIVE 'X'
#define DEAD '.'

/* Declaration of data structure */
typedef struct{
  char current;
  char next;
} cell;

/* Declaration of functions */
void initField(const int rows, const int cols, cell field[rows][cols]);
void loadGlider(const int rows, const int cols, cell field[rows][cols]);
void loadSemaphore(const int rows, const int cols, cell field[rows][cols]);
void loadRandom(const int rows, const int cols, cell field[rows][cols]);
void loadCustom(const int rows, const int cols, cell field[rows][cols]);
void printWorld(const int rows, const int cols, cell field[rows][cols]);
int CellNeighbour(const int rows, const int cols, cell field[rows][cols]);



/* Function:    main
* Description: Start and run games, interact with the user.
* Input:       About what initial structure and whether to step or exit.
* Output:      Information to the user, and the game field in each step.
*/

int main(void) {

  const int rows = 20;
  const int cols = 20;
  cell field[rows][cols];
  int counting[rows][cols];

  initField(rows,cols, field);
  printWorld(rows,cols,field);
  CellNeighbour(rows,cols,field);//test



    for (int i = 0; i < rows; i++){
        for (int j = 0; j < cols; j++){
            printf("%d ", counting[i][j]);
        }
        printf("\n");
    }




  return 0;
}


/* Function:    initField
* Description: Initialize all the cells to dead, then asks the user about
*              which structure to load, and finally load the structure.
* Input:       The field array and its size.
* Output:      The field array is updated.
*/

void initField(const int rows, const int cols, cell field[rows][cols]) {

  for (int r = 0 ; r < rows ; r++) {
    for (int c = 0 ; c < cols ; c++) {
      field[r][c].current = DEAD;
    }
  }

  printf("Select field spec to load ([G]lider, [S]emaphore, [R]andom ");
  printf("or [C]ustom): ");

  int ch = getchar();

  /* Ignore following newline */
  if (ch != '\n') {
    getchar();
  }

  switch (ch) {
    case 'g':
    case 'G':
    loadGlider(rows, cols, field);
    break;
    case 's':
    case 'S':
    loadSemaphore(rows, cols, field);
    break;
    case 'r':
    case 'R':
    loadRandom(rows, cols, field);
    break;
    case 'c':
    case 'C':
    default:
    loadCustom(rows, cols, field);
    break;
  }
}


/* Function:    loadGlider
* Description: Inserts a glider into the field.
* Input:       The field array and its size.
* Output:      The field array is updated.
*/

void loadGlider(const int rows, const int cols, cell field[rows][cols]) {

  field[0][1].current = ALIVE;
  field[1][2].current = ALIVE;
  field[2][0].current = ALIVE;
  field[2][1].current = ALIVE;
  field[2][2].current = ALIVE;
}


/* Function:    loadSemaphore
* Description: Inserts a semaphore into the field.
* Input:       The field array and its size.
* Output:      The field array is updated.
*/

void loadSemaphore(const int rows, const int cols, cell field[rows][cols]) {

  field[8][1].current = ALIVE;
  field[8][2].current = ALIVE;
  field[8][3].current = ALIVE;
}


/* Function:    loadRandom
* Description: Inserts a random structure into the field.
* Input:       The field array and its size.
* Output:      The field array is updated. There is a 50 % chance that a cell
*              is alive.
*/

void loadRandom(const int rows, const int cols, cell field[rows][cols]) {

}


/* Function:    loadCustom
* Description: Lets the user specify a structure that then is inserted into
*              the field.
* Input:       The field array and its size.
* Output:      The field array is updated.
*/

void loadCustom(const int rows, const int cols, cell field[rows][cols]) {

  printf("Give custom format string: ");
  do {
    int r, c;
    scanf("%d,%d", &r, &c);
    field[r][c].current = ALIVE;
  } while (getchar() != '\n');
}
/* Function:    printWorld
* Description: Prints the current field
* Input:       The field array and its size.
* Output:      The field array is updated.
*/


void printWorld(const int rows, const int cols, cell field[rows][cols]){

  char c = '\n';

  while(c == '\n'){
    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        printf("%c ", field[i][j].current);
      }
      printf("\n");
    }
    c = getchar();
    if(c != '\n'){
      break; // hoppa ut ur loopen till main funktionen
    }

  }
}

void evolve(const int rows,const int cols,cell field[rows][cols]){

  for(int i = 0;i<rows;i++){
    for(int j =0;j<cols;j++){
      if(field[rows][cols].current == ALIVE  && ArrayDatCorresponds2NmbofNeighb[rows][cols]<2){
      }
      if(field[rows][cols].current == ALIVE && ArrayDatCorresponds2NmbofNeighb[rows][cols] ==3 ||ArrayDatCorresponds2NmbofNeighb[rows][cols] ==2 ){
        field[rows][cols].next = ALIVE;
      }
      if(field[rows][cols].current == ALIVE && ArrayDatCorresponds2NmbofNeighb[rows][cols] >= 4 ){
        field[rows][cols].next = DEAD;
      }
      if(field[rows][cols].current == DEAD && ArrayDatCorresponds2NmbofNeighb[rows][cols] ==3){
        field[rows][cols].next = ALIVE;
      }
    }
  }



int CellNeighbour(const int rows, const int cols, cell field[rows][cols]){

  int i,j;
  int count =0;
  for( i =0;i<rows;i++){
    for( j = 0;j<cols;j++){
  int StoreArray[rows][cols] =0;
 }
}

  for( i =0;i<rows;i++){
    for( j = 0;j<cols;j++){
      if(field[rows-1][cols-1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows][cols-1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows+1][cols-1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows+1][cols].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows+1][cols+1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows][cols+1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows-1][cols+1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows-1][cols].current == ALIVE){
        StoreArray[i][j]=count++;
      }
    }
  }


  return StoreArray; 
}

Below is the function which I am having issues with: 以下是我遇到问题的功能:

int CellNeighbour(const int rows, const int cols, cell field[rows][cols]){

  int i,j;
  int count =0;
  for( i =0;i<rows;i++){
    for( j = 0;j<cols;j++){
  int StoreArray[rows][cols] =0;
 }
}

  for( i =0;i<rows;i++){
    for( j = 0;j<cols;j++){
      if(field[rows-1][cols-1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows][cols-1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows+1][cols-1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows+1][cols].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows+1][cols+1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows][cols+1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows-1][cols+1].current == ALIVE){
        StoreArray[i][j]=count++;
      }
      if(field[rows-1][cols].current == ALIVE){
        StoreArray[i][j]=count++;
      }
    }
  }


  return StoreArray; 
}

If I initilize a 20x20 field where I have some ALIVE cells. 如果我初始化一个20x20的字段,其中有一些ALIVE单元格。

Then I would expect, after printing out a 5x5(just to make it simple) which calculates how many neighbours each cell has, a grid which looks something like this: 然后,我希望在打印出5x5(只是为了简化起见)之后,它会计算出每个单元格有多少个邻居,看起来像这样的网格:

2 2 0 0 0
2 3 0 0 0
0 0 0 0 0
0 1 1 0 0
0 0 0 0 0

You can't return arrays in C. And since you're not allowed to use pointers, you'll have to wrap the array in a struct. 您不能在C中返回数组。由于不允许使用指针,因此必须将数组包装在结构中。 Example: 例:

typedef struct {
    int data[rows][cols];
} MyStruct;

MyStruct func()
{
    MyStruct my_struct;

    // Fill my_struct.data with what you need.
    // ...

    return my_struct;
}

As I mentioned in my comment, you cannot return array types from a function. 正如我在评论中提到的那样,您不能从函数返回数组类型。 The right way to do this would be to pass the target array as a parameter: 正确的方法是将目标数组作为参数传递:

const int rows = 20;
const int cols = 20;
cell field[rows][cols];
int counting[rows][cols];
...
CellNeighbor( rows, cols, field, counting );

You'd then define your CellNeighbor function as: 然后,将CellNeighbor函数定义为:

void CellNeighbour(const int rows, const int cols, cell field[rows][cols], int counts[rows][cols])
{
  int i,j;
  int count =0;

  // you could probably replace the following with memset( counts, 0, rows * cols * sizeof counts[0][0]
  for( i =0;i<rows;i++){
    for( j = 0;j<cols;j++){
      counts[i][i] =0;
    }
  }

  for( i =0;i<rows;i++){
    for( j = 0;j<cols;j++){
      if(field[i][j].current == ALIVE){
        counts[i][j]=count++;
      }
      if(field[i][j-1].current == ALIVE){
        counts[i][j]=count++;
      }
      ...
    }
  }
}

Now, you're not explicitly using pointers anywhere, so this should satisfy the conditions of the assignment. 现在,您不会在任何地方显式使用指针,因此这应该满足分配条件。

But... 但...

Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T " will be converted ("decay") to an expression of type "pointer to T ", and the value of the expression will be the address of the first element of the array. 除非它是sizeof或一元&运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则类型“ T N元素数组”的表达式将被转换(“ decay”)为类型为“指向T指针”的表达式,该表达式的值将是数组第一个元素的地址。

So when you call CellNeighbor( rows, cols, field, counting ) , the expression field is converted from type " rows -element array of cols -element array of cell " ( cell[rows][cols] ) to type "pointer to cols -element array of cell " ( cell (*)[cols] ). 因此,当调用CellNeighbor( rows, cols, field, counting )表达 field由类型变换“ rows -元素的阵列cols的-元素阵列cell (” cell[rows][cols]以输入“指针cols - cell “( cell (*)[cols] )的元素数组。 Similarly, the expression counting is converted from type " rows -element array of cols -element array of int " ( int [rows][cols] ) to "pointer to cols -element array of int " ( int (*)[cols] ). 类似地,表达counting从型转换“ rows的-元素阵列cols的-元素阵列int ”( int [rows][cols]设置为“指针cols的-元素阵列int ”( int (*)[cols] )。

This means CellNeighbor is receiving pointer values for field and counting , not actual arrays. 这意味着CellNeighbor被接收用于指针fieldcounting ,而不是实际的阵列。

In the context of a function parameter declaration, T a[N] and T a[] are "adjusted" to T *a , so the declarations cell field[row][cols] and int counts[row][cols] are being interpreted as cell field (*)[cols] and int counts (*)[cols] in the CellNeighbor function definition. 在函数参数声明的上下文中, T a[N]T a[]被“调整”为T *a ,因此声明cell field[row][cols]int counts[row][cols]CellNeighbor函数定义中解释为cell field (*)[cols]int counts (*)[cols]

If your assignment is serious about "no pointers", as in "no pointers AT ALL, not even implicit pointers as the result of array expression decay", then you cannot pass array expressions as function arguments, period. 如果您的分配是认真对待“没有指针”的,例如“完全没有指针,甚至没有隐式指针,这是数组表达式衰减的结果”,那么您就不能将数组表达式作为函数参数,句点传递。 I have a really hard time believing that's what your instructor intended. 真的很难相信那是您的老师想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM