经典C++笔试题

时间:2022-04-14 19:56:41

1、判断

void main(){  
    char str1[] = "abc";  
    char str2[] = "abc";  
    const char str3[] = "abc";  
    const char str4[] = "abc";  
    const char* str5 = "abc";  
    const char* str6 = "abc";  
    std::cout << std::boolalpha << ( str1==str2 ) << std::endl; //false  
    std::cout << std::boolalpha << ( str3==str4 ) << std::endl; // false  
    std::cout << std::boolalpha << ( str5==str6 ) << std::endl; // true  
    /*分别输出字符串的地址 
    str1,str2,str3,str4位于栈区,向低地址增长 
    str5,str6位于只读数据区,所以地址相同 
    */  
    printf("%p\t%p\n",str1,str2);  
    printf("%p\t%p\n",str3,str4);  
    printf("%p\t%p\n",str5,str6);  
    system("pause");  
}

解答:分别输出false,false,true

str1和str2都是字符数组,每个都有自己的存储器,数组名的值则是各存储器的首地址,所以不等。

str3和str4同上,只是按const语义,他们所指向的数据区不能修改

str5和str6不是数组而是字符指针,并没有分别存储器,"abc"以常量形式存于静态数据区,指针则指向该区的首地址,所以相等。


2、  将 str 中的小写字母转换成大写字母

void UpperCase( char str[] )                                         
{
    for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )
        if( 'a'<=str[i] && str[i]<='z' )
            str[i] -= ('a'-'A' );
}
UpperCase函数传递指针,sizeof(str)==4,字符串长度超过4,就不能够转换

3、非C++内建型别A和B, 在哪几种情况下B能隐式转化为A?

  1. // Case 1 : B公有继承自A  
  2. class B : public A  
  3. {  
  4.     ...  
  5. }  

  1. // Case 2 : B实现了隐式转化为A的转化  
  2. class B   
  3. {  
  4.     operator A();  
  5. }  
  1. // Case 3 : A实现了non-explicit的参数为B的构造函数  
  2. class A   
  3. {  
  4.     A(const B&);  
  5. }  
  1. // Case 4 : 赋值操作  
  2. A & operator=(const A&);  

5、c++空类默认产生的类成员函数
//c++空类默认产生的类成员函数
class Empty
{
public:
Empty();//缺省构造函数
Empty(const Empty&);//拷贝构造函数
~Empty();//析构函数
Empty& operator=(const Empty&);//赋值运算符
Empty* operator&();//取址运算符
const Empty* operator&() const;//取址运算符const 


6判断
//1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等
float a = 1.0f;
cout<<(int)a<<endl;//实际上是以浮点数 a为参数构造了一个整型数1,
cout<<(int&)a<<endl;//告诉编译器将a当作整数看(并没有做任何实质上的转换)

//0以整数形式存放和以浮点形式存放其内存数据是一样的,因此两者相等
float b = 0.0f;
cout<<(int)b<<endl;
cout<<(int&)b<<endl;


7、定义 int **a[3][4], 则变量占有的内存空间为:_____ ?
分析:由于优先级[]>*,所以a是存放二级指针的二维数组;
若(**a)[3][4],则a为指向二维数组的指针;


4、判断

struct Test
{
Test(int){}
Test(){}
void fun(){}
};

        Test a(1);
a.fun();
Test b();//Error,默认构造函数初始化不加括号
b.fun();


8、数组和指针的区别

数组可以再静态存储区和栈上建立,指针可以指向任意类型的存储块

9、判断输出

main()
{
char *p1=“name”;
char *p2;
p2=(char*)malloc(20);
memset (p2, 0, 20);
while(*p2++ = *p1++);
printf(“%s\n”,p2);//p2指向字符串末端,为空
}

10使用strcat()

main()
{
char *p1;
char *p2;
p1=(char *)malloc(25);
p2=(char *)malloc(25);
strcpy(p1,”Cisco”);
strcpy(p2,“systems”);
strcat(p1,p2);//注意空间的处理
printf(“%s”,p1);
}
尽管给p1,p2都分配了25字节的内存,但是使用strcat可以将函数连接在一起

11有哪几种情况只能用intialization list而不能用assignment?

当类中含有 const、reference 成员变量;基类的构造函数都需要初始化表。

12、初始化vector

vector< vector<int>> ivv;

ivv[0].push_back(1);

cout<<ivv[0][0]<<endl;

-----------------------------代码错误,没有初始化vector<int>就使用

vector<vector<int>> ivv;

ivv.push_back(vector<int>());

ivv[0].push_back(1);

cout<<ivv[0][0]<<endl;

------------------------------可以使用 vector<vector<int>> ivv(10);进行多数的初始化


13.继承的优缺点

1、类继承是在编译时刻静态定义的,且可直接使用,
2、类继承可以较方便地改变父类的实现。(对于子类改变父类的实现)
缺点:
1、因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现
2、父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为
3、如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。
这种依赖关系限制了灵活性并最终限制了复用性。


14、c++在头文件中进行类的声明,在对应的实现文件中进行类的定义有什么意义?

h为编译器提供一个索引,连接obj对象和主程序
编译器在编译的时候,如果需要,则去查找h,找到了h,再找对应的obj,就可以找到类的方法了
但是如果直接写入到同一个文件(例如hpp),主程序没有索引,也不清楚具体的类实现了没有,只能一次次重复的编译相同的代码,这样实际上没有把这个类该有的东西抽象出来