1、1.new、delete、malloc、free关系delete会调用对象的析构函数,和new相应free只会释放内存,new调用构造函数。malloc与free是C+/C语言的标准库函数,new/delete是C+的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的规定。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不可以把执行构造函数和析构函数的任务强加于malloc/free。因此C+语言需要一个能完毕动态内存分派和初始化工作的
2、运算符new,以及一个能完毕清理与释放内存工作的运算符delete。注意new/delete不是库函数。2.delete与 delete 区别?delete只会调用一次析构函数,而delete会调用每一个成员的析构函数。在More Effective C+中有更为具体的解释:“当delete操作符用于数组时,它为每个数组元素调用析构函数,然后调用operatordelete来释放内存。”delete与New配套,delete 与new 配套 MemTest*mTest1=newMemTest10;MemTest*mTest2=newMemTest;int*pInt1=newint10; int
3、*pInt2=new int; deletepInt1; /-1- deletepInt2; /-2- deletemTest1;/-3- deletemTest2;/-4- 在-4-处报错。这就说明:对于内建简朴数据类型,delete和delete功能是相同的。对于自定义的复杂数据类型,delete和delete不能互用。delete删除一个数组,delete删除一个指针简朴来说,用new分派的内存用delete删除用new分派的内存用delete删除delete会调用数组元素的析构函数。内部数据类型没有析构函数,所以问题不大。假如你在用delete时没用括号,delete就会认为指向的是单
4、个对象,否则,它就会认为指向的是一个数组。3.C C+ JAVA共同点,不同之处?4.继承优缺陷。类继承是在编译时刻静态定义的,且可直接使用,类继承可以较方便地改变父类的实现。但是类继承也有一些局限性之处。一方面,由于继承在编译时刻就定义了,所以无法在运营时刻改变从父类继承的实现。更糟的是,父类通常至少定义了子类的部分行为,父类的任何改变都也许影响子类的行为。假如继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。(待补充)5.C+有哪些性质(面向对象特点)?封装,继承和多态。在面向对象程序设计语言中,封装是运用可重用成分构造软件
5、系统的特性,它不仅支持系统的可重用性,并且尚有助于提高系统的可扩充性;消息传递可以实现发送一个通用的消息而调用不同的方法;封装是实现信息隐蔽的一种技术,其目的是使类的定义和实现分离。6.子类析构时要调用父类的析构函数吗?析构函数调用的顺序是先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经所有销毁了。定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数;析构的时候恰好相反:先调用派生类的析构函数、然后调用基类的析构函数JAVA无析构函数深拷贝和浅拷贝 7.多态,虚函数,纯虚函数8.求下面函数的返回值(微软)int func(x) int countx = 0
6、; while(x) countx +; x = x&(x-1); return countx; 假定x = 9999。 答案:8。思绪:将x转化为2进制,看具有的1的个数。9.什么是“引用”?申明和使用“引用”要注意哪些问题?答:引用就是某个目的变量的“别名”(alias),对引用的操作与对变量直接操作效果完全相同。申明一个引用的时候,牢记要对其进行初始化。引用声明完毕后,相称于目的变量名有两个名称,即该目的原名称和引用名,不能再把该引用名作为其他变量名的别名。声明一个引用,不是新定义了一个变量,它只表达该引用名是目的变量名的一个别名,它自身不是一种数据类型,因此引用自身不占存储单元,系统也
7、不给引用分派存储单元。不能建立数组的引用。10.将“引用”作为函数参数有哪些特点?(1)传递引用给函数与传递指针的效果是同样的。这时,被调函数的形参就成为本来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目的对象(在主调函数中)的操作。(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分派存储单元,形参变量是实参变量的副本;假如传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。(3)使用指针作为函数的
8、参数虽然也能达成与使用引用的效果,但是,在被调函数中同样要给形参分派存储单元,且需要反复使用*指针变量名的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清楚。11.在什么时候需要使用“常引用”?假如既要运用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。常引用声明方式:const 类型标记符 &引用名=目的变量名;例1 int a ; const int &ra=a; ra=1; /错误 a=1; /对的 例2 string foo( ); void bar(string & s);
9、 那么下面的表达式将是非法的: bar(foo( ); bar(hello world); 因素在于foo( )和hello world串都会产生一个临时对象,而在C+中,这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型,这是非法的。引用型参数应当在能被定义为const的情况下,尽量定义为const 。12.将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?格式:类型标记符 &函数名(形参列表及类型说明) /函数体 好处:在内存中不产生被返回值的副本;(注意:正是由于这点因素,所以返回一个局部变量的引用是不可取的。由于随着该局部
10、变量生存期的结束,相应的引用也会失效,产生runtime error! 注意事项:(1)不能返回局部变量的引用。这条可以参照Effective C+1的Item 31。重要因素是局部变量会在函数返回后被销毁,因此被返回的引用就成为了无所指的引用,程序会进入未知状态。 (2)不能返回函数内部new分派的内存的引用。这条可以参照Effective C+1的Item 31。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分派内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分派)就无法释
11、放,导致memory leak。(3)可以返回类成员的引用,但最佳是const。这条原则可以参照Effective C+1的Item 30。重要因素是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值经常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。假如其它对象可以获得该属性的非常量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。(4)流操作符重载返回值申明为“引用”的作用:流操作符,这两个操作符经常希望被连续使用,例如:cout hello endl;因此这两个操作符的返回值应当是一个仍然支持这两个操作符的流引用。可
12、选的其它方案涉及:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个操作符事实上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用操作符。因此,返回一个流对象引用是惟一选择。这个唯一选择很关键,它说明了引用的重要性以及无可替代性,也许这就是C+语言中引入引用这个概念的因素吧。 赋值操作符=。这个操作符象流操作符同样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。例3i nclude int
13、&put(int n);int vals10;int error=-1;void main()put(0)=10; /以put(0)函数值作为左值,等价于vals0=10; put(9)=20; /以put(9)函数值作为左值,等价于vals9=20; coutvals0; cout=0 & n=9 ) return valsn; else coutsubscript error; return error; (5)在此外的一些操作符中,却千万不能返回引用:+-*/ 四则运算符。它们不能返回引用,Effective C+1的Item23具体的讨论了这个问题。重要因素是这四个操作符没有side
14、effect,因此,它们必须构造一个对象作为返回值,可选的方案涉及:返回一个对象、返回一个局部变量的引用,返回一个new分派的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,第2、3两个方案都被否决了。静态对象的引用又由于(a+b) = (c+d)会永远为true而导致错误。所以可选的只剩下返回一个对象了。13.“引用”与多态的关系?引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。例4 Class A; Class B : Class A.; B b; A & ref = b;14.“引用”与指针的区别是什么?1) 引用必须
15、被初始化,指针不必。 2) 引用初始化以后不能被改变,指针可以改变所指的对象。 2) 不存在指向空值的引用,但是存在指向空值的指针。指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用自身就是目的变量的别名,对引用的操作就是对目的变量的操作。此外,就是上面提到的对函数传ref和pointer的区别。15.什么时候需要“引用”?流操作符、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。以上 2-8 参考:16.结构与联合有和区别? (1). 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合
16、中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。(2). 对于联合的不同成员赋值, 将会对其它成员重写,本来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。17.面关于“联合”的题目的输出?a)i nclude unionint i;char x2;a;voidmain()a.x0 = 10; a.x1 = 1;printf(%d,a.i);答案:266 (低位低地址,高位高地址,内存占用情况是Ox010A)b) main() union /*定义一个联合*/ int i; struct /*在联合中定义一个结构*/ ch
17、ar first; char second; half; number; number.i=0x4241; /*联合成员赋值*/ printf(%c%cn, number.half.first, mumber.half.second); number.half.first=a; /*联合中结构成员赋值*/ number.half.second=b; printf(%xn, number.i); getch(); 答案: AB (0x41相应A,是低位;Ox42相应B,是高位)6261 (number.i和number.half共用一块地址空间)18.关联、聚合(Aggregation)以及组合
18、(Composition)的区别?涉及到UML中的一些概念:关联是表达两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;聚合表达has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表达聚合关系:从实现的角度讲,聚合可以表达为: class A . class B A* a; .而组合表达contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表达组合关系:实现的形式是: class A. class B A a; .27.main 函数执行以前,还会执行什么代码?答案:全局对象的构造函数
19、会在main 函数之前执行。28.描述内存分派方式以及它们的区别?1)从静态存储区域分派。内存在程序编译时就已经分派好,这块内存在程序的整个运营期间都存在。例如全局变量,static 变量。2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分派运算内置于解决器的指令集。3)从堆上分派,亦称动态内存分派。程序在运营时用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。29.struct 和 class 的区别答案:stru
20、ct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class 在其他方面是功能相称的。从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺少封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应当使用 struct 关键字,否则,你应当使用 class 关键字。 30.当一个类A 中没有任何成员变量与成员函数,这时sizeof(A)的值是多少?答案:假如不是零,请解释一下编译器为什么
21、没有让它为零。(Autodesk)肯定不是零。举个反例,假如是零的话,声明一个class A10对象数组,而每一个对象占用的空间是零,这时就没办法区分A0,A1了。值 为1.32.比较C+中的4种类型转换方式? 请参考:,重点是static_cast, dynamic_cast和reinterpret_cast的区别和应用。dynamic_casts在帮助你浏览继承层次上是有限制的。它不能被用于缺少虚函数的类型上,它被用于安全地沿着类的继承关系向下进行类型转换。如你想在没有继承关系的类型中进行转换,你也许想到static_cast44.写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函
22、数。KMP算法效率最佳,时间复杂度是(n+m),详见:48.指针找错题分析这些面试题,自身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的进一步剖析则可进一步增强自身的内功。2.找错题 试题1:以下是引用片段:void test1() /数组越界char string10;char* str1 = ;strcpy( string, str1 );试题2:以下是引用片段:void test2()char string10, str110; int i;for(i=0; i10; i+)str1= a;strcpy( string, str1 );试题3:以下是引用片段:void test
23、3(char* str1)char string10;if( strlen( str1 ) = 10 )strcpy( string, str1 );解答:试题1字符串str1需要11个字节才干存放下(涉及末尾的0),而string只有10个字节的空间,strcpy会导致数组越界;试题2,假如面试者指出字符数组str1不能在数组内结束可以给3分;假如面试者指出strcpy(string,str1)调用使得从 str1内存起复制到string内存起所复制的字节数具有不拟定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;对试题3,if(strlen(str1) = 10)应改为i
24、f(strlen(str1) 10),由于strlen的结果未记录0所占用的1个字节。剖析:考核对基本功的掌握(1)字符串以0结尾;(2)对数组越界把握的敏感度;(3)库函数strcpy的工作方式,49.假如编写一个标准strcpy函数?总分值为10,下面给出几个不同得分的答案:2分 以下是引用片段:void strcpy( char *strDest, char *strSrc )while( (*strDest+ = * strSrc+) != 0 );4分以下是引用片段:void strcpy( char *strDest, const char *strSrc )/将源字符串加cons
25、t,表白其为输入参数,加2分while( (*strDest+ = * strSrc+) != 0 );7分 以下是引用片段:void strcpy(char *strDest, const char *strSrc)/对源地址和目的地址加非0断言,加3分assert( (strDest != NULL) &(strSrc != NULL) );while( (*strDest+ = * strSrc+) != 0 );10分 以下是引用片段: /为了实现链式操作,将目的地址返回,加3分!char * strcpy( char *strDest, const char *strSrc )ass
26、ert( (strDest != NULL) &(strSrc != NULL) ); /对源地址和目的地址加非0断言char *address = strDest;while( (*strDest+ = * strSrc+) != 0 );return address; /为了实现链式操作,将目的地址返回从2分到10分的几个答案我们可以清楚的看到,小小的strcpy居然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才干写一个完美的strcpy啊!(4)对strlen的掌握,它没有涉及字符串末尾的0。读者看了不同分值的strcpy版本,应当也可以写出一个10分的strlen函数了, int
27、 strlen( const char *str ) /输入参数const以下是引用片段:assert( strt != NULL ); /断言字符串地址非0int len=0; /注,一定要初始化。while( (*str+) != 0 )len+;return len;试题4:以下是引用片段: void GetMemory( char *p )/内存分派p = (char *) malloc( 100 );void Test( void )char *str = NULL;GetMemory( str );strcpy( str, hello world );printf( str );
28、试题5:以下是引用片段: char *GetMemory( void )char p = hello world;return p;void Test( void )char *str = NULL;str = GetMemory();printf( str );试题6:以下是引用片段: void GetMemory( char *p, int num )*p = (char *) malloc( num );void Test( void )char *str = NULL;GetMemory( &str, 100 );strcpy( str, hello );printf( str );试
29、题7:以下是引用片段: void Test( void )char *str = (char *) malloc( 100 );strcpy( str, hello );free( str );. /省略的其它语句解答:试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完char *str = NULL; GetMemory( str );后的str仍然为NULL;试题5中char p = hello world;return p;的p数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误
30、,其根源在于不理解变量的生存期。试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句*p = (char *) malloc( num );后未判断内存是否申请成功,应加上: if ( *p = NULL ) ./进行申请内存失败解决试题7存在与试题6同样的问题,在执行char *str = (char *) malloc(100);后未进行内存是否申请成功的判断;此外,在free(str)后未置str为空,导致也许变成一个“野”指针,应加上: str = NULL;试题6的Test函数中也未对mallo
31、c的内存进行释放。剖析:试题47考察面试者对内存操作的理解限度,基本功扎实的面试者一般都能对的的回答其中5060的错误。但是要完全解答对的,却也绝非易事。 对内存操作的考察重要集中在: (1)指针的理解; (2)变量的生存期及作用范围; (3)良好的动态内存申请和释放习惯。再看看下面的一段程序有什么错误:以下是引用片段:swap( int* p1,int* p2 )int *p;*p = *p1;*p1 = *p2;*p2 = *p;在swap函数中,p是一个“野”指针,有也许指向系统区,导致程序运营的崩溃。在VC+中DEBUG运营时提醒错误“Access Violation”。该程序应当改为
32、以下是引用片段:swap( int* p1,int* p2 )int p;p = *p1;*p1 = *p2;*p2 = p;51.h头文献中的ifndef/define/endif 的作用?答:防止该头文献被反复引用。52.i nclude 与 i nclude file.h的区别?答:前者是从Standard Library的途径寻找和引用file.h,而后者是从当前工作途径搜寻并引用file.h。53.在C+ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?C+语言支持函数重载,C语言不支持函数重载。C+提供了C连接互换指定符号extern “C”解决名字匹配问题。一
33、方面,作为extern是C/C+语言中表白函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。通常,在模块的头文献中对本模块提供应其它模块引用的函数和全局变量以关键字extern声明。例如,假如模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文献即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目的代码中找到此函数。extern C是连接申明(linkage declaration),被extern C修饰的变量和函数是按照C语言方式编译和连接的
34、,来看看C+中对类似C的函数是如何编译的:作为一种面向对象的语言,C+支持函数重载,而过程式语言C则不支持。函数被C+编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为: void foo( int x, int y );该函数被C编译器编译后在符号库中的名字为_foo,而C+编译器则会产生像_foo_int_int之类的名字(不同的编译器也许生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C+就是靠这种机制来实现函数重载的。例如,在C+中,函数void foo( i
35、nt x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。同样地,C+中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量也许与全局变量同名,我们以.来区分。而本质上,编译器在进行编译时,与函数的解决相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。未加extern C声明时的连接方式假设在C+中,模块A的头文献如下:/ 模块A头文献moduleA.h#ifndef MODULE_A_H#define MODULE_A_Hint foo( int
36、 x, int y );#endif在模块B中引用该函数:/ 模块B实现文献moduleB.cppi nclude moduleA.hfoo(2,3);加extern C声明后的编译和连接方式加extern C声明后,模块A的头文献变为:/ 模块A头文献moduleA.h#ifndef MODULE_A_H#define MODULE_A_Hextern C int foo( int x, int y );#endif在模块B的实现文献中仍然调用foo( 2,3 ),其结果是:(1)模块A编译生成foo的目的代码时,没有对其名字进行特殊解决,采用了C语言的方式;(2)连接器在为模块B的目的代码
37、寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。假如在模块A中函数声明了foo为extern C类型,而模块B中包含的是extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。所以,可以用一句话概括extern “C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更进一步地理解许多问题):实现C+与C及其它语言的混合编程。明白了C+中extern C的设立动机,我们下面来具体分析ext
38、ern C通常的使用技巧:extern C的惯用法1)在C+中引用C语言中的函数和变量,在包含C语言头文献(假设为cExample.h)时,需进行下列解决: extern Ci nclude cExample.h而在C语言的头文献中,对其外部函数只能指定为extern类型,C语言中不支持extern C声明,在.c文献中包含了extern C时会出现编译语法错误。C+引用C函数例子工程中包含的三个文献的源代码如下:/* c语言头文献:cExample.h */#ifndef C_EXAMPLE_H#define C_EXAMPLE_Hextern int add(int x,int y);#e
39、ndif/* c语言实现文献:cExample.c */i nclude cExample.hint add( int x, int y )return x + y;/ c+实现文献,调用add:cppFile.cppextern Ci nclude cExample.hint main(int argc, char* argv)add(2,3);return 0;假如C+调用一个C语言编写的.DLL时,当涉及.DLL的头文献或声明接口函数时,应加extern C 。(2)在C中引用C+语言中的函数和变量时,C+的头文献需添加extern C,但是在C语言中不能直接引用声明了extern C的
40、该头文献,应当仅将C文献中将C+中定义的extern C函数声明为extern类型。C引用C+函数例子工程中包含的三个文献的源代码如下:/C+头文献 cppExample.h#ifndef CPP_EXAMPLE_H#define CPP_EXAMPLE_Hextern C int add( int x, int y );#endif/C+实现文献 cppExample.cppi nclude cppExample.hint add( int x, int y )return x + y;/* C实现文献 cFile.c/* 这样会编译犯错:i nclude cExample.h */int
41、main( int argc, char* argv )add( 2, 3 );return 0;15题目的解答请参考C+中extern “C”含义深层探索注解:几道c笔试题(含参考答案)1. What is displayed when f() is called given the code:class Number public:string type; Number(): type(“void”) explicit Number(short) : type(“short”) Number(int) : type(“int”) ;void Show(const Number& n) co
42、ut n.type; void f()short s = 42;Show(s); a) void b) short c) int d) None of the above选C;虽然传入的是short类型,但是short类型的构造函数被生命被explicit,也就是只能显示类型转换,不能使用隐式类型转换2. Which is the correct output for the following codedouble dArray2 = 4, 8, *p, *q;p = &dArray0;q = p + 1;cout q p endl; cout (int)q - (int)p endl;a)
43、 1 and 8 b) 8 and 4 c) 4 and 8 d) 8 and 1。第二个选A;第一个是指针加减,按照的是指向地址类型的加减,只跟类型位置有关,q和p指向的数据类型以实际数据类型来算差一个位置,因此是1。而第二个加减是实际指针值得加减,在内存中一个double类型占据8个字节,因此是854.Sony笔试题 1完毕下列程序 * *.*. *.*.*. *.*.*.*. *.*.*.*.*. *.*.*.*.*.*. *.*.*.*.*.*.*. *.*.*.*.*.*.*.*. #includeusing namespace std;#define N 8int main()int i,j,k;for(i=0;iN;i+)for(j=0;j=i;j+) cout*; for(k=0;ki;k+) cout.;coutendl;return 0;2完毕程序,实现对数组的降序排序 #includ