Daily question 1

1.分析下述程序执行的结果:

#include<iostream>
using namespace std;
class cla{
	static int n;
	public:
		cla() {
			n++;
		}
		~ cla() {
			n--;
		}
		static int get_n() {
			return n;
		}
};
int cla::n=0;
  
int main() {
	cla *p=new cla;
	delete p;
	cout<<" n="<<cla::get_n()<<endl;
	return 0;
}

分析:

类的实例化:cla *p=new cla,p分配在栈上,p指向的对象分配在堆上。
n为静态成员变量,没有this指针,属于类域,所有对象共享。
实例化——调用构造函数,所以n++;
delete——调用析构函数,所以n--。
最后输仍旧为0。

2. 假定有类AB,有相应的构造函数定义,能正确执行

AB a(4),b(5),c[3],*p[2]={&a,&b};

语句,请问执行完此语句后共调用该类的构造函数次数为_5_.

分析:

只有给对象分配空间才调用构造函数。

a(4),一个对象a,调用1次构造函数;

b(5),一个对象b,调用1次构造函数;

c[3],三个对象c[0],c[1],c[2],调用3次构造函数;

*p[2],指针数组,其元素分别指向a和b,所以没有调用构造函数。总共5次。

3. 请找出下面程序中有哪些错误:

int main()
{
   int i=10;
   int j=1;
   const int *p1;//(1)
   int const *p2=&i; //(2)
   p2=&j;//(3)
   int *const p3=&i;//(4)
   *p3=20;//(5)
   *p2=30;//(6)
   p3=&j;//(7)
return 0;
}

分析:

(1)const int*p1:表示不能通过指针p1修改它指向的内存单元的值,但是p1本身可修改。

(2)int const*p2=&i:与p1相同,即不能修改p2指向的内存单元的值,但是可以修改p2使其指向其它的内存单元。这里p2指向了整型变量i

(3)p2=&j:修改p2,使其指向整型变量 j ,由(2)可知(3)没错。

(4)int *constp3=&i:p3本身是指向整型变量的常指针,即p3初始化后不能再指向其它的内存单元,但是可以修改p3指向的内存单元的值。这里p3指向了整型变量i。

(5)*p3=20:通过p3将变量i的值修改为2,由(4)可知(5)没错。

(6)*p2=30:通过p2修改它所指向的内存单元的值,由(2)可知(6)错误。

(7)p3=&j:修改p3,使其指向j,由(4)可知(7)错误。

