C++基本数据类型
常量与变量
这个内容也是老生常谈的知识点了,需要掌握的滚瓜烂熟。
变量
变量是由C++有效类型创建申请的一块存储区域的名称,它的存储区域大小由类型决定。比如我们常用的int,double都是不同的数据类型,而这些不同的数据类型在计算机中占用的内存区域的大小也是不同的。
这里要注意:变量名只是一个标识符,不占用内存,在编译时转换成变量的地址存放在寄存器中。
变量一般分为三种类型
- 局部变量,在一个函数内部或者一片代码块中定义的变量;
- 形式参数变量,即在函数定义时作为参数被定义的变量;
- 全局变量,在所有函数外部定义的变量;
在程序的设计中一般尽可能的减少全局变量的使用
常量
**最简单的理解:**常量在就是程序执行中不可以改变的量,它可以是任意的基本数据类型,常量只能在定义的时候初始化。
一般我们用两种方法来定义常量:
- 使用 #define 预处理器。
- 使用 const 关键字。
大部分的时候都是不推荐使用define的,因为define只是一种替换,define是在预编译的时候执行的,他有时候会出现一些问题,比较麻烦
在传入参数的时候使用const关键字,可以保证传入的参数不会被修改,保证了数据的可靠性
一般还是用const定义常量比较多,define相对const而言比较少
左值与右值
这里再使用一个左值与右值的概念,因为涉及到赋值的内容
左值是有标识符、可以取地址的表达式,最常见的情况有:变量、函数或数据成员的名字返回左值引用的表达式,如 ++x:因为++x的返回结果是x本身,这个地址是可取的
右值是没有标识符、不可以取地址的表达式,一般也称之为“临时对象”。最常见的情况有:返回非引用类型的表达式,如 x++:x++返回的结果是temp,并不是x本身
在内存四区的知识点中会涉及到变量的生存周期,了解内存四区之后再来学习效果会更好
局部变量的值存储在动态存储区,全局变量的值存储在静态存储区。
总结:不管是常量还是变量,都是在内存空间上申请一块区域,只是这块区域是不同的。常量和变量的不可以修改只是从编译器的角度出发,实际上不管是变量还是常量,甚至是已经编译好的代码,都是有办法可以修改的。
因为所有的数据本质上都是存在内存里面的,理论上都是可以修改的
破解外挂和缓冲区攻击其实就是利用这种机制,修改内存中的数据。
类型转换
关于类型转换,之前写过一篇文章讲过一些内容,这里复习一遍
讲到类型转换的内容,从C语言到C++
C语言中强制类型转换的问题
- sizeof()返回的结果是unsigned类型!不是int类型
- 不要把无符号类的数据和有符号的数据进行比较!
- 尽量不要使用强制类型转换,因为出现了错误很难排查
- 类型转换在底层语言中运用比较广泛,不清楚转换后的类型容易出现BUG
如以下代码所示:
sizeof返回的是unsigned的类型,而thre是int类型的数据,他们比较的时候,会产生一个隐式的类型转换!
有符号数会被转换为无符号数,比较的结果有很大的不确定性
因此:在对两个变量进行比较的时候,一定要考虑到他们的数据类型是否是一致的!
#include <iostream>
using namespace std;
int main() {
int array[] = { 1,2,3 };
cout << sizeof(array) / sizeof(array[0]) << endl;
int compare = -1;
int len = sizeof(array) / sizeof(array[0]);
cout << typeid(sizeof(array[0])).name() << endl;
cout << typeid(len).name() << endl;
return 0;
}
看到输出的结果可以知道,sizeof返回的结果其实并不是int的类型,而且是unsinged的数据类型
C++中提供了static_cast () 的数据类型转换方式
当然也可以使用强制类型转换,但是最好使用C++提供的方式
#include <iostream>
using namespace std;
double GetSum(int n) {
double result = 0.0;
for (int i = 1; i < n + 1; i++) {
result += static_cast<double>(1) / i ;
}
return result;
}
int main() {
cout << GetSum(100) << endl;
return 0;
}