C / C++ 面试题

15 全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?

  • 全局变量是整个程序都可访问的变量,谁都可以访问,生存期在整个程序从运行到结束(在程序结束时所占内存释放);
  • 而局部变量存在于模块(子程序,函数)中,只有所在模块可以访问,其他模块不可直接访问,模块结束(函数调用完毕),局部变量消失,所占据的内存释放。
  • 操作系统和编译器,可能是通过内存分配的位置来知道的,全局变量分配在全局数据段并且在程序开始运行的时候被加载.局部变量则分配在堆栈里面。

16 简述C、C++程序编译的内存分配情况

  • 从静态存储区域分配:

内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在。速度快、不容易出错, 因为有系统会善后。例如全局变量,static 变量,常量字符串等。

  • 在栈上分配:

在执行函数时,函数内局部变量的存储单元都在栈上创建,函数执行结束时这些存储单元自动被释 放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。大小为2M。

  • 从堆上分配:

即动态内存分配。程序在运行的时候用 malloc 或new 申请任意大小的内存,程序员自己负责在何 时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活。如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,另外频繁地分配和释放不同大小的堆空间将会产生 堆内碎块。

一个C、C++程序编译时内存分为5 大存储区:堆区、栈区、全局区、文字常量区、程序代码区。

17 简述strcpy、sprintf 与memcpy 的区别

  • 操作对象不同,strcpy 的两个操作对象均为字符串,sprintf 的操作源对象可以是多种数据类型, 目的操作对象是字符串,memcpy 的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。
  • 执行效率不同,memcpy 最高,strcpy 次之,sprintf 的效率最低。
  • 实现功能不同,strcpy 主要实现字符串变量间的拷贝,sprintf 主要实现其他数据类型格式到字 符串的转化,memcpy 主要是内存块间的拷贝。

「注意」 :strcpy、sprintf 与memcpy 都可以实现拷贝的功能,但是针对的对象不同,根据实际需求,来 选择合适的函数实现拷贝功能。

18 请解析( (void ( )( ) )0)( )的含义

  • void (*0)( ) :是一个返回值为void,参数为空的函数指针0。
  • (void (*)( ))0:把0转变成一个返回值为void,参数为空的函数指针。
  • (void ( )( ))0:在上句的基础上加*表示整个是一个返回值为void,无参数,并且起始地址为0的函数的名字。
  • ((void ( )( ))0)( ):这就是上句的函数名所对应的函数的调用。

19 C语言的指针和引用和c++的有什么区别?

  • 指针有自己的一块空间,而引用只是一个别名;
  • 使用sizeof看一个指针的大小是4,而引用则是被引用对象的大小;
  • 作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引 用的修改都会改变引用所指向的对象;
  • 可以有const指针,但是没有const引用;
  • 指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能 被改变;
  • 指针可以有多级指针(**p),而引用止于一级;
  • 指针和引用使用++运算符的意义不一样;
  • 如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄露。

20 typedef 和define 有什么区别

  • 用法不同:typedef 用来定义一种数据类型的别名,增强程序的可读性。define 主要用来定义 常量,以及书写复杂使用频繁的宏。
  • 执行时间不同:typedef 是编译过程的一部分,有类型检查的功能。define 是宏定义,是预编译的部分,其发生在编译之前,只是简单的进行字符串的替换,不进行类型的检查。
  • 作用域不同:typedef 有作用域限定。define 不受作用域约束,只要是在define 声明后的引用 都是正确的。
  • 对指针的操作不同:typedef 和define 定义的指针时有很大的区别。

「注意」 :typedef 定义是语句,因为句尾要加上分号。而define 不是语句,千万不能在句尾加分号。

21 指针常量与常量指针区别

指针常量是指定义了一个指针,这个指针的值只能在定义时初始化,其他地方不能改变。常量指针 是指定义了一个指针,这个指针指向一个只读的对象,不能通过常量指针来改变这个对象的值。指针常量强调的是指针的不可改变性,而常量指针强调的是指针对其所指对象的不可改变性。

「注意」 :无论是指针常量还是常量指针,其最大的用途就是作为函数的形式参数,保证实参在被调用 函数中的不可改变特性。

22 简述队列和栈的异同

队列和栈都是线性存储结构,但是两者的插入和删除数据的操作不同,队列是"先进先出",栈是 "后进先出"。

「注意」 :区别栈区和堆区。堆区的存取是"顺序随意",而栈区是"后进先出"。栈由编译器自动分 配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。堆一般由程序员 分配释放, 若程序员不释放,程序结束时可能由OS 回收。分配方式类似于链表。它与本题中的堆和栈是两回事。堆栈只是一种数据结构,而堆区和栈区是程序的不同内存存储区域。

23 设置地址为0x67a9 的整型变量的值为0xaa66

int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa66;

「注意」 :这道题就是强制类型转换的典型例子,无论在什么平台地址长度和整型数据的长度是一样的, 即一个整型数据可以强制转换成地址指针类型,只要有意义即可。

24 编码实现字符串转化为数字

编码实现函数atoi(),设计一个程序,把一个字符串转化为一个整型数值。例如数字:"5486321 ", 转化成字符:5486321。

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') //滤除非数字字符
{
continue;
}
if(num !=0 || temp != '0') //滤除字符串开始的0 字符
{
temp -= 0x30; //将数字字符转换为数值
num += temp *int( pow(10 , n - 1 -i) );
}
}
if(isNegative) //如果字符串中有负号,将数值取反
{
return (0 - num);
}
else
{
return num; //返回转换后的数值
}
}

25 C语言的结构体和C++的有什么区别

  • C语言的结构体是不能有函数成员的,而C++的类可以有。
  • C语言的结构体中数据成员是没有private、public和protected访问限定的。而C++的类的成员有这些访问限定。
  • C语言的结构体是没有继承关系的,而C++的类却有丰富的继承关系。

「注意」 :虽然C的结构体和C++的类有很大的相似度,但是类是实现面向对象的基础。而结构体只可以简单地理解为类的前身。

相关推荐
坐吃山猪26 分钟前
Electron02-Hello
开发语言·javascript·ecmascript
BBB努力学习程序设计26 分钟前
Java输入输出:让程序能与世界“对话”
java
Mr Lee_27 分钟前
Smali 文件生成dex装箱算法整合
开发语言·python·算法
电饭叔28 分钟前
《python语言程序设计》2018版--第8章14题利用字符串输入作为一个信用卡号之一(Luhn算法解释)
android·java·python
阿宁又菜又爱玩29 分钟前
Web后端开发入门
java·spring boot·后端·web
Z3r4y31 分钟前
【代码审计】JeecgBoot-3.5.0 四处安全问题分析
java·web安全·代码审计·jeecg-boot
wangmengxxw32 分钟前
微服务-服务配置
java·运维·微服务·云计算·服务配置
姓刘的哦1 小时前
RK3568开发板运行Qt
开发语言·qt
刘晓倩1 小时前
Python3的Sequence
开发语言·python