logo资料库

C语言C++常见面试题(含答案).pdf

第1页 / 共28页
第2页 / 共28页
第3页 / 共28页
第4页 / 共28页
第5页 / 共28页
第6页 / 共28页
第7页 / 共28页
第8页 / 共28页
资料共28页,剩余部分请下载后查看
2020/8/3 让微信排版变 Nice 1 变量的声明和定义有什么区别 变 量 的 定 义 为 变 量 分 配 地 址 和 存 储 空 间 , 变 量 的 声 明 不 分 配 地 址 。 一 个 变 量 可 以 在 多 个 地 方 声 明 , 但 是 只 在 一 个 地 方 定 义 。 加 入 e x t e r n 修 饰 的 是 变 量 的 声 明 , 说 明 此 变 量 将 在 文 件 以 外 或 在 文 件 后 面 部 分 定 义 。 说 明 : 很 多 时 候 一 个 变 量 , 只 是 声 明 不 分 配 内 存 空 间 , 直 到 具 体 使 用 时 才 初 始 化 , 分 配 内 存 空 间 , 如 外 部 变 量 。 int main() { extern int A; //这是个声明而不是定义,声明A是一个已经定义了的外部变量 //注意:声明外部变量时可以把变量类型去掉如:extern A; dosth(); //执行函数 } int A; //是定义,定义了A为整型的外部变量 2 简述#ifdef、#else、#endif和#ifndef的作用 利用#ifdef、#endif将某程序功能模块包括进去,以向特定用户提供该功能。在不需要时用户可轻易将其屏 蔽。 #ifdef MATH #include "math.c" #endif 在子程序前加上标记,以便于追踪和调试。 #ifdef DEBUG printf ("Indebugging......!"); #endif 应对硬件的限制。由于一些具体应用环境的硬件不一样,限于条件,本地缺乏这种设备,只能绕过硬件,直 接写出预期结果。 注 意 : 虽 然 不 用 条 件 编 译 命 令 而 直 接 用 i f 语 句 也 能 达 到 要 求 , 但 那 样 做 目 标 程 序 长 ( 因 为 所 有 语 句 都 编 译 ) , 运 行 时 间 长 ( 因 为 在 程 序 运 行 时 间 对 i f 语 句 进 行 测 试 ) 。 https://mdnice.com 1/28
2020/8/3 让微信排版变 Nice 而 采 用 条 件 编 译 , 可 以 减 少 被 编 译 的 语 句 , 从 而 减 少 目 标 程 序 的 长 度 , 减 少 运 行 时 间 。 3 写出int 、bool、 float 、指针变量与 “零值”比较的if 语句 //int与零值比较 if ( n == 0 ) if ( n != 0 ) //bool与零值比较 if (flag) // 表示flag为真 if (!flag) // 表示flag为假 //float与零值比较 const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x <= EPSINON) //其中EPSINON是允许的误差(即精度)。 //指针变量与零值比较 if (p == NULL) if (p != NULL) 4 结构体可以直接赋值吗 声 明 时 可 以 直 接 初 始 化 , 同 一 结 构 体 的 不 同 对 象 之 间 也 可 以 直 接 赋 值 , 但 是 当 结 构 体 中 含 有 指 针 “ 成 员 ” 时 一 定 要 小 心 。 注 意 : 当 有 多 个 指 针 指 向 同 一 段 内 存 时 , 某 个 指 针 释 放 这 段 内 存 可 能 会 导 致 其 他 指 针 的 非 法 操 作 。 因 此 在 释 放 前 一 定 要 确 保 其 他 指 针 不 再 使 用 这 段 内 存 空 间 。 5 sizeof 和strlen 的区别 sizeof是一个操作符,strlen是库函数。 sizeof的参数可以是数据的类型,也可以是变量,而strlen只能以结尾为‘\0’的字符串作参数。 编译器在编译时就计算出了sizeof的结果,而strlen函数必须在运行时才能计算出来。并且sizeof计算的是数 据类型占内存的大小,而strlen计算的是字符串实际的长度。 数组做sizeof的参数不退化,传递给strlen就退化为指针了 6 C 语言的关键字 static 和 C++ 的关键字 static 有什么区别 https://mdnice.com 2/28
2020/8/3 让微信排版变 Nice 在 C 中 s t a t i c 用 来 修 饰 局 部 静 态 变 量 和 外 部 静 态 变 量 、 函 数 。 而 C + + 中 除 了 上 述 功 能 外 , 还 用 来 定 义 类 的 成 员 变 量 和 函 数 。 即 静 态 成 员 和 静 态 成 员 函 数 。 注 意 : 编 程 时 s t a t i c 的 记 忆 性 , 和 全 局 性 的 特 点 可 以 让 在 不 同 时 期 调 用 的 函 数 进 行 通 信 , 传 递 信 息 , 而 C + + 的 静 态 成 员 则 可 以 在 多 个 对 象 实 例 间 进 行 通 信 , 传 递 信 息 。 7 C 语言的 malloc 和 C++ 中的 new 有什么区别 new 、delete 是操作符,可以重载,只能在C++ 中使用。 malloc、free 是函数,可以覆盖,C、C++ 中都可以使用。 new 可以调用对象的构造函数,对应的delete 调用相应的析构函数。 malloc 仅仅分配内存,free 仅仅回收内存,并不执行构造和析构函数 new 、delete 返回的是某种数据类型指针,malloc、free 返回的是void 指针。 注 意 : m a l l o c 申 请 的 内 存 空 间 要 用 f r e e 释 放 , 而 n e w 申 请 的 内 存 空 间 要 用 d e l e t e 释 放 , 不 要 混 用 。 8 写一个 “标准”宏MIN # d e f i n e m i n ( a , b ) ( ( a ) < = ( b ) ? ( a ) : ( b ) ) 9 ++i和i++的区别 + + i 先 自 增 1 , 再 返 回 , i + + 先 返 回 i , 再 自 增 1 10 volatile有什么作用 状态寄存器一类的并行设备硬件寄存器。 一个中断服务子程序会访问到的非自动变量。 多线程间被几个任务共享的变量。 注 意 : 虽 然 v o l a t i l e 在 嵌 入 式 方 面 应 用 比 较 多 , 但 是 在 P C 软 件 的 多 线 程 中 , v o l a t i l e 修 饰 的 临 界 变 量 也 是 非 常 实 用 的 。 11 一个参数可以既是const又是volatile吗 可 以 , 用 c o n s t 和 v o l a t i l e 同 时 修 饰 变 量 , 表 示 这 个 变 量 在 程 序 内 部 是 只 读 的 , 不 能 改 变 的 , 只 在 程 序 外 部 条 件 变 化 下 改 变 , 并 且 编 译 器 不 会 优 化 这 个 变 量 。 每 次 使 用 这 个 变 量 时 , 都 要 小 心 地 去 内 存 读 取 这 个 变 量 的 值 , 而 不 是 去 寄 存 器 读 取 它 的 备 份 。 https://mdnice.com 3/28
2020/8/3 让微信排版变 Nice 注 意 : 在 此 一 定 要 注 意 c o n s t 的 意 思 , c o n s t 只 是 不 允 许 程 序 中 的 代 码 改 变 某 一 变 量 , 其 在 编 译 期 发 挥 作 用 , 它 并 没 有 实 际 地 禁 止 某 段 内 存 的 读 写 特 性 。 12 a 和&a 有什么区别 & a : 其 含 义 就 是 “ 变 量 a 的 地 址 ” 。 * a : 用 在 不 同 的 地 方 , 含 义 也 不 一 样 。 在声明语句中,*a只说明a是一个指针变量,如int *a; 在其他语句中,*a前面没有操作数且a是一个指针时,*a代表指针a指向的地址内存放的数据,如b=*a; *a前面有操作数且a是一个普通变量时,a 代 表 乘 以 a , 如 c = b a。 13 用C 编写一个死循环程序 while(1) { } 注 意 : 很 多 种 途 径 都 可 实 现 同 一 种 功 能 , 但 是 不 同 的 方 法 时 间 和 空 间 占 用 度 不 同 , 特 别 是 对 于 嵌 入 式 软 件 , 处 理 器 速 度 比 较 慢 , 存 储 空 间 较 小 , 所 以 时 间 和 空 间 优 势 是 选 择 各 种 方 法 的 首 要 考 虑 条 件 。 14 结构体内存对齐问题 请 写 出 以 下 代 码 的 输 出 结 果 : #include struct S1 { int i:8; char j:4; int a:4; double b; }; struct S2 { int i:8; char j:4; double b; int a:4; }; https://mdnice.com 4/28
2020/8/3 让微信排版变 Nice struct S3 { int i; char j; double b; int a; }; int main() { printf("%d\n",sizeof(S1)); // 输出8 printf("%d\n",sizeof(S1); // 输出12 printf("%d\n",sizeof(Test3)); // 输出8 return 0; } sizeof(S1)=16 sizeof(S2)=24 sizeof(S3)=32 说 明 : 结 构 体 作 为 一 种 复 合 数 据 类 型 , 其 构 成 元 素 既 可 以 是 基 本 数 据 类 型 的 变 量 , 也 可 以 是 一 些 复 合 型 类 型 数 据 。 对 此 , 编 译 器 会 自 动 进 行 成 员 变 量 的 对 齐 以 提 高 运 算 效 率 。 默 认 情 况 下 , 按 自 然 对 齐 条 件 分 配 空 间 。 各 个 成 员 按 照 它 们 被 声 明 的 顺 序 在 内 存 中 顺 序 存 储 , 第 一 个 成 员 的 地 址 和 整 个 结 构 的 地 址 相 同 , 向 结 构 体 成 员 中 s i z e 最 大 的 成 员 对 齐 。 许 多 实 际 的 计 算 机 系 统 对 基 本 类 型 数 据 在 内 存 中 存 放 的 位 置 有 限 制 , 它 们 会 要 求 这 些 数 据 的 首 地 址 的 值 是 某 个 数 k ( 通 常 它 为 4 或 8 ) 的 倍 数 , 而 这 个 k 则 被 称 为 该 数 据 类 型 的 对 齐 模 数 。 15 全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎 么知道的? 全局变量是整个程序都可访问的变量,谁都可以访问,生存期在整个程序从运行到结束(在程序结束时所占 内存释放); 而局部变量存在于模块(子程序,函数)中,只有所在模块可以访问,其他模块不可直接访问,模块结束 (函数调用完毕),局部变量消失,所占据的内存释放。 操作系统和编译器,可能是通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行 的时候被加载.局部变量则分配在堆栈里面。 16 简述C、C++程序编译的内存分配情况 https://mdnice.com 5/28
2020/8/3 让微信排版变 Nice 从静态存储区域分配: 内 存 在 程 序 编 译 时 就 已 经 分 配 好 , 这 块 内 存 在 程 序 的 整 个 运 行 期 间 都 存 在 。 速 度 快 、 不 容 易 出 错 , 因 为 有 系 统 会 善 后 。 例 如 全 局 变 量 , s t a t i c 变 量 , 常 量 字 符 串 等 。 在栈上分配: 在 执 行 函 数 时 , 函 数 内 局 部 变 量 的 存 储 单 元 都 在 栈 上 创 建 , 函 数 执 行 结 束 时 这 些 存 储 单 元 自 动 被 释 放 。 栈 内 存 分 配 运 算 内 置 于 处 理 器 的 指 令 集 中 , 效 率 很 高 , 但 是 分 配 的 内 存 容 量 有 限 。 大 小 为 2 M 。 从堆上分配: 即 动 态 内 存 分 配 。 程 序 在 运 行 的 时 候 用 m a l l o c 或 n e w 申 请 任 意 大 小 的 内 存 , 程 序 员 自 己 负 责 在 何 时 用 f r e e 或 d e l e t e 释 放 内 存 。 动 态 内 存 的 生 存 期 由 程 序 员 决 定 , 使 用 非 常 灵 活 。 如 果 在 堆 上 分 配 了 空 间 , 就 有 责 任 回 收 它 , 否 则 运 行 的 程 序 会 出 现 内 存 泄 漏 , 另 外 频 繁 地 分 配 和 释 放 不 同 大 小 的 堆 空 间 将 会 产 生 堆 内 碎 块 。 一 个 C 、 C + + 程 序 编 译 时 内 存 分 为 5 大 存 储 区 : 堆 区 、 栈 区 、 全 局 区 、 文 字 常 量 区 、 程 序 代 码 区 。 17 简述strcpy、sprintf 与memcpy 的区别 操作对象不同,strcpy 的两个操作对象均为字符串,sprintf 的操作源对象可以是多种数据类型, 目的操作 对象是字符串,memcpy 的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。 执行效率不同,memcpy 最高,strcpy 次之,sprintf 的效率最低。 实现功能不同,strcpy 主要实现字符串变量间的拷贝,sprintf 主要实现其他数据类型格式到字 符串的转 化,memcpy 主要是内存块间的拷贝。 注 意 : s t r c p y 、 s p r i n t f 与 m e m c p y 都 可 以 实 现 拷 贝 的 功 能 , 但 是 针 对 的 对 象 不 同 , 根 据 实 际 需 求 , 来 选 择 合 适 的 函 数 实 现 拷 贝 功 能 。 18 请解析(*(void (*)( ) )0)( )的含义 void (*0)( ) : 是一个返回值为void,参数为空的函数指针0。 (void (*)( ))0: 把0转变成一个返回值为void,参数为空的函数指针。 *(void (*)( ))0: 在上句的基础上加*表示整个是一个返回值为void,无参数,并且起始地址为0的函 数的名字。 (*(void (*)( ))0)( ): 这就是上句的函数名所对应的函数的调用。 19 C语言的指针和引用和c++的有什么区别? 指针有自己的一块空间,而引用只是一个别名; https://mdnice.com 6/28
2020/8/3 让微信排版变 Nice 使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小; 作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引 用的修改都会改变引用所指向的对 象; 可以有const指针,但是没有const引用; 指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能 被改变; 指针可以有多级指针(**p),而引用止于一级; 指针和引用使用++运算符的意义不一样; 如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄露。 20 typedef 和define 有什么区别 用法不同:typedef 用来定义一种数据类型的别名,增强程序的可读性。define 主要用来定义 常量,以及 书写复杂使用频繁的宏。 执行时间不同:typedef 是编译过程的一部分,有类型检查的功能。define 是宏定义,是预编译的部分,其 发生在编译之前,只是简单的进行字符串的替换,不进行类型的检查。 作用域不同:typedef 有作用域限定。define 不受作用域约束,只要是在define 声明后的引用 都是正确 的。 对指针的操作不同:typedef 和define 定义的指针时有很大的区别。 注 意 : t y p e d e f 定 义 是 语 句 , 因 为 句 尾 要 加 上 分 号 。 而 d e f i n e 不 是 语 句 , 千 万 不 能 在 句 尾 加 分 号 。 21 指针常量与常量指针区别 指 针 常 量 是 指 定 义 了 一 个 指 针 , 这 个 指 针 的 值 只 能 在 定 义 时 初 始 化 , 其 他 地 方 不 能 改 变 。 常 量 指 针 是 指 定 义 了 一 个 指 针 , 这 个 指 针 指 向 一 个 只 读 的 对 象 , 不 能 通 过 常 量 指 针 来 改 变 这 个 对 象 的 值 。 指 针 常 量 强 调 的 是 指 针 的 不 可 改 变 性 , 而 常 量 指 针 强 调 的 是 指 针 对 其 所 指 对 象 的 不 可 改 变 性 。 注 意 : 无 论 是 指 针 常 量 还 是 常 量 指 针 , 其 最 大 的 用 途 就 是 作 为 函 数 的 形 式 参 数 , 保 证 实 参 在 被 调 用 函 数 中 的 不 可 改 变 特 性 。 22 简述队列和栈的异同 队 列 和 栈 都 是 线 性 存 储 结 构 , 但 是 两 者 的 插 入 和 删 除 数 据 的 操 作 不 同 , 队 列 是 “ 先 进 先 出 ” , 栈 是 “ 后 进 先 出 ” 。 注 意 : 区 别 栈 区 和 堆 区 。 堆 区 的 存 取 是 “ 顺 序 随 意 ” , 而 栈 区 是 “ 后 进 先 出 ” 。 栈 由 编 译 器 自 动 分 配 释 放 , 存 放 函 数 的 参 数 值 , 局 部 变 量 的 值 等 。 其 操 作 方 式 类 似 于 数 据 结 构 中 的 栈 。 堆 一 般 由 程 序 员 分 配 释 放 , 若 程 序 员 不 释 放 , 程 序 结 束 时 可 能 由 https://mdnice.com 7/28
2020/8/3 让微信排版变 Nice O S 回 收 。 分 配 方 式 类 似 于 链 表 。 它 与 本 题 中 的 堆 和 栈 是 两 回 事 。 堆 栈 只 是 一 种 数 据 结 构 , 而 堆 区 和 栈 区 是 程 序 的 不 同 内 存 存 储 区 域 。 23 设置地址为0x67a9 的整型变量的值为0xaa66 int *ptr; ptr = (int *)0x67a9; *ptr = 0xaa66; 注 意 : 这 道 题 就 是 强 制 类 型 转 换 的 典 型 例 子 , 无 论 在 什 么 平 台 地 址 长 度 和 整 型 数 据 的 长 度 是 一 样 的 , 即 一 个 整 型 数 据 可 以 强 制 转 换 成 地 址 指 针 类 型 , 只 要 有 意 义 即 可 。 24 编码实现字符串转化为数字 编 码 实 现 函 数 a t o i ( ) , 设 计 一 个 程 序 , 把 一 个 字 符 串 转 化 为 一 个 整 型 数 值 。 例 如 数 字 : “ 5 4 8 6 3 2 1 ” , 转 化 成 字 符 : 5 4 8 6 3 2 1 。 int myAtoi(const char * str) { int num = 0; //保存转换后的数值 int isNegative = 0; //记录字符串中是否有负号 int n =0; char *p = str; if(p == NULL) //判断指针的合法性 { return -1; } while(*p++ != '\0') //计算数字符串度 { n++; } p = str; if(p[0] == '-') //判断数组是否有负号 { isNegative = 1; } char temp = '0'; for(int i = 0 ; i < n; i++) { char temp = *p++; if(temp > '9' ||temp < '0') //滤除非数字字符 { https://mdnice.com 8/28
分享到:
收藏