2014-03-02 39 views
0

我開始編寫這段代碼以獲得樂趣,我很驚訝它編譯和工作。 (我正在使用Dev C++進行編譯)。我想創建一個結構數組,但是在我創建數組之前,它存儲並讀取了它們已經是數組的值。爲什麼會這樣呢,又如何創建一個結構數組,以便跟蹤數組的總大小?像沒有聲明數組的結構數組行爲

#include <iostream> 
using namespace std; 

struct Shape 
{ 
public: 
int x,y,z; 
}; 

struct Triangle: public Shape 
{ 
public: 
int tNum; 
}; 

struct Rectangle: public Shape 
{ 
public: 
int rNum; 
float differentNum; 
}; 

struct Circle: public Shape 
{ 
public: 
int cNum; 
}; 

int main(void) 
{ int i; 
Triangle tri; 
Rectangle rec; 
Circle cir; 
Shape *arr[3]={&tri, &rec, &cir}; 

for(i=1;i<5;i++){ arr[1][i].x=i*2; cout<<"set tri["<<i<<"] "<<i*2<<endl;} cout<<endl; 
for(i=1;i<5;i++){ arr[2][i].x=i*9; cout<<"set rec["<<i<<"] "<<i*9<<endl;} cout<<"-----------------"<<endl; 

for(i=1;i<5;i++){ cout<<"read tri["<<i<<"] "<<arr[1][i].x<<endl;} cout<<endl; 
for(i=1;i<5;i++){ cout<<"read rec["<<i<<"] "<<arr[2][i].x<<endl;} 

system("pause"); 
return(0); 
} 

/*output 
set tri[1] 2 
set tri[2] 4 
set tri[3] 6 
set tri[4] 8 

set rec[1] 9 
set rec[2] 18 
set rec[3] 27 
set rec[4] 36 
-----------------` 
read tri[1] 2 
read tri[2] 4 
read tri[3] 6 
read tri[4] 8 

read rec[1] 9 
read rec[2] 18 
read rec[3] 27 
read rec[4] 36*/ 

回答

3

你有3 Shape*變量,每個變量指示的堆棧中的一個陣列爲有效Shape實例:

  • arr[0]是指向tri實例,因此arr[0][0]tri實例。
  • arr[1]指向rec實例,所以arr[1][0]rec實例。
  • arr[2]指向cir實例,所以arr[2][0]cir實例。

arr的任何其他用途基本上是非法的(即使它可能工作)。

雖然不建議,認爲rec實例和cir實例出現在tri情況後,立即堆棧的事實,可以讓你在幾個其他方式使用arr和「活着」:

  • arr[0][1]rec實例,它出現在tri實例之後的堆棧中。
  • arr[0][2]cir實例,它出現在rec實例之後的堆棧中。
  • arr[1][1]cir實例,它出現在rec實例之後的堆棧中。

正如以下注釋之一所指出的那樣,它確實取決於堆棧的實現。

通過arr訪問內存的任何其他(不同)嘗試都是潛在的內存訪問衝突。

這裏是你應該怎麼可能做到這一點:

#include <string> 
using namespace std; 

class Shape 
{ 
protected: 
    Shape() {} 
    virtual ~Shape() {} 
    string type; 
    int x,y,z; 
public: 
    string GetType() const {return type;} 
    void SetX(int val) {x = val;} 
    void SetY(int val) {y = val;} 
    void SetZ(int val) {z = val;} 
}; 

class Triangle : public Shape 
{ 
public: 
    Triangle():type("Triangle") {} 
    void SetNum(int val) {tNum = val;} 
private: 
    int tNum; 
}; 

class Rectangle : public Shape 
{ 
public: 
    Rectangle():type("Rectangle") {} 
    void SetNum(int val) {rNum = val;} 
    void SetDifferentNum(float val) {differentNum = val;} 
private: 
    int rNum; 
    float differentNum; 
}; 

class Circle : public Shape 
{ 
public: 
    Circle():type("Circle") {} 
    void SetNum(int val) {cNum = val;} 
private: 
    int cNum; 
}; 

... 

Triangle tri; 
Rectangle rec; 
Circle cir; 
Shape* arr[3] = {&tri, &rec, &cir}; 
int  size = sizeof(arr)/sizeof(*arr); 
for (i=0; i<size; i++) 
{ 
    arr[i]->SetX(i*2); 
    cout << "set " << arr[i]->GetType() << "[" << i << "] = " << i*2 << endl; 
} 
+0

結果取決於堆棧增長還是減少。 –

+0

@ brian beuning,謝謝你指出。無論如何,我確實強調了「中間」的答案,「任何其他使用arr'基本上都是非法的(即使它可能有效)」。 –

+0

哦,好的,謝謝。有沒有辦法讓我創建一個rec的指針數組,並仍然使用這種方法,我打電話給arr? – user3341184

0

你必須要對一些嚴重的未定義行爲這裏;你的代碼沒有做你認爲正在做的事情。例如,arr[2]是指向cir的指針,但arr[2][1]arr[2][2]是指向未初始化的內存塊的指針。從你的定義

Shape *arr[3]={&tri, &rec, &cir}; 

您可以安全地訪問arr[0](指針tri),arr[1](指針rec)和arr[2](指針cir),但僅此而已。