您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 招聘面试 > 《程序员面试宝典》集锦
《程序员面试宝典》集锦新浪微博:@雪静胡天1、C语言中的printf()函数是怎么计算参数的?C语言中的printf()函数计算参数时是从右到左压栈的。例:inta[]={6,7,8,9,10};int*p=a;printf(“%d%d\n”,*p,*(p++));printf(“%d%d\n”,*p,*(++p));输出结果7688解析:指针初始化指向数组第一个元素,即*p=6,由于printf()函数计算参数时是从右到左压栈的,先计算*(p++),该表达式等价于*p=6,p++,即先将6压栈,再执行p++,此时*p=7,故再将7进行压栈,输出时7和6先后出栈,故先输出7再输出6;第二条输出语句也是一样,注意此时指针指向7,先计算*(++p),该表达式等价于p++,*p=8,故将8进行压栈,此时依然有*p=8,故第二次压栈的依然是8,输出时两个8先后出栈,故先后输出两个8。2、if语句中常量相等条件比较判断应注意什么?应将常量写在前面例:if(‘A’==a)int*p=(int*)malloc(sizeof(int)*8);if(NULL==p)解析:如果出于疏忽把“==”写成“=”的话,因为编译器不允许对常量进行赋值,就可以检查到错误。3、什么是强制类型转换?当操作数的类型不同,而且不属于基本数据类型时,经常需要将操作数转化为所需要的类型,这个过程即为强制类型转换。强制类型转换具有两种形式:显式强制转换和隐式强制类型转换。(1)显式强制类型转换C中显式强制类型转换很简单,格式如下:TYPEb=(TYPE)a;其中,TYPE为类型描述符,如int,float等。经强制类型转换运算符运算后,返回一个具有TYPE类型的数值,这种强制类型转换操作并不改变操作数本身,运算后操作数本身未改变。(2)隐式强制类型转换a、执行算术运算时,低类型(短字节)可以转换为高类型(长字节);例如:int型转换成double型,char型转换成int型等等;b、赋值表达式中,等号右边表达式的值的类型自动隐式地转换为左边变量的类型,并赋值给它;c、函数调用时,将实参的值传递给形参,系统首先会自动隐式地把实参的值的类型转换为形参的类型,然后再赋值给形参;d、函数有返回值时,系统首先会自动隐式地将返回表达式的值的类型转换为函数的返回类型,然后再赋值给调用函数返回;隐式强制转换两个通用的指导原则:a、为防止精度失损,如果必要的话,类型总是被提升为较宽的类型;b、所有含有小于整型的有序类型的算术表达式在计算之前其类型都会被转换成整型;4、运算符的优先级是怎么排序的?优先级运算符名称或含义使用形式结合方向说明1[]数组下标数组名[整型表达式]左到右()圆括号(表达式)/函数名(形参表).成员选择(对象)对象.成员名-成员选择(指针)对象指针-成员名2-负号运算符-表达式右到左单目运算符(类型)强制类型转换(数据类型)表达式++自增运算符++变量名/变量名++单目运算符--自减运算符--变量名/变量名--单目运算符*取值运算符*指针表达式单目运算符&取地址运算符&左值表达式单目运算符!逻辑非运算符!表达式单目运算符~按位取反运算符~表达式单目运算符sizeof长度运算符sizeof表达式/sizeof(类型)3/除表达式/表达式左到右双目运算符*乘表达式*表达式双目运算符%余数(取模)整型表达式%整型表达式双目运算符4+加表达式+表达式左到右双目运算符-减表达式-表达式双目运算符5左移表达式表达式左到右双目运算符右移表达式表达式双目运算符6大于表达式表达式左到右双目运算符=大于等于表达式=表达式双目运算符小于表达式表达式双目运算符=小于等于表达式=表达式双目运算符7==等于表达式==表达式左到右双目运算符!=不等于表达式!=表达式双目运算符8&按位与整型表达式&整型表达式左到右双目运算符9^按位异或整型表达式^整型表达式左到右双目运算符10|按位或整型表达式|整型表达式左到右双目运算符11&&逻辑与表达式&&表达式左到右双目运算符12||逻辑或表达式||表达式左到右双目运算符13?:条件运算符表达式1?表达式2:表达式3右到左三目运算符14=赋值运算符变量=表达式右到左/=除后赋值变量/=表达式*=乘后赋值变量*=表达式%=取模后赋值变量%=表达式+=加后赋值变量+=表达式-=减后赋值变量-=表达式=左移后赋值变量=表达式=右移后赋值变量=表达式&=按位与后赋值变量&=表达式^=按位异或后赋值变量^=表达式|=按位或后赋值变量|=表达式15,逗号运算符表达式,表达式,…左到右从左向右顺序运算基本的优先级需要记住:指针最优,单目运算优于双目运算。如正负号。先乘除(模),后加减。先算术运算,后移位运算,最后位运算。请特别注意:13+2&7等价于(1(3+2))&7.逻辑运算最后计算。5、位运算符的特殊应用有哪些?例1:用一个表达式判断一个数X是不是2的N次方(2,4,8,16,„),不可用循环语句解析:2,4,8,16这样的数转换为二进制是10,100,1000,10000.如果X减1后与X做与运算,结果为0,那么X就为2的N次方。答案:!(X&(X-1))例2:下面代码:Intf(intx,inty){Return(x&y+(x^y)1);}F(729,271)=解析:x&y是取x和y的相同位,x^y是取x和y的不同同位,右移相当于除2,所以这个函数的功能是取两个数的平均值答案:(729+271)/2=500例3:如何将a,b的值进行交换,并且不使用任何中间变量解析:a=(a^b)^b,b=(a^b)^a答案:a=a^b;b=a^b;a=a^b;6、C语言和C++各自的特点是什么?C是一种结构化的语言,重点在于算法和数据结构。C程序的设计者首先考虑的是如何通过一个过程,对输入进行运算处理得到输出,而对于C++,首先要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。7、在C/C++中,const的用法有哪些?(1)在C程序中,const主要有定义常量、修饰函数参数、修饰函数返回值;(2)在C++程序中,const可以修饰类中的常成员函数和定义常对象,常成员函数不能更新对象的数据成员,也不能调用该类中没有用const修饰的普通成员函数,常对象必须初始化,并且不能更新,常对象只能调用它的常成员函数,而不能调用普通函数。const可以实现函数重载。const修饰的常量必须初始化。8、#define宏定义的使用应注意哪些?#define不能以分号结尾,要注意给每个变量加上括号9、const常量和#define宏定义有什么区别?(1)const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只能进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误(边际效应)。(2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++程序中只使用const常量而不是用宏常量,即const完全可以取代宏常量。10、sizeof的定义及其用法?sizeof是C/C++中的一个操作符(operator),简单的说其作用就是返回一个对象或者类型所占的内存字节数。例1:inta[100]={0};int*p;p=a;printf(%d%d\n,sizeof(p),sizeof(a));输出结果是多少?答案:4400例2:classA1{public:inta;staticintb;};coutsizeof(A1)endl;解析:静态变量是存放在全局数据区的,sizeof(A1)在计算的时候是不会计算在内的,所以栈区相当于只有a一个变量答案:4例3:inta=1;staticb=2;typedefstruct{intc;staticintd;}ABC;voidmain(){inte=1;staticf=2;ABCabc;printf(%d\n,sizeof(a));printf(%d\n,sizeof(b));printf(%d\n,sizeof(abc));printf(%d\n,sizeof(abc.c));printf(%d\n,sizeof(abc.d));printf(%d\n,sizeof(e));printf(%d\n,sizeof(f));}问:输出什么?解析:原子数据类型(整型、字符型、浮点型)无论存储在全局数据区还是在栈区,sizeof都会计算其实际所占字节数大小;而复合数据类型(类、结构体)不一样,当有成员数据类型定义为静态的时候(静态变量存储于全局数据区),在sizeof计算的时候只计算存储于栈区部分所占字节数大小答案:4444444例:4:classBase1{public:virtualvoidf(int){coutBase::f(int)endl;}};classBase2:publicvirtualBase1{private:doublea;inti;};coutsizeof(Base2)endl;//输出多少?解析:基类Base1含有虚函数会涉及虚指针,占4个字节,子类Base2是从基类Base1虚继承的,也会涉及虚指针,占4个字节,double类型占8个字节,int占4个字节,由于字节对齐原则,所以一共有24个字节答案:2411、什么是数据对齐?(1)现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。(2)访问数据的地址要满足一定的条件,能被这个数据的长度所整除。例如,1字节数据已经是对齐的,2字节的数据的地址要被2整除,4字节的数据地址要被4整除。(3)数据对齐并不是操作系统的内存结构的一部分,而是CPU结构的一部分。(4)当CPU访问正确对齐的数据时,它的运行效率最高。当数据大小的数据模数的内存地址是0时,数据是对齐的。例如,WORD值应该总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,如此等等。当CPU试图读取的数据值没有正确对齐时,CPU可以执行两种操作之一。即它可以产生一个异常条件,也可以执行多次对齐的内存访问,以便读取完整的未对齐数据值。12、strlen的用法strlen返回一个类型为size_t的值,用来计算字符串中所包含字符的个数。strlen的返回类型是在头文件stddef.h中定义的,它是一个无符号类型整数。13、sizeof和strlen的使用区别?(1)sizeof的操作符的结果类型是size_t,它在头文件中的typedef为unsignedint类型。该类型保证能容纳实现所建立的最大对象的字节大小。(2)sizeof是运算符,strlen是函数。(3)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以“\0”结尾的。sizeof()还可以用函数做参数,返回sizeof(函数返回值类型)的值。(4)数组做sizeof的参数不退化,传递给strlen就退化为指针。(5)大部分编译程序在编译的时候就把sizeof计算过了,是类型或者变量的长度。这就是sizeof(x)可以用来定义数组维数的原因。(6)strlen的结果是要在运行的时候才能计算出来,用来计算字符串的长度,而不是类型占内存的大小。(7)sizeof后如果是类型必须加括号,如果是变量名可以不加括号。这是因为sizeof是个操作数而不是个函数。(8)当使用了一个结构类型或者变量时,sizeof返回实际大小。当使用一静态的空间数组时,sizeof返回全部数组的尺寸。sizeof操作符不能返回被动态分配的数组或外部数组的尺寸。(9)数组作为参数传给函数时传的是指针而不是数组,传递的是数组
本文标题:《程序员面试宝典》集锦
链接地址:https://www.777doc.com/doc-1040362 .html