面試問題匯總 精選 分析 解答 職業規劃 part 1

C/C++/C#面試題精選(1)

題目(一):C++中我們可以用static修飾一個類的成員函數,也可以用const修飾類的成員函數(寫在函數的最后表示不能修改成員變量,不是指寫在前面表示返回值為常量)。請問:能不能同時用staticconst修飾類的成員函數?

分析:答案是不可以。C++編譯器在實現const的成員函數的時候為了確保該函數不能修改類的實例的狀態,會在函數中添加一個隱式的參數const this*。但當一個成員為static的時候,該函數是沒有this指針的。也就是說此時static的用法和static是沖突的。

我們也可以這樣理解:兩者的語意是矛盾的。static的作用是表示該函數只作用在類型的靜態變量上,與類的實例沒有關系;而const的作用是確保函數不能修改類的實例的狀態,與類型的靜態變量沒有關系。因此不能同時用它們。

題目(二):運行下面C++代碼,輸出是什么?

class A

{

};

?

class B

{

public:

???????B() {}

???????~B() {}

};

?

class C

{

public:

???????C() {}

???????virtual ~C() {}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????printf("%d, %d, %d/n",sizeof(A),sizeof(B),sizeof(C));

???????return 0;

}

分析:答案是1, 1, 4class A是一個空類型,它的實例不包含任何信息,本來求sizeof應該是0。但當我們聲明該類型的實例的時候,它必須在內存中占有一定的空間,否則無法使用這些實例。至于占用多少內存,由編譯器決定。Visual Studio 2008中每個空類型的實例占用一個byte的空間。

class Bclass A的基礎上添加了構造函數和析構函數。由于構造函數和析構函數的調用與類型的實例無關(調用它們只需要知道函數地址即可),在它的實例中不需要增加任何信息。所以sizeof(B)sizeof(A)一樣,在Visual Studio 2008中都是1

class Cclass B的基礎上把析構函數標注為虛擬函數。C++的編譯器一旦發現一個類型中有虛擬函數,就會為該類型生成虛函數表,并在該類型的每一個實例中添加一個指向虛函數表的指針。在32位的機器上,一個指針占4個字節的空間,因此sizeof(C)4

題目(三):運行下面的C++代碼,得到的結果是什么

class A

{

private:

???????int m_value;

?

public:

???????A(int value)

???????{

???????????????m_value = value;

???????}

???????void Print1()

???????{

???????????????printf("hello world");

???????}

???????void Print2()

???????{

???????????????printf("%d", m_value);

???????}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????A* pA = NULL;

???????pA->Print1();

???????pA->Print2();

?

???????return 0;

}

分析:答案是Print1調用正常,打印出hello world,但運行至Print2時,程序崩潰。調用Print1時,并不需要pA的地址,因為Print1的函數地址是固定的。編譯器會給Print1傳入一個this指針,該指針為NULL,但在Print1中該this指針并沒有用到。只要程序運行時沒有訪問不該訪問的內存就不會出錯,因此運行正常。在運行print2時,需要this指針才能得到m_value的值。由于此時this指針為NULL,因此程序崩潰了。

題目(四):運行下面的C++代碼,得到的結果是什么

class A

{

private:

???????int m_value;

?

public:

???????A(int value)

???????{

???????????????m_value = value;

???????}

???????void Print1()

???????{

???????????????printf("hello world");

???????}

???????virtualvoid Print2()

???????{

???????????????printf("hello world");

???????}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????A* pA = NULL;

???????pA->Print1();

???????pA->Print2();

?

???????return 0;

}

分析:答案是Print1調用正常,打印出hello world,但運行至Print2時,程序崩潰。Print1的調用情況和上面的題目一樣,不在贅述。由于Print2是虛函數。C++調用虛函數的時候,要根據實例(即this指針指向的實例)中虛函數表指針得到虛函數表,再從虛函數表中找到函數的地址。由于這一步需要訪問實例的地址(即this指針),而此時this指針為空指針,因此導致內存訪問出錯。

題目(五):C++中靜態成員函數能不能同時也是虛函數

分析:答案是不能。調用靜態成員函數不要實例。但調用虛函數需要從一個實例中指向虛函數表的指針以得到函數的地址,因此調用虛函數需要一個實例。兩者相互矛盾。

博主何海濤對本博客文章享有版權。網絡轉載請注明出處。整理出版物請和作者聯系。有任何建議或意見,歡迎在評論中告知,或者加我微博http://weibo.com/zhedahht與我交流。


C/C++/C#面試題精選(2)

題目(六):運行下列C++代碼,輸出什么?

struct Point3D

