西邮移动应用开发实验室笔试题

来源:互联网 发布:淘宝默认几天自动付款 编辑:程序博客网 时间:2024/05/21 19:32
1.递归和循环有什么区别
递归算法: 
优点:代码简洁、清晰,并且容易验证正确性。(如果你真的理解了算法的话,否则你更晕)
缺点:它的运行需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理,比如参数传递需要压栈等操作,会对执行效率有一定影响。但是,对于某些问题,如果不使用递归,那将是极端难看的代码。
循环算法:
优点:速度快,结构简单。
缺点:并不能解决所有的问题。有的问题适合使用递归而不是循环。如果使用循环并不困难的话,最好使用循环。

总结1. 一般递归调用可以处理的算法,也通过循环去解决常需要额外的低效处理 。
2. 现在的编译器在优化后,对于多次调用的函数处理会有非常好的效率优化,效率未必低于循环。
2.数组的长度可以改变吗?为什么?
不可以。你定义数组的时候就已经规定了数组的大小了,用变量来做数组长度c是不允许的。但是我们可以用指针和malloc一起来动态分配数组实现伪动态数组。
3.结构体和共用体有什么区别?分别在什么场合使用?
共用体就是几个不同的变量共占于同一段内存的结构,其变量中,在每一个瞬时只能有一个起作用,也就是在某时里只能存储一个数据,当存入新的,本来的那个就被刷掉了,当数据使用两种或更多种格式(但不会同时使用)时,用它可以节省空间。
结构体是用户自定义的类型,比数组更灵活,同一个结构可以存储多种类型的数据,它用处很广,最常见的是用它保存一个记录。
两者通常结合在一起使用,实用性大大提高。
4.阐述你理解的atuo,static,register,exterm含义。
个 .c 文件会被编译为一个 .o 文件,这个就是一个编译单元。最后所有的编译单元被链接起来,就是一个库或一个程序。 
一 个变量/函数,只要是在全局声明的,链接之后都隐含地在所有编译单元中可见。但你的声明可能仅出现在一个 .c 文件中,这就暗示你不想把这个名字暴露给其它编译单元,这种情况下就得用 static 关键字,表示这个名字具有“内部链接”,只对当前编译单元有效。但还有一种可能,你确实想暴露这个名字,但其它的编译单元希望知道这个名字被声明为什么类 型,所以你需要在别的编译单元中用 extern 关键字描述这个声明,表示它具有“外部链接”,是在别的编译单元中定义的。不过通常的办法是在头文件中写出这个声明,让需要这个声明的文件包含它。 
static 代表“内部链接”,就是说这个变量是定义在编译单元上的,程序开始执行前就已经存在,所以会有“函数退出后仍保持值”的效果;与此相对,函数中定义的自动 变量是定义在栈上的,函数执行结束函数调用的活动记录就被清除。 

总结下来就是,extern/static 指出一个名字具有外部链接还是内部链接;名字的作用域只和名字被定义的位置有关。 

  C 语言中的每一个变量和函数有两个属性:数据类型和数据的存储类别。数据类型(整形、字符型等),存储类别是指数据在内存中存储的方法,存储方法有两大类: 静态存储类和动态存储类。具体包括四种:自动的(auto),静态的(static),寄存器的(register)和外部的(extern)。

 auto 变量:函数中的局部变量,如不专门声明static,一般都是动态地分配存储空间。自动变量:在调用该函数时系统会给他们分配存储空间,一旦函数调用结束 这些存储空间就会自动释放。关键字“auto”可以省略,不写则隐含确定为“自动存储类别”,属于动态存储方式。

 register 变量:一般变量的值都是存储在内存中,(当程序需要用到哪一个变量的值,由控制器发出指令将内存中该变量的值送到运算器,完了如果需要存数,再从运算器将 数据送到内存中存放。)所以就引出一个问题,如果我们进行一段频繁的运算,则存储变量的值肯定要花费不少时间,所以C语言允许将局部变量的值存放在寄存器 中,这样需要时就直接搬用,不必再进行过内存。提高运算速度。

5.break和continue有什么区别?分别在什么场合使用?

continue语句是不可以在单独的switch语句中使用,但可以在一个循环内的switch语句中使用。含有continue的循环语句,在遇到continue语句后,代码先不按照常规的从上往下的代码执行顺序执行,而是马上回到循环入口转入下一次循环。

