初学 C++ 必须掌握的核心重点

1. 变量与数据类型:强类型语言的基础

C++ 是强类型语言,变量在使用前必须声明类型,且类型转换需要显式处理(除非是隐式安全转换)。

#include <iostream> using namespace std; int main() { // 1. 基础数据类型声明 int age = 20; // 整型,4字节(多数系统) double height = 175.5; // 浮点型,8字节 char gender = 'M'; // 字符型,1字节 bool isStudent = true; // 布尔型,1字节 // 2. 易错点:类型不匹配的隐式转换(可能丢失精度) int num1 = 10; double num2 = 3.14; int result = num1 + num2; // 隐式转换:double→int,结果为13(丢失小数部分) cout << "隐式转换结果:" << result << endl; // 正确做法:显式转换 double correctResult = (double)num1 + num2; // 显式转换int→double,结果为13.14 cout << "显式转换结果:" << correctResult << endl; return 0; } 

关键说明

  • 声明变量时必须指定类型,如int a;而非a;
  • 浮点型(float/double)转整型会直接截断小数,而非四舍五入;
  • 优先使用double而非float,精度更高且计算更稳定。
2. 指针与引用:C++ 的核心特性(新手最易懵)

指针是存储变量内存地址的变量,引用是变量的 “别名”,二者语法和用途差异极大,是初学重点也是难点。

cpp

运行

#include <iostream> using namespace std; int main() { int a = 10; // 1. 指针:用*定义,&取地址,*解引用 int* p = &a; // p存储a的地址 cout << "a的地址:" << &a << endl; cout << "指针p的值(a的地址):" << p << endl; cout << "指针解引用(a的值):" << *p << endl; *p = 20; // 修改指针指向的变量值 cout << "修改后a的值:" << a << endl; // 2. 引用:用&定义,必须初始化,不能更改指向 int& ref = a; // ref是a的别名 ref = 30; // 修改引用等价于修改a cout << "修改引用后a的值:" << a << endl; // 错误示例:引用不能空初始化,也不能重新指向 // int& ref2; // 编译报错:引用必须初始化 // int b = 50; // ref = b; // 不是更改指向,而是把b的值赋给a return 0; } 

关键说明

  • 指针声明:类型* 变量名(如int* p),引用声明:类型& 变量名(如int& ref);
  • 指针可以为空(int* p = nullptr;),引用必须绑定有效变量;
  • 指针可以重新指向其他变量,引用一旦绑定则终身指向该变量。
3. 函数重载:C++ 与 C 的核心区别之一

函数重载允许定义同名函数,只要参数列表(个数 / 类型 / 顺序)不同,返回值不同不构成重载。

cpp

运行

#include <iostream> using namespace std; // 函数重载:同名,参数类型不同 int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; } // 函数重载:同名,参数个数不同 int add(int a, int b, int c) { return a + b + c; } // 错误示例:仅返回值不同,不构成重载(编译报错) // double add(int a, int b) { // return (double)a + b; // } int main() { cout << "int加法:" << add(10, 20) << endl; // 调用int版本 cout << "double加法:" << add(3.14, 2.86) << endl; // 调用double版本 cout << "三数加法:" << add(1,2,3) << endl; // 调用三参数版本 return 0; } 

关键说明

  • 函数重载的核心是 “参数列表不同”,返回值不参与重载判断;
  • 重载函数的调用由编译器根据实参类型 / 个数自动匹配;
  • C 语言不支持函数重载,C++ 通过 “名字修饰” 实现重载。

二、易混淆相似知识点的区分

1. = 赋值 vs == 相等判断

新手最易把赋值运算符=当成相等判断==,导致逻辑错误。

cpp

运行

#include <iostream> using namespace std; int main() { int a = 5; // 错误示例:if条件中用=(赋值)而非==(判断) if (a = 10) { // 实际是把a赋值为10,非0值为true,条件永远成立 cout << "错误:条件中用了赋值运算符,a=" << a << endl; } // 正确示例:用==判断相等 if (a == 10) { // 此时a已经被赋值为10,条件成立 cout << "正确:条件中用了相等判断,a=" << a << endl; } return 0; } 

