1 c/c++面试题
目录
3.c语言关键字static与c++的关键字static有什么区别?
1.变量的声明与定义有什么区别?
为变量分配地址空间的称为定义,不分配地址空间的称为声明。一个变量可以再多个地方声明,但只能在一个地方定义。加入extern修饰的是变量的声明,说明此变量将在文件以外或者文件以后部分定义。说明很多时候一个变量只声明不分配内存空间,直到使用时才初始化,分配内存空间,如外部变量。
2.sizeof与strlen的区别?
在 C 语言中,sizeof和strlen是两个常用但功能完全不同的工具,主要区别如下:
本质与用途
sizeof:是一个运算符,用于计算变量、数据类型或表达式所占用的内存字节数
strlen:是标准库函数(需要#include <string.h>),用于计算字符串中字符的个数(不包括结束符'\0')
处理对象
sizeof:可以用于任何数据类型(int、float、数组、结构体等)和变量
strlen:只能用于以'\0'结尾的字符串(字符数组)
计算结果
sizeof:计算的是整个对象所占用的内存大小,对于字符串数组会包含结束符'\0'
strlen:计算的是从起始地址到第一个'\0'之间的字符数,不包含'\0'
其他差异
sizeof在编译时计算结果,而strlen在运行时计算
sizeof的结果是size_t类型,strlen的返回值也是size_t类型
对未初始化的字符数组使用strlen可能导致不可预测的结果(因为可能找不到'\0')
数组作为sizeof的参数不退化 作为strlen的参数 退化为指针
简单来说,sizeof关注 "内存大小",strlen关注 "字符串长度",这是它们最核心的区别。
3.c语言关键字static与c++的关键字static有什么区别?
1. 相同点(两种语言共有的特性)
- 修饰全局变量:将全局变量的作用域限制在当前文件(内部链接)
- 修饰局部变量:延长局部变量的生命周期至程序结束,保留上次的值
- 修饰函数:将函数的作用域限制在当前文件(内部链接)
2.不同点
- c++的static还可以用来定义成员变量与函数,及静态成员与静态成员函数。
3. 核心区别总结
| 特性 | C 语言中的static |
C++ 中的static |
|---|---|---|
| 基本功能 | 控制作用域和生命周期 | 包含 C 的所有功能 |
| 类相关 | 不支持(无类概念) | 支持静态成员变量、静态成员函数 |
| 面向对象 | 无相关特性 | 用于实现类级别的共享数据和方法 |
简单说,C++ 中的static继承了 C 语言的所有功能,并在面向对象编程中扩展了新的用途,主要用于实现类级别的共享数据和方法。
4.c中的malloc与c++中的new有什么区别?
C 语言中的malloc和 C++ 中的new都是用于动态内存分配的工具,但它们在功能、用法和特性上有显著区别,主要差异如下:
1. 本质与所属范畴
-
malloc:是 C 语言标准库函数(需
#include <stdlib.h>),在 C++ 中也可使用 -
new:是 C++ 的关键字,是 C++ 语言本身的一部分,不是函数
2. 功能范围
-
malloc:仅负责分配指定大小的内存块,返回
void*类型指针 -
new:不仅分配内存,还会自动调用对象的构造函数初始化对象
// C语言风格(malloc)
int* p1 = (int*)malloc(sizeof(int)); // 仅分配内存,未初始化
if (p1 == NULL) { /* 处理内存分配失败 */ }
// C++风格(new)
int* p2 = new int; // 分配内存并初始化(基本类型默认初始化)
int* p3 = new int(10); // 分配内存并初始化为10
// 对于类对象
class MyClass {
public:
MyClass() { /* 构造函数 */ }
};
MyClass* obj1 = (MyClass*)malloc(sizeof(MyClass)); // 仅分配内存,未调用构造函数
MyClass* obj2 = new MyClass; // 分配内存并调用构造函数
3. 内存分配失败处理
-
malloc:分配失败时返回
NULL指针,需要手动检查 - new:分配失败时默认抛出
std::bad_alloc异常(可指定不抛出异常,返回NULL)
4. 数组内存分配
- malloc:分配数组时需手动计算总字节数,返回的指针需显式转换
- new:支持数组形式,会自动计算大小,并对数组元素调用构造函数
// 分配数组
int* arr1 = (int*)malloc(5 * sizeof(int)); // C风格
int* arr2 = new int[5]; // C++风格,会默认初始化
int* arr3 = new int[5] {1, 2, 3, 4, 5}; // C++11后支持初始化列表
// 对应释放
free(arr1);
delete[] arr2; // 注意数组要用delete[]
delete[] arr3;
5. 对应释放方式
- malloc 分配的内存:必须用
free()释放,且free()不调用析构函数 - new 分配的内存:必须用
delete释放(数组用delete[]),会自动调用析构函数
6. 重载能力
- malloc:作为库函数,无法重载
- new:可以重载,允许自定义内存分配策略(通过重载
operator new)
总结对比表
| 特性 | malloc | new |
|---|---|---|
| 性质 | 库函数 | 关键字 |
| 功能 | 仅分配内存 | 分配内存 + 调用构造函数 |
| 返回类型 | void*(需显式转换) | 具体类型指针(无需转换) |
| 失败处理 | 返回 NULL | 默认抛出异常 |
| 数组分配 | 需手动计算大小 | 支持new[]语法 |
| 释放方式 | free() | delete/delete[] |
| 析构函数 | 不调用 | 自动调用 |
| 重载 | 不能 | 可以 |
5.简述c,c++程序编译的内存分配请情况?
c,c++内存分配方式可以分为以下三种:
(1).从静态存储区域分配:
特点:程序启动时分配,生命周期贯穿整个程序
内容:全局变量(定义在函数外的变量)
static修饰的静态变量(包括全局静态和局部静态)
分类:已初始化区:存储初始化的全局 / 静态变量
未初始化区(BSS 段):存储未初始化的全局 / 静态变量(默认初始化为 0)
(2).在栈上分配:
特点:自动分配与释放,遵循 "先进后出" 原则
内容:函数的局部变量(包括形参)
函数调用时的返回地址
临时变量和上下文信息
大小:通常固定(可配置),较小(几 MB)
(3).从堆上分配:
特点:动态分配,需手动管理(C 用malloc/free,C++ 用new/delete)
内容:程序运行中动态申请的内存
如动态数组、对象等
大小:较大(可达 GB 级别),受限于系统内存
(4).常量存储区:
特点:存储只读数据,不可修改
内容:字符串常量(如"hello world")
const修饰的常量(C++ 中可能优化到栈或全局区)
(5).程序代码区:
特点:存储可执行代码,只读(防止意外修改)
内容:程序的机器指令
函数体的二进制代码
一个c,c++程序编译时内存分为5大存储区域:堆区,栈区,全局区,程序代码区,文字常量区
更多推荐
所有评论(0)