題目(六):運(yùn)行下列C++代碼,輸出什么?structPoint3D{intx;inty;intz;};int_tmain(intargc, _TCHAR* argv[]){Point3D* pPoint = NU
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的前面加上了取地址符號(hào),運(yùn)行到此時(shí)的時(shí)候,會(huì)在pPoint的指針地址上加z在類(lèi)型Point3D中的偏移量8。由于pPoint的地址是0,因此最終offset的值是8。
&(pPoint->z)的語(yǔ)意是求pPoint中變量z的地址(pPoint的地址0加z的偏移量8),并不需要訪(fǎng)問(wèn)pPoint指向的內(nèi)存。只要不訪(fǎng)問(wèn)非法的內(nèi)存,程序就不會(huì)出錯(cuò)。
題目(七):運(yùn)行下列C++代碼,輸出什么?
class A
{
public:
A()
{
Print();
}
virtual void Print()
{
printf("A is constructed.\n");
}
};
class B: public A
{
public:
B()
{
Print();
}
virtual void 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. 調(diào)用B的構(gòu)造函數(shù)時(shí),先會(huì)調(diào)用B的基類(lèi)及A的構(gòu)造函數(shù)。然后在A的構(gòu)造函數(shù)里調(diào)用Print。由于此時(shí)實(shí)例的類(lèi)型B的部分還沒(méi)有構(gòu)造好,本質(zhì)上它只是A的一個(gè)實(shí)例,他的虛函數(shù)表指針指向的是類(lèi)型A的虛函數(shù)表。因此此時(shí)調(diào)用的Print是A::Print,而不是B::Print。接著調(diào)用類(lèi)型B的構(gòu)造函數(shù),并調(diào)用Print。此時(shí)已經(jīng)開(kāi)始構(gòu)造B,因此此時(shí)調(diào)用的Print是B::Print。
同樣是調(diào)用虛擬函數(shù)Print,我們發(fā)現(xiàn)在類(lèi)型A的構(gòu)造函數(shù)中,調(diào)用的是A::Print,在B的構(gòu)造函數(shù)中,調(diào)用的是B::Print。因此虛函數(shù)在構(gòu)造函數(shù)中,已經(jīng)失去了虛函數(shù)的動(dòng)態(tài)綁定特性。
題目(八):運(yùn)行下列C#代碼,輸出是什么?
namespace ChangesOnString
{
class Program
{
static void Main(string[] args)
{
String str = "hello";
str.ToUpper();
str.Insert(0, " WORLD");
Console.WriteLine(str);
}
}
}
答案:輸出是hello。由于在.NET中,String有一個(gè)非常特殊的性質(zhì):String的實(shí)例的狀態(tài)不能被改變。如果String的成員函數(shù)會(huì)修改實(shí)例的狀態(tài),將會(huì)返回一個(gè)新的String實(shí)例。改動(dòng)只會(huì)出現(xiàn)在返回值中,而不會(huì)修改原來(lái)的實(shí)例。所以本題中輸出仍然是原來(lái)的字符串值hello。
如果試圖改變String的內(nèi)容,改變之后的值可以通過(guò)返回值拿到。用StringBuilder是更好的選擇,特別是要連續(xù)多次修改的時(shí)候。如果用String連續(xù)多次修改,每一次修改都會(huì)產(chǎn)生一個(gè)臨時(shí)對(duì)象,開(kāi)銷(xiāo)太大。
題目(九):在C++和C#中,struct和class有什么不同?
答案:在C++中,如果沒(méi)有標(biāo)明函數(shù)或者變量是的訪(fǎng)問(wèn)權(quán)限級(jí)別,在struct中,是public的;而在class中,是private的。
在C#中,如果沒(méi)有標(biāo)明函數(shù)或者變量的訪(fǎng)問(wèn)權(quán)限級(jí)別,struct和class中都是private的。struct和class的區(qū)別是:struct定義值類(lèi)型,其實(shí)例在棧上分配內(nèi)存;class定義引用類(lèi)型,其實(shí)例在堆上分配內(nèi)存。
題目(十):運(yùn)行下圖中的C#代碼,輸出是什么?
namespace StaticConstructor
{
class A
{
public A(string text)
{
Console.WriteLine(text);
}
}
class B
{
static A a1 = new A("a1");
A a2 = new A("a2");
static B()
{
a1 = new A("a3");
}
public B()
{
a2 = new A("a4");
}
}
class Program
{
static void Main(string[] args)
{
B b = new B();
}
}
}
答案:打印出四行,分別是a1、a3、a2、a4。
在調(diào)用類(lèi)型B的代碼之前先執(zhí)行B的靜態(tài)構(gòu)造函數(shù)。靜態(tài)函數(shù)先初始化類(lèi)型的靜態(tài)變量,再執(zhí)行靜態(tài)函數(shù)內(nèi)的語(yǔ)句。因此先打印a1再打印a3。接下來(lái)執(zhí)行B b = new B(),即調(diào)用B的普通構(gòu)造函數(shù)。構(gòu)造函數(shù)先初始化成員變量,在執(zhí)行函數(shù)體內(nèi)的語(yǔ)句,因此先后打印出a2、a4。
Python交流群
635448130點(diǎn)擊加入群聊UI設(shè)計(jì)交流群
579150876點(diǎn)擊加入群聊Unity交流群
495609038點(diǎn)擊加入群聊HTML5交流群
645591648點(diǎn)擊加入群聊