考研复试 - C语言
1.局部变量能否和全局变量重名?
能,局部会屏蔽全局。要用全局变量,需要使用"::"
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
2.如何引用一个已经定义过的全局变量?
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量名写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
3.全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错
4.语句for( ;1 ;)有什么问题?它是什么意思?
和while(1)相同。(无限循环)
5.do……while和while有什么区别?
前一个循环一遍再判断,后一个判断以后再循环
6.static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
7.程序的局部变量存在于(堆栈)中,全局变量存在于(静态区)中,动态申请数据存在于(堆)中。
8.队列和栈有什么区别?
队列先进先出,栈后进先出
9.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
C用宏定义,C++用inline
10.结构体和类的区别
- 类可以继承,结构体不可以
- 类是引用类型,结构体是值类型
- 类在堆中分配内存,结构体在栈中分配内存
11.构造函数和析构函数
构造函数的功能是在创建对象时,使用给定的值来将对象初始化。
析构函数的功能是用来释放一个对象的。在对象删除前,用它来做一些清理工作,它与构造函数的功能正好相反。
12.面向对象的三大特征
面向对象的三大特征:
- 封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
- 继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。
- 多态性:多态性是指允许不同类的对象对同一消息作出响应。比如同样的加法,把两个时间加在一起和把两个整数加在一起肯定完全不同。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
13.什么是预编译?何时需要预编译?
预编译又称预处理,是整个编译过程最先做的工作,即程序执行前的一些预处理工作。主要处理#开头的指令。如拷贝#include包含的文件代码、替换#define定义的宏、条件编译#if等。
何时需要预编译:
- 总是使用不经常改动的大型代码体。
- 程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
14.static关键字的作用?
Static的用途主要有两个,一是用于修饰存储类型使之成为静态存储类型,二是用于修饰链接属性使之成为内部链接属性。
- 静态存储类型:
在函数内定义的静态局部变量,该变量存在内存的静态区,所以即使该函数运行结束,静态变量的值不会被销毁,函数下次运行时能仍用到这个值。
在函数外定义的静态变量——静态全局变量,该变量的作用域只能在定义该变量的文件中,不能被其他文件通过extern引用。 - 内部链接属性: 静态函数只能在声明它的源文件中使用。
15.const关键字的作用?
- 声明常变量,使得指定的变量不能被修改。
- 修饰函数形参,使得形参在函数内不能被修改,表示输入参数
- 修饰函数返回值,使得函数的返回值不能被修改。
16.c和c++ 中struct的主要区别
c中的struct不可以含有成员函数,而c++ 中的struct可以。
c++ 中struct和class的主要区别在于默认的存取权限不同,
struct默认为public ,而class默认为private
17.数组和链表的区别?
数组属于顺序存储的线性表 访问块 大小限定
链表属于链式存储的线性表 删除插入块 大小可动态改变
【标准答案】
数组:数据顺序存储,固定大小;
链表:数据可以随机存储,大小可动态改变
18.结构体的赋值?
C语言中对结构体变量的赋值或者在初始化或者在定义后按字段赋值。
19.三种基本的数据模型?
按照数据结构类型的不同,将数据模型划分为层次模型、网状模型和关系模型。
20.多进程与多线程?
- 进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。
- 线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
- 两者都可以提高程序的并发度,提高程序运行效率和响应时间。
- 线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
21.C语言中程序结构包括三种:
顺序结构 、 循环结构 、 选择结构
22.C语言是由什么构成的?基本单位是什么?
由函数构成,基本单位也是是函数
23.堆栈溢出一般是由什么原因导致的?
【标准答案】没有回收垃圾资源。
24.不能做switch()的参数类型是:
switch的参数不能为实型。
注:必须是整数型常量,包括char,short,int,long等,不能是浮点数。
25.模块化准则
把一个大问题分解为许多小问题,每个小问题由一个函数来解决,每个函数都完成一个特定的功能,各个小问题应该尽量独立,即所谓高内聚,低耦合。函数内部应该是高内聚,完成一些紧密相关的任务,函数之间应该只有一些非常必要的联系,即低耦合。
26.C语言中指针的作用
C语言指针的作用很多,最直接的就是直接操作内存
直接操作内存的优点:
- 效率更高,因为是直接操作内存
- 可以写复杂度更高的数据结构,程序员可以操作内存
- 编写出简洁,紧凑,高效的程序
27.指针和引用的区别是什么?传值,传引用和传地址的区别是什么?
- 指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。
- 指针是一个实体,而引用仅是个别名
- 指针可以改变所指的对象,而引用只能在定义时被初始化一次,之后不可以变。
- 指针可以为空,不存在指向空值的引用
- 指针不必初始化,引用必须初始化
- 指针传递也叫值传递,引用传递的是地址
- 从内存分配来看:程序为指针变量分配内存区域,而引用不需要
-
- 传值:堆栈中开辟了内存空间,以存放由主调函数放进来的实参的值,从而形成了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
- 传引用:(变量的别名)真正的以地址的方式传递参数,传递之后,形参和实参都是同一个对象,只是他们的名字不同而已,对形参的修改将影响实参的值。
- 传地址:传地址之后实参和形参都指向同一个对象。
28.常量指针、指针常量
- 常量指针:首先是一个指针,是一个指向常量的指针, const int *p = &a;指针所指向的地址内容是不可修改的
- 作用:设置常量指针指向一个常量,防止出现修改常量的误操作;
- 指针常量:首先是一个常量,再才是个指针,常量的性质是不能修改的,指针的内容实际是一个地址,那么指针常量就是内容不可修改的常量,不能修改这个指针所指向的地址,一开始初始化,指向哪就只能指向哪。
- 不可改变地址的指针,但是可以对它所指向的内容进行修改。
29.什么是野指针,如何避免,野指针和空指针的区别
“野指针”不是NULL指针,而是指向“垃圾”的内存指针。
其主要原因:指针变量没有被初始化,或者指针p被free或者delete之后,没有置为NULL;
如何避免出现野指针:
- 把指针指向NULL
- 使用malloc分配内存
空指针:是一个特殊的指针值,也是唯一一个对应任何指针类型都合法的指针值,指针变量具有空指针值,表示他当时处于闲置状态,没有指向有意义的东西。
30.递归和迭代的区别
递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己.
迭代:利用变量的原值推算出变量的一个新值.
如果递归是自己调用自己的话,迭代就是A不停的调用B.递归中一定有迭代,但是迭代中不一定有递归,大部分可以相互转换.能用迭代的不用递归,递归调用函数,浪费空间,并且递归太深容易造成堆栈的溢出.
31.引用”与指针的区别是什么?
- 指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;
- 而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
32.在什么时候需要使用“常引用”?
解析:如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const类型标识符 &引用名=目标变量名;
33.简述数组与指针的区别
解析:数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
34.什么是高内聚低耦合
耦合:是对一个软件结构内各个模块之间相互依赖程度的度量;耦合的强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。
内聚:则标志一个模块内各个元素彼此结合的紧密程度;内聚从功能角度衡量模块内的联系,好的内聚模块应当恰好做一件事。
耦合性与内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事,它描述的是模块内的功能联系;耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。
35.评价算法的指标
1.正确性2.可读性3.健壮性4效率与低存储量
36.将“引用”作为函数返回值类型的好处
好处:在内存中不产生被返回值的副本;
37.如何判断一棵二叉树是否是平衡二叉树
如何判断一棵二叉树是否是平衡二叉树 问题:判断一个二叉排序树是否是平衡二叉树
38.串的三种存储结构
- 定长顺序存储表示
- 堆分配存储表示
- 链式存储结构
39.线性表和广义表的区别和联系
线性表是广义表的特例,当广义表中的元素均为原子时,广义表即为线性表。
40.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
为了告诉c++编译器,这个函数要到c库中去找。
41.链表中头指针、头结点的作用
头结点是为了操作的方便设立的,头指针是指向第一个结点的指针。