Home C&C++函数库 c++ 语法 程序源码 Linux C库

数据结构体

☞ 数据结构体



结构体是在一个名称下组合在一起的一组数据元素。这些数据元素称为成员, 可以有不同的类型和不同的长度。在c++中可以使用以下语法声明数据结构:

struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

其中type_name是结构类型的名称,object_name是具有该结构类型的对象的有效标识符集。 在大括号{}中,有一个包含数据成员的列表,每个成员都用类型和有效标识符作为名称来指定。

例如:

struct product {
  int weight;
  double price;
} ;

product apple;
product banana, melon;

这声明了一个称为product的结构类型,并定义了它有两个成员:weight和price, 每一个都是不同的基本类型。这个声明创建了一个新类型(product),然后用它来声明该类型的三个对象(变量) :apple、banana和melon。请注意,一旦声明了产品,就可以像使用其他类型一样使用它。

在结构体定义的末尾,在分号(;)结束之前,可选字段object_names可用于直接声明结构体类型的对象。 例如,结构对象apple、banana和melon可以在定义数据结构类型的时候声明:

struct product {
  int weight;
  double price;
} apple, banana, melon;

在本例中,当指定了object_names时,类型名称(product)变成可选的: 结构体需要一个type_name或object_names中至少一个名称,但不能是两个。

清楚地区分什么是结构类型名称(product),什么是这种类型的对象 (apple, banana, 和 melon)是很重要的。许多对象(如apple, banana, 和 melon) 可以在一个结构类型(product)中声明。

一旦声明了确定结构类型的三个对象(apple、banana和melon),就可以直接访问其成员。 它的语法就是在对象名和成员名之间插入一个点(.)。 例如,可以将这些元素当作各自类型的标准变量来操作:

apple.weight
apple.price
banana.weight
banana.price
melon.weight
melon.price

它们中的每一个都有对应于它们引用的成员的数据类型:apple.weight, banana.weight,和 melon.weight 是int类型的,而 apple.price, banana.price, 和 melon.price 是double。

下面是一个使用结构类型的实际例子:

// example about structures
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct movies_t {
  string title;
  int year;
} mine, yours;

void printmovie (movies_t movie);

int main ()
{
  string mystr;

  mine.title = "2001 A Space Odyssey";
  mine.year = 1968;

  cout << "Enter title: ";
  getline (cin,yours.title);
  cout << "Enter year: ";
  getline (cin,mystr);
  stringstream(mystr) >> yours.year;

  cout << "My favorite movie is:\n ";
  printmovie (mine);
  cout << "And yours is:\n ";
  printmovie (yours);
  return 0;
}

void printmovie (movies_t movie)
{
  cout << movie.title;
  cout << " (" << movie.year << ")\n";
}
Enter title: Alien
Enter year: 1979

My favorite movie is:
 2001 A Space Odyssey (1968)
And yours is:
 Alien (1979)

这个例子展示了对象的成员如何像常规变量一样工作。 例如,成员 yours.year是一个有效的int类型变量, mine.title也是一个有效的字符串类型变量。

但是对象mine和yours也是具有类型(类型为movies_t)的变量。 例如,它们都被传递给printmovie函数,就像它们是简单变量一样。 因此,结构体的特性之一是能够分别引用其成员或作为一个整体引用整个结构。 在这两种情况下使用相同的标识符:结构体的名称。

因为结构体是类型,所以也可以作为数组的类型来构造它们的表或数据库:

// array of structures
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct movies_t {
  string title;
  int year;
} films [3];

void printmovie (movies_t movie);

int main ()
{
  string mystr;
  int n;

  for (n=0; n<3; n++)
  {
    cout << "Enter title: ";
    getline (cin,films[n].title);
    cout << "Enter year: ";
    getline (cin,mystr);
    stringstream(mystr) >> films[n].year;
  }

  cout << "\nYou have entered these movies:\n";
  for (n=0; n<3; n++)
    printmovie (films[n]);
  return 0;
}

void printmovie (movies_t movie)
{
  cout << movie.title;
  cout << " (" << movie.year << ")\n";
}
Enter title: Blade Runner
Enter year: 1982
Enter title: The Matrix
Enter year: 1999
Enter title: Taxi Driver
Enter year: 1976

You have entered these movies:
Blade Runner (1982)
The Matrix (1999)
Taxi Driver (1976)

☞ 结构体指针



像任何其他类型一样,结构体可以有它自己的指针类型:

struct movies_t {
  string title;
  int year;
};

movies_t amovie;
movies_t * pmovie;

这里movie是一个结构类型movies_t的对象,而pmovie是一个指向结构类型movies_t对象的指针。 因此,下面的代码也是有效的:

pmovie = &amovie;

指针pmovie的值将被赋值为对象movie的地址。

现在,让我们看另一个混合了指针和结构的例子,它将引入一个新的操作符:箭头操作符(->):

// pointers to structures
#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct movies_t {
  string title;
  int year;
};

int main ()
{
  string mystr;

  movies_t amovie;
  movies_t * pmovie;
  pmovie = &amovie;

  cout << "Enter title: ";
  getline (cin, pmovie->title);
  cout << "Enter year: ";
  getline (cin, mystr);
  (stringstream) mystr >> pmovie->year;

  cout << "\nYou have entered:\n";
  cout << pmovie->title;
  cout << " (" << pmovie->year << ")\n";

  return 0;
}
Enter title: Invasion of the body snatchers
Enter year: 1978

You have entered:
Invasion of the body snatchers (1978)

箭头操作符(->)是一个解引用操作符, 专门用于指向具有成员的对象的指针。该操作符用于直接从对象的地址访问对象的成员。 例如,在上面的例子中:

pmovie->title

等于:

(*pmovie).title

两个表达式,pmovie->title和(*pmovie).title 是有效的,并且它们都访问了pmovie指针所指向的数据结构的成员 title。 它不同于:

*pmovie.title


这相当于:

*(pmovie.title)

这将访问结构对象pmovie的假想指针成员title所指向的值(事实并非如此,因为title不是指针类型)。 下面的面板总结了指针和结构成员的操作符的可能组合:

表达式 说明 相当于
a.b 对象a的成员b
a->b a所指向的对象的成员b (*a).b
*a.b 对象a的成员b所指向的值 *(a.b)

☞ 结构体嵌套



结构体也可以嵌套,即结构体的元素本身就是另一个结构体:

struct movies_t {
  string title;
  int year;
};

struct friends_t {
  string name;
  string email;
  movies_t favorite_movie;
} charlie, maria;

friends_t * pfriends = &charlie;

在前面的声明之后,下面所有的表达式都是有效的:

charlie.name
maria.favorite_movie.title
charlie.favorite_movie.year
pfriends->favorite_movie.year


(顺便说一下,后两个表达式指向同一个成员)



联系我们 免责声明 关于CandCplus 网站地图