这是我第一次面试笔试题,因为题目不多,并且都是些老生常谈的题目,于是我便在这记录了下来。一来可以分享下我的经历,二来也可以做为巩固。题目就六个,可以尝试自己回答,参考答案我已经给出(基本出自《牛叉公司面试题集之C和C++版本.pdf》)。
1、 static全局变量与普通的全局变量有什么区别?static 局部变量和普通局部变量有什么区别?static 函数与普通函数有什么区别?
答: 1) 全局变量(外部变量)的说明之前再冠以 static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
2) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了作用范围。
3) static 函数与普通函数作用域不同,仅在本文件。只在当前源文件中明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包综上所述:
static全局变量与普通的全局变量有什么区别:
static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:
static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
2、c中内存分为那几个区分别有什么作用。内存分配有哪几种。
答:1)栈:用来存放函数的形参和函数内的局部变量。由编译器分配空间,在函数执行完后由编译器自动释放。2)堆:用来存放由动态分配函数(如malloc)分配的空间。是由程序员自己手动分配的,并且必须由程序员使用free释放。如果忘记用free释放,会导致所分配的空间一直占着不放,导致内存泄露。3)全局局:用来存放全局变量和静态变量。存在于程序的整个运行期间,是由编译器分配和释放的。4)文字常量区:例如char *c = “123456”;则”123456”为文字常量,存放于文字常量区。也由编译器控制分配和释放。程序代码区:用来存放程序的二进制代码。
内存分配方式有三种:
[1]从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
[2]在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
[3]从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大小的堆空间将会产生堆内碎块。
3、设有以下说明和定义:
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 data)+sizeof(max));的执行结果是:52
答:DATE 是一个 union, 变量公用空间. 里面最大的变量类型是 int[5], 占用 20 个字节. 所以它的大小是20. data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32. 所以结果是 20 + 32 = 52. 当然…在某些 16 位编辑器下, int 可能是 2字节,那么结果是 int2 + DATE10 + double8 = 20
4、请写出一个函数实现字符串反转。例如:输入“abcd”倒序后变为“dcba”输出。
int main()
{
char* src = “hello,world”;
int len = strlen(src);
char* dest = (char*)malloc(len+1);//要为分配一个空间
char* d = dest;
char* s = &src[len-1]; //指向最后一个字符
while( len– != 0 )
*d++=*s–;
*d = 0; //尾部要加’ ’
printf(“%sn”,dest);
free(dest); // 使用完,应当释放空间,以免造成内存汇泄露
dest = NULL; //防止产生野指针
return 0;
}
可怜我还用VC6.0
下面是运行结果。
结果多了个n. 是因为 printf(“%sn”,dest);
%s后面多了个n
应该是
5、请写一个函数用于判断断处理器大小端。
void checkCPU()
{
union w
{
int a;
char b;
}c;
c.a = 1;
if (c.b == 1 ) {
printf(“Little_endiann”);
}
else
printf(“Big_endiann”);
}
linux内核中在arch/arm/kernel/setup.c中有这样的定义:
static union { char c[4]; unsigned long l; } endian_test __initdata = { { ’l’, ’?’, ’?’, ’b’ } };
#define ENDIANNESS ((char)endian_test.l)
可以仿着写,这样你印象更好。
6、写个函数实现冒泡排序。
//时间复杂度为0(n*n);
void BubbleSort(elemtype x[],int n)
{
Int i,j;
BOOL exchange; //记录交换标志
for(i=1;i<n;++i) //最多做n-1趟排序
{
Exchange = false;
For(j=n-1;j>=i;–j)
{
If(x[j]>x[j+1])
{
x[0] = x[j];
X[j] = x[j+1];
X[j+1] = x[0];
Exchange = true; //发生了交换,设置标志为真.
}
}
if (!Exchange ) //为发生替换,提前终止算法
return;
}
}