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.简单阐述你了解的排序算法?
排序的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。