{

???????int x;

???????int y;

???????int z;

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????Point3D* pPoint = NULL;

???????int offset = (int)(&(pPoint)->z);

?

???????printf("%d", offset);

???????return 0;

}

答案:輸出8。由于在pPoint->z的前面加上了取地址符號,運行到此時的時候,會在pPoint的指針地址上加z在類型Point3D中的偏移量8。由于pPoint的地址是0,因此最終offset的值是8

&(pPoint->z)的語意是求pPoint中變量z的地址(pPoint的地址0z的偏移量8),并不需要訪問pPoint指向的內存。只要不訪問非法的內存,程序就不會出錯。

題目(七):運行下列C++代碼,輸出什么?

class A

{

public:

???????A()

???????{

???????????????Print();

???????}

???????virtualvoid Print()

???????{

???????????????printf("A is constructed./n");

???????}

};

?

class B:public A

{

public:

???????B()

???????{

???????????????Print();

???????}

?

???????virtualvoid Print()

???????{

???????????????printf("B is constructed./n");

???????}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????A* pA =new B();

???????delete pA;

?

???????return 0;

}

答案:先后打印出兩行:A is constructed. B is constructed.調用B的構造函數時,先會調用B的基類及A的構造函數。然后在A的構造函數里調用Print。由于此時實例的類型B的部分還沒有構造好,本質上它只是A的一個實例,他的虛函數表指針指向的是類型A的虛函數表。因此此時調用的PrintA::Print,而不是B::Print。接著調用類型B的構造函數,并調用Print。此時已經開始構造B,因此此時調用的PrintB::Print

同樣是調用虛擬函數Print,我們發現在類型A的構造函數中,調用的是A::Print,在B的構造函數中,調用的是B::Print。因此虛函數在構造函數中,已經失去了虛函數的動態綁定特性。

題目(八):運行下列C#代碼,輸出是什么?

namespace ChangesOnString

{

???classProgram

???{

???????staticvoid Main(string[] args)

???????{

???????????String str ="hello";

???????????str.ToUpper();

???????????str.Insert(0," WORLD");

?

???????????Console.WriteLine(str);

???????}

???}

}

答案:輸出是hello。由于在.NET中,String有一個非常特殊的性質:String的實例的狀態不能被改變。如果String的成員函數會修改實例的狀態,將會返回一個新的String實例。改動只會出現在返回值中,而不會修改原來的實例。所以本題中輸出仍然是原來的字符串值hello

如果試圖改變String的內容,改變之后的值可以通過返回值拿到。用StringBuilder是更好的選擇,特別是要連續多次修改的時候。如果用String連續多次修改,每一次修改都會產生一個臨時對象,開銷太大。

題目(九):C++C#中,structclass有什么不同

答案:C++中,如果沒有標明函數或者變量是的訪問權限級別,在struct中,是public的;而在class中,是private的。

???????????????C#中,如果沒有標明函數或者變量的訪問權限級別,structclass中都是private的。structclass的區別是:struct定義值類型,其實例在棧上分配內存;class定義引用類型,其實例在堆上分配內存。

題目(十):運行下圖中的C#代碼,輸出是什么

namespace StaticConstructor

{

???classA

???{

???????public A(string text)

???????{

???????????Console.WriteLine(text);

???????}

???}

?

???classB

???{

???????staticA a1 =new A("a1");

???????A a2 =newA("a2");

?

???????static B()

???????{

???????????a1 =newA("a3");

???????}

?

???????public B()

???????{

???????????a2 =newA("a4");

???????}

???}

?

???classProgram

???{

???????staticvoid Main(string[] args)

???????{

???????????B b =newB();

???????}

???}

}

答案:打印出四行,分別是a1a3a2a4

在調用類型B的代碼之前先執行B的靜態構造函數。靜態函數先初始化類型的靜態變量,再執行靜態函數內的語句。因此先打印a1再打印a3。接下來執行B b = new B(),即調用B的普通構造函數。構造函數先初始化成員變量,在執行函數體內的語句,因此先后打印出a2a4

博主何海濤對本博客文章享有版權。網絡轉載請注明出處。整理出版物請和作者聯系。有任何建議或意見,歡迎在評論中告知,或者加我微博http://weibo.com/zhedahht與我交流。

C/C++/C#面試題精選(3)

題目(11):運行下圖中的C#代碼,輸出是什么?

namespace StringValueOrReference

{

???class Program

???{

???????internal staticvoid ValueOrReference(Type type)

???????{

???????????String result = "The type " + type.Name;

?

???????????if (type.IsValueType)

???????????????Console.WriteLine(result + " is a value type.");

???????????else

???????????????Console.WriteLine(result + " is a reference type.");

???????}

?

???????internal staticvoid ModifyString(String text)

???????{

???????????text = "world";

???????}

?

???????static void Main(string[] args)

???????{

???????????String text = "hello";

?

???????????ValueOrReference(text.GetType());

???????????ModifyString(text);

?

???????????Console.WriteLine(text);

???????}

???}

}

