嵌软笔试面试——经典题
零值
1、请填写 bool , float, 指针变量 与“零值”比较的 if语句。
提示:这里“零值”可以是 0, 0.0 , FALSE 或者“空指针”。例如 int 变量 n 与“零值”比较的 if 语句为: if ( n == 0 ) if ( n != 0 ) 以此类推。
(1) 请写出 bool flag 与“零值”比较的 if 语句:
【标准答案】if ( flag ) if ( !flag )
如下写法不得分
if(flag == TRUE) || if(flag == 1) || if(flag == FLASE) || if(flag == 0)
**(2)**请写出 float x 与“零值”比较的 if 语句:
【标准答案】 const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x <= EPSINON)
不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。
如下写法不得分
if( x == 0.0) || if(x != 0.0)
(3) 请写出 char *p 与“零值”比较的 if 语句
【标准答案】 if (p == NULL) if (p != NULL)
如下写法不得分
if(p == 0) || if(p)
sizeof计算
以下为 Linux下的 32 位 C程序,请计算 sizeof 的值。
char str[] = “Hello” ; char *p = str ; int n = 10;
请计算
(1)sizeof (str ) = (2)sizeof ( p ) =
(3) sizeof ( n ) =
【标准答案】(1)6、(2)4、(3)4
(4) void Func ( char str[100]){}
请计算 sizeof( str ) =
(5) void *p = malloc( 100 );
请计算sizeof ( p ) =
【标准答案】(4)4、(5)4
变量定义
用变量a给出下面的定义
e) 一个有10个指针的数组,该指针是指向一个整型数的;
f) 一个指向有10个整型数数组的指针 ;
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数;
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数;
【标准答案】
e)int * a[10];
f)int (*a)[10] *
*g)int (*a)(int);
h) int (*a[10])(int)
分析代码
设有以下说明和定义:
1 2 3 4 5 6
typedef union { long i; int k[5]; char c; } DATE; struct data { int cat; DATE cow; double dog; } too; DATE max;
则语句 printf("%d",sizeof(struct date)+sizeof(max));的执行结果是:
【标准答案】DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20
data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32.
所以结果是 20 + 32 = 52.
当然…在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20
请问以下代码有什么问题:
1 2 3 4 5 6 7 8
int main() { char a; char *str=&a; strcpy(str,"hello"); printf(str); return 0; }
【标准答案】没有为str分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。
请问以下代码有什么问题:
1 2 3 4
char* s="AAA"; printf("%s",s); s[0]='B'; printf("%s",s);
有什么错?
【标准答案】“AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。
cosnt char* s=“AAA”;
然后又因为是常量,所以对是s[0]的赋值操作是不合法的。
|
|
|
|
请简述以下两个 for 循环的优缺点。
数组和链表的区别
数组:数据顺序存储,固定大小;
链表:数据可以随机存储,大小可动态改变
解释代码
int (*s[10])(int) 表示的是什么啊
【标准答案】int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。
c和c++中的struct有什么不同?
【标准答案】c和c++中struct的主要区别是c中的struct 不可以含有成员函数,而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同, struct默认为public,而class默认为private
1 2 3 4 5 6 7 8
int main() { int x=3; printf("%d",x); return 1; } // 问函数既然不会被其它函数调用,为什么要返回1? 【标准答案】mian中,c标准认为0表示成功,非0表示错误。具体的值是某中具体出错信息。
struct计算
|
|
分析(指针)
|
|
指针
|
|
内存分析
堆栈溢出一般是由什么原因导致的?
【标准答案】没有回收垃圾资源。
关于内存的思考题(1)你能看出有什么问题?
volatile
关键字volatile有什么含意? 并给出三个不同的例子。
【参考答案】一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量
3). 多线程应用中被几个任务共享的变量
关键字volatile有什么含意?
【标准答案】提示编译器对象的值可能在编译器未监测到的情况下改变。
头文件
头文件中的 ifndef/define/endif 干什么用?
【标准答案】防止该头文件被重复引用。
#include <filename.h> 和 #include “filename.h” 有什么区别?
【标准答案】对于#include <filename.h> ,编译器从标准库路径开始搜索 filename.h ;
对于#include “filename.h” ,编译器从用户的工作路径开始搜索 filename.h 。
如何引用一个已经定义过的全局变量?
【标准答案】可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了
,那么在编译期间会报错,如果你用extern方式引用
时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
【标准答案】可以,在不同的C文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。
const & static
const 有什么用途?(请至少说明两种)
【标准答案】:
(1)可以定义 const 常量
(2)const 可以修饰函数的参数、返回值,甚至函数的定义体。被 const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
static有什么用途?(请至少说明两种)
【标准答案】
- 限制变量的作用域(static全局变量);
- 设置变量的存储域(static局部变量)。
A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
【标准答案】static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
他们都放在静态数据区,但是编译器对他们的命名是不同的。
如果要使变量在其他模块也有意义的话,需要使用extern关键字。
static全局变量与普通的全局变量有什么区别?
【标准答案】 static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别
【标准答案】static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别?
【标准答案】static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
堆栈
队列和栈有什么区别?
【标准答案】队列先进先出,栈后进先出。
Heap与stack的差别。
【标准答案】Heap是堆,stack是栈。
Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。Stack空间有限,Heap是很大的自由存储区C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行
程序的局部变量存在于栈(stack)中,全局变量存在于静态数据区 中,动态申请数据存在于**堆( heap)**中。
用两个栈实现一个队列的功能?要求给出算法和思路!
【参考答案】设2个栈为A,B, 一开始均为空. 入队:
将新元素push入栈A; 出队:
(1) 判断栈B是否为空;
(2) 如果不为空,则将栈A中所有元素依次pop出并push到栈B;
(3) 将栈B的栈顶元素pop出;
宏&编译
用宏定义写出swap(x,y),即交换两数。
【标准答案】
#define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);
写一个“标准”宏,这个宏输入两个参数并返回较小的一个。
【标准答案】#define Min(X, Y) ((X)>(Y)?(Y):(X))//结尾没有;
用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
【参考答案】#define SECONDS_PER_YEAR (60 * 60* 24 * 365)UL
已知一个数组table,用一个宏定义,求出数据的元素个数。
【标准答案】
#define NTBL(table) (sizeof(table)/sizeof(table[0]))
什么是预编译,何时需要预编译:
【标准答案】1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如,思考一下下面的例子:
#define dPS struct s * typedef struct s * tPS;
以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?
【参考答案】这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子:
dPS p1,p2; tPS p3,p4;
第一个扩展为
struct s * p1, p2;
上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。
extern “C”
在 C++ 程序中调用被 C 编译器编译后的函数, 为什么要加 extern “C”?
【标准答案】C++语言支持函数重载,C 语言不支持函数重载。函数被 C++编译后在库中的名字与 C 语言的不同。假设某个函数的原型为: void foo(int x, int y); 该函数被 C 编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int 之类的名字。 C++ 提供了 C 连接交换指定符号 extern“C”来解决名字匹配问题。
代码分析2
|
|
- 找出程序的错误
|
|
other
|
|
代码编写
|
|