سؤال

أنا أحاول إرجاع صفيف بيانات الأعضاء من أصغر 2D Array الكائن في محاولة لإدراج مجموعة إلى أكبر 2D array الكائن.ولكن عندما يحاول هذا, لقد جئت إلى مشكلتين.

المشكلة الأولى هي أنني أريد العودة إلى اسم 2D array, ولكن أنا لا أعرف كيفية بشكل صحيح جملة للعودة 2D اسم مجموعة.

هذا هو ما 2D مجموعة بيانات الأعضاء يبدو

private:
int pieceArray[4][4];
// 2D Smaller Array

وأريد أن عودة هذه المجموعة إلى وظيفة ، ولكن هذا يسبب خطأ التحويل:

int Piece::returnPiece()
{
    return pieceArray; //not vaild
    // return the 2D array name
}

أنا تعبت باستخدام هذا نوع الإرجاع وعملت:

int Piece::returnPiece()
{
    return pieceArray[4][4];
}

ولكن أنا غير متأكد ما إذا كان هذا هو ما أريد كما أريد أن أعود مجموعة و كل من المحتوى.

والمشكلة الأخرى InsertArray() وظيفة حيث أنني من شأنه أن يضع returnPiece() وظيفة في InsertArray()'s الحجة.

المشكلة مع InsertArray() هو الحجة ، ها هي رمز لذلك:

void Grid::InsertArray( int arr[4][4] ) //Compiler accepts, but does not work
{
    for(int i = 0; i < x_ROWS ; ++i)
    {
         for (int j = 0; j < y_COLUMNS ; ++j)
         {
             squares[i][j] = arr[i][j];
         }
    }
}

المشكلة مع ذلك هو أنه لا تقبل returnPiece () ، و إذا كنت إزالة "[4][4]" ، مترجم لا تقبل.

في الغالب هذه كلها أخطاء في بناء الجملة, ولكن كيف يمكنني حل هذه المشاكل ؟

  1. تعود كلها pieceArray في returnPiece()
  2. بناء الجملة الصحيح عن الحجة في InsertArray()
  3. حجة InsertArray() قبول returnPiece()

3 هذه هي المشاكل الرئيسية التي كنت بحاجة إلى مساعدة مع ، وكان نفس المشكلة عند محاولة استخدام المؤشر مؤشر الأسلوب.لا أحد يعرف كيفية حل هذه 3 مشاكل ؟

هل كانت مفيدة؟

المحلول

عند تمرير الصفيف الخاص بك حولها ، عليك أن تقرر ما إذا كنت تريد أن تجعل نسخة من مجموعة ، أو إذا كنت ترغب فقط في عودة مؤشر إلى الصفيف.من أجل العودة المصفوفات, لايمكنك (بسهولة) عودة نسخة - يمكنك إرجاع مؤشر (أو المرجعية في C++).على سبيل المثال:

// Piece::returnPiece is a function taking no arguments and returning a pointer to a
// 4x4 array of integers
int (*Piece::returnPiece(void))[4][4]
{
    // return pointer to the array
    return &pieceArray;
}

استخدام سميها مثل ذلك:

int (*arrayPtr)[4][4] = myPiece->returnPiece();
int cell = (*arrayPtr)[i][j];  // cell now stores the contents of the (i,j)th element

ملاحظة التشابه بين نوع الإعلان باستخدام قوسين ، dereferencing المشغل *, و بين قوسين هي في نفس الأماكن.

الخاص بك الإعلان عن Grid::InsertArray هو الصحيح - فإنه يأخذ وسيطة واحدة ، وهو 4x4 مجموعة من الاعداد الصحيحه.هذا هو نداء-من قبل-القيمة:كلما كنت اسميها ، يمكنك جعل نسخة 4x4 مجموعة ، وبالتالي أي تعديل تقوم لا تنعكس في مجموعة مرت في.إذا كنت بدلا من ذلك يريد استخدام الاتصال عن طريق الإشارة, هل يمكن تمرير مؤشر إلى صفيف بدلا من ذلك:

// InsertArray takes one argument which is a pointer to a 4x4 array of integers
void Grid::InsertArray(int (*arr)[4][4])
{
     for(int i = 0; i < x_ROWS; i++)
     {
         for(int j = 0; j < y_COLUMNS ; j++)
             squares[i][j] = (*arr)[i][j];
     }
}

هذه نوع الإعلانات مع مؤشرات إلى المصفوفات متعددة الأبعاد يمكن الحصول على مربكة حقا بسرعة.أوصي صنع typedef لأنه مثل ذلك:

// Declare IntArray4x4Ptr to be a pointer to a 4x4 array of ints
typedef int (*IntArray4x4Ptr)[4][4];

ثم يمكنك أن يعلن الخاص بك وظائف أكثر قابلية للقراءة:

IntArray4x4Ptr Piece::returnPiece(void) { ... }
void Grid::InsertArray(IntArray4x4Ptr arr) { ... }

يمكنك أيضا استخدام cdecl برنامج للمساعدة في فك معقدة C/C++ أنواع.

نصائح أخرى

يبدو أنك تحتاج إلى قراءة أكثر على مؤشرات في C++ على تمرير بالرجوع مقابلتمر القيمة.

الخاص بك returnPiece الطريقة بأنها تعود قيمة خلية واحدة.وبالنظر إلى مؤشر (على سبيل المثال ، [4][4]) تعود على نسخة من محتويات الخلية, حتى أنك لن تكون قادرا على تغيير ذلك ، أو أكثر بشكل صحيح ، تغيير من شأنه أن يغير نسخ.

أنا متأكد من شخص ما سوف تعطيك بناء الجملة الصحيح, ولكن أنا حقا أن يوصي تعلم هذه الأشياء وإلا يمكنك استخدام التعليمات البرمجية التي تحصل بشكل غير صحيح.

هنا هو كيف نفعل ذلك:

class Array {
  public:

    Array() {
      for (int i = 0; i < 4; ++i)
      {
         for (int j = 0; j < 4; ++j)
         {
            (*this)(i, j) = 0;
         }
      }
    }


    int &operator()(int i, int j)
    {
      return pieceArray[i][j];
    }

  private:
    int pieceArray[4][4];
};

ثم يمكنك أن تفعل شيئا مثل:

  Array x; // create 4x4 array
  x(1, 2) = 3; // modify element

مشكلة مع آدم روزنفيلد هو arrayPtr في هذا قطعة::pieceArray يمكن أن تتغير من تحت لك.(نسخ-بالرجوع مقابل نسخة من القيمة.)

نسخة-ب-القيمة غير فعالة.ولكن إذا كنت تريد حقا أن تفعل ذلك فقط الغش:

struct FOO { int  piece [4][4]; };

FOO Piece::returnPiece()
{
  FOO f;
  memcpy( f.piece, pieceArray, sizeof(pieceArray) );
  return f;
}

void Grid::InsertArray( const FOO & theFoo )
{
  // use theFoo.piece[i][j]
}

بالطبع, أفضل, أكثر وجوه المنحى الحل, يمكن أن يكون returnPiece() إنشاء والعودة قطعة أو مجموعة الكائن.(كما خوان اقترح...)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top