0

私は、ポインターオフセット表記でポインターと配列を使用してクラスプロジェクトプログラムに取り組んできました(私は思います)。以下は、プロジェクトに使用された図です

プロジェクトのプロンプト

*網掛けのボックスはポインタを表します。影のないボックスは、動的に割り当てられた 2 次元の int 配列を表します。プログラムは、名前のないアイテムの名前付き識別子を作成できません。行数と列数はユーザー入力になります。図の楕円は、行と列のサイズが可変であることを表しています。垂直配列は、ポインターの配列です。垂直配列要素のそれぞれは、整数の 1 次元配列を指します。

ダイアグラム

プログラムでは、s、t、u、および v で表されるポインターを介してのみ整数配列を参照します。関数に渡すときは、常にこれらのポインターを渡す必要があります。関数呼び出しで実パラメータを逆参照することはできません。また、ポインターを操作するためだけに、ポインターを逆参照して変数に代入することもできません。*

#include <iostream>
using namespace std;


void fillArray(int **pArray, int rows, int columns)
{
    for(int row = 0; row < rows; row++)
    {
        *(pArray + row) = new int;
        cout << "Enter " <<  " row " << row + 1<< endl;

        for(int col = 0; col < columns; col++)
        {
            cin >> *(*(pArray + row) + col);
        }
    }
}

void printArray(int **pArray, int rows, int columns)
{
    for(int row = 0; row < rows; row++)
    {
        cout << "Row " << row + 1 << endl;
        for(int col = 0; col < columns; col++)
        {
            int num = *(*(pArray + row) + col);
            cout << num << " ";
        }
        cout << endl;

    }
}

void reverseArray(int **pArray, int rows, int columns)
{
    for(int row = 0; row < rows; row++)
    {
        cout << "Reversed Row " << row + 1 << endl;
        for(int col = columns - 1; col >= 0; col--)
        {
            int num = *(*(pArray + row) + col);
            cout << num << " ";
        }
        cout << endl;
    }
}


int main()
{
    int rows;
    int columns;
    cout << ("Input number of rows: ");
    cin >> rows;
    cout << ("Input number of columns: ");
    cin >> columns;

    int **pArray;                   //Initialize array

    int ****s;                      //Initialize pointers s, t, u, v
    **s = pArray;
    int ****t;
    *t = *s;
    int ****u;
    **u = pArray;
    int ****v;
    *v = *u;


    pArray = new int*[rows];        //create pointer to rows. 1st level of indirection
    *pArray = new int[columns];     //create pointer to columns. 2nd level of indirection

    fillArray(pArray, rows, columns);
    printArray(pArray, rows, columns);
    reverseArray(pArray, rows, columns);

    //Loop to terminate program
    while (true)
    {
        cout << "\nEnter letter \'q\' to terminate program\n";
        char c;
        cin >> c;

        if(c == 'q')
            break;
    }
}

コードのフォーマットが悪くて申し訳ありません。コードブロックでのコピペの仕方がわかりませんでした。

私の質問は、プログラムで図をどのように実装するかです。ポインター オフセットを使用して配列を作成し、独自の名前でラベル付けする基本から始めました。

ポインター変数 's、t、u、v' を使用するには、すべての参照を変更する必要があると思います。どんな助けでも大歓迎です。

4

1 に答える 1

1

少なくともある程度役立つように、配列が固定されているかバリアントであるかについての質問は明確ではないことに注意してください。2つのサイズが与えられています。列数(幅)と行数(高さ)。また、次のステートメントにも注意してください。

「プログラムでは、整数配列のみを参照してください...」

ナンセンスです。'cols'整数配列がありますが、1つではありません。

int rows, cols; // acquire rows and cols from wherever.

// create the row vector that will hold the column pointers.
//  this constitutes the first grey box above the main array.

int **rowsp = new int*[rows];


// for each slot we just allocated, set the value an allocation
//  of 'int' values. the list will be `cols` wide

for (int i=0;i<rows;)
    rowsp[i++] = new int[cols];


// thats both white boxes and the first grey box. rowsp points
//  to the allocated pointer array holding 'rows' pointers, each 
//  pointing to an int array hold 'cols' ints.

// now we make the two pointers that point at rowsp
int ***p1 = &rowsp;
int ***p2 = p1;

