赞
踩
- #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。
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次。
- 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)错误。
A.宏定义不检查参数正确性,会有安全隐患
B.宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量
C.宏的嵌套定义过多会影响程序的可读性,而且很容易出错
D.相对于函数调用,宏定义可以提高程序的运行效率
分析:
《Effective C++》第一条 1. 尽量用const和inline, 而不用#define
使用const比使用define有一下几种好处:
(1)const会进行数据类型检查,而define不会,const关键字定义常量比宏更安全。
(2)const效率高,因为const定义的常量,没有在内存中存储,而是在符号表中,每次访问这个数据的时候,少了从内存中读取和存储过程,效率高。因此尽量还是使用const常量。
- 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
A.当使用free释放掉一个指针内容后,指针变量的值被置为NULL
B.32位系统下任何类型指针的长度都是4个字节
C.指针的数据类型声明的是指针实际指向内容的数据类型
D.野指针是指向未分配或者已经释放的内存地址
分析:
free 掉一个指针后,指针仍然指向原来的地址。free 的意义在于告诉系统目标地址被回收。系统可以把此内存给其他变量使用。但是原来指针仍然是指向此内存。如果用此指针操作内存是非法的,俗称野指针。为了数据安全,一般free 掉一个指针后,还要将此指针置为NULL。
32 位系统中MAR(内存地址寄存器)为32位,可寻址范围为2的32次方Byte,共大约不足4G的内存空间。指针中保存内存地址,所以大小和MAR大小相同。
指针的类型用于确定指针所指的对象的类型,因此初始化或赋值时必须保证类型匹配。指针用于间接访问对象,并给予指针的类型提供可执行的操作,例如,int型指针只能把其指向的对象当作int型数据来处理,如果该指针指向了其他类型(如double类型)的对象,则在指针上执行的任何操作都有可能出错。
一个有效的指针必然是以下三种状态之一:保存一个特定的对象的地址;指向某个对象后面的另一对象;或者是0值。
- 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
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: 用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整形数
- int I=1;
- if(I<=0)
- printf("****\n") ;
- else
- printf("%%%%\n");
分析:在printf中的%作为转义符,两个%才相当于1个%。
- 链接: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。
分析:a是一个数组,数组大小3*4,数组中存放着指针的指针,在32为系统下,指针大小4B,所以结果为4*3*4=48.
分析:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。