本文记录了C++中的数据类型以及基本运算,这部分是典型的每次记每次忘类型,所以烙印在此,以便用时随时查阅。
主要参考:http://www.runoob.com/cplusplus/cpp-data-types.html
1. C++中的数据类型
(1)基本类型
C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C++ 数据类型:
类型 |
关键字 |
布尔型 |
bool |
字符型 |
char |
整型 |
int |
浮点型 |
float |
双浮点型 |
double |
无类型 |
void |
宽字符型 |
wchar_t |
一些基本类型可以使用一个或多个类型修饰符进行修饰:
- signed
- unsigned
- short
- long
下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。
注意:不同系统会有所差异。
类型 |
位 |
范围 |
char |
1 个字节 |
-128 到 127 或者 0 到 255 |
unsigned char |
1 个字节 |
0 到 255 |
signed char |
1 个字节 |
-128 到 127 |
int |
4 个字节 |
-2147483648 到 2147483647 |
unsigned int |
4 个字节 |
0 到 4294967295 |
signed int |
4 个字节 |
-2147483648 到 2147483647 |
short int |
2 个字节 |
-32768 到 32767 |
unsigned short int |
2 个字节 |
0 到 65,535 |
signed short int |
2 个字节 |
-32768 到 32767 |
long int |
8 个字节 |
-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
signed long int |
8 个字节 |
-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long int |
8 个字节 |
0 to 18,446,744,073,709,551,615 |
float |
4 个字节 |
+/- 3.4e +/- 38 (~7 个数字) |
double |
8 个字节 |
+/- 1.7e +/- 308 (~15 个数字) |
long double |
16 个字节 |
+/- 1.7e +/- 308 (~15 个数字) |
wchar_t |
2 或 4 个字节 |
1 个宽字符 |
从上表可得知,变量的大小会根据编译器和所使用的电脑而有所不同。
(2)存储方式:
类型 |
描述 |
bool |
存储值 true 或 false。 |
char |
通常是一个八位字节(一个字符)。这是一个整数类型。 |
int |
对机器而言,整数的最自然的大小。 |
float |
单精度浮点值。单精度是这样的格式,1位符号,8位指数,23位小数。 |
double |
双精度浮点值。双精度是1位符号,11位指数,52位小数。 |
void |
表示类型的缺失。 |
wchar_t |
宽字符类型。 |
整型数都按二进制的形式存储;
对浮点数的解释详见:https://blog.csdn.net/zl3090/article/details/84303694
2. 常量
常量包括数值型常量和字符型常量两大类。
常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。
常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值。
常量就像是常规的变量,只不过常量的值在定义后不能进行修改。
(1)整数常量
整数常量可以是十进制、八进制或十六进制的常量。
a. 前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
b. 后缀指定类型:后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
各种情况的示例如下:
85 // 十进制
0213 // 八进制
0x4b // 十六进制
30 // 整数
30u // 无符号整数
30l // 长整数
30ul // 无符号长整数
(2)浮点数常量
浮点常量由整数部分、小数点、小数部分和指数部分组成。可以使用小数形式或者指数形式来表示浮点常量:
a. 当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者;
b. 当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。
示例如下:
3.14159 // 合法的
314159E-5L // 合法的
510E // 非法的:不完整的指数
210f // 非法的:没有小数或指数
.e55 // 非法的:缺少整数或分数
在程序中,无论写成小数形式还是指数形式,在内存中都是以指数形式(浮点形式)储存的。
(3)布尔常量
布尔常量共有两个,它们都是标准的 C++ 关键字:
不应把 true 的值看成 1,把 false 的值看成 0。
(4)字符常量
字符常量是括在单引号中。如果常量以 L(仅当大写时)开头,则表示它是一个宽字符常量(例如 L'x'),此时它必须存储在 wchar_t 类型的变量中。否则,它就是一个窄字符常量(例如 'x'),此时它可以存储在 char 类型的简单变量中。
字符常量是以它的ASCII码存储在内存中的。
a. 普通字符常量:
单引号中放的一个字符就是普通字符常量,如'a'等,在内存中占一个字节,单引号中只能放一个字符,'AB'这种是不合法的,字符常量是区分大小写的,'A'和'a'是两个不同的字符常量。
b. 转义字符常量:
前边带斜杠的字符,表示特殊的含义,如下所示:
转义序列 |
含义 |
\\ |
\ 字符 |
\' |
' 字符 |
\" |
" 字符 |
\? |
? 字符 |
\a |
警报铃声 |
\b |
退格键 |
\f |
换页符 |
\n |
换行符 |
\r |
回车 |
\t |
水平制表符 |
\v |
垂直制表符 |
\ooo |
一到三位的八进制数 |
\xhh . . . |
一个或多个数字的十六进制数 |
表中需要说明的是,八进制字符\ooo表示一到三位八进制数组成的字符,ooo均为0-7组成的数字,可以是相同或者不同的数字;例如'\101'表示八进制ASCII码101代表的字符,对应十进制数65,也就是对应字母A;而十六进制字符\xhh表示一到二位十六进制字符组成的字符,x是十六进制数的标志,不能被替换,而hh均为0-F组成的数字,可以相同或者不同。
c. 字符串常量:
用双引号引起来的字符代表字符串常量,此处有别于python中不区分单双引号,c++中单引号只表示单个字符,而双引号表示字符串,需要注意的是,双引号中可以放单个字符,但是此时仍是一个字符串,如"a"与'a'不同,"a"是字符串常量,在内存中占两个字节(包括\0,下边注意中细说),而'a'是字符常量,在内存中占一个字符,也就是说char类型只能定义字符,而不能定义字符串,即:
char c; //定义字符变量,一个字节
c = 'a'; //正确
c = "a"; //错误,不能容纳字符串类型
注意:编译系统会在字符串最后自动加一个'\0'作为结束的标志,它不是字符串的一部分,但是会占据一个字节的内存,如字符串"abc\n",该字符串包含4个字符,分别是a,b,c,\n,编译系统遇到 \ 时,会把它认作转义字符的标志,会将它和它后边的字符一起作为一个转义字符,若与后边的字符不能构成合法的转义字符,则编译会报错;但是该字符串在内存中占据5个字节,是因为最后包含\0字符。若想将 \ 单独作为一个字符,上述字符串应该写作"abc\\n",此时的字符为a,b,c,\,n。
(5)定义常量(符号常量)
在 C++ 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器。
- 使用 const 关键字。
实例如下:
#include <iostream>
using namespace std;
#define LENGTH 10 //注意,此处不是语句,没有分号
#define WIDTH 5
#define NEWLINE '\n'
int main()
{
int area;
area = LENGTH * WIDTH;
cout << area;
cout << NEWLINE;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
const int LENGTH = 10; //使用 const 前缀声明指定类型的常量
const int WIDTH = 5;
const char NEWLINE = '\n';
int area;
area = LENGTH * WIDTH;
cout << area;
cout << NEWLINE;
return 0;
}
注意:符号常量虽然有名字,但不是变量,编译中只要遇到这个名字,都会被替换成它对应的数值。
#define和const的区别:
#define是定义的符号常量,也就是说它用一个符号代替了一个字符串(或常量),在编译时,系统会把所有的符号常量替换为指定的字符串,它没有类型,在内存中并没有以符号常量命名的存储单元;
而const确切来说定义的是常变量,它具有变量的特征,也就是说具有类型,在内存中存在着以它命名的存储单元,可以用sizeof测出其长度,它与一般变量的区别是变量值不允许修改,也就是只读变量。
3. 变量
变量由变量名和变量值组成,其中,变量名代表内存中的一个存储单元,在编译中由系统分配一个地址;变量值代表相应存储单元中的数据值。
命名规则:
a. 只能由数字、字母或下划线构成;
b. 第一个字符只能是字母或下划线;
c. 大小写字母对应着不同的变量;
d. 变量名不能与c++的关键字、系统函数名和类名相同;
e. 常用驼峰命名法(以小写字母开头,下一个单词首字母大写,如studentName);
f. 命名有长度限制,一般不超过32字符。
变量的定义:
数据类型 变量名列表
示例:
float a,b,c,d;
C++对变量使用前先定义的好处:
a. 凡是未事先定义的,不作为变量名,可以保证程序中变量名使用正确,避免变量名写错的情况;
b. 为每一变量指定确定的类型,从而分配对应的存储单元;
c. 为每一变量指定确定的类型,编译时可以检查运算是否合法,如%运算要求左右两边都是int型。
4.运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C++ 内置了丰富的运算符,并提供了以下类型的运算符:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 杂项运算符
(1)算术运算符
下表显示了 C++ 支持的算术运算符。
假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 |
描述 |
实例 |
+ |
把两个操作数相加 |
A + B 将得到 30 |
- |
从第一个操作数中减去第二个操作数 |
A - B 将得到 -10 |
* |
把两个操作数相乘 |
A * B 将得到 200 |
/ |
分子除以分母 |
B / A 将得到 2 |
% |
取模运算符,整除后的余数 |
B % A 将得到 0 |
++ |
自增运算符,整数值增加 1 |
A++ 将得到 11 |
-- |
自减运算符,整数值减少 1 |
A-- 将得到 9 |
此处需要说明的是:
a. 除法/运算,若两个数都是整数,则结果为整数,小数部分不管超没超过0.5,都会被舍去,负数也一样,原则是向0取整,也就是说取更靠近0的整数,如-5/3 = -1;
b. 取余%运算,要求左右两边都是整数,否则会报错;
c. +、-、*、/中若有一个数是float型的,则结果是double型的,因为运算时会对所有float型的数据按照double型处理。
d. 运算中char和short都会被先转换成int型,float都会被转成double型,其他两个不同类型运算的转换级别是:
int到unsiged到long到double,最终输出什么类型以两个数据中级别高的为准,并且转换并不经过中间步骤,是一步到位的。
e. 自增自减类型:
++i是在i使用前先将i的值加1,再使用;
i++是先使用原始值,再将i加1;
自减同理,示例:
//谭浩强书中习题2-7
#include <iostream>
using namespace std;
int main()
{
int i,j,m,n;
i = 8;
j = 10;
m = ++i + j++;
n = (++i) + (j++) + m;
cout << i << '\t' << j << '\t' << m << '\t' << n << '\t';
return 0;
}
输出为10,12,19,41,m中自增运算有无括号效果相同。
(2)关系运算符
下表显示了 C++ 支持的关系运算符。
假设变量 A 的值为 10,变量 B 的值为 20,则:
运算符 |
描述 |
实例 |
== |
检查两个操作数的值是否相等,如果相等则条件为真。 |
(A == B) 不为真。 |
!= |
检查两个操作数的值是否相等,如果不相等则条件为真。 |
(A != B) 为真。 |
> |
检查左操作数的值是否大于右操作数的值,如果是则条件为真。 |
(A > B) 不为真。 |
< |
检查左操作数的值是否小于右操作数的值,如果是则条件为真。 |
(A < B) 为真。 |
>= |
检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 |
(A >= B) 不为真。 |
<= |
检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 |
(A <= B) 为真。 |
(3)逻辑运算符
下表显示了 C++ 支持的关系逻辑运算符。
假设变量 A 的值为 1,变量 B 的值为 0,则:
运算符 |
描述 |
实例 |
&& |
称为逻辑与运算符。如果两个操作数都非零,则条件为真。 |
(A && B) 为假。 |
|| |
称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 |
(A || B) 为真。 |
! |
称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 |
!(A && B) 为真。 |
(4)位运算符
运算符 |
描述 |
实例 |
& |
如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 |
(A & B) 将得到 12,即为 0000 1100 |
| |
如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 |
(A | B) 将得到 61,即为 0011 1101 |
^ |
如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 |
(A ^ B) 将得到 49,即为 0011 0001 |
~ |
二进制补码运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0。 |
(~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 |
<< |
二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 |
A << 2 将得到 240,即为 1111 0000 |
>> |
二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 |
A >> 2 将得到 15,即为 0000 1111 |
(5)赋值运算符
下表列出了 C++ 支持的赋值运算符:
运算符 |
描述 |
实例 |
= |
简单的赋值运算符,把右边操作数的值赋给左边操作数 |
C = A + B 将把 A + B 的值赋给 C |
+= |
加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 |
C += A 相当于 C = C + A |
-= |
减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 |
C -= A 相当于 C = C - A |
*= |
乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 |
C *= A 相当于 C = C * A |
/= |
除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 |
C /= A 相当于 C = C / A |
%= |
求模且赋值运算符,求两个操作数的模赋值给左边操作数 |
C %= A 相当于 C = C % A |
<<= |
左移且赋值运算符 |
C <<= 2 等同于 C = C << 2 |
>>= |
右移且赋值运算符 |
C >>= 2 等同于 C = C >> 2 |
&= |
按位与且赋值运算符 |
C &= 2 等同于 C = C & 2 |
^= |
按位异或且赋值运算符 |
C ^= 2 等同于 C = C ^ 2 |
|= |
按位或且赋值运算符 |
C |= 2 等同于 C = C | 2 |
(6)杂项运算符
下表列出了 C++ 支持的其他一些重要的运算符。
运算符 |
描述 |
sizeof |
sizeof 运算符返回变量的大小。例如,sizeof(a) 将返回 4,其中 a 是整数。 |
Condition ? X : Y |
条件运算符。如果 Condition 为真 ? 则值为 X : 否则值为 Y。 |
, |
逗号运算符会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。 |
.(点)和 ->(箭头) |
成员运算符用于引用类、结构和共用体的成员。 |
Cast |
强制转换运算符把一种数据类型转换为另一种数据类型。例如,int(2.2000) 将返回 2。 |
& |
指针运算符 & 返回变量的地址。例如 &a; 将给出变量的实际地址。 |
* |
指针运算符 * 指向一个变量。例如,*var; 将指向变量 var。 |
(7) C++ 中的运算符优先级
运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
例如 x = 7 + 3 * 2,在这里,x 被赋值为 13,而不是 20,因为运算符 * 具有比 + 更高的优先级,所以首先计算乘法 3*2,然后再加上 7。
下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
类别 |
运算符 |
结合性 |
后缀 |
() [] -> . ++ - - |
从左到右 |
一元 |
+ - ! ~ ++ - - (type)* & sizeof |
从右到左 |
乘除 |
* / % |
从左到右 |
加减 |
+ - |
从左到右 |
移位 |
<< >> |
从左到右 |
关系 |
< <= > >= |
从左到右 |
相等 |
== != |
从左到右 |
位与 AND |
& |
从左到右 |
位异或 XOR |
^ |
从左到右 |
位或 OR |
| |
从左到右 |
逻辑与 AND |
&& |
从左到右 |
逻辑或 OR |
|| |
从左到右 |
条件 |
?: |
从右到左 |
赋值 |
= += -= *= /= %=>>= <<= &= ^= |= |
从右到左 |
逗号 |
, |
从左到右 |
两个比较典型的例子:
a的初值为12,
a*a = 2+3,结果是60,自右向左结合,先计算2+3;
a +=a-=a*=a,结果是0,自右向左结合,每一步a都变化了,始终是自己跟自己做运算。