区分要点

  • =:赋值运算符,作用是把右侧值赋给左侧变量,有返回值(赋值后变量的值);
  • ==:关系运算符,作用是判断左右两侧是否相等,返回布尔值(true/false);
  • 避坑技巧:把常量写在左边,如if (10 == a),若误写为if (10 = a)会直接编译报错。
2. const 常量 vs #define 宏定义

二者都能定义 “常量”,但const是编译期类型安全的,#define是预处理阶段的文本替换,无类型检查。

cpp

运行

#include <iostream> using namespace std; // 宏定义:预处理阶段替换,无类型,无作用域 #define PI 3.14 #define MAX(a,b) (a)>(b)?(a):(b) // const常量:编译期处理,有类型,有作用域 const double PI_CONST = 3.1415926; const int MAX_NUM = 100; int main() { // 1. 类型检查差异 // #define无类型:PI可以赋给任意类型变量,无警告 int pi_int = PI; // const有类型:若类型不匹配,编译器会警告 // int pi_const = PI_CONST; // 编译器警告:double转int丢失精度 // 2. 宏替换的坑(文本替换,可能导致非预期结果) int a = 3, b = 2; int res = MAX(a++, b++); // 展开为(a++)>(b++)?(a++):(b++),a和b会被多次自增 cout << "宏定义MAX结果:" << res << ",a=" << a << ",b=" << b << endl; // res=4, a=5, b=3 // 3. const作用域:仅在当前作用域有效,宏全局有效 { const int local_const = 5; cout << "局部const:" << local_const << endl; } // cout << local_const; // 编译报错:未定义的标识符 return 0; } 

区分要点

  • const:有数据类型,编译器会做类型检查,作用域受 {} 限制,占用内存;
  • #define:无数据类型,预处理阶段直接文本替换,无作用域,不占用内存;
  • 初学建议:优先使用const定义常量,避免宏替换的坑。
3. 结构体(struct)vs 类(class)

C++ 中structclass都能定义自定义类型,核心区别是默认访问权限默认继承方式

cpp

运行

#include <iostream> using namespace std; // struct:默认访问权限public struct Student { string name; // public int age; // public void showInfo() { // public cout << "Struct:姓名=" << name << ",年龄=" << age << endl; } }; // class:默认访问权限private class Teacher { string name; // private int age; // private public: // 必须显式声明public才能外部访问 void setInfo(string n, int a) { name = n; age = a; } void showInfo() { cout << "Class:姓名=" << name << ",年龄=" << age << endl; } }; int main() { // struct:成员可直接访问 Student s; s.name = "小明"; s.age = 18; s.showInfo(); // class:private成员不可直接访问,需通过public方法 Teacher t; // t.name = "李老师"; // 编译报错:private成员不可访问 t.setInfo("李老师", 35); t.showInfo(); return 0; } 

区分要点

  • 访问权限:struct默认publicclass默认private
  • 继承方式:struct默认公有继承,class默认私有继承;
  • 用途习惯:struct多用于单纯的数据聚合,class多用于封装数据和方法的对象。

总结

  1. 核心基础:C++ 是强类型语言,变量声明必须指定类型,指针和引用是核心特性,指针可空可重定向,引用必须初始化且不可改指向;
  2. 易混语法=是赋值、==是判断,const是类型安全的常量、#define是文本替换,函数重载仅看参数列表不看返回值;
  3. 核心区别structclass的核心差异是默认访问权限,前者默认 public,后者默认 private。

这些要点是初学 C++ 的核心,掌握并区分这些知识点,能帮你避开 80% 的新手错误,为后续学习类、继承、多态等进阶内容打下坚实基础。

Read more

【Docker进阶篇】告别OOM Kill!Java容器化内存与CPU限制实战指南

【Docker进阶篇】告别OOM Kill!Java容器化内存与CPU限制实战指南

