类型 | 长度 |
---|---|
short | 至少16bit |
int | 至少和short一样长 |
long int | 至少和int一样长 |
long long int | 至少和long一样长 |
long long int和long int不一样长
C的数据类型符号常量
符号常量 | 表示 |
---|---|
CHAR_BIT | char的位数 |
CHAR_MAX | char的最大值 |
CHAR_MIN | char的最小值 |
SCHAR_MAX | signed char的最大值 |
SCHAR_MIN | signed char的最小值 |
UCHAR_MAX | unsigned char的最大值 |
SHRT_MAX | unsigned char的最小值 |
SHRT_MIN | short的最大值 |
USHRT_MAX | short的最小值 |
INT_MAX | int的最大值 |
INT_MIN | int的最小值 |
UNIT_MAX | unsigned int的最大值 |
LONG_MAX | long int的最大值 |
LONG_MIN | long int的最小值 |
ULONG_MAX | unsigned long int 的最大值 |
LLONG_MAX | long long的最大值 |
LLONG_MIN | long long的最小值 |
ULLONG_MAX | unsigned long long 的最大值 |
上表的常量均定义在库中
我们先说一下计算机中的原码,反码,补码
可以先想想在计算机中数字是怎么存储的,二进制存储的,比如我要存储数据15那么就是二进制1111
,这个好办,但是如果要存储-15呢,好像没有-
,那该怎么办呢,这是一种解决办法:
我们知道了计算机中的负数的表示方法就可以看数据范围与溢出了,我们先定义一个int t=INT_MAX;
然后t++;看看得到什么,变成了-INT_MAX了,这就是溢出。顺便说一下unsigned int,因为不用考虑负数所以少表示了INT_MAX的数据,可以一直往上接,所以可以做这么一个实验,unsigned int m=2INT_MAX;(UNIT_MAX=INT_MAX2)然后m++;看输出得到0;然后m++;得到1
整型字面值:
如何确定常量的类型:
cout<<1234;
如何确定1234
的类型:
l
或者L
就认为是long常量,如果是u
或者U
就认为是unsigned int常量,ul
不论顺序,都认为是unsigned int ,当然还有ull
,Ull
,uLL
,ULL
。顺便提一下,从上面负数的表示我们也就知道了,为什么对于同一个数据类型unsigned会比正常的表示范围大一倍
wcha_t ss=L'p';
wcout<<L'e';
比char多了一个L,因为有这个标记所以系统会分配两个char的空间去存储这个p
int a=10;
bool t=a;
cout<<int(t)
输出是1,一旦被bool转换,只要非0直接转化为1
还有就是bool的输出格式:
bool a=true;
cout<<a;
输出是1
想要输出true
需要这样写
cout.setf(ios_base::boolalpha);
bool a=true;
cout<<a;
输出就是true,看一下cout.setf(ios_base::boolalpha);
首先是cout.setf(),就是ostream类下的cout对象的方法setf,参数是ios_base域下的boolalpha,实际上这个boolalpha是一个枚举,他对应了一个数值。
#define
来使用预处理器的方法定义一个常量,现在我们使用const限定符,这样的好处是指定了数据的类型,更加“智能”,分别运行下面两个程序#include
#include
#define primer a
using namespace std;
int main() {
cout << a;
return 0;
}
#include
#include
using namespace std;
const string a="primer";
int main() {
cout << a;
return 0;
}
第一个会报错,是因为#define
只是简单地替换,cout不知道一个primer
是什么,但是因为const有数据类型,所以可以轻易输出
const的另一个好处是他可以限定常量的作用于,最后一个是他可以应用于复杂的数据类型,比如结构体
关于有效位数的显示,使用了ostream类的setf()方法
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
std::cout.precision(3);
第一行是禁用科学计数法,第二行是规定小数点位数,注意了,和刚才说的一样,里面是一个枚举值,所以可以写一个int把设置存储下来,以后就可以直接用了。
然后写一下浮点常量,就是正常数字后面加F或者L(大写是为了字母数字分开)
就说一个取模运算和求余运算的区别
通常取模运算也叫取余运算,它们返回结果都是余数 唯一的区别在于:
当 x 和 y 的正负号一样的时候,两个函数结果是等同的;当 x 和 y 的符号不同时,rem 函数结果的符号和 x 的一样,而 mod 和 y 一样。
这是由于这两个函数的生成机制不同,rem 函数采用 fix 函数,而 mod 函数采用了 floor 函数(这两个函数是用来取整的,fix 函数向 0 方向舍入,floor 函数向无穷小方向舍入)。 rem(x,y)命令返回的是 x-n.*y,如果 y 不等于 0,其中的 n = fix(x./y),而 mod(x,y) 返回的是 x-n.*y,当 y 不等于 0 时,n=floor(x./y)
两个异号整数取模取值规律 (当是小数时也是这个运算规律,这一点好像与 C 语言的不太一样)
先将两个整数看作是正数,再作除法运算:
1、能整除时,其值为 0
2、不能整除时,其值=除数×(整商+1)-被除数
在普通的类型转化中加宽缩窄是接受的,但是在{}
初始运算符中确实不允许缩窄的例如char t {99};
是不被允许的
int a=int(123.33);
int b=(int)123.33;
其中后者是c-风格的,但是在c++中更希望是前者,这样就好像强制类型转化是一个函数,更符合OOP的思想
强制类型转化不会修改值的本身,而是新建了一个目标格式的副本,但是不用该滥用强制转换
static_cast(value)