4. 下列关于C/C++的宏定义,不正确的是(B

A.宏定义不检查参数正确性,会有安全隐患

B.宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量

C.宏的嵌套定义过多会影响程序的可读性,而且很容易出错

D.相对于函数调用,宏定义可以提高程序的运行效率

分析:

《Effective C++》第一条 1. 尽量用const和inline, 而不用#define

使用const比使用define有一下几种好处:

(1)const会进行数据类型检查,而define不会,const关键字定义常量比宏更安全。

(2)const效率高,因为const定义的常量,没有在内存中存储,而是在符号表中,每次访问这个数据的时候,少了从内存中读取和存储过程,效率高。因此尽量还是使用const常量。

5.以下程序统计给定输入中每个大写字母的出现次数(不需要检查合法性),以下能补全程序,正确功能的选项是(D

void
AlphabetCounting(char a[],int n){
  int
count[26]={},i,kind=0;
  
for(i=0;i<n;++i) (____________);
  
for(i=0;i<26;++i){
    
if(++kind>1) putchar(';');
    
printf("%c=%d",(____________));
   }
}

A.++count[a[i]-'z'] 'Z'-i,count['Z'-i]

B.++count['A'-a[i]] 'A'+i,count[i]

C.++count[i] i,count[i]

D.++count['Z'-a[i]] 'Z'-i,count[i]

分析:
题意为输入设定全是大写 (ASCII码A-Z为65-90,递增):

一、count存储A-Z的个数,即count[0]存储A的个数,于是 ++count[a[i]-‘A’]; 'A’+i,count[i];

二、count存储Z~A的个数,即count[0]存储Z的个数,于是 ++count[‘Z’-a[i]]; ’Z’-i,count[i]。 所以答案为D

6.下面关于"指针"的描述不正确的是(A)

A.当使用free释放掉一个指针内容后,指针变量的值被置为NULL
B.32位系统下任何类型指针的长度都是4个字节
C.指针的数据类型声明的是指针实际指向内容的数据类型
D.野指针是指向未分配或者已经释放的内存地址

分析:

  1. free 掉一个指针后,指针仍然指向原来的地址。free 的意义在于告诉系统目标地址被回收。系统可以把此内存给其他变量使用。但是原来指针仍然是指向此内存。如果用此指针操作内存是非法的,俗称野指针。为了数据安全,一般free 掉一个指针后,还要将此指针置为NULL。

  2. 32 位系统中MAR(内存地址寄存器)为32位,可寻址范围为2的32次方Byte,共大约不足4G的内存空间。指针中保存内存地址,所以大小和MAR大小相同。

  3. 指针的类型用于确定指针所指的对象的类型,因此初始化或赋值时必须保证类型匹配。指针用于间接访问对象,并给予指针的类型提供可执行的操作,例如,int型指针只能把其指向的对象当作int型数据来处理,如果该指针指向了其他类型(如double类型)的对象,则在指针上执行的任何操作都有可能出错。

  4. 一个有效的指针必然是以下三种状态之一:保存一个特定的对象的地址;指向某个对象后面的另一对象;或者是0值。

7. 有如下C++代码:那么输出为  barfoob_bar

struct A{
  void foo(){printf("foo");}
  virtual void bar(){printf("bar");}
  A(){bar();}
};
struct B:A{
  void foo(){printf("b_foo");}
  void bar(){printf("b_bar");}
};

A *p=new B;
p->foo();
p->bar();

分析:
virtual 只能出现在类中,代表虚函数的意思。
回归本题。virtual 标识bar()这个函数是虚函数,也就是打开了可以扩展使用子类函数的功能,实现了类的多态。
A *p=new B;
B继承A,所以先进行A的构造函数   =======输出bar
p->foo()  执行A类中的foo函数。==========输出foo
p->bar() 这里特别了,因为将B的值赋值A,所以,p满足多态前提条件,然后bar是虚函数,执行B中的=========输出b_bar

8.类模板的使用实际上是类模板实例化成一个具体的___。

9.在C++, 下列哪一个可以做为对象继承之间的转换 (A,B

A.static_cast

B.dynamic_cast

C.const_cast

D.reinterpret_cast

分析:
dynamic_cast:   通常在基类和派生类之间转换时使用
const_cast:   主要针对const和volatile的转换
static_cast:   一般的转换(no run-time check)通常,如果你不知道该用哪个,就用这个。   
reinterpret_cast:   用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整形数

10.执行下面语句后的输出为 %%.

int I=1;
if(I<=0) 
    printf("****\n") ;
else 
    printf("%%%%\n");

分析:在printf中的%作为转义符,两个%才相当于1个%。

11. 求函数返回值,输入x=9999,8

链接:https://www.nowcoder.com/questionTerminal/4de9136a27bf46cf8fbf4667fc7a0158?toCommentId=52226
来源:牛客网

int func(int x){
    int count=0;
    while (x)
    {
        count++;
        x=x&(x-1);//与运算
    }
    return count;
}

分析:

n&(n-1)就是判断一个数二进制中1的个数。
一个数与这个数减1的结果进行'&'按位与运算,结果为:这个数二进制数最右边的1变为0;

举例说明如下:

X=5;  

5&(5-1) = 010 1 & (0100) = 010 0

经过上述计算,5的二进制最右边的1变为了0,由此可知,题目中count是用以统计x的二进制中1的个数的

9999的二进制表示为:10011100001111 共有8个1,显然,答案为8。

11.32位系统中,定义**a[3][4],则变量占用内存空间为(48)。

分析:a是一个数组,数组大小3*4,数组中存放着指针的指针,在32为系统下,指针大小4B,所以结果为4*3*4=48.

12.二维数组X按行顺序存储,其中每个元素占1个存储单元。若X[4][4]的存储地址为Oxf8b82140,X[9][9]的存储地址为Oxf8b8221c,则X[7][7]的存储地址为()。

分析:

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值