// and finally, setup s,t,u,v
int ****s = &p1;
int ****t = s;
int ****u = &p2;
int ****v = u;

素晴らしいですが、あなたの質問の文脈を読んで、これはまったく正しくありません。質問によると、使用できるポインタは4つだけです{s,t,u,v}。最後のint配列まで構築できるように、適切な型で宣言する必要があります。上記(現時点ではスローウェイコード)を見ると、4つのレベルの間接参照が必要であることがわかります。したがって、今回は、、、、、およびから始めてstに向かって進みます。uv

int ****s = new int***; // p1 in the prior code
int ****t = s;          // points to the same p1

int ****u = new int***; // p2 in the prior code
int ****v = u;          // points to the same p2

次に、p1とp2が共通のポインターを指すようにする必要があります。このポインターはrowsp、上からの出力コードへのポインターになります(つまり、s、t、u、およびvが完了すると、最終的にはすべてのポインターへのパスが必要になります)

*s = new int**;         // s-->p1-->rowsp, t-->p1-->rows
*u = *s;                // u-->p2-->rowsp, v-->p2-->rowsp

次に、intへのポインタを含む実際の行ベクトルを割り当てる必要があります。

**s = new int*[rows];   // the integer pointer array.

そして最後に、この配列に'cols'-lengthint-arraysを入力します。

for (int i=0;i<cols;++i)
{
    *(**s+i) = new int[ cols ]();
    for (int j=0;j<cols;++j)
        *(*(**s+i)+j) = i+j; // <== beautiful dereference chain =P
}

これを正しく行った場合、以下はすべて同じことを指しているはずです。

cout << "**s = " << **s << endl;
cout << "**t = " << **t << endl;
cout << "**u = " << **u << endl;
cout << "**v = " << **v << endl;

私はこの狂気をあなた自身のダイムで機能するように動かしておきます。上からのコードベース全体が、1つの連続したリストの下に表示されます。ideone.comでもライブで見ることができます:

#include <iostream>

using namespace std;

int main()
{
    static const int rows = 8; // yours would come from user input
    static const int cols = 9;

    int ****s = new int***; // s --> p1
    int ****t = s;          // t --> p1

    int ****u = new int***; // u --> p2
    int ****v = u;          // v --> p2

    *s = new int**;         // s-->p1-->rowsp, t-->p1-->rows
    *u = *s;                // u-->p2-->rowsp, v-->p2-->rowsp

    **s = new int*[rows];   // s --> p1 --> rowsp --> int*[rows]

    for (int i=0;i<rows;++i)
    {
        *(**s+i) = new int[ cols ];
        for (int j=0;j<cols;++j)
            *(*(**s+i)+j) = (i+j) % cols; // <== beautiful dereference chain =P
    }

    cout << "**s = " << **s << endl;
    cout << "**t = " << **t << endl;
    cout << "**u = " << **u << endl;
    cout << "**v = " << **v << endl << endl;;

    cout << "======= S =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**s+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    cout << "======= T =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**t+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    cout << "======= U =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**u+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    cout << "======= V =======" << endl;
    for (int i=0;i<rows;++i)
    {
        for (int j=0;j<cols;++j)
            cout << *(*(**v+i)+j) << ' ';
        cout << endl;
    }
    cout << endl;

    // delete rows.
    for (int i=0;i<rows;++i)
        delete [] *(**s+i);

    // delete row pointer array
    delete [] **s;

    // delete rowsp pointer
    delete *s;

    // and finally, delete s and u (or t and v)
    delete s;
    delete u;

    return 0;
}

出力(ポインターは異なります)

**s = 0x100103b60
**t = 0x100103b60
**u = 0x100103b60
**v = 0x100103b60

======= S =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 

======= T =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 

======= U =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 

======= V =======
0 1 2 3 4 5 6 7 8 
1 2 3 4 5 6 7 8 0 
2 3 4 5 6 7 8 0 1 
3 4 5 6 7 8 0 1 2 
4 5 6 7 8 0 1 2 3 
5 6 7 8 0 1 2 3 4 
6 7 8 0 1 2 3 4 5 
7 8 0 1 2 3 4 5 6 
于 2013-01-30T04:07:40.230 に答える