目录
一.类型转换
1.C语言中的类型转换
2.C++中的类型转换
二.IO流
1. C语言的输入与输出
2. 流是什么
3. stringstream
一.类型转换
1.C语言中的类型转换
(1)隐式类型转换,编译阶段自动进行,不能转换就编译报错。(相关类型)
(2)强制类型转换,用户自行检查
例如:
缺点:转换的可读性差,显式类型转换的转换形式都相同,难以跟踪转换错误,隐式类型转换可能有精度丢失的问题。
2.C++中的类型转换
为解决C语言类型转换的可读性,安全性的缺点,C++引入了四种命名的强制类型转换操作符。
(1)static_cast
用于相关类型之间的类型转换,非多态类型的转换,编译器执行的隐式类型转换都可以用static_cast,不相关的类型会编译报错,用法:
(2)reinterpret_cast
用于不相关类型的转换,例如上述的int类型的a转换为int*:
(3)const_cast
用于删除变量的const属性(const——cast中的类型必须是指针或引用):
这里两次打印出的a都是100,因为const常量取数据时被编译器优化了,没有到内存中取数据,而是优化到了寄存器,要防止这种优化,将变量用volatile关键字修饰,让每一次取数据a时,都强制到内存读取。例如:
(4)dynamic_cast
用于动态转换的向下转型。
向上转型:将子类指针或引用转换为父类指针或引用(安全的转换,赋值兼容,编译器原生支持)
向下转换:将父类指针或引用转换为子类指针或引用(不安全的转型,需用dynamic_cast)
注意:
1.dynamic_cast只能用于父类含有虚函数的类。
2.dynamic_cast 会先检查是否能转型成功,能转型成功就转换,反之返回0
例如:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using std::cout;
using std::endl;
class base
{
public:
virtual void fun(){}
};
class derive:public base
{
};
void fun(base* b)
{
derive* p1 = static_cast<derive*>(b);
derive* p2 = dynamic_cast<derive*>(b);
cout << p1 << endl;
cout << p2 << endl << endl;
}
int main()
{
base b;
derive d;
fun(&b);
fun(&d);
return 0;
}
输出:
可见static_cast没有类型安全检查,而dynamic_cast有。
注意:dynamic_cast 是C++一种运行时类型识别的机制,即RTTI:Run-time Type identifification,还有两种方式,一种是typeid,一种是decltype。
二.IO流
1. C语言的输入与输出
缓冲区的作用:
1.屏蔽掉低级IO的实现(封装系统调用),使代码可移植性更强。2.使这部分的内容实现"行"读取的行为(C语言封装的)。
2. 流是什么
### cin为缓冲流,键盘输入的数据会保存在我们的缓冲区当中,当要提取的时候会从缓冲区去拿。读取到回车的时候会刷新缓冲区。
### 空格和回车都作为数据之间的分隔符。
### cin和cout可以直接输入和输出所有内置类型,因为标准库已经全部重载了内置类型的输入输出函数。
### 对于自定义类型,如果要支持cin和cout的标准输入输出,需要对<<或>>进行重载。
### istream类型对象转换为逻辑条件判断值。- 类似于运算符重载。比如 while(cin>>i){}
### VS编译器下输入ctrl+z表示输入结束即eof
### 文件内容的数据格式有二进制文件和文本文件
### 文件流对象操作文件的步骤
- 定义文件流对象
- 使用对象成员函数打开磁盘文件
- 对文件进行读写操作或使用成员函数读写操作
- 关闭文件
使用示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
int main()
{
/*ifstream ifile(只输入用)
ofstream ofile(只输出用)
fstream iofile(既输入又输出用)*/
string str = "hello world ,123456\n";
ofstream ofs("text.txt");
ofs << str;
ofs.close();
return 0;
}
于是可以打开text.txt文件看到
3. stringstream
序列化与反序列化:
将整形数据类型转换成字符串的数据类型的过程叫做序列化,反之叫做反序列化。
C与C++:
在c语言中可以用这个itoa函数或者用sprintf函数进行转化
在c++中可以使用stringstrem类对象进行转化
测试代码:
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main()
{
int num1 = 127863;
string str;
stringstream trans;
trans << num1;
trans >> str;
cout << str << endl;
//如果要进行多次转化需要用clear函数清空trans内部上次的转换状态
trans.clear();
double num2 = 898.19;
trans << num2;
trans >> str;
cout << str << endl;
//trans.str(""); 将底层string对象设置为""空字符串
string s = trans.str();//返回trans对象中管理的string
cout << s << endl;
return 0;
}
输出:
总结:
stringstream在其底层维护了一个string类型的对象用来保存结果。多次数据类型转化时,需用clear()来清空,但clear()不会将 stringstream底层的string对象清空。可使用s. str("")方法将底层string对象设置为""空字符串。可使用s.str()将让stringstream返回其底层的string对象。stringstream使用string类对象代替字符数组,可以避免缓冲区溢出的危险,不用格式化控制stringstream使用更方便,更安全。