C++ 基础核心知识

news2026/3/21 7:09:24
C 基础核心知识C作为一门兼具高效性和灵活性的编程语言是系统开发、游戏引擎、嵌入式编程等领域的核心工具。本文将从变量类型、指针与引用、核心关键字、数据类型、宏 与高级修饰符、函数指针等高频基础知识点入手夯实编程基础。一、变量的三类核心形态局部、静态局部、全局变量是程序存储数据的基本单元根据作用域、生命周期和存储位置的差异可分为局部变量、静态局部变量和全局变量 三类其特性和使用场景各有侧重是理解C内存管理的基础。1. 核心特性对比2. 实用场景解析局部变量最常用的变量类型适合存储临时数据比如循环计数器、函数内部的中间计算结果。例如遍历数组时的索引变量int i函数内临时存储计算值的int temp用完自动释放栈内存使用安全且无冗余开销。静态局部变量适合需要“记忆状态”的场景比如统计函数调用次数、递归深度控制、单例模式的懒汉式实现。例如void countCall() { static int count 0; // 仅首次调用初始化后续调用保留值 cout 调用次数 count endl; } // 多次调用依次输出1、2、3...全局变量用于存储整个程序需共享的全局数据比如系统配置信息、全局缓冲区、跨模块的状态标识。但需谨慎使用过多全局变量会导致程序耦合度升高、难以维护和调试使用时可添加清晰注释必要时用static修饰限制在当前文件内避免跨文件命名冲突。二、指针与引用C的核心内存操作符指针和引用是C区别于其他高级语言的核心特性二者均用于间接操作变量实现内存的灵活访问但在语法、本质、功能和使用场景上差异显著正确区分是避免内存错误的关键。1. 核心区别总结2. 适用场景指针的适用场景动态内存分配new/delete例如创建动态数组int* arr new int[10]、自定义类的动态对象遍历复杂数据结构链表、树、图通过指针移动访问下一个节点node-next实现灵活的内存遍历处理可选参数允许传递nullptr表示“无参数”适配多场景函数调用多级间接访问如指针的指针int** p适用于二维数组、函数内修改外部指针函数返回多个值通过指针将结果输出到函数外部。引用的适用场景函数参数传递尤其是大型对象如自定义类实例、std::string、std::vector避免拷贝开销提升程序效率。例如void printString(const string s)直接引用原对象而非创建拷贝函数返回值优化实现链式调用如cout a boperator返回ostream避免返回值拷贝类成员引用必须在构造函数初始化列表中绑定确保引用的生命周期与类对象一致适用于类的关联属性替代指针简化代码在无需重新绑定的场景下用引用替代指针让代码更简洁、安全。3. 核心注意事项指针使用前必须判空if (p ! nullptr)避免野指针未初始化、悬空指针指向已释放内存导致程序崩溃引用不能绑定临时变量如int a 10;非法除非是const引用const int a 10;合法编译器会创建临时对象动态内存分配的指针需手动释放delete/delete[]否则会造成内存泄漏建议优先使用智能指针std::unique_ptr/std::shared_ptr替代裸指针。三、核心关键字C的关键字是控制程序语法规则、内存行为、访问权限的核心其中const、static是最常用且易混淆的基础关键字掌握其不同场景的语义是编写规范、高效C代码的前提。1. const常量修饰符保证只读特性const的核心语义是只读可修饰变量、指针、引用、成员函数、函数参数等是保证程序安全性、防止意外修改的重要工具其修饰对象不同语义也略有差异。饰普通变量const int max 100变量值初始化后不可修改必须在定义时初始化修饰指针分为两种场景核心看const与*的位置指针常量int* const pconst修饰指针本身指针的指向不可修改但指向的值可修改指向常量的指针const int* pconst修饰指向的值值不可修改但指针的指向可修改修饰引用const int ref引用的对象为只读防止通过引用修改原对象是函数参数传递的常用方式修饰类成员函数void show() const函数后加const表示该函数不修改类的任何非静态成员变量是类的常成员函数修饰函数参数void func(const int x)防止函数内部修改传入的参数值同时避免拷贝开销。2. static静态修饰符控制生命周期与作用域static主要用于控制变量/函数的生命周期、作用域和访问权限在不同场景下作用不同核心分为“全局/函数内”和“类内”两大使用场景。静态局部变量函数内延长生命周期至程序结束作用域仍限于当前函数内仅初始化一次静态全局变量/函数文件内将作用域限制在当前文件内实现“文件私有”避免跨文件命名冲突函数默认具有外部链接属性加static后变为内部链接类的静态成员变量属于类而非某个对象所有类实例共享同一份数据需在类外单独初始化int ClassName::var 0存储在数据段类的静态成员函数属于类而非对象无隐式的this指针只能访问类的静态成员变量/函数可通过类名直接调用ClassName::func()无需创建对象。3. new/delete 与 malloc/free内存管理核心对比new/delete是C原生的内存操作运算符malloc/free是C标准库的内存管理函数二者均用于动态内存分配但在语法、功能、特性上差异显著C开发中优先使用new/delete替代malloc/free。4. 其他基础常用关键字对比使用建议C开发中优先使用new/delete替代malloc/free优先使用nullptr替代NULL避免类型二义性和内存管理错误。四、数据类型与强制类型转换是强类型语言数据类型决定了变量的内存大小、取值范围和可执行操作强制类型转换用于实现不同类型间的转换C提供了类型安全的转换运算符替代C语言的隐式转换明确转换意图。1. 基本数据类型C的基本数据类型分为整型、浮点型、字符型、布尔型其中整型遵循**“最小长度规则”**具体长度可通过sizeof运算符查询不同平台可能略有差异核心类型如下整型short至少16位/2字节、int至少与short等长通常32位/4字节、long至少32位/4字节、long long至少64位/8字节无符号整型在整型前加unsigned如unsigned int、unsigned long不存储负数最大值为对应有符号整型的2倍适合存储计数类、索引类数据浮点型float单精度4字节、double双精度8字节、long double扩展精度≥8字节用于存储小数双精度是开发中的默认选择字符型char1字节、wchar_t宽字符2/4字节用于存储单个字符char可分为有符号默认和无符号unsigned char布尔型bool取值为true1或false0用于逻辑判断。注意可通过climits、cfloat头文件查看不同数据类型的取值范围如INT_MAXint的最大值、FLT_MAXfloat的最大值。2. 强制类型转换C提供4种类型安全的强制转换运算符替代C语言的(类型)变量隐式转换明确转换意图减少转换错误不同运算符适用于不同场景不可混用示例// static_cast基本类型转换 int a 10; double b static_castdouble(a) / 3; // 3.33333 // dynamic_cast类层次转换 class Base { virtual void func() {} }; class Derived : public Base {}; Base* p new Derived; Derived* d dynamic_castDerived*(p); // 转换成功 // const_cast移除const属性 const int c 20; int* pc const_castint*(c); // *pc 30; // 非法修改原常量行为未定义 // reinterpret_cast指针类型强制转换 int x 100; int* px x; char* pc reinterpret_castchar*(px);五、宏与高级修饰符易混淆核心概念辨析在C开发中#define宏、inline、constexpr、volatile、extern是高频易混淆的语法元素其中#define是C语言兼容的预处理语法其余均为C的高级修饰符掌握其差异是编写高效、安全代码的关键。1. #define 与 inline宏替换 vs 内联函数二者均试图减少函数调用开销但实现原理、阶段和安全性天差地别inline是C推荐的函数优化手段优先用inline替代#define定义宏函数。2. #define 与 const宏常量 vs 常量变量二者均用于定义“不可变值”但const是C强类型的常量修饰符#define是无类型的预处理替换生产环境优先使用const替代#define定义常量。3. constexpr 与 const编译期常量 vs 运行期只读变量C11引入constexpr强化了“编译期常量”的语义弥补了const“只读但未必是编译期常量”的缺陷constexpr是更强的const。4. volatile 易变变量修饰符禁止编译器优化volatile是C中容易被忽略但至关重要的修饰符核心语义是**“告诉编译器该变量的值可能被程序外部因素修改禁止对其进行任何优化”**确保每次访问都直接读取内存而非缓存到寄存器。核心特性禁止编译器优化编译器不会将volatile变量的值缓存到寄存器每次读写都直接访问内存避免优化导致的错误不保证原子性volatile仅保证内存可见性不保证多线程下的操作原子性如volatile int a仍可能出现竞态条件需配合互斥锁/原子操作可与const结合const volatile int a; 表示“变量值不可被本程序修改但可能被外部修改且每次访问都读内存”适用于硬件寄存器操作无传递性volatile int* pp是普通指针*p是volatile值修改p的指向不受限制。适用场景嵌入式开发硬件寄存器操作寄存器地址固定值可能被硬件/外设修改中断处理程序中断服务函数中修改的变量需防止编译器优化多线程开发多线程共享的变量保证内存可见性需配合内存屏障信号处理函数信号处理中修改的全局变量避免编译器优化为死循环。示例// 嵌入式串口接收寄存器操作寄存器地址固定值由硬件修改 #define UART_RX_REG 0x12345678 // 串口接收寄存器物理地址 volatile int* rx_reg (volatile int*)UART_RX_REG; void read_uart_data() { while (*rx_reg 0); // 循环等待寄存器值变化禁止编译器优化为死循环 int data *rx_reg; // 直接读取内存中的寄存器值获取硬件数据 }5. extern 与 static作用域与链接属性控制反向关键字二者均用于控制变量/函数的链接属性和跨文件访问性是C模块化开发的核心修饰符作用完全相反extern实现跨文件共享static实现文件/作用域私有。关键注意全局变量/函数默认具有extern属性若想限制为文件私有需显式加staticextern仅作声明除非初始化不分配内存避免重复定义。六、函数指针与指针函数1. 函数指针指向函数的指针变量核心概念函数在内存中拥有唯一的入口地址函数指针是一种特殊的指针变量其值为函数的内存入口地址通过函数指针可以间接调用函数实现“函数的参数化传递”是回调函数、策略模式的核心基础。函数指针的类型由函数的返回值和参数列表决定与函数名无关函数名本身就是函数的入口地址如func等价于func。定义语法函数指针的定义需严格匹配目标函数的返回值类型和参数列表类型个数顺序括号不可省略优先级问题有两种定义方式直接定义返回值类型 (*函数指针名)(参数类型1, 参数类型2, ...);示例int (*pFunc)(int, int);// 指向“接收两个int、返回int”的函数类型别名定义推荐简化复杂类型typedef int (*FuncType)(int, int); // typedef方式 using FuncType int (*)(int, int); // C11 using方式更直观 FuncType pFunc; // 定义函数指针变量使用步骤与示例步骤定义匹配的函数 → 将函数地址赋值给函数指针 → 通过函数指针间接调用函数*可省略。#include iostream using namespace std; // 1. 定义匹配的函数 int add(int a, int b) { return a b; } int sub(int a, int b) { return a - b; } int main() { // 2. 定义函数指针并赋值可省略 int (*pFunc)(int, int) add; // 3. 间接调用函数两种方式等价*可省略 cout (*pFunc)(2, 3) endl; // 标准写法输出5 cout pFunc(5, 2) endl; // 简化写法输出3 // 重新指向其他匹配函数 pFunc sub; cout pFunc(5, 2) endl; // 输出3 return 0; }核心使用场景回调函数操作完成后自动调用预先注册的函数如C语言qsort的比较函数、异步操作的完成回调、框架钩子函数策略模式将不同业务逻辑封装为函数通过函数指针动态选择执行策略替代大量if-else/switch提升代码灵活性类的成员函数指针类的非静态成员函数含隐式this指针需指定类名定义int (Math::*pMemFunc)(int, int) Math::add;不可省略函数表/插件架构通过函数指针数组存储多个同类型函数实现动态函数调用适用于插件、驱动开发。回调函数示例#include iostream #include cstdlib // qsort头文件 using namespace std; // 回调函数1int升序比较 int compare_asc(const void* a, const void* b) { return *(const int*)a - *(const int*)b; } // 回调函数2int降序比较 int compare_desc(const void* a, const void* b) { return *(const int*)b - *(const int*)a; } int main() { int arr[] {3,1,4,2}; int n sizeof(arr)/sizeof(arr[0]); // qsort第四个参数是函数指针动态传递比较策略 qsort(arr, n, sizeof(int), compare_asc); // 升序排序 for(int x : arr) cout x ; // 1 2 3 4 qsort(arr, n, sizeof(int), compare_desc); // 降序排序 for(int x : arr) cout x ; // 4 3 2 1 return 0; }2. 指针函数返回指针类型的函数核心概念指针函数是一种普通函数其核心特征是返回值为指针类型语法上无特殊修饰仅需将返回值类型声明为指针即可是动态内存分配、返回数组/对象地址的常用方式定义语法返回值类型* 函数名(参数类型1, 参数类型2, ...);示例int* createArr(int n);// 返回int类型指针的函数接收一个int参数使用示例#include iostream using namespace std; // 指针函数动态创建int数组返回数组指针 int* createArr(int n) { if (n 0) return nullptr; int* arr new int[n]; // 动态分配堆内存 for(int i0; in; i) { arr[i] i * 2; // 初始化数组 } return arr; // 返回堆内存指针 } int main() { int* p createArr(5); if (p ! nullptr) { for(int i0; i5; i) { cout p[i] ; // 0 2 4 6 8 } delete[] p; // 手动释放堆内存避免泄漏 p nullptr; } return 0; }核心注意事项指针函数不能返回栈内存指针如int* func() { int a; return a; }栈内存随函数调用结束销毁返回后会成为悬空指针若返回堆内存指针调用者需手动释放内存delete/delete[]避免内存泄漏指针函数的返回值可做链式访问如node* getNext(node* p) { return p-next; }可连续调用getNext(getNext(p))。3. 函数指针与指针函数核心对比记忆技巧看括号和*的结合关系——(*名)是函数指针名是指针类型* 名()是指针函数名是函数。七、结构体与类C面向对象的基础载体struct和class是C实现面向对象编程的核心载体二者功能几乎完全一致仅默认访问权限和默认继承方式不同适用于不同的编程场景。1. 核心区别2. 实用示例#include iostream #include string using namespace std; // struct纯数据结构默认public仅存储数据 struct Student { string name; // 公有成员可直接访问 int age; float score; }; // class封装数据与操作默认private通过公有接口访问 class Calculator { private: // 默认private外部不可访问 int result; // 私有属性仅类内可修改 public: // 构造函数初始化属性 Calculator() : result(0) {} // 公有方法提供外部访问接口 void add(int num) { result num; } void sub(int num) { result - num; } int getResult() const { return result; } // const成员函数不修改属性 }; int main() { // struct使用直接访问成员 Student s {张三, 18, 95.5}; cout 姓名 s.name 年龄 s.age endl; // class使用通过公有接口访问 Calculator cal; cal.add(10); cal.sub(3); cout 计算结果 cal.getResult() endl; // 7 return 0; }注意struct在C中并非单纯的C语言结构体也支持成员函数、构造函数、继承、多态等面向对象特性仅默认规则与class不同开发中可根据设计意图选择无需严格区分。八、总结C基础知识点核心围绕内存管理、类型安全、作用域控制、代码解耦四大核心思想展开核心要点可归纳为变量管理掌握局部、静态局部、全局变量的生命周期和存储位置理解栈区、数据段的内存特性避免内存越界内存操作区分指针与引用的本质差异合理使用指针实现动态内存管理优先用引用简化代码、提升安全性杜绝裸指针的内存泄漏关键字使用掌握const只读、static作用域/生命周期的多场景语义掌握new/delete与malloc/free的核心差异优先用constexpr编译期常量、inline内联函数替代#define提升代码类型安全类型转换放弃C语言的隐式转换使用C的4种类型安全转换运算符根据场景选择static_cast/dynamic_cast/const_cast/reinterpret_cast特殊修饰符volatile保证内存可见性硬件/多线程extern/static控制跨文件访问性实现模块化开发函数指针掌握函数指针的定义和使用理解其在回调函数、策略模式中的核心作用区分函数指针与指针函数的语法差异面向对象基础理解struct与class的核心区别掌握封装的基本思想通过类的公有接口访问私有成员保证代码的可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2432615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…