答案:輸出兩行。第一行是The type String is reference type. 第二行是hello。類型String的定義是public sealed class String {...},既然是class,那么String就是引用類型。

在方法ModifyString里,對text賦值一個新的字符串,此時改變的不是原來text的內容,而是把text指向一個新的字符串"world"。由于參數text沒有加ref或者out,出了方法之后,text還是指向原來的字符串,因此輸出仍然是"hello".

題目(12):運行下圖中的C++代碼,輸出是什么?

#include<iostream>

?

class A

{

private:

???????int n1;

???????int n2;

public:

???????A(): n2(0), n1(n2 + 2)

???????{

???????}

?

???????void Print()

???????{

???????????????std::cout << "n1: " << n1 << ", n2: " << n2 << std::endl;

???????}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????A a;

???????a.Print();

?

???????return 0;

}

答案:輸出n1是一個隨機的數字,n2為0。在C++中,成員變量的初始化順序與變量在類型中的申明順序相同,而與它們在構造函數的初始化列表中的順序無關。因此在這道題中,會首先初始化n1,而初始n1的參數n2還沒有初始化,是一個隨機值,因此n1就是一個隨機值。初始化n2時,根據參數0對其初始化,故n2=0。

題目(13):編譯運行下圖中的C++代碼,結果是什么?(A)編譯錯誤;(B)編譯成功,運行時程序崩潰;(C)編譯運行正常,輸出10。請選擇正確答案并分析原因。

#include<iostream>

?

class A

{

private:

???????int value;

?

public:

???????A(int n)

???????{

???????????????value = n;

???????}

?

???????A(A other)

???????{

???????????????value = other.value;

???????}

?

???????void Print()

???????{

???????????????std::cout << value << std::endl;

???????}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????A a = 10;

???????A b = a;

???????b.Print();

?

???????return 0;

}

答案:編譯錯誤。在復制構造函數中傳入的參數是A的一個實例。由于是傳值,把形參拷貝到實參會調用復制構造函數。因此如果允許復制構造函數傳值,那么會形成永無休止的遞歸并造成棧溢出。因此C++的標準不允許復制構造函數傳值參數,而必須是傳引用或者常量引用。在Visual Studio和GCC中,都將編譯出錯。

題目(14):運行下圖中的C++代碼,輸出是什么?

int SizeOf(char pString[])

{

???????return sizeof(pString);

}

?

int _tmain(int argc, _TCHAR* argv[])

{

???????char* pString1 = "google";

???????int size1 = sizeof(pString1);

???????int size2 = sizeof(*pString1);

?

???????char pString2[100] = "google";

???????int size3 = sizeof(pString2);

???????int size4 = SizeOf(pString2);

?

???????printf("%d, %d, %d, %d", size1, size2, size3, size4);

?

???????return 0;

}

答案:4, 1, 100, 4。pString1是一個指針。在32位機器上,任意指針都占4個字節的空間。*pString1是字符串pString1的第一個字符。一個字符占一個字節。pString2是一個數組,sizeof(pString2)是求數組的大小。這個數組包含100個字符,因此大小是100個字節。而在函數SizeOf中,雖然傳入的參數是一個字符數組,當數組作為函數的參數進行傳遞時,數組就自動退化為同類型的指針。

題目(15):運行下圖中代碼,輸出的結果是什么?這段代碼有什么問題?

#include<iostream>

?

class A

{

public:

???????A()

???????{??????std::cout << "A is created." << std::endl;???????}

?

???????~A()

???????{??????std::cout << "A is deleted." << std::endl;???????}

};

?

class B :public A

{

public:

???????B()

???????{??????std::cout << "B is created." << std::endl;???????}

?

???????~B()

???????{??????std::cout << "B is deleted." << std::endl;???????}

};

?

int _tmain(int argc, _TCHAR* argv[])

{

???????A* pA = new B();

???????delete pA;

?

???????return 0;

}

答案:輸出三行,分別是:A is created. B is created. A is deleted。用new創建B時,回調用B的構造函數。在調用B的構造函數的時候,會先調用A的構造函數。因此先輸出A is created. B is created.

接下來運行delete語句時,會調用析構函數。由于pA被聲明成類型A的指針,同時基類A的析構函數沒有標上virtual,因此只有A的析構函數被調用到,而不會調用B的析構函數。

