C++题总结

第一天总结

1.局部变量能否和全局变量重名?

答案: 能,局部会屏蔽全局。要用全局变量,需要使用"::"。 局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。 对于有些编译器而言,在同一个函数内 可以 定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
参考代码:

int A = 10;
int main()
{
    int A = 9;
    cout << A << endl; //输出A等于9
    cout << ::A << endl;  //输出A等于10
    return 0;
}

2.不能把字符串"HELLO!"赋给数组b的语句是(B)

答案:

A.  char b[10]={'H''E''L''L''O''!''\0'};
B.  char b[10];b="HELLO!";
C.  char b[10];strcpy(b,"HELLO!");
D.  char b[10]="HELLO!";

A. 空格符号和空字符是不一样的,在ASCII里面,空格(space)符号的ASCII码是0x20,而空字符是0x0,完全不一样的2个字符。
空字符一般来描述一个字符串的结尾,其实是控制符的一种,但不能理解为没有字符,应该理解为代表什么都没有的字符。好比回车0x0A和换行0x0D虽然不显示,但是也是控制字符的一种。
字符串的概念: 在C语言中,字符串是指由若干个有效字符(其中包括字母、数字、转义字符、等)组成的系列,以’\0’作为字符串结束标志。’\0’是一个“空操作”字符,它不做任何操作,只是一个标志。’\0’的代码值为0,它不计入串的长度。
B. b是表示数组的首地址,不能赋值。
C. C 库函数 char *strcpy(char *dest, const char *src) 把 src 所指向的字符串复制到 dest。 需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。

3.变量void (*s[5])(int)表示意思为(函数指针数组)

答案: 这是一个标准的函数指针数组,s[5]说明s是一个数组,数组的内容是void (*)(int)类型的函数指针,该指针指向的函数参数为int,返回值为void。
函数指针数组:
char * (*pf)(char * p) 定义的是一个函数指针pf,既然pf 是一个指针,那就可以储存在一
个数组里:char * (*pf[3]) (char * p); (*pf[3]) 是一个指针素组, (pf[3])(char * p) 数组内
有3 个指向函数的指针,char * (*pf[3]) (char * p) 函数指针指向函数返回的是 char
类型。
函数指针数组的指针:
顾名思义这个指针指向 函数指针数组,下面就定义一个简单的函数指针数组指针:
char * (*(*pf)[3])(char * p);(*pf)[3] 数组指针,pf 是指针,pf 指向一个包含了3个元素的
数组。(*(*)[3])(char * p) 这个数组里面存的是指向函数的指针。
char * (*(*pf)[3])(char * p); 这些指针指向返回值类型为char *、参数为 char * 的函数。

4.以下程序的输出是:

#include <iostream>
using namespace std;
template <typename T>
void print(T t)
{
	cout<<"The value is "<<t<<endl;
}

template <>
void print<char *>(char* c)
{
	cout<<"The string is " << c <<endl;
}

int main()
{
	char str[] = "TrendMicro[char]";
	unsigned char ustr[] = "TrendMicro[unsigned char]";
	print(str);
	print(ustr);
	return 0;
}

The string is TrendMicro[char]<br>The value is TrendMicro[unsigned char]

答案: 模板函数和普通函数都符合条件时,优先执行普通函数

5.分析一下这段程序的输出:

#include<iostream>
 using namespace std;
 class B
 {
 public:
     B()
     {
         cout << "default constructor" << " ";
     }
     ~B()
     {
         cout << "destructed" << " ";
     }
     B(int i): data(i)
     {
         cout << "constructed by parameter" << data << " ";
     } 
     private: int data;
 }; 
 B Play( B b)
 {
     return b;
 } 
 int main(int argc, char *argv[])
 {
     B temp = Play(5);
     return 0;
 }

constructed by parameter5 destructed destructed

答案:

  1. 调用Play函数需要将5隐式类型转换为Play函数中的形参b,会调用B的B(int i): data(i),打印“constructed by parameter5”。
  2. Play函数返回时需要调用B的复制构造函数给对象temp初始化。
  3. Play函数返回后需要调用b的析构函数,将Play函数的形参释放,打印“destructed”。
  4. main函数返回后需要释放temp,打印“destructed”。

6.下面可用于字符串复制的函数有:

答案: strcpy,sprintf,memcpy
memcpy()函数:

从数组a复制k个元素到数组b中:memcpy(b,a,sizeof(int/double)*k)
数组a全部复制到数组b中:memcpy(b,a,sizeof(a))

strcpy()函数:

char *strcpy(char *destin, char *source);
功能:将source指向的字符串拷到destin,会覆盖之前的,source包含'\0'

sprintf()函数:

把信息输出到字符串,保证字符串足够大 
char a[20]; 
memset(a,0,sizeof(a)); 
sprintf(a,"%d%d%d%d",4,5,6,7); for(int i=0;i<sizeof(a);i++){
  printf("%d ",a[i]);
}
//输出20位 52 53 54 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