🍃 予枫:个人主页 📚 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》 💻 Debug 这个世界,Return 更好的自己! 引言 做Java容器化部署的小伙伴,大概率都踩过这样的坑:明明给容器配置了–memory限制,JVM也设了-Xmx参数,结果应用还是频繁被OOM Kill;要么就是CPU限制设太高,资源浪费严重,设太低又导致应用卡顿。今天就彻底搞懂Java容器化中CPU和内存限制的核心逻辑,避开配置陷阱,让应用稳定运行不翻车! 文章目录 * 引言 * 一、为什么Java容器化,内存和CPU配置容易出问题? * 二、容器内存限制(--memory)配置指南(重点避坑) * 2.1 容器内存的组成的部分 * 2.2 内存配置黄金比例(实战可用) * 实战示例(重点) * 2.3 关键避坑点(必看) * 三、容器CPU限制(--cpus)

By Ne0inhk
Flutter 三方库 openapi_dart_common 的鸿蒙化适配指南 - 实现具备强类型契约的高性能 API 通讯模型、支持端侧 OpenAPI/Swagger 协议的自动化生成与对齐实战

Flutter 三方库 openapi_dart_common 的鸿蒙化适配指南 - 实现具备强类型契约的高性能 API 通讯模型、支持端侧 OpenAPI/Swagger 协议的自动化生成与对齐实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 openapi_dart_common 的鸿蒙化适配指南 - 实现具备强类型契约的高性能 API 通讯模型、支持端侧 OpenAPI/Swagger 协议的自动化生成与对齐实战 前言 在进行 Flutter for OpenHarmony 的企业级前后端分离开发时,如何保证客户端请求代码与后端 API 定义的绝对同步?手动编写 API 模型不仅低效,且极易引发类型不匹配导致的生产 Bug。openapi_dart_common 是 OpenAPI (Swagger) 官方生成器在 Dart 端的基石库。它提供了一套标准的序列化、参数处理及抽象拦截器机制。本文将探讨如何在鸿蒙端构建极致稳健的工程化接口层。 一、原直观解析 / 概念介绍 1.1

By Ne0inhk
Flutter 三方库 mobx_codegen — 自动化驱动的高性能响应式状态管理(适配鸿蒙 HarmonyOS Next ohos)

Flutter 三方库 mobx_codegen — 自动化驱动的高性能响应式状态管理(适配鸿蒙 HarmonyOS Next ohos)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net。 在 Flutter 状态管理的璀璨星空中,MobX 以其“透明的函数式响应式编程”(TFRP)特性脱颖而出。它让开发者能以声明式的方式描述状态,而让框架自动处理状态变更到 UI 刷新的全过程。 在 Flutter for OpenHarmony 开发中,手动编写 MobX 繁琐的连接代码不仅效率低,且容易出错。mobx_codegen 库通过解析注解,自动生成高性能的底层观察逻辑。今天,我们将探索如何利用自动化力量,在鸿蒙平台上构建出极其灵动的响应式应用。 一、为什么需要 mobx_codegen? 1.1 MobX 的魔法核心 MobX 包含三个核心概念:Observables(被观察的状态)、Actions(改变状态的动作)和 Reactions(对新状态的自动响应)

By Ne0inhk

服务器HBA卡与RAID卡:到底有什么区别?

1.本质定义与功能定位 1.1 HBA卡(主机总线适配器) 定义:HBA(Host Bus Adapter)是连接服务器内部I/O通道与外部存储设备的硬件接口卡,主要承担协议转换和物理连接功能。 核心功能: * 提供高速数据传输通道 * 实现协议转换(如SCSI、SAS、SATA、FC等) * 将存储设备透明呈现给操作系统 * 支持直接设备访问,无中间处理层 1.2 RAID卡(磁盘阵列控制器) 定义:RAID(Redundant Array of Independent Disks)卡是专门管理多个硬盘组成磁盘阵列的硬件控制器,具备数据冗余和性能优化功能。 核心功能: * 实现RAID级别配置(RAID 0/1/5/6/10等) * 提供数据冗余保护与容错机制 * 优化磁盘读写性能(条带化、缓存等) * 支持热插拔与故障磁盘替换

By Ne0inhk