由于pA實際上是指向一個B的實例的指針,但在析構的時候只調用了基類A的析構函數,卻沒有調用B的析構函數。這就是一個問題。如果在類型B中創建了一些資源,比如文件句柄、內存等,在這種情況下都得不到釋放,從而導致資源泄漏。

?

博主何海濤對本博客文章享有版權。網絡轉載請注明出處http://blog.csdn.net/cadcisdhht。整理出版物請和作者聯系。有任何建議或意見,歡迎在評論中告知,或者加我微博http://weibo.com/zhedahht與我交流。


C/C++/C#面試題精選(4)

問題(16):運行如下的C++代碼,輸出是什么?

class A

{

public:

???virtualvoid Fun(int number = 10)

???{

???????std::cout <<"A::Fun with number " << number;

???}

};

?

class B:public A

{

public:

???virtualvoid Fun(int number = 20)

???{

???????std::cout <<"B::Fun with number " << number;

???}

};

?

int main()

{

???B b;

???A &a = b;

???a.Fun();

}

答案:輸出B::Fun with number 10。由于a是一個指向B實例的引用,因此在運行的時候會調用B::Fun。但缺省參數是在編譯期決定的。在編譯的時候,編譯器只知道a是一個類型a的引用,具體指向什么類型在編譯期是不能確定的,因此會按照A::Fun的聲明把缺省參數number設為10。

???????????這一題的關鍵在于理解確定缺省參數的值是在編譯的時候,但確定引用、指針的虛函數調用哪個類型的函數是在運行的時候。

問題(17):運行如下的C代碼,輸出是什么?

char* GetString1()

{

???char p[] ="Hello World";

???return p;

}

?

char* GetString2()

{

???char *p ="Hello World";

???return p;

}

?

?

int _tmain(int argc, _TCHAR* argv[])

{

???printf("GetString1 returns: %s. /n", GetString1());

???printf("GetString2 returns: %s. /n", GetString2());

?

???return 0;

}

答案:輸出兩行,第一行GetString1 returns: 后面跟的是一串隨機的內容,而第二行GetString2 returns: Hello World.兩個函數的區別在于GetString1中是一個數組,而GetString2中是一個指針。

當運行到GetString1時,p是一個數組,會開辟一塊內存,并拷貝"Hello World"初始化該數組。接著返回數組的首地址并退出該函數。由于p是GetString1內的一個局部變量,當運行到這個函數外面的時候,這個數組的內存會被釋放掉。因此在_tmain函數里再去訪問這個數組的內容時,結果是隨機的。

當運行到GetString2時,p是一個指針,它指向的是字符串常量區的一個常量字符串。該常量字符串是一個全局的,并不會因為退出函數GetString2而被釋放掉。因此在_tmain中仍然根據GetString2返回的地址得到字符串"Hello World"。

問題(18):運行下圖中C#代碼,輸出的結果是什么?

namespace StaticVariableInAppDomain

{

???[Serializable]

???internalclassA : MarshalByRefObject

???{

???????publicstaticint Number;

?

???????publicvoid SetNumber(int value)

???????{

???????????Number = value;

???????}

???}

?

???[Serializable]

???internalclassB

???{

???????publicstaticint Number;

?

???????publicvoid SetNumber(int value)

???????{

???????????Number = value;

???????}

???}

?

???classProgram

???{

???????staticvoid Main(string[] args)

???????{

???????????String assamblyName =Assembly.GetEntryAssembly().FullName;

???????????AppDomain domain =AppDomain.CreateDomain("NewDomain");

?

???????????A.Number = 10;

???????????String nameOfA =typeof(A).FullName;

???????????A a = domain.CreateInstanceAndUnwrap(assamblyName, nameOfA)asA;

???????????a.SetNumber(20);

???????????Console.WriteLine("Number in class A is {0}",A.Number);

?

???????????B.Number = 10;

???????????String nameOfB =typeof(B).FullName;

???????????B b = domain.CreateInstanceAndUnwrap(assamblyName, nameOfB)asB;

???????????b.SetNumber(20);

???????????Console.WriteLine("Number in class B is {0}",B.Number);

???????}

???}

}

答案:輸出兩行,第一行是Number in class A is 10,而第二行是Number in class B is 20。上述C#代碼先創建一個命名為NewDomain的應用程序域,并在該域中利用反射機制創建類型A的一個實例和類型B的一個實例。我們注意到類型A是繼承自MarshalByRefObject,而B不是。雖然這兩個類型的結構一樣,但由于基類不同而導致在跨越應用程序域的邊界時表現出的行為將大不相同。

