目錄表

國立屏東大學 資訊工程學系 物件導向程式設計

13. 結構體


C++的structure和C語言一樣,並沒有太大的差異,但是你可以直接把結構體的名稱視為是一種新的資料型態名稱:

struct point
{
   int x, y;
};


struct        // 這個宣告是錯誤的,因為沒有定義結構體的名稱
{             // 或是使用 -std=gnu++11參數,因為C++11已支援
   int x, y;
} s1, s2;     


int main()
{
   struct point p1;
   point p2;         // C++允許不用寫struct
   point p3 = {5,5};
   point p4 {10,10}; // C++11 允許不用寫=, 編譯時記得要加 -std=gnu++11 參數 
   
   struct { int i, j; } t1; //在區域內允許定義匿名的結構體
   
   ...
}

此外,由於C++比起C語言多支援一些新的資料型態與類別,這些也可以用在結構體的內部,例如可以使用string類別的物件(當然也可以使用其它類別的物件)。

對structure不熟悉的同學,請參考C語言的結構體

接下來,我們將介紹一些在C++中,與結構體相關的一些新的用法:

13.1 動態結構體

我們可以利用「new」,動態地建立結構體,並在不需要使用時,將其回收。下面的例子宣告了一個指標並將其指向以new配置的一個結構體所在的位址:

point *p1 = new point;

使用此方式,你必須要以「- >」存取其內部的資料欄位,或是以間接存取的方式配合「.」來存取,例如:

p1->x = 5;
(*p1).y = 6;

13.2 動態結構體陣列

下面的程式範例,宣告並動態配置了結構體的陣列:

#include <iostream>
using namespace std;

struct point
{
  int x, y;
};

int main()
{
  point *pdata = new point [10];

  for(int i=0;i<10;i++)
  {
    pdata[i].x=pdata[i].y=i;
  }

  cout << "pdata[0].x = " << pdata[0].x << endl;
  cout << "pdata[0].x = (*pdata).x = " << (*pdata).x << endl;
  cout << "pdata[2].x = " << pdata[2].x << endl;

//  pdata++;
  cout << "(pdata+2)->x = " << (pdata+2)->x << endl;
  cout << "(*(point *)(pdata+3)).x = " << (*(point *)(pdata+3)).x << endl;
  cout << "(*pdata).x = " << (*pdata).x << endl;

  delete [] pdata;
  return 0;
}

再看看下面這個二維結構體陣列的例子:

#include <iostream>
using namespace std;

#define ROW 3
#define COL 2

struct point
{
  int x, y;
};

int main()
{
  // 宣告並動態配置一個二維的point陣列
  // declare a two dimensional array of points
  // , i.e., point[ROW][COL].
  // by using an array of pointers to arrays.
  // It has been newed in a loop. 

  point **p2d = new point *[ROW];

  for(int i=0;i<ROW;i++)
  {
    p2d[i]=new point [COL];
    for(int j=0;j<COL;j++)
    {
      p2d[i][j].x = p2d[i][j].y = (i+1)*(j+1);
    }
  }

  cout << "p2d[i][j]=" << endl;
  cout << "i\\j|\t0  |\t1  |" << endl;
  cout << "---+-------+-------+" << endl;
  
  for(int i=0;i<ROW;i++)
  {
    cout << " " << i << " | ";
    for(int j=0;j<COL;j++)
      cout << "(" << p2d[i][j].x << "," << p2d[i][j].y << ") | ";
    cout << endl;
  }

  cout << endl;
  cout << "p2d[0][0].x = (*p2d)[0].x = " << (*p2d)[0].x << endl;
  cout << "p2d[0][1].x = (*p2d)[1].x = " << (*p2d)[1].x << endl;
  cout << "p2d[2][0].x = (*(p2d+2))[0].x = " << (*(p2d+2))[0].x << endl;

  cout << endl;
  cout << "p2d[2][0].x = (*(p2d+2))->x = " << (*(p2d+2))->x  << endl;
  cout << "p2d[2][1].x = ((*(p2d+2))+1)->x = " << ((*(p2d+2))+1)->x << endl;

  for(int i=0;i<ROW;i++)
    delete [] p2d[i];
  delete [] p2d;

  return 0;
}

其執行結果如下:

[11:57 user@ws ch13]$ ./a.out 
p2d[i][j]=
i\j|	0  |	1  |
---+-------+-------+
 0 | (1,1) | (2,2) | 
 1 | (2,2) | (4,4) | 
 2 | (3,3) | (6,6) | 

p2d[0][0].x = (*p2d)[0].x = 1
p2d[0][1].x = (*p2d)[1].x = 2
p2d[2][0].x = (*(p2d+2))[0].x = 3

p2d[2][0].x = (*(p2d+2))->x = 3
p2d[2][1].x = ((*(p2d+2))+1)->x = 6
[11:57 user@ws ch13]$