C/C++常见笔试面试题之常考关键字

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/owen7500/article/details/52693011

C/C++常见笔试面试题之常考关键字

1.描述volatile的作用

答:volatile主要是用来指示编译器不要对自己修饰的对象执行优化,警告编译器被修饰的变量可能被出乎意料的修改。volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知因素更改,比如:操作系统、硬件或者其他线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再执行优化,从而可以提供对特殊地质的稳定访问。对于一般情况下,变量可能被优化存储在寄存器中,最近的下次需要使用时直接读取寄存器即可,但是这个过程中,该变量所在的内存地址存储的变量可能已经被外部改变,如操作系统、硬件等。而volatile修饰的变量就不会被优化存储在寄存器中,而是每次直接读取内存中的最新值。

2.const关键字有哪些用途,它和static有哪些区别?

答:对于const关键字,它主要是用来定义一个只读变量。 const关键字至少有下列n个作用:
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。

对于static关键字,则是用于声明一个具有全局生命周期的静态变量。且该值只可以被初始化一次,但可以被修改。static关键字至少有下列n个作用:
(1)设置变量的存储域,函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)限制变量的作用域,在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)限制函数的作用域,在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

3.const和#define有什么区别,大多数情况下那种更优?

答:const是用于定义一个有类型的只读常变量。而#define是宏定义,是在编译期间对定义的变量进行直接文本替换,不做类型检查。变量定义时,大多数情况下const相对于#define来说有着更优的表现效果。基于以下几点原因:
1.const对数据进行类型检查,#define不进行类型检查;
2.某些编译器支持对const对象进行调试,所有编译器都不支持对#define进行调试;
3.const变量存放在内存的静态数据区域,所以在程序运行期间const变量只有一个拷贝,而#define修饰的变量则会在每处都进行展开,拥有多个拷贝;

其余区别:
1.#define可以用来定义宏函数,而const不行。
2.const除了可以修饰常变量外,还可以用于修饰指针、函数形参等等,修饰功能更强大。

4.C++中引用编译过的C代码为什么需要“extern C”

答:主要目的是为了解决函数名字匹配保证兼容性。由于C++支持函数重载,而C语言不支持函数重载,C语言中函数编译后得到的汇编代码中函数名与原函数名基本相同,如func()编译后成为_func,重载函数经过编译后得到函数名并不是原来的函数名,而是函数与参数类型的结合,因此两者函数调用的方式不一样。为了C++中能够调用C中的代码,使用extern C来表明对于包括函数采用C语言的方式调用,而不采用C++的方式调用。
extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数extern “C”是连接申明(linkage declaration),被extern “C”修饰的变量和函数是按照C语言方式编译和连接的。

5.sizeof是函数还是关键字?

答:sizeof 是运算符关键字,sizeof可以采用 sizeof int;的使用方式。

6.new/delete是函数吗?它们和malloc/free有何区别?

答:new/delete是C++中的运算符,malloc/free是C标准库中提供的函数。他们都是用于动态申请内存和释放内存的组合。它们的主要区别有:
1.malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符
2.new能够自动分配空间大小
3.对于用户自定义的对象而言,用maloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++需要一个能对对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存工作的运算符delete—简而言之 new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能。

7.new/delete和malloc/free会初始化内存和清空内存内容吗?

答:new操作会调用对象的构造函数初始化内存区域,但malloc只负责申请内存不会初始化。(但在vs平台上测试时,发现malloc申请的内存会被初始化为一个特殊的数:cdcdcdcd(4字节整数))。delete操作会调用对象的析构函数,并释放空间,而free只负责释放空间,两者在释放空间时,默认情况下不会清空原有内容(这就是新内存中值为随机数的原因)。(vs平台下测试发现,delete和free两者操作后都会清除原来的空间,并赋值为另一个特殊的数:feeefeee(四字节整数))
测试代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

int main()
{
    int *p = (int*)malloc(10 * sizeof(int));
    int *q = new int[10];

    for (int i = 0; i < 10;++i)
    {
        p[i] = i;
        q[i] = i;
    }

    delete q;
    free(p);
    system("pause");
    return 0;
}

测试截图:
申请内存之后的结果:
这里写图片描述
赋值之后内存区域结果:
这里写图片描述
释放之后内存区域结果:
这里写图片描述

7.struct和class有哪些区别?struct可以实现class的功能吗?

答:struct关键字继承自C语言,class是C++独有。在C++中两者最主要区别在于申明类时的默认权限不同,struct默认的权限是public,class的默认权限是private。在C++中class还可以用于申明模板类型,而struct不能。

展开阅读全文

没有更多推荐了,返回首页