?????由于A繼承MarshalByRefObject,那么a實際上只是在缺省的域中的一個代理,它指向位于NewDomain域中的A的一個實例。當a.SetNumber時,是在NewDomain域中調用該方法,它將修改NewDomain域中靜態變量A.Number的值并設為20。由于靜態變量在每個應用程序域中都有一份獨立的拷貝,修改NewDomain域中的靜態變量A.Number對缺省域中的靜態變量A.NewDomain沒有任何影響。由于Console.WriteLine是在缺省的應用程序域中輸出A.Number,因此輸出仍然是10。

???B只從Object繼承而來的類型,它的實例穿越應用程序域的邊界時,將會完整地拷貝實例。在上述代碼中,我們盡管試圖在NewDomani域中生成B的實例,但會把實例b拷貝到缺省的域。此時,調用b.SetNumber也是在缺省的域上進行,它將修改缺省的域上的A.Number并設為20。因此這一次輸出的是20。

問題(19):運行下圖中C代碼,輸出的結果是什么?

int _tmain(int argc, _TCHAR* argv[])

{

???char str1[] ="hello world";

???char str2[] ="hello world";

?

???char* str3 ="hello world";

???char* str4 ="hello world";

?

???if(str1 == str2)

???????printf("str1 and str2 are same./n");

???else

???????printf("str1 and str2 are not same./n");

?

???if(str3 == str4)

???????printf("str3 and str4 are same./n");

???else

???????printf("str3 and str4 are not same./n");

?

???return 0;

}

答案:輸出兩行。第一行是str1 and str2 are not same,第二行是str3 and str4 are same。

str1和str2是兩個字符串數組。我們會為它們分配兩個長度為12個字節的空間,并把"hello world"的內容分別拷貝到數組中去。這是兩個初始地址不同的數組,因此比較str1和str2的值,會不相同。str3和str4是兩個指針,我們無需為它們分配內存以存儲字符串的內容,而只需要把它們指向"hello world“在內存中的地址就可以了。由于"hello world”是常量字符串,它在內存中只有一個拷貝,因此str3和str4指向的是同一個地址。因此比較str3和str4的值,會是相同的。

問題(20):運行下圖中C#代碼,輸出的結果是什么?并請比較這兩個類型各有什么特點,有哪些區別。

namespace Singleton

{

???publicsealedclass Singleton1

???{

???????private Singleton1()

???????{

???????????Console.WriteLine("Singleton1 constructed");

???????}

???????publicstaticvoid Print()

???????{

???????????Console.WriteLine("Singleton1 Print");

???????}

???????privatestaticSingleton1 instance =new Singleton1();

???????publicstaticSingleton1 Instance

???????{

???????????get

???????????{

???????????????return instance;

???????????}

???????}

???}

?

???publicsealedclass Singleton2

???{

???????Singleton2()

???????{

???????????Console.WriteLine("Singleton2 constructed");

???????}

???????publicstaticvoid Print()

???????{

???????????Console.WriteLine("Singleton2 Print");

???????}

???????publicstaticSingleton2 Instance

???????{

???????????get

???????????{

???????????????returnNested.instance;

???????????}

???????}

???????classNested

???????{

???????????static Nested() { }

?

???????????internalstaticreadonly Singleton2 instance =new Singleton2();

???????}

???}

?

???classProgram

???{

???????staticvoid Main(string[] args)

???????{

???????????Singleton1.Print();

???????????Singleton2.Print();

???????}

???}

}

答案:輸出三行:第一行“Singleton1 constructed”,第二行“Singleton1 Print”,第三行“Singleton2 Print”。

當我們調用Singleton1.Print時,.NET運行時會自動調用Singleton1的靜態構造函數,并初始化它的靜態變量。此時會創建一個Singleton1的實例,因此會調用它的構造函數。Singleton2的實例是在Nested的靜態構造函數里初始化的。只有當類型Nested被使用時,才回觸發.NET運行時調用它的靜態構造函數。我們注意到我們只在Sington2.Instance里面用到了Nested。而在我們的代碼中,只調用了Singleton2.Print。因此不會創建Singleton2的實例,也不會調用它的構造函數。

這兩個類型其實都是單例模式(Singleton)的實現。第二個實現Singleton2只在真的需要時,才會創建實例,而第一個實現Singleton1則不然。第二個實現在空間效率上更好。

博主何海濤對本博客文章享有版權。網絡轉載請注明出處http://blog.csdn.net/cadcisdhht。整理出版物請和作者聯系。有任何建議或意見,歡迎在評論中告知,或者加我微博http://weibo.com/zhedahht與我交流。

C/C++/C#面試題精選(5)

問題(21):C#是一門托管語言,那么是不是說明只要用C#,就能保證不會出現內存泄露和其他資源泄漏?如果不是,在哪些情況下可能會出現泄漏?

