ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

C++基础语法深度拆解:从sizeof到运算符优先级

C++基础语法深度拆解:从sizeof到运算符优先级 简介这份C讲义笔记面向零基础入门者与希望系统梳理语法体系的进阶学习者覆盖从环境搭建到面向对象编程的完整知识链路。内容以Visual Studio为开发工具从创建项目、编写Hello World程序讲起逐步展开注释、变量、常量、关键字、标识符命名规则与整型、浮点型、字符型等数据类型并延伸至指针、数组、结构体、类、运算符重载、模板与异常处理等核心与提高内容帮助读者建立扎实的编程基础。资源包共1个PDF文件约5.07MB排版紧凑、目录清晰便于按章节检索与打印学习。目前已有25926人学习下载适合作为课堂配套讲义或自学复习手册配合代码示例反复练习可快速掌握C语法要点与常见易错细节。1. 从一份 C 讲义笔记说起为什么基础语法值得反复拆很多人学 C 的路径是看视频、抄代码、跑通 Hello World然后直接跳到指针和类。结果一到sizeof、类型转换、运算符优先级就卡壳。这份「C 入门、核心、提高讲义笔记」的价值恰恰在于它把最容易被跳过的地基部分写得很细——从第一个程序的四个步骤到变量、常量、关键字、标识符命名规则再到整型、浮点型、字符型、布尔型的内存占用和取值范围最后落到算术、赋值、比较、逻辑四类运算符。它适合两类人一是刚配好 VS Code 或 Visual Studio、准备系统过一遍 C 基础的初学者二是写了几年业务代码、但说不清long在 Windows 和 Linux 下为什么字节数不同、char和int之间到底怎么转换的熟手。下面按「环境与程序结构 → 类型系统 → 运算符 → 输入输出与排错」的顺序把这份讲义里的知识点拆成能直接复现的操作。2. Visual Studio 工程结构与第一个 C 程序的编译链路2.1 创建项目、源文件与编译运行的四个步骤讲义里把写一个 C 程序拆成创建项目、创建文件、编写代码、运行程序四步这个顺序不是形式主义它对应了 IDE 背后的真实链路项目决定编译器和链接器参数源文件是编译单元代码经过预处理、编译、汇编、链接才变成可执行文件。在 Visual Studio 里右键「源文件」→「添加」→「新建项」给文件起名时后缀必须是.cpp否则默认按 C 编译iostream和namespace会直接报错。// hello.cpp #include iostream // 引入标准输入输出流库 using namespace std; // 展开 std 命名空间省去 std:: 前缀 int main() { // 程序入口操作系统从这里开始执行 cout Hello world endl; // 向控制台输出并换行 system(pause); // 暂停防止控制台窗口一闪而过 return 0; // 返回 0 表示正常结束 }#include iostream是预处理指令把流库的声明在编译前插入当前文件using namespace std;让cout、endl可以直接写代价是命名冲突风险变大工程里更推荐写std::cout。main的返回值类型必须是intreturn 0是给操作系统的退出码。system(pause)依赖 Windows 的pause命令跨平台项目里通常用cin.get()替代。2.2 注释、变量初始化与常量定义的两种方式注释分单行//和多行/* */编译器在预处理阶段就会把它们替换成空格所以注释写多少都不影响运行体积。变量定义语法是数据类型 变量名 初始值;讲义特别强调「必须给初始值」因为局部变量不初始化时里面是栈上的垃圾值读出来是未定义行为。#define DAY 7 // 宏常量预处理阶段直接文本替换 int main() { int a 10; // 定义并初始化整型变量 const int MONTH 12; // const 常量编译期检查类型 // DAY 8; // 报错宏常量不可修改 // MONTH 24; // 报错const 变量不可修改 return 0; }#define是预处理宏没有类型不占变量空间调试时看不到符号const是真正的变量有类型、有作用域编译器能做类型检查。现代 C 里定义常量优先用const或constexpr宏只留给条件编译和头文件保护。2.3 关键字表与标识符命名规则讲义列出的关键字表asm、auto、bool、break、case、catch、char、class、const、continue、default、delete、do、double、else、enum、explicit、extern、false、float、for、friend、goto、if、inline、int、long、mutable、namespace、new、operator、private、protected、public、register、return、short、signed、sizeof、static、struct、switch、template、this、throw、true、try、typedef、typeid、typename、union、unsigned、using、virtual、void、volatile、wchar_t、while是 C 保留的标识符变量名撞上任何一个都会编译失败。标识符规则四条不能是关键字、只能由字母数字下划线组成、首字符必须是字母或下划线、区分大小写。实际项目里我一般用snake_case给变量、PascalCase给类型、k前缀给常量避免和标准库符号冲突。命名风格示例常见场景snake_caseplayer_score局部变量、函数参数PascalCaseGameEngine类名、结构体名kConstantkMaxRetry编译期常量m_memberm_buffer类成员变量3. 数据类型的内存布局sizeof、取值范围与类型选择3.1 整型家族与 sizeof 实测C 整型有short、int、long、long long标准只规定相对大小关系short int long long long具体字节数由平台决定。讲义给出的结论是short2 字节、int4 字节、long在 Windows 和 32 位 Linux 下 4 字节、64 位 Linux 下 8 字节、long long8 字节。用sizeof可以直接验证#include iostream using namespace std; int main() { cout short: sizeof(short) endl; // 通常 2 cout int: sizeof(int) endl; // 通常 4 cout long: sizeof(long) endl; // Windows 4 / Linux64 8 cout long long: sizeof(long long) endl;// 通常 8 return 0; }sizeof是编译期运算符不是函数返回size_t类型。它作用于类型时加括号作用于变量时可省略。跨平台传输数据时不要假设long是 4 字节固定宽度用cstdint里的int32_t、int64_t。3.2 浮点型、字符型与 ASCII 编码浮点型分float4 字节约 7 位有效数字和double8 字节1516 位有效数字。写float f 3.14;会有精度警告正确写法是3.14f。科学计数法3e2表示 3003e-2表示 0.03。字符型char占 1 字节存的是 ASCII 码而不是字符本身所以char ch a; cout (int)ch;输出 97ch 97;也能得到a。单引号只能包一个字符双引号是字符串混用直接编译错误。char ch a; cout ch endl; // a cout (int)ch endl; // 97查看 ASCII 码 ch 97; // 用 ASCII 赋值 cout ch endl; // a转义字符里最常用的是\n换行、\t制表、\\反斜线、\0空字符。\t对齐输出时比空格可靠但遇到中文字符宽度不一致仍会错位终端表格建议用printf的宽度控制。3.3 字符串、bool 与 cin 输入C 风格字符串char str[] hello;本质是字符数组加结尾\0C 风格string str hello;需要#include string支持拼接、比较、长度查询。bool占 1 字节true本质是 1false是 0但任何非零值赋给bool都会变成 1。输入用cin 变量它会跳过空白字符所以读字符串时遇到空格就停要读整行得用getline(cin, str)。#include iostream #include string using namespace std; int main() { int a 0; double d 0; char ch 0; string str; bool flag true; cin a d ch str flag; // 连续输入空白分隔 cout a d ch str flag endl; return 0; }cin输入失败时流会进入 fail 状态后续读取全部失效工程里要配合cin.clear()和cin.ignore()恢复。bool用cin读时输入0得false输入非零得true但输入字母会失败。4. 运算符优先级与前置后置递增的求值顺序4.1 算术、取模与整数除法陷阱算术运算符 - * / %里整数相除结果仍是整数10 / 3得 3 而不是 3.33想要小数必须至少一个操作数是浮点。取模%只能用于整型10 % 3得 1除数为 0 时除法和取模都会触发运行时错误。int a 10, b 3; cout a / b endl; // 3整数除法截断 cout a % b endl; // 1 double d1 0.5, d2 0.25; cout d1 / d2 endl; // 2浮点除法 // cout d1 % d2; // 编译错误浮点不能取模4.2 前置与后置递增的差别a先自增再参与表达式a先参与表达式再自增。讲义里的例子int b a * 10;和int b a * 10;结果不同前者a先变 11 再乘后者先用 10 乘再让a变 11。同一表达式里对同一变量多次自增是未定义行为实际代码里应拆成独立语句。int a2 10; int b2 a2 * 10; // a211, b2110 int a3 10; int b3 a3 * 10; // b3100, a3114.3 比较、逻辑运算符与短路求值比较运算符返回boolcout输出时显示 1 或 0。逻辑运算符!、、||里和||有短路特性a b中a为假就不再算ba || b中a为真就不再算b。这个特性常被用来做空指针保护比如if (ptr ptr-valid())。运算符含义示例结果!逻辑非!01逻辑与1 00||逻辑或1 || 01相等4 30!不等4 ! 31赋值运算符 - * / %是复合写法a 2等价a a 2。优先级上算术 比较 逻辑 赋值拿不准就加括号这比背优先级表可靠。5. 用编译器警告和调试器定位类型与运算符问题5.1 打开警告级别让编译器替你查类型Visual Studio 默认警告级别偏低很多隐式转换不会提示。项目属性 → C/C → 常规 → 警告等级设为/W4再把「将警告视为错误」打开float f 3.14;这类精度丢失会直接编译失败。GCC/Clang 对应-Wall -Wextra -Werror。g -stdc17 -Wall -Wextra -Werror -o hello hello.cpp-stdc17指定标准版本-Wall -Wextra打开常用警告-Werror把警告升级为错误。CI 里加这三个参数能挡掉大量signed/unsigned比较、未使用变量、隐式窄化的问题。5.2 断点、监视窗口与 sizeof 验证在main里对变量行按 F9 下断点F5 启动调试鼠标悬停变量能看到当前值。监视窗口里输入sizeof(long)可以直接看到平台差异输入(int)ch能看到 ASCII 码。调试时如果发现int变量显示成乱码多半是没初始化栈上残留了上一次函数调用的数据。5.3 常见编译错误对照错误信息原因处理uninitialized local variable used局部变量未初始化定义时给初始值cannot convert from const char [6] to char双引号赋给 char改用单引号或 stringday: undeclared identifier宏定义在函数之后把#define移到文件顶部C4996 system: This function is unsafe安全函数警告改用cin.get()或定义_CRT_SECURE_NO_WARNINGS提示system(pause)在提交作业或跨平台项目里尽量去掉用cin.get()替代否则 Linux 下会报sh: pause: command not found。5.4 用 static_assert 在编译期卡住类型假设C11 起可以用static_assert在编译期验证类型大小把平台假设变成编译错误而不是运行时 bug#include cstdint static_assert(sizeof(int) 4, int 不是 4 字节检查平台); static_assert(sizeof(long long) 8, long long 不是 8 字节);static_assert第一个参数是常量表达式第二个是失败时的提示信息。把它放在头文件里换平台编译时立刻暴露问题比等到运行时数据错乱再查要省事得多。配合int32_t、int64_t这类固定宽度类型跨平台代码的可移植性会稳很多。本文还有配套的精品资源点击获取
返回列表