C++学习基础笔记之数据类型
让用户输入账号并登录
项目实现
#include <iostream> #include <Windows.h>
int main(void) { char name; int pwd;
std::cout << "请输入账号:"; std::cin >> name;
std::cout << "请输入密码:"; std::cin >> pwd;
/* std::cout << "1.删库" << std::endl; std::cout << "2.篡改" << std::endl; std::cout << "3.ddos" << std::endl; std::cout << "4.DNS劫持" << std::endl; std::cout << "5.reboot" << std::endl; */
system("pause"); return 0; } |
注意:该实现存在以下问题,
- 账号名称太简单,只能输入单个字符
- 密码只能是整数,太简单,不安全。
- 密码输入时,不能隐藏
以上问题在项目3中解决.
项目精讲
C++的数据类型
已使用的数据类型: 字符串类型, 整数类型
什么是数据类型?
现实社会中的人, 分成很多”类型”
“物以类聚, 人以群分”
不同类型的人, 思考问题,处理问题的方式都不一样。
计算机中的数据, 也分成很多类型:
int |
unsigned int |
char |
unsigned char |
long |
long long |
unsigned long |
short |
unsigned short |
float |
double |
各种指针类型 |
枚举类型 |
struct结构类型 |
union联合类型 |
bool |
string |
类 |
C++ 完全支持C语言的各种数据类型。
不同数据类型的区别:
- 表示意义不同
- 占用内存不同
- 表示的范围不同
- 使用方法不同
数据类型使用不当,将导致严重的后果。
- 对于程序员:隐藏BUG
- 对于系统:隐藏灾难
因数据类型使用不当,产生数据溢出,导致阿丽亚娜5型运载火箭自爆
1996年6月4日,阿丽亚娜5型运载火箭的首次发射点火后,火箭开始偏离路线,最终被逼引爆自毁,整个过程只有短短30秒。阿丽亚娜5型运载火箭基于前一代4型火箭开发。在4型火箭系统中,对一个水平速率的测量值使用了16位的变量及内存,因为在4型火箭系统中反复验证过,这一值不会超过16位的变量,而5型火箭的开发人员简单复制了这部分程序,而没有对新火箭进行数值的验证,结果发生了致命的数值溢出。发射后这个64位带小数点的变量被转换成16位不带小数点的变量,引发了一系列的错误,从而影响了火箭上所有的计算机和硬件,瘫痪了整个系统,因而不得不选择自毁,4亿美金变成一个巨大的烟花。
构建IT大厦的砖块:变量
变量,不是数学中的变量。
为什么要使用变量
程序在运行时,需要保存很多内容常常变化的数据。
比如,射击类游戏中不断变化的“分数”。
世界中的芸芸众生:
程序中的数据:
一个程序运行时,大量数据存储在“变量”中。
数据在大量变量之间“计算”、“交换”。
变量是处理数据的基本实体。
变量是什么
变量,是内存中的一块存储空间,即一小块内存。
变量和数据类型有什么关系?
变量,是一个盒子,盒子里保存了“数据”
数据又分成很多“类型”(数据类型)
=> 变量的类型,就是变量中数据的类型。
=> 变量在定义(创建)时,必须先指定它的类型。
【相当于:制作一个盒子时,必须先确认这个盒子是用来装什么的】
=> 1个变量只有1个类型,而且不能改成其他类型
变量的定义
定义形式1:
int x;
int y;
定义形式2:(不推荐)
int x, y;
定义形式3:(定义的时候,设置一个初始值)
int x = 100;
代码解读:
int a; //定义了一个变量 a = 100; |
内存的存储单位-“字节”
内存的存储单位,是字节。
一个字节,包含8位二进制位。
变量名的命名规范
1)只能包含3种字符(数字、大/小写字母,下划线)
2)不能以数字开头(即,只能以字母或下划线开头)
int 2name; //非法
3)不能和“关键字”同名(c语言内部已经使用的“名称”),比如类型名int
变量名的最大长度,C语言没有规定。
最大长度限制,取决于编译器,一般都在32以上。
变量名,最好“顾名思义”,不用使用汉语拼英的简写!
比如:用name表示姓名,用power表示功率。
命名风格:
1)下划线风格
int student_age; (一般用于变量名、函数名)
2)小驼峰风格
int studentAge; (一般用于变量名、函数名)
1)大驼峰风格
class StudentAge; (一般用于“类名”)
2)全部大写 (一般用于宏)
#define MAX_AGE 30
请忘记“匈牙利命名法”(属性+类型+对象描述)
用于计数的整数类型
原始人,使用结绳计数,这个“数”就是整数
int类型
使用最多的整数类型
在内存中占4个字节
表示范围:- (2的31次方) ~ 2的31次方-1 【正负21亿左右】
长整形long
long 也就是 long int
可用来存储更大的整数。
在32位系统上,占4个字节,和int相同
在64位系统上,占8个字节【正负9百亿亿左右】
长长整形long long
用来存储整数。
在内存中占8字节。
很少使用,仅用于特殊的计算。
短整形short
用来存储整数。
在内存中占2字节。
用于存储小范围的整数
表示范围:- (2的15次方) ~ 2的15次方-1 【正负3万多】
------------------------ 分割线 ---------------------------
无符号类型, 铁公鸡-概不赊欠-没有负数
unsigned int
unsigned long
unsigned long long
unsigned short
最小值都是0, 最大值是对应的有符号数的2倍。
经典用法:
unsigned short port; //用来表示网络通信的端口号(0-65535)
unsigned int num; //表示编号(0到四十多亿)
用于单个字符的数据类型
char
某学员的字母故事.
单个字符:
‘0’ ‘1’ ‘2’ ‘3’ ...... ‘9’
‘a’ ‘b’ ‘c’ ‘d’ ...... ‘z’
‘A’ ‘B’ ‘C’ ‘D’ ...... ‘Z’
‘,’ ‘-’ ‘!’ ‘#’ .......
单个字符常量, 要求用‘’括起来
字符类型char
一个字节。
char name = ‘a’;
内存示意图:
字符的实际表示:
所有的字符,使用对应的ASCII值来存储。
为什么?(因为计算机中只能存储0和1的组合)
ASCII码,使用1个字节(包含8个二进制位,即8个0和1的组合)
比如:’A’ , 用 0100 0001 来表示, 就是65
‘B’, 用 0100 0010 来表示, 就是66
char name = ‘a’;
char name = ‘a’;
等效于:
char name = 97;
char类型的另一种用法
用来表示小范围的整数(-128 ~ 127)
不过现在开发时,小范围的整数,也常常直接用int类型。
实例:
int x = 0;
x = ‘a’ + 1; // 97 + 1
注意:
1 和 ‘1’的区别.
int x = 1;
char y = ‘1’; //49
3.5用于精确计算的数据类型(浮点型)
需要精确计算的数学、工程应用,用整数类型不合适。
生活中的”敏感数据”
float类型(单精度浮点类型)
用来存储带小数部分的数据。
在内存中占用4个字节
表示范围:-3.4*10^38~+3.4*10^38 (不需记忆)
精度:最长7位有效数字(是指7位10进制位)
float y = 1.123456789;
//精度只能取值到 1.1234568, 在第7位(整数部分不算)是四舍五入后的值。
float类型的存储方式:
符号位:0代表正数,1代表负数
阶码: 指数+127
符号位 尾数 * 2 ^ (阶码-127)
转化过程:(了解)
float x = 13.625;
13.625 的转化:
13.625
13 -> 1101 倒除法:
.625 -> .101 0.625 * 2 = 1.25 取整 1 ,剩下0.25 0.25 * 2 = 0.5 取整 0 , 剩下0.5 0.5 * 2 = 1 取整 1 ,剩下0 按顺序得到 101(直到小数部分为0)
13.625 => 1101.101
1101.101 小数点向左移动3位 => 1.101101 (要求移动到整数部分只有1位) 所以,阶码 = 3 + 127 = 130 二进制形式为:10000010
移位后的小数部分是 .101101 尾数存储二进制的101101
实际存储为:
|
double类型(双精度浮点类型)
用来存储带小数部分的数据。
8个字节
具体的存储方式和float相似.
表示范围:-1.7*10^308~1.7*10^308(不需记忆)
精度:最长16位有效数字(是指16位10进制位)
double y = 1.12345678901;
浮点类型的常量
带小数的常量默认都是double类型
3.14 是double类型
3.14f 强制指定是float类型
可以用”科学计数法”表示浮点类型的常量
1.75E5 或 1.75 e5
1.75E5就是1.75乘以10的5次方(100000), 175000.0
注意:
1 是int类型的常量
1.0 是double类型的常量
浮点数据的输出控制
#include<iostream> #include<Windows.h>
using namespace std;
int main(void){ double value = 12.3456789;
// 默认精度是6,所以输出为 12.3457 //(默认情况下,精度是指总的有效数字) cout << value << endl;
// 把精度修改为4, 输出12.35, 对最后一位四舍五入 // 精度修改后,持续有效,直到精度再次被修改 cout.precision(4); cout << value << endl;
// 使用定点法, 精度变成小数点后面的位数 // 输出12.3457 cout.flags(cout.fixed); cout << value << endl;
// 定点法持续有效 // 输出3.1416 cout << 3.1415926535 << endl;
// 把精度恢复成有效数字位数 cout.unsetf(cout.fixed); cout << value << endl; //输出12.35 cout << 3.1415926535 << endl; //输出3.142
system("pause"); return 0; } |
向计算机输入数据
当缓冲区为空时,程序才会暂停,让用户输入数据。
输入回车后,数据全部送到输入缓冲区。
#include<iostream> #include<Windows.h> int main(void){ char girlType; int salary; float height;
std::cout << "请输入您的理想类型:\n A:贤惠型 \n B:泼辣新 \n C: 文艺型 \n D:运动型" << std::endl; std::cin >> girlType;
std::cout << "请输入您的月收入:" << std::endl; std::cin >> salary;
std::cout << "请输入您的身高:[单位-米]" << std::endl; std::cin >> height;
std::cout << "您的理想类型是: " << girlType << std::endl; std::cout << "您的月收入是: " << salary << "元" << std::endl; std::cout << "您的身高是: " << height << "米" << std::endl;
system("pause"); return 0; } |
小结:
对于char, int, float等基本数据类型, 直接使用std::cin >> 输入即可.
特别注意:
输出使用 std::cout <<
输入使用 std::cin >>
记忆诀窍:
输入, 需要一个很”尖”的 >> 才能实现插入.
3.7两种不同的的常量
字面常量
int类型字面常量:1, 2, 3, 100
long 类型字面常量:200L (或200l, 建议用大写字母L)
注意:使用vs编译时,默认都是win32平台,
所以即使在64位系统中,long也只有4个字节
long long 类型字面常量:100000000000LL(一千亿,建议用大写字母LL)
char类型字面常量:’a’, ‘b’, ‘X’, ‘-’
float类型字面常量:3.14f
double类型字面常量: 3.0 3.14
16进制常量:
123 = 1x100 + 2x10 + 3x1
0x11 (相当于17)
以0x作为前缀
说明:16进制
10进制 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16进制 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
8进制常量
以0作为前缀
011(相当于9)
说明:16进制和8进制,只是给程序员使用起来更方便,
在计算机中,数据都存储为2进制。
字面常量的缺点:
程序的可读性变差。
代码的可维护性差。
符号常量
1)#define宏定义的符号常量
#define MAX_AGE 35
在编译的预处理阶段,直接把MAX_AGE替换为35
2)const修饰的符号常量
const int maxAge = 35;
maxAge = 30; //错误!编译失败
注意:const修饰的符号常量,又叫“只读变量”。
本质上,是一个变量,只是被const限制。
常见错误总结
- 变量名错误
变量名不能使用关键字
int char; //编译失败
变量名不能和函数名同名
int system; //会导致后面不能使用system函数
- 变量还没有定义,就直接使用
age = 20;
变量一定要先定义,再使用。
- 变量的输入与使用顺序不当
//以下为错误代码
#include<iostream> #include<Windows.h>
using namespace std;
int main(void){ int age; int num;
num = age * 360;
cout << "请输入您的年龄: "; cin >> age;
cout << "这是您在地球的" << num <<"天" << endl;
system("pause"); return 0; } |
num = age * 360;
计算完字符,num和age没有任何关系!
而不是数学中的理解: num永远是age的360倍【不适用于C、C++】
- 数据输入时,数据的类型不匹配
#include<iostream> #include<Windows.h>
using namespace std;
int main(void){ int age; int num;
cout << "请输入您的年龄: "; cin >> age;
num = age * 360; cout << "这是您在地球的" << num <<"天" << endl;
system("pause"); return 0; } |
输入的是字母l和0
类型不匹配,此时输入失败,变量的值还是原来的值
说明:
变量如果不做初始化,它的值是不确定的。
良好的编程习惯:变量在定义时,进行初始化:
int age = 0;
- 输入数据时,前面的数据输入错误,导致后面的数据都不能输入
#include <iostream> #include <Windows.h> #include <string>
int main(void) { int a; int b; int c;
std::cin >> a >> b >> c;
std::cout << "a=" << a << std::endl; std::cout << "b=" << b << std::endl; std::cout << "c=" << c << std::endl;
system("pause"); return 0; } |
解决方案:
#include <iostream> #include <Windows.h> #include <string>
using namespace std;
int main(void) { int a; int b; int c;
//std::cin >> a >> b >> c; std::cout << "请输入a: "; std::cin >> a; if (cin.fail()) { //检查输入时是否发生了错误 cout << "输入错误,应该输入一个整数" << endl; //清除错误标记,使得后续输入可以正常进行 //但是已经输入的数据还在输入缓冲区 cin.clear(); cin.sync(); //清空输入缓冲区 }
std::cout << "请输入b: "; std::cin >> b; if (cin.fail()) { cout << "输入错误,应该输入一个整数" << endl; cin.clear(); //清除错误标记,使得后续输入可以正常进行 cin.sync(); //清空输入缓冲区 }
std::cout << "请输入c: "; std::cin >> c; if (cin.fail()) { cout << "输入错误,应该输入一个整数" << endl; cin.clear(); //清除错误标记,使得后续输入可以正常进行 }
std::cout << "a=" << a << std::endl; std::cout << "b=" << b << std::endl; std::cout << "c=" << c << std::endl;
system("pause"); return 0; } |
if语句的具体用法在后面会详细讲解。
计算机英语加油站
单词/关键字 |
说明 |
char |
character 字符 |
int |
integer 整数 |
short |
短的 |
long |
长的 |
unsinged |
无符号的 |
double |
双倍的 |
float |
浮动, 浮点数 |
name |
名称,名字 |
password |
密码 常简写为pwd |
precision |
精度 应用: cout.precision(4) |
flags |
flag的复数 flag:标记 应用:cout.flags(xxx); |
fixed |
固定的 应用:cout.flags(cout.fixed); |
unset |
复原 应用:cout.unsetf(cout.fixed); |
const |
常量 constant 不变的 |
The variable 'age' is being used without being initialized. 变量’age’没有被初始化就使用了 解析: The variable 'age' is being used without being initialized. [变量] [使用] [没有] [初始化] |