答案:C#不能保證沒有資源泄漏。比如如下幾種情況可能會造成資源泄漏:(1) 調用Nativecode,比如用P/Invoke或者調用COM;(2) 讀寫文件時的,沒有及時closestream, 或者ADO.NET連數據庫時,沒有及時關閉連接,也算資源泄漏?(3)注冊事件后沒有remove,導致publisher和subscriber的強依 賴,垃圾回收可能會被推遲;(4).NET還定義了一些方法直接申請非托管內存,比如Marshal.AllocHGlobal和Marshal.AllocCoTaskMem。通過這種方式得到的內存,如果沒有及時釋放,也會造成內存泄露。

問題(22):下面的兩段C#有哪些不同?

[csharp] view plaincopy
  1. static?void?CatchException1()??
  2. {??
  3. ????try??
  4. ????{??
  5. ????????Function();??
  6. ????}??
  7. ????catch??
  8. ????{??
  9. ????????throw;??
  10. ????}??
  11. }??
  12. ??
  13. static?void?CatchException2()??
  14. {??
  15. ????try??
  16. ????{??
  17. ????????Function();??
  18. ????}??
  19. ????catch?(Exception?e)??
  20. ????{??
  21. ????????throw?e;??
  22. ????}??
  23. }??
答案:兩個函數的catch都是重新拋出截獲的exception,但拋出的exception的callstack是不一樣的。對于第一種方法,exception的callstack是從最開始的拋出地點開始的。對于第二種方法,exception的callstack是從CatchException2開始的,最初拋出的地方相關的信息被隱藏了。

問題(23):運行下圖中的C++代碼,打印出的結果是什么?

[cpp] view plaincopy
  1. bool?Fun1(char*?str)??
  2. {??
  3. ????printf("%s\n",str);??
  4. ????return?false;??
  5. }??
  6. ??
  7. bool?Fun2(char*?str)??
  8. {??
  9. ????printf("%s\n",str);??
  10. ????return?true;??
  11. }??
  12. ??
  13. int?_tmain(int?argc,?_TCHAR*?argv[])??
  14. {??
  15. ????bool?res1,res2;??
  16. ????res1?=?(Fun1("a")&&?Fun2("b"))?||?(Fun1("c")?||?Fun2("d"));??
  17. ????res2?=?(Fun1("a")&&?Fun2("b"))?&&(Fun1("c")?||?Fun2("d"));??
  18. ??
  19. ????return?res1||?res2;??
  20. }??
答案:打印出4行,分別是a、c、d、a。

在C/C++中,與、或運算是從左到右的順序執行的。在計算rest1時,先計算Fun1(“a”)&& Func2(“b”)。首先Func1(“a”)打印出內容為a的一行。由于Fun1(“a”)返回的是false,無論Func2(“b”)的返回值是true還是false,Fun1(“a”)&& Func2(“b”)的結果都是false。由于Func2(“b”)的結果無關重要,因此Func2(“b”)會略去而不做計算。接下來計算Fun1(“c”)|| Func2(“d”),分別打印出內容c和d的兩行。

??????????????? 在計算rest2時,首先Func1(“a”)打印出內容為a的一行。由于Func1(“a”)返回false,和前面一樣的道理,Func2(“b”)會略去不做計算。由于Fun1(“a”)&& Func2(“b”)的結果是false,不管Fun1(“c”)&& Func2(“d”)的結果是什么,整個表達式得到的結果都是false,因此Fun1(“c”) || Func2(“d”)都將被忽略。

問題(24):運行下面的C#代碼,打印出來的結果是什么?

[csharp] view plaincopy
  1. struct?Person??
  2. {??
  3. ????public?string?Name;??
  4. ??
  5. ????public?override?string?ToString()??
  6. ????{??
  7. ????????return?Name;??
  8. ????}??
  9. }??
  10. ??
  11. class?Program??
  12. {??
  13. ????static?void?Main(string[]args)??
  14. ????{??
  15. ????????ArrayListarray?=?new?ArrayList();??
  16. ????????Personjim?=?new?Person(){Name?=?"Jim"};??
  17. ????????array.Add(jim);??
  18. ??
  19. ????????Personfirst?=?(Person)array[0];??
  20. ????????first.Name?=?"Peter";??
  21. ??
  22. ????????Console.WriteLine(array[0].ToString());??
  23. ????}??
  24. }??
答案:Person的定義是一個struct,因此是一個值類型。在運行到語句Person first =(Person)array[0]的時候,first是array[0]的一個拷貝,first和array[0]不是一個實例。因此修改first對array[0]沒有影響。

問題(25):運行下面的C++代碼,打印的結果是什么?

