欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > C++学习:六个月从基础到就业——C++基础语法回顾:数据类型、变量与常量

C++学习:六个月从基础到就业——C++基础语法回顾:数据类型、变量与常量

2025/3/24 22:19:08 来源:https://blog.csdn.net/qq_53773901/article/details/146445974  浏览:    关键词:C++学习:六个月从基础到就业——C++基础语法回顾:数据类型、变量与常量

C++学习:六个月从基础到就业——C++基础语法回顾:数据类型、变量与常量

本文是"C++学习:六个月从基础到就业"系列的第一篇技术文章,主要回顾C++的基本数据类型、变量定义和常量使用,为后续深入学习打下基础。查看完整系列目录了解更多内容。

引言

编程的本质是对数据的处理,而数据类型、变量与常量是任何编程语言的基础构建块。在C++中,对这些基础概念的深入理解不仅能让我们编写出正确的代码,还能帮助我们编写更高效、更安全的程序。本文将详细介绍C++中的数据类型、变量声明与常量定义,并探讨一些常见的陷阱和最佳实践。

基本数据类型

C++提供了丰富的内置数据类型,可以分为以下几类:

整型

整型用于表示整数值,根据大小和符号不同分为多种类型:

类型关键字典型大小值范围
字符型char1字节-128到127或0到255
整型int4字节 − 2 31 -2^{31} 231 2 31 − 1 2^{31-1} 2311
短整型short2字节-32,768到32,767
长整型long至少4字节至少 − 2 31 -2^{31} 231 2 31 − 1 2^{31-1} 2311
长长整型long long8字节 − 2 63 -2^{63} 263 2 63 − 1 2^{63-1} 2631

每种整型都有对应的无符号版本,使用unsigned关键字修饰:

unsigned int a = 42;  // 只能存储非负数
unsigned char b = 255; // 范围是0-255

注意:整型的具体大小依赖于编译器和平台,表中给出的是最常见的大小。C++标准只规定了最小范围。

浮点型

浮点型用于表示实数:

类型关键字典型大小精度
单精度浮点float4字节约7位十进制数字
双精度浮点double8字节约15位十进制数字
扩展精度浮点long double至少8字节,通常16字节取决于实现

浮点数的例子:

float pi_approx = 3.14f;  // f后缀表示float类型
double precise_pi = 3.1415926535;
long double very_precise_pi = 3.1415926535897932384L;  // L后缀表示long double

布尔型

布尔型用于表示真值或假值:

bool is_valid = true;
bool has_error = false;

字符型

字符型用于表示单个字符:

char ch = 'A';  // 单引号表示字符字面量
wchar_t wide_ch = L'你';  // 宽字符,用于表示Unicode字符
char16_t utf16_ch = u'你';  // UTF-16编码字符
char32_t utf32_ch = U'你';  // UTF-32编码字符

空类型

void类型表示没有值:

void function() {// 不返回任何值的函数
}

变量声明与初始化

变量是命名的内存位置,用于存储数据。在C++中,有多种方式可以声明和初始化变量。

变量声明

基本的变量声明语法为:

type variable_name;  // 声明但不初始化
type variable_name = initial_value;  // 声明并初始化
type variable_name(initial_value);  // 构造函数风格的初始化
type variable_name{initial_value};  // 统一初始化(C++11)

例如:

int count;  // 声明一个整型变量,未初始化(包含垃圾值)
int count = 0;  // 声明并初始化为0
int count(0);  // 等同于上一行
int count{0};  // C++11统一初始化语法

统一初始化(C++11)

C++11引入的花括号初始化(统一初始化)是推荐的初始化方式,它有以下优点:

  1. 防止窄化转换(narrowing conversion):
int a = 3.14;  // 允许,但会截断为3
// int b{3.14};  // 错误:不允许窄化转换
int b{3};  // 正确
  1. 可以初始化数组和容器:
int array[] = {1, 2, 3, 4, 5};
std::vector<int> vec{1, 2, 3, 4, 5};

变量命名规则

变量名必须遵循以下规则:

  • 只能包含字母、数字和下划线
  • 必须以字母或下划线开头
  • 区分大小写
  • 不能使用C++关键字

常见的命名约定:

  • 驼峰命名:firstName, lastName
  • 下划线分隔:first_name, last_name
  • 成员变量常使用前缀或后缀:m_count, count_

常量

常量是程序执行期间值不会改变的变量。C++提供了多种定义常量的方式。

const关键字

const关键字用于定义编译时常量或运行时常量:

const int MAX_STUDENTS = 30;  // 编译时常量
const int array_size = get_size();  // 运行时常量,依赖于函数返回值

const也可以用于指针:

const int* p;  // 指向常量的指针(不能通过p修改所指对象)
int* const p;  // 常量指针(p不能指向其他对象)
const int* const p;  // 指向常量的常量指针(两者都不能改变)

constexpr关键字(C++11)

constexpr用于定义编译时常量,并且编译器会在编译时计算其值:

constexpr int square(int x) {return x * x;
}constexpr int result = square(5);  // 编译时计算为25

constexpr的优势在于它强制编译时求值,可以用在数组大小、模板参数等需要编译时常量的场合。

枚举常量

枚举是一种用户定义的类型,可以用来定义一组相关的常量:

// 传统枚举
enum Color {RED,    // 默认值为0GREEN,  // 1BLUE    // 2
};// C++11引入的限定作用域枚举
enum class Fruit : int {  // 可以指定底层类型APPLE,ORANGE,BANANA
};Color c = RED;  // 正确
// int i = RED;   // 正确,传统枚举可以隐式转换为整数
Fruit f = Fruit::APPLE;  // 正确,必须使用作用域运算符
// int j = Fruit::APPLE;  // 错误,限定作用域枚举不允许隐式转换

