像一个结构数组一样,没有声明数组

时间:2014-03-02 18:16:38

标签: c++ arrays class struct output

我开始编写这段代码以获得乐趣,我很惊讶它编译和工作。 (我正在使用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*/

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

你有一些严重的未定义的行为在这里;你的代码没有做你认为它正在做的事情。例如,arr[2]是指向cir的指针,但arr[2][1]arr[2][2]是指向未初始化的内存块的指针。根据您的定义

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

您可以安全地访问arr[0](指向tri的指针),arr[1](指向rec的指针)和arr[2](指向{{的指针) 1}}),但那就是全部。

相关问题