(转)结构体中使用string所引发的问题
1.在程序中使用结构体。
#include <iostream>
#include <string>
using namespace std;
struct list
{
string name;
double price;
float volume;
};
int main()
{
list number1={"mingzhe",88.0,1.76,};
list number2={"zhanghuanghui",66.1,1.65,};
cout<<"Expand your guest list with "<<number1.name<<" and "<<number2.name<<endl;
cout<<"You can have both for "<<number1.price+number2.price<<"!"<<endl;
return 0;
}
刚开始编译时20多个错,吓我一跳,后来发现,原来是初始化时,各个变量我用分号隔开了。实际上声明的时候是用分号隔开,初始化赋值的时候就像数组一样用逗号分隔了。解决了这个问题后,发现还有两个错误。如下:
报错:error C2552: 'number1' : non-aggregates cannot be initialized with initializer list
MSDN中C2552说的是:
Compiler Error C2552
'identifier' : non-aggregates cannot be initialized with initializer list
The specified identifier was incorrectly initialized.
An initializer list is needed to initialize the following types:
- An array
- A class, structure, or union that does not have constructors, private or protected members, base classes, or virtual functions
These types are known as “aggregates.”
也 就是说标识符没有被正确初始化。结构中可以初始化的只能是数组或者一些没有构造函数、私有成员以及保护成员和基类、虚函数的类、结构体、共用体。所以这里 对string类对象name进行初始化就是非法了。VC++6.0中是这样的,据说更高级的没有这个问题,我没有试过。
所以程序中使用数组char name[20];代替string name;就可以了。但是有一个warning。
warning C4305: 'initializing' : truncation from 'const double' to 'float'
出在给float类型变量赋值的语句上。MSDN上说:
Compiler Warning (level 1) C4305
'identifier' : truncation from 'type1' to 'type2'
The specified identifier type was converted to a smaller type. Information was lost in the casting.
百 度了下原因。简单来说,Float为单精度,内存中占4个字节,有效数位是7位(因为有正负,所以不是8位),在我的电脑且VC++6.0平台中默认显示 是6位有效数字;double为双精度,占8个字节,有效数位是16位,但在我的电脑且VC++6.0平台中默认显示同样是6位有效数字(见我的 double_float文件)
还有,有个例子:在C和C++中,如下赋值语句
float a=0.1;
编译器报错:warning C4305: 'initializing' : truncation from 'const double ' to 'float '
原因:
在C/C++中(也不知道是不是就在VC++中这样),上述语句等号右边0.1,我们以为它是个float,但是编译器却把它认为是个double(因为小数默认
double),所以要报这个warning,一般改成0.1f就没事了。
通常的做法,经常使用double,而不喜欢使用float。
突然想起来前面看过说:如果不指定类型,输入的小数默认为double类型。
2.结构可以将string类作为成员吗?
呃,刚发现下面马上讲这个问题。不过自己动手发现问题然后解决问题还是跟按部就班学习的感觉是不一样的。这里是这么解释的,取决于编译器,有些编译器不支持把string类对象作为成员的结构进行初始化。看来vc++6.0是不支持了。
3.C++使用户定义的类型和内置类型尽可能相似。
可以将结构作为参数传递给函数,函数也可以返回一个结构;可以使用赋值操作符“=”将结构赋值给另一个同类型的结构。
4. 结构数组的初始化。
使用一个被括在花括号中、用逗号分隔的值列表,其中每个值本身又是一个被括在花括号中、用逗号分隔的值的列表。List name[2]={ {“mingzhe”,0.5,21.2},{“huanghui”,0.4,21.1} };
5. 结构中的位字段。(还不是很明白)。
6. 共用体。
能够存储不同的数据类型,但是只能同时存储其中的一种类型。也就是说,结构可以同时存储int、long和double,但是公用体只能存储int、long或double。共用体的句法与结构相似,但是含义不同。比如:
#include <iostream>
using namespace std;
union one4all
{
int int_val;
long long_val;
double double_val;
};
int main()
{
one4all pail;
pail.int_val=15;
cout<<pail.int_val<<endl;
pail.double_val=1.38;
cout<<pail.double_val<<endl;
return 0;
}
可 以使用one4all变量来存储int long或者double,条件是在不同的时间进行。由于共用体每次只能存储一个值,所以他必须有足够的空间来存 储最大的成员。所以共用体的长度为其最大成员的长度。共用体的用途之一就是,当数据项使用两种或更多种格式(但不会同时使用)时,可以节省空间。
7. 枚举。
Enum提供了另一种创建符号常量的方式,这种方法可以代替const。比如:
Enum spectrum{red,orange,yellow,green,blue,white};将red等作为符号常量,他们对应整数值0-7,这些常量叫枚举量。
8. 在C++创建指针时,计算机将分配用来存储地址的内存,但是不会分配用来存储指针所指向的数据的内存。为数据提供空间是一个独立的步骤,忽略这一步无疑是自找麻烦。
一定要在对指针应用接触引用操作符*之前,将指针初始化为一个确定的适当的地址。这是使用指针的金科玉律。