今日C/C++学习笔记20260223

今日C/C++学习笔记20260223

1. 字节序(Endianness)检测

概念

  • 大端序:高位字节存储在低地址。
  • 小端序:低位字节存储在低地址。

检测代码(利用指针)

c 复制代码
#include <stdio.h>
int main() {
    unsigned int x = 0x12345678;
    unsigned char *p = (unsigned char*)&x;
    if (*p == 0x78)
        printf("小端序\n");
    else
        printf("大端序\n");
    return 0;
}
  • 使用 unsigned char* 避免符号扩展。
  • 若第一个字节为 0x78 则为小端,否则为大端(通常 0x12)。

2. 宏定义中的括号重要性

错误示例

c 复制代码
#define AREA(r) PI*r*r
// AREA(1+2) 展开为 PI*1+2*1+2,结果错误

正确写法

c 复制代码
#define AREA(r) (PI * (r) * (r))
  • 每个参数加括号 (r) 防止优先级问题。
  • 整个表达式加括号 (...) 防止外部运算符干扰。

3. 逻辑与(&&) vs 按位与(&)

运算符 名称 返回值 短路 典型用途
&& 逻辑与 0 或 1 条件组合、安全访问
& 按位与 整数 位掩码、标志位提取

示例

c 复制代码
int a = 0, b = 1;
if (a && (b = 2)) { }  // b 仍为 1(短路)
if (a & (b = 2)) { }   // b 变为 2(无短路)

4. 枚举(enum)不能直接输出名称

枚举成员在编译后替换为整数值,运行时无法获取名字。

解决方案:建立映射表

c 复制代码
enum Color { RED, GREEN, BLUE };
const char* color_names[] = {"RED", "GREEN", "BLUE"};
printf("%s\n", color_names[GREEN]);  // 输出 "GREEN"

5. 逻辑运算的短路求值

  • &&:左为假则右不计算。
  • ||:左为真则右不计算。

不影响最终逻辑结果,但可能跳过副作用(赋值、函数调用等)。

6. printf 格式符注意事项

  • %zu:用于 size_t 类型(sizeof 返回的类型),可移植性好。
  • %lld:用于 long long,不应用于 size_t(可能类型不匹配)。
  • 浮点数 %.2f 采用四舍五入(向远离零的方向),而非截断或银行家舍入。

7. 数组大小计算

c 复制代码
int arr[10];
size_t total_bytes = sizeof(arr);               // 40
size_t element_count = sizeof(arr) / sizeof(arr[0]);  // 10

除数必须是 sizeof(arr[0]),而不是 arr[0](后者是元素值,未初始化时危险)。

8. stdout 与 stderr 的缓冲差异

  • stdout:行缓冲(终端),全缓冲(重定向到文件)。
  • stderr:无缓冲,每次输出立即写入。

测试程序可通过循环写入大量字符,比较耗时,体会缓冲带来的性能差异。

9. 贪吃蛇游戏优化:消除闪烁

闪烁原因

使用 system("cls") 清屏后再逐字符绘制,屏幕短暂空白造成闪烁。

优化方法:局部刷新

  • 只更新变化的部分(蛇头、蛇尾、食物、分数)。
  • 使用 gotoxy() 定位光标,直接覆盖旧内容。
  • 隐藏光标(hideCursor()),调整控制台窗口大小。

核心代码片段

c 复制代码
void gotoxy(int x, int y) {
    COORD coord = {x, y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void move() {
    // 计算新头位置,判断是否吃到食物
    // 移动身体,记录旧尾部
    if (!eat) {
        gotoxy(oldTailX, oldTailY);
        printf("  ");        // 清除旧尾部
    } else {
        // 更新分数、生成新食物、绘制新食物
    }
    gotoxy(snakeX[0], snakeY[0]);
    printf("■");             // 绘制新头部
}

10. C++ 范围 for 循环(Range-based for)

cpp 复制代码
int arr[10] = {0};
for (auto b : arr) {
    std::cout << b << std::endl;  // 输出每个元素
}
  • 变量类型需指定或使用 auto
  • 遍历时最好使用 const auto& 避免拷贝(若元素类型较大)。

总结

  • 熟练掌握指针与类型转换有助于理解内存布局(字节序)。
  • 宏定义时务必加括号,避免优先级陷阱。
  • 区分逻辑与和按位与,理解短路求值。
  • 枚举输出需手动映射。
  • 使用正确的格式化输出(%zu 等)提高可移植性。
  • 优化控制台程序时,避免频繁清屏,改用局部刷新。
  • 利用 C++ 现代特性(如范围 for、auto)简化代码。

注:以上内容基于今日学习对话整理,可作为复习参考。

相关推荐
sakiko_25 分钟前
UIKit学习笔记3-布局、滚动视图、隐藏或显示视图
前端·笔记·学习·objective-c·swift·uikit
谭欣辰34 分钟前
LCS(最长公共子序列)详解
开发语言·c++·算法
Cando学算法39 分钟前
鸽笼原理(抽屉原理)
c++·算法·学习方法
嵌入式-老费1 小时前
瑞芯微soc的学习和应用(题外话之esp32开发)
学习
郝学胜-神的一滴2 小时前
跨平台动态库与头文件:从原理到命名的深度解析
linux·c++·程序人生·unix·cmake
代码中介商2 小时前
C++ 仿函数(Functor)深度解析:从基础到应用
开发语言·c++
王老师青少年编程2 小时前
csp信奥赛C++高频考点专项训练之字符串 --【字符串基础】:[NOIP 2018 普及组] 标题统计
c++·字符串·csp·高频考点·信奥赛·专项训练·标题统计
辰同学ovo2 小时前
从全局登录状态管理学习 Redux
前端·javascript·学习·react.js
ting94520002 小时前
告别无效学习:Scholé 如何用 AI 重构职场学习,让学习直接嵌入工作流
人工智能·学习·重构
xian_wwq2 小时前
【学习笔记】Harness到底是什么
笔记·学习·ai·harness