break和continue语句在循环内的switch语句中使用时,break是跳出本switch,switch后面的代码继续执行,而continue是不执行switch后的代码,可以理解为跳出循环,接着进入下一次循环。

使用break语句,循环数次后便退出了循环。而没有使用break语句的话,循环要遍历完整个数组。而continue语句可以让你直接在遍历并查找符合条件的元素过程中直接处理这些符合条件的元素,而不用先找到符合条件的元素集,然后再在外面另外写方法重新遍历这些新找到的元素并做处理。



6.取余和取模有什么区别?

通常取模运算也叫取余运算,它们返回结果都是余数。rem和mod唯一的区别在于:

    当x和y的正负号一样的时候,两个函数结果是等同的;当x和y的符号不同时,rem函数结果的符号和x的一样,而mod和y一样。
这是由于这两个函数的生成机制不同,rem函数采用fix函数,而mod函数采用了floor函数(这两个函数是用来取整的,fix函数向0方向舍入,floor函数向无穷小方向舍入)




7.rand随机数是怎么产生的?

我感觉各种编程语言返回的随机数(确切地说是伪随机数)实际上都是根据递推公式计算的一组数值,当序列足够长,这组数值近似满足均匀分布。一般来说就是int array=math.random()。python中也有产生随机数,但是我不太懂这个。



8.简单阐述你了解的排序算法?

排序的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。

In-place sort(当需要对大量数据进行排序时,它不占用额外内存或占用常数的内存):插入排序、选择排序、冒泡排序、堆排序、快速排序。
Out-place sort:归并排序、计数排序、基数排序、桶排序。
stable sort:插入排序、冒泡排序、归并排序、计数排序、基数排序、桶排序。
unstable sort:选择排序(5 8 5 2 9)、快速排序、堆排序。



9.strlen实现原理?它和sizeof有什么区别?
sizeof 是C 语言的一种单目运算符,如++、--等,并不是函数,sizeof 的优先级为2 级,比/、% 等3 级运算符优先级高,sizeof以字节的形式给出操作数的存储空间的大小。而 strlen 是一个函数,是由 C 语言的标准库提供的。strlen 计算的  是字符串的长度。 




10.case与default子句可以变换顺序吗?
C语言中的switch语句是一种用于多分支选择的语句, 其一般形式为:switch(表达式){     case 常量表达式1:  语句1;    case 常量表达式2:  语句2;    …     case 常量表达式n:  语句n;    default:  语句n+1;}其语义是:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
在switch语句中,“case 常量表达式”只相当于一个语句标号, 表达式的值和某标号相等则转向该标号执行,但不能在执行完该标号的语句后自动跳出整个switch 语句,为了避免上述情况,C语言还提供了一种break语句,专用于跳出switch语句,break 语句只有关键字break,没有参数,在每一case语句之后增加break 语句, 使每一次执行之后均可跳出switch语句。



11.对于二维数组,按行遍历与按列遍历有什么区别?
对c语言而言,数组在内存中是按行储存的,按行遍历时可以由指向数组第一个数的指针一直往下走,就可以遍历完整个数组,其效率较高,而按列遍历则要获得指向每一列的第一行的元素的指针,然后每次将指针指下一行。另外,先列后行”遍历发生的页面交换次数要比“先行后列”多,且cache命中率相对较低。



12.说说你对数组与链表的理解?
数组和链表都是数据结构的一种,而他们最大的区别在于,使用数组能够快速访问数组中的每个元素,而使用链表可以方便的操纵每个数据项。 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。链表则动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项),如果再说的简单点的话,就是数组在内存中是逐个存放的,也就是说倘若数组的第一个元素在地址A,则数组第二个元素就在地址A+1。而链表则不是,链表每个节点没有相对固定的位置关系。某个节点在地址A其后的节点不一定是A+1,而在内存的其他空闲区域,呈现一种随机的状态。



13.指针是什么?指针的指针是什么?
我感觉指针其实就是变量,只不过指针变量指向的不是某个具体的值,而是指向这个值所在的内存的地址.指针和其它变量一样,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实际信息的内存地址。定义它的时候你需要在变量名称前加一个*p。
而指向指针的指针声明的是指针,只是这指针指向另一个指针。如int **p是声明p是一个指针,它指向一个指向int变量的指针。 再如b=**p是把指针p指向的指针所指变量值赋给b。而且指针的指针只有1个哦,类似p++、p--的操作都是不对的。



0 0
原创粉丝点击