假设创建一个结构体:struct inflatable{ ... }; 标识符inflatable就是这种数据结构格式的名称。
C++允许在声明结构变量时省略关键字struct; 在C++中,结构标记的用法与基本类型名相同。
可以同时完成定义结构和创建结构变量的工作。为此,只需将变量名放在结束括号的后面即可:
struct perks
{
int key_number;
char car[12];
}mr_smith, ms_jones; 这样就创建了两个变量。
甚至可以初始化以这种方式创建的变量:
struct perks
{
int key_number;
char car[12];
}mr_glitz =
{
7,
"aaaa"
};不过将结构定义和变量声明分开,可以使程序更易于阅读和理解。
还可以声明没有名称的结构类型,方法时省略名称,同时定义一种结构类型和一个这种类型的变量:
struct
{
int x;
int y;
}position;
这样就创建一个名为position的结构变量。可以使用成员操作符来访问它的成员(如position.x),但是这种类型没有名称,因此以后无法创建这种类型的变量。
inflatable guests[2] =
{
{"a",0.2,21.99},
{"asa",0.3,12.89}
};
与C语言一样,C++也允许指定占用特定位数的结构成员,这使得创建与某个硬件设备上的寄存器对应的数据结构非常方便。
字段的类型应为整型或枚举,接下来时冒号,冒号后面是一个数字,它指定了使用的位数。 可以使用没有名字的字段来提供间距。每个成员都被称为 位字段(bit field)。
枚举:
C++的enum工具提供了另一种创建符号常量的方式,这种方式可以替代const。它还允许定义新类型,但必须按照严格的限制进行。使用enum的句法与使用结构相似。
枚举的取值范围定义如下: 首先要找出上限,需要知道枚举量的最大值。找到大于这个最大值的,最小的2的幂,将它减去1,得到的便是取值范围的上限。 要计算下限,需要知道枚举量的最小值。如果它不小于0,则取值范围的下限为0;否则,采用与寻找上限相同的方式,但加上负号。例如最小的枚举量为-6,而比它小的,最大的2的幂是-8(加上符号),因此下限为-7。
时常要想三个问题:
(1):信息存储在何处?
(2):存储的值为多少?
(3):存储的信息是什么类型?
面向对象编程与传统的过程性编程的区别在于,OOP强调的是在运行阶段(而不是编译阶段)进行决策。运行阶段指的是程序正在运行时,编译阶段指的是编译器程序将程序组合起来。 运行阶段决策就好比度假时,选择参观哪些景点取决于天气和当时的心情; 而编译阶段决策更像不管在什么条件下,都坚持预先设定的日程安排。
指针的危险:
在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。为数据提供空间时一个独立的步骤,忽略这一步无疑是自找麻烦。
例如: int *fellow;
*fellow = 223323;
fellow确实是一个指针,但它指向哪里呢? 上述代码没有将地址赋给fellow,那么223323将被放在哪里呢?我们不知道,由于fellow没有被初始化,它可能是任何值。不管值是什么,程序都将它解释为存储223323的地址。 这种错误可能会导致一些最隐匿、难以追踪的Bug。
我们将指针初始化为变量的地址;变量是在编译时分配的、有名称的内存,而指针只是为可以通过名称直接访问的内存提供了一个别名。
指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。 在这种情况下,只通过指针来访问内存。 在C语言中,可以用库函数malloc() 来分配内存; 在C++中 仍然可以这样做,但C++还有更好的方法————new操作符。
例子: int *pn = new int;
new int 告诉程序,需要适合存储int的内存。new操作符根据类型来确定需要多少字节的内存。然后,它找到这样的内存,并返回返回其地址。接下来,将地址赋给pn,pn是被声明为指向int的指针。 现在,pn是地址, 而*pn是存储在那里的值。
上述方法引出了一个问题: pn指向的内存没有名称,如何称呼它呢? 我们说,pn指向一个数据对象。这里的“对象”不是“面向对象编程”中的对象,而是一样“东西”。术语“数据对象”比“变量”更通用,它指的是为数据项分配的内存块。因此,变量也是数据对象,但pn指向的内存不是变量。
数据对象:指的是为数据项分配的内存块。
为一个数据对象(可以是结构,也可以是基本类型)获得并指定分配内存的通用格式如下:
typeName pointer_name = new typeName;
计算机可能会由于没有足够的内存而无法满足new的请求。在这种情况下,new将返回0.在C++中,值为0的指针被称为空值指针(null pointer)。C++确保空值指针不会指向有效的数据,因此它常被用来表示操作符或函数失效,如果成功,他们将会返回一个有用的指针。
使用delete来释放new的内存。
例如 int *ps = new int;
delete ps;
这将释放ps指向的内存,但不会删除指针ps本身。还可以将ps重新指向另一个新分配的内存块。(一定要配对使用new和delete,否则会发生内存泄露 (memory leak)),也就是 被分配的内存再也无法使用了。
不要尝试释放已经释放的内存块,C++标准指出,这样做的结果将是不确定的。这意味着声明情况都有可能发生。 另外不能使用delete来释放声明变量所获得的内存。 (注意: 只能用delete来释放使用new分配的内存, 不过对于空指针使用delete是安全的) (变量存放的地方于 new的内存所在地不一样。所以不行 一个是栈 中 一个是堆中)。
使用delete的关键在于,将它用于new分配的内存。这并不意味着要使用用于new的指针,而是用于new的地址。
使用new和delete时,应遵守以下规则:
(1) 不要使用delete来释放不是new分配的内存
(2)不要使用delete释放同一个内存块两次
(3)如果使用new[]为数组分配内存,则应使用delete[]来释放
(4)如果使用new[]为一个实体分配内存,则应使用delete(没有方括号)来释放
(5)对空值指针使用delete是安全的。