从零到一学习C++(基础篇) 作者:羡鱼肘子
温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。
温馨提示2:本篇会尽量避免一些术语,尽量用更加通俗的语言介绍c++的基础,但术语也是很重要的。
基本类型
基本类型就像「容器」
C++的基本类型就像不同大小的盒子,用来装不同种类的数据。主要分为4类:
类型 | 作用 | 例子 |
---|---|---|
整数 | 存整数(没有小数点) | 0, -5, 100 |
浮点数 | 存小数 | 3.14, -0.5, 2.0 |
字符 | 存单个字母/符号 | 'A', 'b', '7', '#' |
布尔 | 存「是」或「否」 | true(是), false(否) |
整型(Integer Types)
整数类型用来存整数,有不同的大小(能存的数字范围不同):
类型 | 大小(通常情况) | 例子范围 |
---|---|---|
int |
4字节 | -2亿到2亿左右 |
short |
2字节 | -32768到32767 |
long |
4或8字节 | 更大的范围 |
long long |
8字节 | 超级大的整数(C++11) |
int age = 25; // 存年龄
short score = 100; // 存分数
long population = 8000000000L; // 存全球人口
浮点型(Floating-Point Types)
浮点数类型:存小数
浮点数用来存带小数点的数,就像科学计算器:
类型 | 大小(通常) | 特点 |
---|---|---|
float |
4字节 | 存小数,但精度不高 |
double |
8字节 | 存小数,精度更高(默认) |
float pi = 3.14f; // 末尾加f表示float
double price = 99.99; // 默认是double
字符型(Character Types)
字符类型:存单个字母
char
类型存一个字符(字母、数字、符号),用单引号包裹:
char grade = 'A'; // 成绩等级
char symbol = '#'; // 符号
小秘密:计算机实际存储的是ASCII码(数字),比如'A'其实是65:
char letter = 65; // 等价于 'A'
布尔型(Boolean Type)
布尔类型:简单的「开关」
bool
只有两个值:true
(真)或false
(假),常用于条件判断:
bool isRaining = true; // 现在下雨吗?
bool hasPassed = false; // 考试通过了吗?
空类型(Void Type)
空类型:void
void
表示「无类型」,暂时记住两种用途:
①函数不返回值时用void
:
void sayHello() { // 这个函数没有返回值
std::cout << "Hello!";
}
② 指针(暂时不用深究,后面会学)
类型这么多,如何去选择呢?
默认整数:用int
(除非数字太大或太小)
默认小数:用double
明确范围:比如小的分数用short
,钱用double等
单个字符:用char
常见错误提醒
#include
using namespace std;
int main()
{
int a = 5;
double b = 3.14;
double c = a + b; // 可以,但反过来可能有问题
cout <<"c is :"<< c << endl;
int d = a - b; // 可能有问题
cout <<"d is :"<< d << endl;
int e =a*b; // 可能有问题
cout <<"e is :"<< e << endl;
return 0;
}
欧克,我们来看看运行结果(自己先算然后和结果对比)
#include
using namespace std;
int main()
{
short a = 32767; // maximum value of a short integer
short b = -32768; // minimum value of a short integer
short c=32768; // out of range value of a short integer
short d=-32769; // out of range value of a short integer
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "d = " << d << endl;
return 0;
}
int x; // 危险!x的值是随机的垃圾值
int y = 0; // 正确做法:给初始值
小练习:看看你的电脑
#include
using namespace std;
int main() {
cout << "int的大小:" << sizeof(int) << "字节" << endl;
cout << "double的大小:" << sizeof(double) << "字节" << endl;
return 0;
}
类型转换
温馨提示:好的程序员像水一样适应类型系统,而不是强行扭曲它。当需要频繁使用强制转换时,可能意味着设计需要改进。
基础概念:类型转换的本质
类型转换就是让数据在不同类型的"容器"之间传递。就像把水从大杯子倒进小杯子,可能溢出也可能刚好合适。
int a = 42;
double b = a; // 把int的水倒进double的杯子(自动转换)
隐式转换(自动转换)
编译器自动完成的类型转换,就像水流自动调整形状
转换方向 | 示例 | 说明 |
---|---|---|
小类型→大类型 | short →int |
安全,不会丢失数据 |
整型→浮点型 | int →double |
可能丢失精度 |
非布尔→布尔 | int →bool (0为false) |
需特别注意,
|
自己试试看:
int num = 10;
double d = num + 3.14; // num自动转为double
bool flag = num; // num非0,flag为true
double pi = 3.1415;
int truncated = pi; // 直接截断小数部分(结果为3)
unsigned int u = -1; // 结果是4294967295(32位系统)
显式转换(强制转换)
程序员主动要求的类型转换,就像用工具强制改变容器形状。
转换类型 | 适用场景 | 安全等级 | 示例 |
---|---|---|---|
static_cast |
基本类型转换、父子类指针 | ★★★★ | double d = 3.14; int i = static_cast |
dynamic_cast |
多态类指针/引用向下转型 | ★★★☆ | Derived* pd = dynamic_cast |
const_cast |
移除const属性 | ★★☆☆ | const int* p; int* np = const_cast |
reinterpret_cast |
低级二进制重新解释 | ★☆☆☆ | int* ip; char* cp = reinterpret_cast |
目前来说:强推static_cast ,其他的以后会介绍
float f = 3.14f;
int n = static_cast(f); // 明确告知编译器意图
类型转换应用的一点小建议
优先使用隐式转换:当转换明显安全时
int i = 42;
long l = i; // 不需要显式转换
慎用强制转换:转换前问问自己:
这个转换真的必要吗?
是否存在更安全的替代方案?
如果失败会怎样?
类型转换性能影响:
转换类型 | 性能开销 |
---|---|
基本类型转换 | 几乎为零 |
dynamic_cast | 较高(RTTI检查) |
reinterpret_cast | 无(编译期完成) |
避免C风格转换:
// 危险的老式写法
int* p = (int*)malloc(sizeof(int));
// 现代C++写法
int* p = static_cast(malloc(sizeof(int)));
类型转换验证工具
#include
#include
using namespace std;
int main()
{
int variable = 10;
// 查看转换后的实际类型
std::cout << typeid(variable).name() << std::endl;
// 使用static_assert编译期检查
static_assert(sizeof(int) == 4, "int不是4字节");
return 0;
}
字面值常量(Literal Constants)
字面值常量(Literal Constant)是指在程序中直接以字面形式出现的常量,它们具有固定的值,在程序运行期间不会改变。
整型字面值(Integer Literals)
十进制:直接写数字,如 42
八进制:以 0
开头,如 052
(对应十进制的42)
十六进制:以 0x
或 0X
开头,如 0x2A
(对应十进制的42)
二进制(C++14起):以 0b
或 0B
开头,如 0b101010
int a = 42; // 十进制
int b = 052; // 八进制(42)
int c = 0x2A; // 十六进制(42)
int d = 0b101010;// 二进制(42)
浮点型字面值(Floating-point Literals)
默认是 double
类型,可用 f
或 F
标记为 float
,l
或 L
标记为 long double
。
写法:
常规写法:3.14
科学计数法:6.02e23
(表示 6.02×10236.02×1023
double pi = 3.14159;
float gravity = 9.8f; // 显式声明为 float
long double big = 1.2e100L; // 长双精度
字符字面值(Character Literals)
用单引号 ''
包裹,如 'A'
。
支持转义字符,如 '\n'
(换行)、'\t'
(制表符)。
char c1 = 'A';
char c2 = '\n'; // 换行符
char c3 = '\x41'; // 十六进制表示(ASCII的'A')
字符串字面值(String Literals)
用双引号 ""
包裹,如 "Hello"
。
字符串末尾隐含空字符 '\0'
(用于标记结束)。
支持转义字符,如 "Hello\nWorld"
。
const char* str = "Hello, C++!";
std::cout << "Line1\nLine2"; // 输出两行
布尔字面值(Boolean Literals)
true
表示真(非零值)。
false
表示假(零值)。
bool isReady = true;
bool isError = false;
指针字面值(Pointer Literal)
空指针:nullptr
(C++11 起,替代 NULL
)
int* ptr = nullptr;
自定义字面值(User-defined Literals,C++11 起)
允许开发者定义后缀来创建自定义类型字面值:
// 定义将 "kg" 后缀转换为千克的自定义字面值
long double operator"" _kg(long double x) {
return x;
}
auto weight = 5.0_kg; // 等价于 5.0L(long double 类型)
下一篇会开始学习c++中的变量