面试题、笔试题总结
http://www.cnblogs.com/kex1n/archive/2011/10/19/2217342.html
1.进程地址空间分布
进程地址空间中最顶部的段是栈,大多数编程语言将之用于存储函数参数和局部变量。调用一个方法或函数会将一个新的栈帧(stack frame)压入到栈中,这个栈帧会在函数返回时被清理掉。
在栈的下方,是我们的内存映射段。内核将文件的内容直接映射到内存。任何应用程序都可以通过Linux的mmap()系统调用请求这种映射。内存映射是一种方便高效的文件I/O方式,所以它被用来加载动态库。创建一个不对应于任何文件的匿名内存映射也是可能的,此方法用于存放程序的数据。
接下来的一块内存空间是堆。
最后,我们看看底部的内存段:BSS,数据段,代码段。=>BSS、数据段统称为静态存储区
在C语言中,BSS和数据段保存的都是静态(全局)变量的内容。区别在于BSS保存的是未被初始化的静态变量内容,他们的值不是直接在程序的源码中设定的。如果你写static int cntActiveUsers,则cntActiveUsers的内容就会保存到BSS中去。而数据段则保存在源代码中已经初始化的静态变量的内容。所以,如果你写static int cntActiveUsers=10,则cntActiveUsers的内容就保存在了数据段中,而且初始值是10。
2.求某个数的开方
方法1: 遍历从1到N的数字,求取平方并和N进行比较。 如果平方小于N,则继续遍历;如果等于N,则成功退出;如果大于N,则失败退出。 复杂度为O(n^0.5)。
方法2: 使用二分查找法,对1到N之间的数字进行判断。 复杂度为O(log n)。
3.以下两个语句的区别是:第一个动态申请的空间里面的值是随机值,第二个进行了初始化,里面的值为0
int *p1 = new int[10]; int *p2 = new int[10]();
4.函数指针
定义一个函数指针:
void (*funcPtr)();
这个例子将funcPtr定义为一个指向函数的指针,这个函数没有参数,返回值为空。
注: *funcPtr 两侧的括号是必须的,如果去掉括号,
void *funcPtr(); // 这表示funcPtr是一个函数,它返回类型为 void*
由于直接定义一个函数指针显得冗长,我们可以使用typedef对其进行简化,如下:
typedef void (*FuncPtrType)();
此时我们将FuncPtrType定义为了一个函数指针类型,
接下来我们可以使用这个类型来定义变量:
FuncPtrType funcPtr; // 这个funcPtr与void (funcPtr*)();中的含义是一样的。
5.下面程序运行后的结果为:to test something
char str[] = "glad to test something"; char *p = str; p++; int *p1 = static_cast<int *>(p); p1++; p = static_cast<char *>(p1); printf("result is %s\n",p);