当前位置: 首页 > news >正文

C/C++ 常见笔试题与陷阱详解

C/C++ 常见笔试题与陷阱详解

在嵌入式开发和 C/C++ 岗位面试中,经常会遇到一些看似简单,但实际考察很深的笔试题。这些题目不仅涉及基础语法,还深入考察了指针、引用、内存存储方式等底层知识。本文结合几个典型案例,带你逐步分析并解决这些问题。


浮点数与匿名引用

来看第一道题:

#include <iostream>
using namespace std;int main() {float a = 1.0; cout << (int&)a << endl; return 0;
}

很多人第一眼会以为 (int&)a强制类型转换,即把 float 转换为 int,那么结果应该输出 1。但实际上,运行结果却是一个很大的整数:

1065353216

原因分析

  1. (int&)a 实际上并不是类型转换,而是创建了一个 匿名的 int 类型引用,并且和 a(float 类型变量)绑定。
  2. 由于引用是 int&,所以编译器会把 a 在内存中的存储形式按 整数的方式解释
  3. float 在内存中是按照 IEEE 754 标准存储的,比如 1.0f 的二进制存储形式对应的整数就是 1065353216

所以结果并不是 1,而是 1.0f 在内存中的整数表示。

对比强制类型转换

如果我们改成强制类型转换:

cout << (int)a << endl;

输出结果就是:

1

所以请务必区分:

  • (int&)a:引用绑定,直接按整型解读内存。
  • (int)a:强制类型转换,得到的是值的转换结果。

构造函数调用次数

题目:假设有如下语句:

A a;
A b(3);
A* p;

问:调用了几次构造函数?

分析

  1. A a; —— 创建了对象 a,调用一次 默认构造函数
  2. A b(3); —— 创建了对象 b,调用一次 带参数的构造函数
  3. A* p; —— 创建了一个指针变量 p,并没有创建对象,所以 不会调用构造函数

所以总共调用 2 次

如果写成:

A* p = new A();

此时会真正创建对象,因此还会额外调用一次构造函数。


左值函数与右值函数

平时我们写的函数大多数是右值函数,比如:

int maxValue(int a, int b) {return (a > b) ? a : b;
}

调用时:

int x = 10, y = 20;
int w = maxValue(x, y); // w = 20

这里 maxValue 的结果只能放在赋值运算符的 右侧

左值函数

如果我们希望函数的返回值能够放在赋值号左侧,例如:

maxValue(x, y) = 100;

就必须让函数返回 引用

改写如下:

int& maxValue(int& a, int& b) {return (a > b) ? a : b;
}int main() {int x = 10, y = 20;maxValue(x, y) += 10;  // 修改较大的那个数cout << "x=" << x << ", y=" << y << endl;return 0;
}

运行结果:

x=10, y=30

这就是 左值函数 的典型用法。


指针输出字符串还是地址?

来看这个例子:

#include <iostream>
using namespace std;int main() {const char* ptr = "Hello World";cout << ptr << endl; int a = 10;int* p = &a;cout << p << endl;return 0;
}

运行结果:

Hello World
0x7ffee4d2a8

为什么?

  • cout 遇到 字符型指针 时,C++ 标准库重载了 << 运算符,会把它当作字符串处理,输出内容而不是地址。
  • cout 遇到其他指针类型(如 int*),则会直接输出指针存储的地址。

如果我们想输出 const char* 的真实地址,可以这样写:

cout << (void*)ptr << endl;

指针交换函数中的陷阱

题目:写一个交换函数,代码如下:

void swap(int* p1, int* p2) {int* temp;temp = p1;p1 = p2;p2 = temp;
}

调用:

int a = 10, b = 20;
swap(&a, &b);

结果:ab 的值没有交换。

问题所在

原因是 p1p2 是局部变量,它们只是指针的副本。交换的是副本的值,并不会影响 ab

正确写法

方法一:交换指针所指向的值。

void swap(int* p1, int* p2) {int temp = *p1;*p1 = *p2;*p2 = temp;
}

方法二:用引用简化写法。

void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}

数组与引用

错误写法

int& arr[3]; // ❌ 编译错误

为什么?因为 不存在“引用的数组”,引用只是别名,本身不是对象,数组元素必须是对象。

正确写法:数组的引用

int nums[3] = {1, 2, 3};
int (&arr)[3] = nums; // arr 是 nums 的引用

此时 arr 就是 nums 的别名,操作 arr 等价于操作 nums


总结

本文整理了几个典型的 C/C++ 笔试题:

  1. 区分 (int&)a(int)a 的差别,理解浮点数存储原理。
  2. 理清构造函数调用次数与对象、指针的关系。
  3. 掌握左值函数的写法,理解引用返回值的重要性。
  4. 记住 cout 对字符型指针做了特殊重载。
  5. 避免交换函数中指针副本的问题。
  6. 理解数组与引用的合法写法。

这些知识点不仅能帮你应对笔试,还能让你在写实际代码时少踩坑。

http://www.lryc.cn/news/625449.html

相关文章:

  • 电脑出现‘无法启动此程序,因为计算机中丢失dll’要怎么办?2025最新的解决方法分析
  • vue3+element-plus 输入框el-input设置背景颜色和字体颜色,样式效果等同于不可编辑的效果
  • 微软行业案例:英格兰足球超级联赛(Premier League)
  • Flask 路由详解:构建灵活的 URL 映射系统
  • Flutter AlwaysScrollableScrollPhysics详解
  • Windows 平板/电脑 上使用 DHCPSRV 搭建 DHCP 服务器
  • 后台管理系统-8-vue3之首页count数据的渲染
  • Flink Stream API - 源码二开详细实现
  • Python爬虫第一课:爬取HTML静态网页小说章节
  • 【教程】在 VMware Windows 虚拟机中使用 WinPE 进行离线密码重置或取证操作
  • CT Micro’s New HV Photo-MOSFET Relay Optocouplers
  • github 上传代码步骤
  • JWT通俗易懂讲解
  • 什么是强化学习
  • 【图像算法 - 18】慧眼辨良莠:基于深度学习与OpenCV的麦田杂草智能识别检测系统(附完整代码)
  • 从 SGD 到梯度累积:Epoch、Batch、Step 的关系全解析
  • 边缘智能体:Go编译在医疗IoT设备端运行轻量AI模型(上)
  • Ansible 角色管理指南
  • Ansible 角色管理
  • Apache IoTDB(4):深度解析时序数据库 IoTDB 在Kubernetes 集群中的部署与实践指南
  • Redisson 分布式锁核心机制解析
  • 2025年09月计算机二级MySQL选择题每日一练——第一期
  • 寻找旋转排序数组中的最小值
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day7
  • web开发,在线%服装商城开发demo,基于html,css,jquery,asp.net,webform,sqlserver数据库
  • hadoop技术栈(九)Hbase替代方案
  • 20250819 强连通分量,边双总结
  • k8s运维实践:高可用Redis Cluster(三主三从)与Proxy部署方案
  • RadioIrqProcess函数详细分析与流程图
  • 【实时Linux实战系列】基于实时Linux的物联网系统设计