C语言程序设计
1.简述C语⾔采取了哪些措施提⾼执⾏效率
●使⽤指针:有些程序⽤其他语⾔也可以实现,但C能够更有效地实现;有些程序⽆法⽤其它语⾔实现,如直接访问硬件,但C却可以。正因为指针可以拥有类似于汇编的寻址⽅式,所以可以使程序更⾼效。
●使⽤宏函数:宏函数仅仅作为预先写好的代码嵌⼊到当前程序,不会产⽣函数调⽤,所以仅仅是占⽤了空间,⽽使程序可以⾼效运⾏。在频繁调⽤同⼀个宏函数的时候,该现象尤其突出。函数和宏函数的区别就在于,宏函数占⽤了⼤量的空间,⽽函数占⽤了时间。
●使⽤位操作:位操作可以减少除法和取模的运算。在计算机程序中数据的位是可以操作的最⼩数据单位,理论上可以⽤"位运算"来完成所有的运算和操作。灵活的位操作可以有效地提⾼程序运⾏的效率。
●将汇编指令嵌⼊到 C 语⾔程序中,汇编语⾔是效率最⾼的计算机语⾔,因此在C语⾔程序中嵌⼊汇编,从⽽充分利⽤⾼级语⾔和汇编语⾔各⾃的特点。
●系统调用:在C语⾔程序中可以调⽤操作系统级的 API,从⽽提⾼程序的运⾏效率。
●条件编译:C语⾔源程序中加上条件编译,让编译器只对满⾜条件的代码进⾏编译,将不满⾜条件的代码舍弃,可以减少编译及执行程序代码量。
●网游之五行牧师循环嵌套中将较长循环设为内置循环,较短循环设为外置循环,以减少cpu跨切循环层的次数,提⾼程序的运⾏效率。 (操作系统页⾯置换相关,减少页⾯置换次数)
2.if…else和switch区别
总结:都是条件选中语句。但switch语句只能取代if语句的一部分功能。
●比较的范围不同:
if 语句可做各种关系比较(只要是 boolean 表达式都可以用 if 判断)
switch语句只能做等式比较,即只能对基本类型进行数值比较。 (switch只能做几个数据类型的等式比较,实现非等式效率低,)
switch之后括号内的表达式只能是整型(byte、short、char和int)、枚举型或字符型表达式,不能是长整型或其他任何类型。
●效率不同:
if 语句每次判断都要读写寄存器一次,判断多效率低。
switch 一次性读取要判断的值,判断多效率高
⼆维数组在逻辑上是⼆维的,在物理上是⼀维的
4.隐式类型转换的四种情况
1、算术运算式中,低类型能够转换为高类型
2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给它
3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参
4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋给调用函数
5.数组越界产生什么后果
数组越界,将会把数据存放到一个未知的区域,而这个未知的区域如果恰好是系统很重要的位置,可能了就会修改系统程序导致系统出错甚至是崩溃,如果这个位置不是和系统有关,可能结果并不明显或者没有产生影响,但为了系统安全需要进行数组下标越界检查。
6.结构体和联合体的区别
联合体是构造数据类型,用几个不同类型的变量共占一段内存,所占内存长度是各最长成员占的内存长度。
结构体是构造数据类型,把不同类型的数据组合成一个整体,所占内存长度是各成员占的内存长度的总和。
7.结构体对⻬规则
1. 数组成员对⻬规则。第⼀个数组成员应该放在offffset为0的地⽅,以后每个数组成员应
该放在offffset 为min(当前成员的⼤⼩,#pargama pack(n))整数倍的地⽅开始(⽐如int在32位机器为4字节,#pargama pack(2),那么从2的倍数地⽅开始存储)。
2. 结构体总的⼤⼩,也就是sizeof的结果,必须是min(结构体内部最⼤成员,#pargama pack(n))的整数倍,不⾜要补⻬。
3. 结构体做为成员的对⻬小年夜是几号规则。如果⼀个结构体B⾥嵌套另⼀个结构体A,还是以最⼤成员类型的⼤⼩对⻬,但是结构体A的起点为A内部最⼤成员的整数倍的地⽅。(struct B⾥存有struct A,A⾥有 char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对⻬规则仍 满⾜原则1、原则2。
8.指针在函数中的应用和特点
●指针作为函数参数:
函数之间参数的传递要对数据进行拷贝,而利用指针作为函数参数传递数据的本质,就是在主调函数和被调函数中,通过指向同一内存地址的不同指针(函数传值时拷贝了一个指针)访问相同的内存区域,从而实现数据的传递和交换。
●指针作为函数的返回值(指针型函数):
不能把一个指向局部变量的指针作为返回值,因为函数内部声明的局部变量在函数结束后其生命周期已经结束,内存会自动释放,这时它的内存地址无意义。如果将其作为函数返回值返回给主调函数并在主调函数中访问这个指针所指向的数据,将产生不可预料的后果。
9.C 语言变量种类
1、自动变量——在函数体内或复合语句中定义的非静态变量称为自动变量。
●C语言编译时,不对自动变量赋初值。
●当程序执行到自动变量的作用域时,程序才为自动变量分配空间。当定义自动变量的函数或复合语句执行结束后,程序释放自动变量的存储空间。
●自动变量保存在程序的动态存储空间。
2、静态局部变量——在函数体内或复合语句中用static定义的变量称为静态局部变量。
●C语言编译时,对静态局部变量赋初值。如懿传大结局
●静态局部变量存储在程序的静态存储空间。
●静态局部变量在程序的整个运行期间均占用程序的静态存储空间,直到程序退出后才释放存储空间。
3、寄存器变量——用register声明的变量。
4、外部变量(全局变量)——在函数的外部定义的变量。它的作用域是从定义处开始,到本程序文件的末尾结束,在此作用域内,全局变量可以为程序的各个函数引用。邓超鹿晗退出跑男
●C语言编译时,对全局变量赋初值。
●全局变量存储在程序的静态存储空间。
●全局变量在程序的整个运行期间均占用程序的静态存储空间,直到程序退出后才释放存储空间。
5、注意:
(1)当引用本源文件后面定义的全局变量或引用在其他源文件中定义的全局变量是,应在引用位置前,利用extern 声明该全局变量,以告诉编译器编译时,引用的是一个外部变量,在编译器连接时,将引用的外部变量的作用域扩展到本文件extern 声明处。
(2)用static 声明的全局变量,不能被其他文件引用。
10.程序的内存分配
答:一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式是类似于链表。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码
11.描述内存分配方式以及它们的区别?
1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多
12.简述数组与指针的区别?
答:数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指
向任意类型的内存块。
用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个 指针变量的字节数,而不是p 所指的内存容量。
13.构造类型有哪些种类?
1、构造类型——是由基本类型按照一定规则构造而成的。(如数组、结构体、共同体、枚举型)
2、构造类型的每个分量(元素),是一个变量,它可以是一个简单类型或者构造类型。
3、构造类型的分量占用相邻的存储空间。
14.函数调用参数传递方法有哪些?
1、值传递——如数值形参。此时,将实参值复制压栈,被调函数对复制到栈中的数值进行操作,不改变原来实参值。比如 void swap(int x,int y) 并不能交换两个参数值。
2、地址传递——如数组形参、指针形参),此时,将实参数组的首地址压栈,被调函数引用实参数组的首地址,到实参数组,对实参数组进行操作,改变实参数组值。即形参数组和实参数组共享同一单元。
3、引用型传递——如引用形参数void swap(int &x,int &y),可以完成值交换。用了引用变量后,就不再为形参开辟内存,所有操作都是直接修改实参变量。
15.变量的作用范围
1、局部变量——在定义局部变量的范围内有效。当局部变量重名时,有效范围小的优先。
●在函数内部定义局部变量
●函数的形式参数
●在某个复合语句中定义的变量。
2、全局变量——在函数之外定义的变量。有效范围是从定义变量的位置开始到源文件结束。
16.static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
●十大暴利行业static全局变量与普通的全局变量区别:全局变量的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别:
1.非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
2.把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
3.static全局变量只初使化一次,普通全局变量不初始化。
发布评论