补充: strcmp()函数:

int strcmp(char * str1,char * str2); 
功能: 比较两个字符串str1,str2
返回: str1<str2,返回负数;str1=str2,返回 0;str1>str2,返回正数,,按位比较

strstr()函数:

char* strstr(char* str1,char* str2);
功能:找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符) 
返回: 返回该位置的指针,如找不到,返回空指针
char b[20]="abcdef";
printf("position:%s\n",strstr(b,"bc"));  //position:bcdef

7.char str[]=”Hello”,sizeof(str)=?

答案: 6。
sizeof计算长度包括字符串结束符\0,strlen不包括。
实际存储为{'H','e','l','l','o','\0'},所以是6个

#include "stdio.h"
int main() {
    char str[] = "hello";
    char *s = "hello";
    int a[] = {3, 5, 7};
    printf("%d\n%d\n%d\n", sizeof(str), sizeof(s), sizeof(a));//输出6, 4, 12
    return 0;
}

8.下面关于虚函数和函数重载的叙述不正确的是?

答案: 虚函数不是类的成员函数。
A: 虚函数不是类的成员函数
B: 虚函数实现了C++的多态性
C: 函数重载允许非成员函数,而虚函数则不行
D: 函数重载的调用根据参数的个数、序列来确定,而虚函数依据对象确定
解释:
虚函数也是类的成员函数,A说法是不正确的;
虚函数和函数重载都实现了C++的多态性,但表现形式不一样,函数重载调用根据参数个数、参数类型等进行区分,而虚函数则是根据动态联编来确定调用什么,故BD说法正确
函数重载可以是类的成员函数也可以是非成员函数,比如:

int fun(int a);
int fun(int a, int b);

这就是非成员重载,虚函数必须是成员函数了,否则就失效了, 所以C对 。

多态性分为编译时多态性运行时多态性
编译时多态性通过静态编联完成,例如函数重载,运算符重载;
运行时多态性则是动态编联完成,主要通过虚函数来实现;
函数重载不需要是成员函数,在类外声明或定义的函数同样可以对其进行重载;
重载的调用主要根据参数个数,参数类型,参数顺序来确定, 函数重载是忽略返回值的。

扩展一下, 提醒大家注意虚函数和纯虚函数区别
虚函数可以在子类中进行重载,也可以不重载而沿用父类中的方法。但纯虚函数必须重载,因为在其声明类中没有函数实现。vritual void func()=0;包含纯虚函数的类为抽象类,抽象类不能声明对象,只能作为基类 。

9. 经 过 以 下 语 句 定 义 后 , 表 达 式z+=x>y?++x:++y 的值为()?

int x=1,y=2,z=3; 

答案: 6。
赋值运算符<逻辑运算符<关系运算符<算数运算符,原式相当于z+=(x>y?++x,++y) 所以结果为6。
这里考察的是运算符运算规则的问题,影响运算符求值顺序的主要是运算符的优先级和结合性。

  • 优先级:主要是不同优先级运算符之间的运算规则;

  • 结合性:主要是优先级相同时运算符需要遵守的运算规则 。
    本题中的表达式,有以下4种运算符,它们是具有不同优先级的运算符,因此这里只需考虑优先级,无需考虑结合性

     复合赋值运算符 +=
     关系运算符 >
     条件运算符 ? :
     增强运算符 ++ 
    

优先级从高到低:增强运算符、关系运算符、条件运算符、赋值运算符
因此求值顺序应该是

    第一步,同时求++x和++y;求得表达式++x为2,且x变为2;表达式++y为3,且y变为3;
    第二步,是判断x>y(注意:此时的x和y已经是进行过第一步后的x和y值);即2 > 3
    第三步,是条件运算;因为2 > 3是F,因此条件表达式的值为++y,即3
    第四步,是复合赋值运算 +=即z += 3,z = z + 3。
    最后得出 z = 6 

10. 下列情况中,不会调用拷贝构造函数的是(B)

A: 用一个对象去初始化同一个类的另一个新对象时
B: 将类的一个对象赋值给该类的另一个对象时
C: 函数的形参对象,调用函数进行形参和实参结合时
D: 函数的返回值是类的对象,函数执行返回调用时
解释:

调用拷贝构造函数的3中情况:

  1. 用一个对象去初始化同一个类的另一个新对象时;
  2. 函数的形参对象,调用函数进行形参和实参结合时 ;
  3. 函数的返回值是类的对象,函数执行返回调用时将一个对象赋值给另一个对象,两个对象都存在,调用的是赋值构造函数,不涉及内存的分配。当被赋值的对象不存在调用的是拷贝构造函数。

C++拷贝构造函数详解C++拷贝构造函数详解

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值