c++面试题总结(1)
1、int a=5,则 ++(a++)的值是()
A、5 B、 6 C、7 D、逻辑错误
a++返回的是一个临时变量,这里是右值,不能再前面++了
2、下面的代码输出什么?(取地址运算符比+运算符的优先级要高)
- int main(void)
- {
- int a[5] = {1, 2, 3, 4, 5};
- int *ptr = (int *)(&a+1);
- printf("%d %d",*(a+1),*(ptr-1));
- return 0;
- }
A、1 6 B、2 4 C、2 5 D、1 5
&a是一个指向数组的指针(行指针),a的步长就是数组的长度。也就是说执行a+1时,a要跨过n个整型数据的长度,输出*ptr就会发现越界了,是一个随机值,那么ptr-1的值就是数组的最后一个值了。
&a+1不是首地址+1, 系统会认为加一个a数组的偏移, 是偏移了一个数组的大小(本例是5个int )
int *ptr = (int *)(&a+1);
则ptr实际上是&(a[5]),也就是a+5
原因如下:
&a 是数组指针, 其类型为int (*)[5];
而指针加1要根据指针类型加上一定的值, 不同类型的指针+1之后增加的大小不同。
a 是长度为5的int数组指针,所以要加5*sizeof(int)
所以,ptr实际是ptr[5]
但是ptr与(&a+1)类型时不一样的(这点很重要)
所以ptr-1只会减去sizeof(int *)
a, &a的地址是一样的,但是意思不一样
a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址
a+1是数组下一元素的地址,即a[1], &a+1是下一个对象的地址,即a[5].
3、以下三条输出语句分别输出什么?
- char str1[] = "abc";
- char str2[] = "abc";
- const char str3[] = "abc";
- const char str4[] = "abc";
- const char* str5 = "abc";
- const char* str6 = "abc";
- cout << boolalpha << ( str1==str2 ) << endl; // 输出什么?
- cout << boolalpha << ( str3==str4 ) << endl; // 输出什么?
- cout << boolalpha << ( str5==str6 ) << endl; // 输出什么?
答:分别输出false,false,true。str1和str2都是字符数组,每个都有其自己的存储区,它们的值则是各存储区首地址,不等;str3和str4同上,只是按const语义,它们所指向的数据区不能修改。str5和str6并非数组而是字符指针,并不分配存储区,其后的“abc”以常量形式存于静态数据区,而它们自己仅是指向该区首地址的指针,所以相等。
4、下面代码的输出是什么?
- float a = 1.0f;
- cout<< (int)a <<endl;
- cout<< (int&)a <<endl;
- cout << boolalpha << ( (int)a==(int&)a ) << endl; // 输出什么?
- float b = 0.0f;
- cout<< (int)b <<endl;
- cout<< (int&)b <<endl;
- cout << boolalpha << ( (int)b==(int&)b ) << endl; // 输出什么?
浮点数的 1.0f 在内存里是这样表示的:
0011 1111 1000 0000 00000000 00000000
这个32位二进制数被当作整数输出就是:
1065353216
而整数的 1 在内存里是这样表示的:
0000 0000 0000 0000 00000000 00000001
所以 (int)a != (int&)a
浮点的0和整数的0 在内存里都是:
0000 0000 0000 0000 00000000 00000000
所以 (int)b == (int&)b
5、以下代码中的两个sizeof用法有问题吗?
- void UpperCase( char str[] ) // 将str 中的小写字母转换成大写字母
- {
- for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )
- {
- if( 'a'<=str[i] && str[i]<='z' )
- {
- str[i] -= ('a'-'A' );
- }
- }
- }
- int main(void)
- {
- char str[] = "aBcDe";
- cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;
- UpperCase( str );
- cout << str << endl;
- return 0;
- }
6、非C++内建型别A和B,在哪几种情况下B能隐式转化为A?
7、以下代码有什么问题?
- struct Test
- {
- Test(int ) { }
- Test() { }
- void fun() { }
- };
- int main(void)
- {
- Test a(1);
- a.fun();
- Test b();
- b.fun();
- return 0;
- }
8、以下代码有什么问题?
- cout<< (true?1:"0") <<endl;
9、以下代码能够编译通过吗,为什么?
- int main(void)
- {
- unsigned int const size1 = 2;
- char str1[ size1 ];
- unsigned int temp = 0;
- cin >> temp;
- unsigned int const size2 = temp;
- char str2[ size2 ];
- return 0;
- }
10、以下反向遍历array数组的方法有什么错误?
- int main(void)
- {
- vector array;
- array.push_back( 1 );
- array.push_back( 2 );
- array.push_back( 3 );
- for( vector::size_type i=array.size()-1; i>=0; --i ) // 反向遍历array数组
- {
- cout << array[i] << endl;
- }
- return 0;
- }
11、以下代码中的输出语句输出吗,为什么?
- struct CLS
- {
- int m_i;
- CLS(int i): m_i( i ) { }
- CLS()
- {
- CLS( 0 );
- }
- };
- int main(void)
- {
- CLS obj;
- cout << obj.m_i << endl;
- return 0;
- }
12、C++中的空类,默认产生哪些类成员函数?
13、 以下代码有什么问题吗?
- int main(void)
- {
- typedef vector IntArray;
- IntArray array;
- array.push_back( 1 );
- array.push_back( 2 );
- array.push_back( 2 );
- array.push_back( 3 );
- // 删除array数组中所有的2
- for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
- {
- if( 2 == *itor )
- {
- array.erase( itor );
- }
- }
- return 0;
- }
14、 写一个函数,完成内存之间的拷贝。[考虑问题是否全面]
答案:
4、分别输出false和true。注意转换的应用。(int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是,(int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。因为以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。对b的两种转换意义同上,但是的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。
注意,程序的输出会显示(int&)a=1065353216,这个值是怎么来的呢?前面已经说了,以浮点数形式存放在内存中,按ieee754规定,其内容为x0000803F(已考虑字节反序)。这也就是a这个变量所占据的内存单元的值。当(int&)a出现时,它相当于告诉它的上下文:“把这块地址当做整数看待!不要管它原来是什么。”这样,内容x0000803F按整数解释,其值正好就是(十进制数)。
通过查看汇编代码可以证实“(int)a相当于重新构造了一个值等于a的整型数”之说,而(int&)的作用则仅仅是表达了一个类型信息,意义在于为cout<<及==选择正确的重载版本。
5、答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为个字节,因此返回。
6、答:
a. class B : public A { ……} // B公有继承自A,可以是间接继承的
b. class B { operator A( ); } // B实现了隐式转化为A的转化
c. class A { A( const B& ); } // A实现了non-explicit的参数为B(可以有其他带默认值的参数)构造函数
d. A& operator= ( const A& ); // 赋值操作,虽不是正宗的隐式类型转换,但也勉强算一个
7、答:变量b定义出错。按默认构造函数定义对象,不需要加括号。
8、答:三元表达式“?:”问号后面的两个操作数必须为同一类型。
9、答:str2定义出错,size2非编译器期间常量,而数组定义要求长度必须为编译期常量。
注释:经过测试,原作者这里解释有误,测试结果这个可以题编译能够通过, 虽然感觉好像是不能通过的, 但是后来想了下, 因为变量给const常量复制, const常量得到其对应的值的拷贝,
后面不能更改。 所以还是可以编译通过,同时str2获得的大小也是输入的值大小!
10、答:首先数组定义有误,应加上类型参数:vector<int> array。其次vector::size_type被定义为unsigned int,即无符号数,这样作为循环变量的i为0时再减就会变成最大的整数,导致循环失去控制。
- int main(void)
- {
- vector<int> array;
- array.push_back(1);
- array.push_back(2);
- array.push_back(3);
- for(int i = array.size() - 1 ; i >= 0 ; --i)
- cout<<array[i]<<endl;
- return 0;
- }
11、答:不能。在默认构造函数内部再调用带参的构造函数属用户行为而非编译器行为,亦即仅执行函数调用,而不会执行其后的初始化表达式。只有在生成对象时,初始化表达式才会随相应的构造函数一起调用。
注释:这个是有输出的,应该是一个随机数字。后面解释确实是对的
12、
- class Empty
- {
- public:
- Empty(); //缺省构造函数
- Empty(const Empty &); //拷贝构造函数
- ~Empty(); //析构函数
- Empty & operator=(const Empty &); //赋值运算符
- Empty* operator&(); //取址运算符
- const Empty* operator&() const; //取址运算符const
- };
13、答:同样有缺少类型参数的问题。另外,每次调用“array.erase(itor);”,被删除元素之后的内容会自动往前移,导致迭代漏项,应在删除一项后使itor--,使之从已经前移的下一个元素起继续遍历。
- int main(void)
- {
- typedef vector<int> IntArray;
- IntArray array;
- array.push_back( 1 );
- array.push_back( 2 );
- array.push_back( 2 );
- array.push_back( 3 );
- // 删除array数组中所有的2
- for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
- {
- if( 2 == *itor )
- {
- itor = array.erase( itor );
- itor--;
- }
- }
- return 0;
- }
注释:单单就这一道题来讲,这样是可以的,但是如果2在第一位或者最后一位仍然会有问题
14、
- // 功能:由src所指内存区域复制count个字节到dest所指内存区域。
- // 说明:src和dest所指内存区域可以重叠,但复制后dest内容会被更改。函数返回指向dest的指针
- void *memmove(void *dest , const void *src , size_t count)
- {
- assert( (dest != NULL) && (src != NULL)); //安全检查
- assert( count > 0 );
- char *psrc = (char *) src;
- char *pdest = (char *) dest;
- //检查是否有重叠问题
- if( pdest < psrc )
- {
- //正向拷贝
- while( count-- )
- *pdest++ = *psrc++;
- }
- else if( psrc < pdest )
- {
- //反向拷贝
- psrc = psrc + count - 1;
- pdest = pdest + count - 1;
- while( count-- )
- *pdest-- = *psrc--;
- }
- return dest;
- }
- // 功能:由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。
- // 说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针
- void *memmcpy(void *dest , const void *src , size_t count)
- {
- assert( (dest != NULL) && (src != NULL)); //安全检查
- assert( count > 0 );
- char *psrc = (char *) src;
- char *pdest = (char *) dest;
- while( count-- )
- *pdest++ = *psrc++;
- return dest;
- }
c++面试题总结(1)的更多相关文章
- .NET面试题系列[8] - 泛型
“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...
- 关于面试题 Array.indexof() 方法的实现及思考
这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...
- 对Thoughtworks的有趣笔试题实践
记得2014年在网上看到Thoughtworks的一道笔试题,当时觉得挺有意思,但是没动手去写.这几天又在网上看到了,于是我抽了一点时间写了下,我把程序运行的结果跟网上的答案对了一下,应该是对的,但是 ...
- 从阿里巴巴笔试题看Java加载顺序
一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...
- JAVA面试题
在这里我将收录我面试过程中遇到的一些好玩的面试题目 第一个面试题:ABC问题,有三个线程,工作的内容分别是打印出"A""B""C",需要做的 ...
- C++常考面试题汇总
c++面试题 一 用简洁的语言描述 c++ 在 c 语言的基础上开发的一种面向对象编程的语言: 应用广泛: 支持多种编程范式,面向对象编程,泛型编程,和过程化编程:广泛应用于系统开发,引擎开发:支持类 ...
- .NET面试题系列[4] - C# 基础知识(2)
2 类型转换 面试出现频率:主要考察装箱和拆箱.对于有笔试题的场合也可能会考一些基本的类型转换是否合法. 重要程度:10/10 CLR最重要的特性之一就是类型安全性.在运行时,CLR总是知道一个对象是 ...
- 我们公司的ASP.NET 笔试题,你觉得难度如何
本套试题共8个题,主要考察C#面向对象基础,SQL和ASP.NET MVC基础知识. 第1-3题会使用到一个枚举类,其定义如下: public enum QuestionType { Text = , ...
- 我设计的ASP.NET笔试题,你会多少呢
本笔试题考查范围包括面向对象基础.HTML.CSS.JS.EF.jQuery.SQL.编码思想.算法等范围. 第1题:接口和抽象类有何区别? 第2题:静态方法和实例方法有何区别? 第3题:什么是多态? ...
- 猫哥网络编程系列:详解 BAT 面试题
从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...
随机推荐
- Python3 学习第五弹:类与面向对象
对于面向对象总是要提到,万物皆对象.好似博大精深的感觉. 接下来一起看看python的面向对象的例子 创建一个对象 class Person: type = 'person' def __init__ ...
- android开发找不到模拟器(PANIC: Could not open:)解决办法
android开发找不到模拟器(PANIC: Could not open:)解决办法 2013/4/3 17:44:15 0人评论 213次浏览 分类:android开发 在系统环境变量设置名为 ...
- 编写jquery插件的分享
一.类级别($.extend) 类级别你可以理解为拓展jquery类,最明显的例子是$.ajax(...),相当于静态方法. 开发扩展其方法时使用$.extend方法,即jQuery.extend(o ...
- HTTP使用BASIC认证的原理及实现方法
一. BASIC认证概述 在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份证的方法,当一个客户端向HTTP服务器进行数据请求时,如果客户 ...
- UVa 575 Skew Binary 歪斜二进制
呵呵,这个翻译还是很直白的嘛,大家意会就好. 第一次看到这个高大上题目还是有点小害怕的,还好题没有做过深的文章. 只要按照规则转化成十进制就好了,而且题目本身也说了最大不超过一个int的范围(2^31 ...
- asp.net webpage
一.服务器脚本基础介绍 首先,我们先复习一下Web服务器页面的基本执行方式: 1. 客户端通过在浏览器的地址栏敲入地址来发送请求到服务器端 2. 服务器接收到请求之后,发给相应的服务器端页面(也就是脚 ...
- find命令下的atime,ctime,mtime
Linux下的find命令在目录结构中搜索文件,并执行指定的操作.linux下的find命令提供了相当多的查找条件,功能很强大,由于find的功能很强大,所以他的选项也很多,今天我们来细说一下find ...
- LeetCode Linked List Cycle II 单链表环2 (找循环起点)
题意:给一个单链表,若其有环,返回环的开始处指针,若无环返回NULL. 思路: (1)依然用两个指针的追赶来判断是否有环.在确定有环了之后,指针1跑的路程是指针2的一半,而且他们曾经跑过一段重叠的路( ...
- for...else循环
如果for循环完整结束,无break打断循环,那么执行else里面的内容,否则不执行. while True: n = raw_input('>') for x in n: if x == 'f ...
- MySQL基础之第16章 数据备份与还原
16.1.数据备份 16.1.1.使用 mysqldump 命令备份 mysqldump [OPTIONS] database [tables]mysqldump [OPTIONS] --databa ...