1. C、C++内置的类型分两种,一种是基本数据类型,一种是复合数据类型,此处我们要讲的结构体便是复合数据类型。

先来讨论一下结构体存在的意义吧,也许你认为基本的数据类型就够了,为什么还要有结构题这种复合数据类型存在呢?其实结构体是很有用的。

2. 比如当我们要存储以为老师的基本信息时,则可能需要存储他的姓名、身高、工资、体重、家庭住址等等。我们希望有一种数据格式可以将所有这些信息存储在一个单元中。数组肯定是不能完成这项艰巨的任务的,因为数组虽然可以存储多个元素,但所有元素的类型必须相同,比如,一个数组可以存储20个int类型的元素,另外一个数组可以存储20个double型的元素,但是我们是不能够在一个数组中一部分元素存储20个int,一部分元素用来存储20个double。这也就是数组相对于结构体的缺陷。


3. C++中的结构体便可以满足存储一位老师基本信息的要需求。结构体是一种币数组更灵活的数据格式,因为同一个结构体可以存储多种类型的数据,这使得我们可以将老师的基本信息存放在一个结构体中从而将数据的表示合并到一起。结构体其实也是C++面向对象的一个基础。
结构体是用户自己定义的类型,定义了这种类型之后,便可以创建结构体变量了(此处也许说成是对象,对理解OOP的帮助更大)。
使用结构体的两个步骤:
A. 定义结构体
B. 创建结构体变量

下面我们创建一个描述一个结构体:

struct worker { char name[20]; int age; double salary; };

struct 是创建结构体的关键字,表明下面将创建的是一个结构体,worker是结构体的名字,此时我们便可以像创建int类型的变量那样创建结构体变量了。

worker tom;

worker Bob;

如果大家对C语言还有映像的话,可能会注意到,此处我创建的两个worker类型的对象时,没有加关键字struct,这里便是C++做的一点改进,这样让我们创建结构体对象时和创建类的对象更加相似了。(注意:C语言创建结构体对象不能省略struct关键字)。

结构体成员的访问是使用“.”成员运算符来实现的,例如此处,我们可以这样访问结构体成员,tom.name,Bob.salary。(tom是一个结构体对象,而tom.name是一个char类型的变量,注意这点区别)。值得一说的是,访问类成员函数如cin.get()的方法是从访问结构体变量的方法衍生而来的。(学语言其实可以学一下语言的发展史)。

4.下面来举一个结构体使用的实例吧

代码如下:

// struct.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<iostream>
struct worker
{
char name[20];
int age;
};
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

worker wor1 =
{
"manTom",
28
};

worker wor2 = { "womenBob", 30 };
cout << "The first worker's name: "
<< wor1.name
<< " age: "
<< wor1.age
<< endl;
cout << "The second worker's name: " << wor2.name << " age: " << wor2.age << endl;

cout <<"sum of age:"<< wor1.age + wor2.age << endl;
system("pause");
return 0;
}

运行截图如下:

关于结构体的详细讲解,C、C++中的区别_C++

5.结构体的声明可以放在两个位置:

放在main()函数的前面,此时叫外部声明,可以被其后面的所有函数使用。

放在main()函数中,此时只能被该声明所属的函数使用。

通常还是使用外部声明,这样所有的函数都可以使用这种类型的结构体。

6.结构体的初始化

C++11做了很大的改进,跟数组一样,结构体变量也可以使用花括号“{}”来初始化。

Worker  wor1{“tom”,28};当然也可以加上等号,这样写Worker  wor1={“tom”,28};

不过我相信大家肯定是最喜欢偷懒的写法吧。

注意:如果花括号内没有包含任何东西,那么各个成员都将被设置为0。

Wor1.age的值被设置为0,而wor1.name的每个字节都被设置为0。

7.可能学的深入的朋友还有一个疑问,string类可以作为结构体的成员吗?

当然答案是yes

例如你可以像下面这样定义结构体。

struct worker { std::string name; //此处你也可以先指出命名空间。 int age; }

8.下面再讲一讲结构体的值传递。

大家可能都知道基本数据类型之间的赋值,例如:

Int a=10;

int b;

b=a;

这样b的值也就是10了,很是方便,但是结构体可以这样赋值吗,例如可以将bob的值赋给tom吗?tom=bob。

下面举个例子:

代码如下:

// struct.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<iostream>
struct worker
{
char name[20];
int age;
};
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;

worker wor1 =
{
"manTom",
28
};
worker wor2;
cout << "The first worker's name: "
<< wor1.name
<< " age: "
<< wor1.age
<< endl;
wor2 = wor1;
cout << "The second worker's name: " << wor2.name << " age: " << wor2.age << endl;

cout <<"sum of age:"<< wor1.age + wor2.age << endl;
system("pause");
return

0; }
运行截图:

关于结构体的详细讲解,C、C++中的区别_struct_02

从上面可以看出,结构体对象之间是可以直接赋值的。

9.最后再说一下结构体数组。结构体数组就是元素为结构体变量的数组。

创建方法和创建基本类型的数组方法一模一样。

例如要创建一个包含50个worker的数组,可以这样:

Worker  wor[50];

Wor是一个worker数组,其中每个元素都是worker对象,可以和成员运算符一起使用。

例如:

Cin>>wor[0].name;

Cout<<wor[0].name;

注意:wor是一个数组,而不是结构体。

结构体数组初始化方法:

worker wor[2]={{“tom”,20},{“bob”,30}};

下面举个例子:

代码如下:

// struct.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include<iostream>
struct worker
{
char name[20];
int age;
};
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
worker wor[2]=
{
{"tom",20},
{"bob",30}
};
cout << "The first worker's name: "
<< wor[0].name
<< " age: "
<< wor[0].age
<< endl;

cout << "The second worker's name: " << wor[1].name << " age: " << wor[1].age << endl;

cout <<"sum of age:"<< wor[0].age + wor[1].age << endl;
system("pause");
return 0;
}

运行截图如下:


关于结构体的详细讲解,C、C++中的区别_C++_03


10.最最后再说一下结构体中的位字段。

与C语言一样,C++允许指定占用特定位数的结构体成员,这使得创建与某个硬件设备上的寄存器对应的数据结构非常方便,学硬件的朋友可能深有体会。

下面举个例子:


Struct torgle_register { unsigned int SN : 4; unsigned int : 4; bool goodIn : 1; bool goodTorgle : 1; };
位字段通常用在底层的编程中。


好了,关于结构体的知识大概就说到这里了。

注:程序中给出的代码都在VS2013中通过编译运行。