C++经典面试题
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非编译器期间常量,而数组定义要求长度必须为编译期常量。
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;
}
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++经典面试题的更多相关文章
- 李洪强iOS经典面试题156 - Runtime详解(面试必备)
李洪强iOS经典面试题156 - Runtime详解(面试必备) 一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...
- 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)
李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...
- 李洪强iOS经典面试题154- 通知与推送
李洪强iOS经典面试题154- 通知与推送 通知与推送 本地通知和远程推送通知对基本概念和用法? image 本地通知和远程推送通知都可以向不在前台运行的应用发送消息,这种消息既可能是即将发生的事 ...
- 李洪强iOS经典面试题153- 补充
李洪强iOS经典面试题153- 补充 补充 有空就来解决几个问题,已经懒癌晚期没救了... UML 统一建模语言(UML,UnifiedModelingLanguage)是面向对象软件的标准化建模 ...
- 李洪强经典面试题152-Runtime
李洪强经典面试题152-Runtime Runtime Runtime是什么 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码, ...
- 李洪强iOS经典面试题147-WebView与JS交互
李洪强iOS经典面试题147-WebView与JS交互 WebView与JS交互 iOS中调用HTML 1. 加载网页 NSURL *url = [[NSBundle mainBundle] UR ...
- 李洪强经典面试题145-Runloop
李洪强经典面试题145-Runloop Runloop 什么是 Runloop? 从字面上讲就是运行循环. 它内部就是do-while循环,在这个循环内部不断地处理各种任务. 一个线程对应一个Ru ...
- 李洪强iOS经典面试题144-数据存储
李洪强iOS经典面试题144-数据存储 数据存储 sqlite中插入特殊字符的方法和接收到处理方法. 除'其他的都是在特殊字符前面加"/",而 ' -> '' .方法:k ...
- 李洪强iOS经典面试题143-绘图与动画
李洪强iOS经典面试题143-绘图与动画 绘图与动画 CAAnimation的层级结构 CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使 ...
- 李洪强iOS经典面试题142-第三方框架及其管理
李洪强iOS经典面试题142-第三方框架及其管理 第三方框架及其管理 使用过CocoaPods吗?它是什么?CocoaPods的原理? CocoaPod是一个第三方库的管理工具,用来管理项目中的第 ...
随机推荐
- 14、NFC技术:使用Android Beam技术传输文本
Android Beam的基本理念 Android Beam的基本理念就是两部(只能是两部)NFC设备靠近时(一般是背靠背),通过触摸一部NFC设备的屏幕,将数据推向另外一部NFC设备.在传递数据的过 ...
- bjfu1299 stl使用
题目超简单,我写解题报告是因为我的代码用了些STL,使代码很简洁. * * Author : ben */ #include <cstdio> #include <cstdlib&g ...
- Linux下IP的配置
修改ip地址1.即时生效:# ifconfig eth0 192.168.1.102 netmask 255.255.255.02.启动生效:修改/etc/sysconfig/network-scri ...
- Sharding & IDs at Instagram(转)
英文原文:http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram 译文:http://ww ...
- linux极点五笔无法输入词组_ibus设置
菜鸟学linux——用的是ubuntu 不知道是不是按个哪些快捷键,极点五笔突然无法输入词组.那个抓狂啊 没关系,设置一下就ok 第一步:右上角输入法,右键——>首选项——>常规——> ...
- MEF(Managed Extensibility Framework)依赖注入学习
MSDN官方资料,并且微软还提供了SimpleCalculator sample学习样例 http://msdn.microsoft.com/en-us/library/dd460648(v=vs.1 ...
- C#图解教程读书笔记(第15章 委托)
委托是C#的一个很重要的知识点. 1.什么是委托 委托在我认为,就是一系列格式相同的方法列表,可能就是定义的名称不一致,参数.返回值等都是一样的. 2.如何声明委托 delegate void MyF ...
- C++STL学习笔记_(3)stack
10.2.4stack容器 Stack简介 ² stack是堆栈容器,是一种"先进后出"的容器. ² stack是简单地装饰deque容器而成为另外的一种容器. ² #inc ...
- Java调用Telnet示例
import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.U ...
- 常见MFC UI界面库[转]
Xtrme toolkit,BCGControlBar,SkinMagic,AppFace,Skin++,Uskin++,SYGUI,LibUIDK,GuiToolkit,GardenUI等等,除了后 ...