[cpp] view plaincopy
  1. class?Base??
  2. {??
  3. public:??
  4. ????voidprint()?{?doPrint();}??
  5. ??
  6. private:??
  7. ????virtual?void?doPrint()?{cout?<<?"Base::doPrint"?<<?endl;}??
  8. };??
  9. ??
  10. class?Derived?:?public?Base??
  11. {??
  12. private:??
  13. ????virtual?void?doPrint()?{cout?<<?"Derived::doPrint"?<<?endl;}??
  14. };??
  15. ??
  16. int?_tmain(int?argc,?_TCHAR*?argv[])??
  17. {??
  18. ????Base?b;??
  19. ????b.print();??
  20. ??
  21. ????Derived?d;??
  22. ????d.print();??
  23. ??
  24. ????return?0;??
  25. }??

答案:輸出兩行,分別是Base::doPrint和Derived::doPrint。在print中調用doPrint時,doPrint()的寫法和this->doPrint()是等價的,因此將根據實際的類型調用對應的doPrint。所以結果是分別調用的是Base::doPrint和Derived::doPrint2。如果感興趣,可以查看一下匯編代碼,就能看出來調用doPrint是從虛函數表中得到函數地址的。


博主何海濤對本博客文章享有版權。網絡轉載請注明出處http://blog.csdn.net/cadcisdhht。整理出版物請和作者聯系。有任何建議或意見,歡迎在評論中告知,或者加我微博http://weibo.com/zhedahht與我交流。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453606.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453606.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453606.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java byte md5_Java開發網 - byte[]按自定義編碼轉換成String(MD5)

差不多了&#xff0c;這樣應該就可以了&#xff0c;剩下的就是擴展能接受的類型了。import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class HashPasswords {public String getPassword(byte[] input) {byte[] digest;synchronized (…

Java線程生命周期

當你需要使用Java線程在多線程環境下進行編程時&#xff0c;理解Java的線程周期與線程的狀態是非常重要的。通過實現Runnale接口或者繼承Thread類&#xff0c;我們可以創建線程&#xff0c;為了啟動一個線程&#xff0c;我們需要創建一個Thread對象&#xff0c;并且調用它的sta…

轉,JSON解析2

JSON 使用講解 這篇文章講解了&#xff0c;JSON的介紹以及使用GSON解析。今天&#xff0c;我們就在Android項目中使用兩種方式解析JSON數據。如果你對JSON&#xff0c;還不熟悉&#xff0c;那么請看JSON 使用講解。 一.搭建服務以及制造JSON數據。 1.服務器選擇的Tomcat&#x…

面試問題匯總 精選 分析 解答 職業規劃 part 2

面試困惑問與答&#xff08;2&#xff09;——感覺挺好&#xff0c;為啥被拒了&#xff1f; 問&#xff1a;技術面試的時候&#xff0c;題目挺簡單的&#xff0c;我覺得自己都做出來了。可最后怎么還是被拒了啊&#xff1f; 答&#xff1a;面試被拒有很多種可能&#xff0c;比…

js順序加載

2019獨角獸企業重金招聘Python工程師標準>>> js想要順序加載&#xff0c;分開js代碼塊&#xff0c;jsp頁面在加載的時候&#xff0c;是順序加載&#xff0c;遇到<script></script>代碼塊&#xff0c;先加載完成&#xff0c;然后繼續往下&#xff0c;遇到…

java swingworker_Java中的SwingWorker

L&#xff06;F物質的輸出(因為您對EDT的不確定性有待測試)run:JButton openDialog >>> Is there EDT ??? trueWorker started >>> Is there EDT ??? falsewaiting 30secondsWorker endeded >>> Is there EDT ??? falsebefore JOptionP…

持續交付與滾動升級

介紹 持續交付是頻繁對軟件應用程序持續更新的概念. 這個想法使在大量頻繁的更新面前, 你不必等待在一個指定的特殊時間點, 并且使你的組織在響應過程中變得更好. 一些 Ansible 用戶每小時都在部署更新給他們的最終用戶甚至更加頻繁 – 每時每刻都有代碼修改的批準. 要實現這一…

2-05 使用固態存儲SSD或PCIe卡

在大量并發的情況下&#xff0c;才能體現固態磁盤的吞吐量&#xff0c;在大并發下提供良好隨機io的性能&#xff0c;這正是關系型數據庫所需要的&#xff0c;相對應機械磁盤&#xff0c;固態磁盤更容易損壞&#xff08;第三點是固態磁盤的缺點&#xff09;&#xff0c;由于固態…

面試問題匯總 精選 分析 解答 職業規劃 part 3