宏常量

虽然C++中仍然支持使用宏定义常量,但这是一种不推荐的方式:

#define PI 3.14159  // 不推荐

与const和constexpr相比,宏常量有以下缺点:

  • 没有类型检查
  • 容易导致意外的文本替换错误
  • 难以调试
  • 不遵守作用域规则

类型转换

C++中的类型转换分为隐式转换和显式转换。

隐式转换

当运算符作用于不同类型的操作数时,会进行隐式类型转换:

int i = 42;
double d = i;  // 隐式将int转换为double
i = d;  // 警告:隐式将double转换为int(可能丢失精度)

显式转换

C++提供了多种显式类型转换方式:

// C风格转换(不推荐)
int i = (int)3.14;// C++风格转换
int j = static_cast<int>(3.14);  // 用于"合理"的转换
const int k = 42;
int* p = const_cast<int*>(&k);   // 移除const限定(危险!)

C++风格的类型转换运算符包括:

  • static_cast: 用于相关类型之间的转换
  • const_cast: 添加或移除const限定
  • reinterpret_cast: 在不相关类型之间进行转换(危险!)
  • dynamic_cast: 用于多态类的安全向下转型

类型推导(C++11)

C++11引入了auto和decltype关键字来实现类型推导。

auto关键字

auto关键字让编译器根据初始化表达式推导变量类型:

auto i = 42;  // i是int类型
auto d = 3.14;  // d是double类型
auto s = "hello";  // s是const char*类型
auto v = {1, 2, 3};  // v是std::initializer_list<int>类型

auto特别适用于复杂类型,如迭代器:

std::vector<int> vec = {1, 2, 3};
for (auto it = vec.begin(); it != vec.end(); ++it) {// 使用auto代替std::vector<int>::iterator
}

decltype关键字

decltype用于获取表达式的类型:

int i = 42;
decltype(i) j = i * 2;  // j的类型与i相同,即intconst int& r = i;
decltype(r) s = j;  // s的类型是const int&

实践与建议

  1. 总是初始化变量:未初始化的变量包含垃圾值,可能导致未定义行为。

  2. 优先使用统一初始化语法int i{42};而不是int i = 42;,以避免窄化转换。

  3. 使用sizeof运算符检查类型大小

std::cout << "Size of int: " << sizeof(int) << " bytes" << std::endl;
  1. 谨慎使用隐式转换:尤其是可能导致精度丢失的转换。

  2. 优先使用const:如果变量不需要修改,将其声明为const。

  3. 使用constexpr进行编译时计算:可以提高性能并捕获错误。

  4. 避免使用宏:优先使用const、constexpr或枚举。

  5. 使用限定作用域枚举enum class而不是传统的enum

  6. 了解变量的生命周期:自动变量、静态变量和动态分配的变量有不同的生命周期。

  7. 使用有意义的变量名:变量名应该清晰表达其用途。

代码示例:数据类型与变量综合运用

下面是一个综合例子,展示了C++中数据类型、变量和常量的用法:

#include <iostream>
#include <vector>
#include <string>// 使用constexpr进行编译时计算
constexpr int factorial(int n) {return n <= 1 ? 1 : n * factorial(n - 1);
}// 使用限定作用域枚举
enum class Season {SPRING,SUMMER,AUTUMN,WINTER
};int main() {// 整数类型int a{10};unsigned int b{20};long long c{1000000000LL}; // LL后缀表示long long字面量// 浮点类型float d{3.14f};double e{2.71828};// 字符和布尔类型char f{'A'};bool g{true};// 常量const double PI{3.14159265359};constexpr int FACTORIAL_5{factorial(5)}; // 编译时计算5!// 使用auto进行类型推导auto h = a + b; // h是unsigned intauto i = d * e; // i是double// 统一初始化的容器std::vector<int> vec{1, 2, 3, 4, 5};// 使用限定作用域枚举Season current_season{Season::SUMMER};// 输出结果std::cout << "a = " << a << ", size: " << sizeof(a) << " bytes" << std::endl;std::cout << "b = " << b << ", size: " << sizeof(b) << " bytes" << std::endl;std::cout << "c = " << c << ", size: " << sizeof(c) << " bytes" << std::endl;std::cout << "d = " << d << ", size: " << sizeof(d) << " bytes" << std::endl;std::cout << "e = " << e << ", size: " << sizeof(e) << " bytes" << std::endl;std::cout << "f = " << f << ", size: " << sizeof(f) << " bytes" << std::endl;std::cout << "g = " << std::boolalpha << g << ", size: " << sizeof(g) << " bytes" << std::endl;std::cout << "PI = " << PI << std::endl;std::cout << "5! = " << FACTORIAL_5 << std::endl;// 安全类型转换int j = static_cast<int>(e); // 从double转为intstd::cout << "e as int = " << j << std::endl;return 0;
}

总结

本文回顾了C++的基本数据类型、变量声明与初始化,以及常量定义。正确理解和使用这些基础概念,是编写高质量C++代码的第一步。在后续的文章中,我们将继续探索C++的其他基础特性,包括运算符、控制流结构和函数等。

希望这篇文章对你有所帮助。如果有任何问题或建议,欢迎在评论区留言讨论!

参考资料

  1. Bjarne Stroustrup. The C++ Programming Language (4th Edition)
  2. Scott Meyers. Effective Modern C++
  3. cppreference.com - 基本类型
  4. C++ Core Guidelines

这是我C++学习之旅系列的第一篇技术文章。查看完整系列目录了解更多内容。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词