当前位置:   article > 正文

Daily question 1_free一个指针的内容后,指针变量的值是多少

free一个指针的内容后,指针变量的值是多少

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

  1. #include<iostream>
  2. using namespace std;
  3. class cla{
  4. static int n;
  5. public:
  6. cla() {
  7. n++;
  8. }
  9. ~ cla() {
  10. n--;
  11. }
  12. static int get_n() {
  13. return n;
  14. }
  15. };
  16. int cla::n=0;
  17. int main() {
  18. cla *p=new cla;
  19. delete p;
  20. cout<<" n="<<cla::get_n()<<endl;
  21. return 0;
  22. }

分析:

类的实例化: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. 请找出下面程序中有哪些错误:

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

分析:

(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

  1. void
  2. AlphabetCounting(char a[],int n){
  3. int
  4. count[26]={},i,kind=0;
  5. for(i=0;i<n;++i) (____________);
  6. for(i=0;i<26;++i){
  7. if(++kind>1) putchar(';');
  8. printf("%c=%d",(____________));
  9. }
  10. }

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

  1. struct A{
  2. void foo(){printf("foo");}
  3. virtual void bar(){printf("bar");}
  4. A(){bar();}
  5. };
  6. struct B:A{
  7. void foo(){printf("b_foo");}
  8. void bar(){printf("b_bar");}
  9. };
  10. A *p=new B;
  11. p->foo();
  12. 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.执行下面语句后的输出为 %%.

  1. int I=1;
  2. if(I<=0)
  3. printf("****\n") ;
  4. else
  5. printf("%%%%\n");

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

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

  1. 链接:https://www.nowcoder.com/questionTerminal/4de9136a27bf46cf8fbf4667fc7a0158?toCommentId=52226
  2. 来源:牛客网
  3. int func(int x){
  4. int count=0;
  5. while (x)
  6. {
  7. count++;
  8. x=x&(x-1);//与运算
  9. }
  10. return count;
  11. }

分析:

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]的存储地址为()。

分析:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/二进制舞者/article/detail/62471
推荐阅读
  

闽ICP备14008679号