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

分析:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章