《劍指Offer——名企面試官精講典型編程題》已經出版 非常感謝博客上的讀者&#xff0c;是大家的關心、支持和鼓勵讓我有信心寫完這本書并最終出版發行&#xff08; china-pub互動網、 亞馬遜卓越網、 淘寶網、 京東網、 當當網上有售&#xff09;。網友們的鼓勵讓我在 博客上的…

java 分布式rpc框架_分布式RPC框架Apache Dubbo(一)

4 Dubbo快速入門Dubbo作為一個RPC框架&#xff0c;其最核心的功能就是要實現跨網絡的遠程調用。本小節就是要創建兩個應用&#xff0c;一個作為服務的提供方&#xff0c;一個作為服務的消費方。通過Dubbo來實現服務消費方遠程調用服務提供方的方法。4.1 服務提供方開發開發步驟…

輕松獲知數據庫事務

標題索引事務作用事務流程隔離級別實例驗證事務作用事務是確保數據庫系統數據的完整性的功能&#xff0c;如現在互聯網行業支付業務&#xff0c;不管服務器出于什么原因異常中斷&#xff0c;客戶要么支付成功要么支付不成功&#xff0c;支付成功數據庫金額即會發生變化&#xf…

Python冒泡排序(4)

Python代碼&#xff1a; """ 冒泡排序&#xff08;4&#xff09;在未排序的數中&#xff0c;通過兩兩比較[換位]的方式&#xff0c;將最小的數移至首位 N個數排序&#xff0c;則需要執行N-1輪&#xff0c;第1輪比較N-1次&#xff0c;后續每輪比上一輪少比較1次本…

打印hello world java_java – 如何打印“hello world”?

數字4946144450195624適合64位&#xff0c;其二進制表示為&#xff1a;10001100100100111110111111110111101100011000010101000該程序對每5位組的字符進行解碼&#xff0c;從右到左00100|01100|10010|01111|10111|11111|01111|01100|01100|00101|01000d | l | r | o | w | | o…

研發人員為什么留不住

研發人員為什么留不住&#xff1f;(1)——問題與現象 研發團隊做為公司的核心&#xff0c;承擔了完成項目為公司賺錢的目的。研發人員在公司倍受重視的同時&#xff0c;并沒有降低流失率。 問題與現象 以下問題相信您會在朋友口中&#xff0c;甚至自己的公司聽到。 老板說&a…

算法與編程--1

1、編寫一個程序&#xff0c;將a.txt文件中的單詞與b.txt文件中的單詞交替合并到c.txt文件中&#xff0c;a.txt文件中的單詞用回車符分隔&#xff0c;b.txt文件中用回車或空格進行分隔。 package com.test;import java.io.File; import java.io.FileNotFoundException; import …

Safari支不支持HTML5錄音? 現在瀏覽器中最好的解決方案是WebRTC下的 navigator.getUserMedia API。...

先放結論&#xff1a;Safari支不支持HTML5錄音&#xff1f; ——據我調查&#xff0c;不支持。 現在瀏覽器中最好的解決方案是WebRTC下的 navigator.getUserMedia API。 可是當使用Can I use查看兼容性的時候&#xff0c;我發現 不過這個是有歷史原因的&#xff0c;我記得RTC是…

python lambda map reduce_簡單了解python filter、map、reduce的區別

這篇文章主要介紹了簡單了解python filter、map、reduce的區別,文中通過示例代碼介紹的非常詳細&#xff0c;對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下python中有一些非常有趣的函數&#xff0c;面試的時候可能會遇到。今天也來總結一下&#xff0c;不…

面試問題匯總 精選 分析 解答 職業規劃 part 4

程序員做業余項目、記筆記和寫博客的重要性【經典】 編程是一種創造過程&#xff0c;業余項目允許程序員在沒有截止日期或各種限制的條件下&#xff0c;以探索形式編程。業余項目之所以重要&#xff0c;有以下幾個原因。 探索新技術 每天都會不斷有新技術出現&#xff0c;而…

NB-IOT連接移動onenet平臺流程

1. 先創建賬號&#xff0c;然后創建產品 2. 創建設備&#xff0c;用ATCGSN和ATCIMI查詢NB-IOT的IMEI和IMSI填寫上去。 3. 創建好的設備。 轉載于:https://www.cnblogs.com/429512065qhq/p/8359247.html

sort,uniq,wc指令簡單用法

sort用于排序&#xff0c;可以根據不同的數據類型來進行排序&#xff0c;例如想要查看最后一個登陸的用戶信息&#xff0c;可以把last和sort結合起來使用&#xff0c;按照登陸時間排序。 使用sort排序&#xff1a; sort常用參數&#xff1a; -f &#xff1a;忽略大小寫的差異 -…