char c = '72';
中的72代表1個(gè)字符,72是8進(jìn)制數(shù),代表ASCII碼字符“:”。
10*a++
中a先進(jìn)行乘法運(yùn)算再自增(筆試中常常喜歡出這類運(yùn)算符優(yōu)先級(jí)容易混淆的輸出問(wèn)題)。
const和static的作用
太常見的問(wèn)題了,下面給出1個(gè)較詳細(xì)的參考答案:
static關(guān)鍵字:
1)函數(shù)體內(nèi)static變量的作用范圍為函數(shù)體。不同于auto變量。該變量的內(nèi)存只被分配1次。因此其值在下次調(diào)用時(shí)仍保持上次的值。
2)在模塊內(nèi)的static全局變量可以被模塊內(nèi)的所有函數(shù)訪問(wèn)。但不能被模塊外的其他函數(shù)訪問(wèn)。
3)在模塊內(nèi)的static函數(shù)只可被這1模塊內(nèi)的其它函數(shù)調(diào)用。這個(gè)函數(shù)的使用范圍被限制在聲明它的模塊內(nèi)。
4)在類中的static成員變量屬于全部類所有,對(duì)類的所有對(duì)象只有1份復(fù)制。
5)在類中的static成員函數(shù)屬于全部類所有,這個(gè)函數(shù)不接受this指針,因此只能訪問(wèn)類的static成員變量。
const關(guān)鍵字:
1)欲禁止1個(gè)變量被改變,可使用const關(guān)鍵字。在定義該const變量時(shí),通常需要對(duì)它進(jìn)行初始化。由于以后就沒(méi)有機(jī)會(huì)再改變它了。
2)對(duì)指針來(lái)講,可以指定指針的本身為const,也能夠指定指針?biāo)赶虻臄?shù)為const。或2者同時(shí)為const。
3)在1個(gè)函數(shù)的聲明中,const可以修飾形參,表明它是1個(gè)輸入?yún)?shù)。在函數(shù)內(nèi)不能改變其值。
4)對(duì)類的成員函數(shù),若指定其為const類型。則表明其是1個(gè)常量函數(shù)。不能修改類的成員變量。
5)對(duì)類的成員函數(shù),有時(shí)候必須指定其返回值為const類型。以使得其返回值不為“左值”。
注意sizeof不是函數(shù)而是運(yùn)算符,所以在計(jì)算變量所占用空間大小時(shí),括號(hào)是可以省略的,但在計(jì)算類型大小時(shí)括號(hào)則不能省略,比如int i = 0; 則sizeof int是毛病的。
有1,2,…,n的無(wú)序數(shù)組,求排序算法,并且要求時(shí)間復(fù)雜度為O(n),空間復(fù)雜度O(1),使用交換,而且1次只能交換兩個(gè)數(shù)。
#include <stdio.h>
int main() {
int a[] = {10, 6, 9, 5, 2, 8, 4, 7, 1, 3};
int i, tmp;
int len = sizeof(a) / sizeof(a[0]);
for(i = 0; i < len;) {
tmp = a[a[i] - 1];
a[a[i] - 1] = a[i];
a[i] = tmp;
if(a[i] == i + 1) i++;
}
for(i = 0; i < len; ++i)
printf("%d ", a[i]);
printf("
");
return 0;
}
易誤解:如果int a[5]
, 那末a與&a是等價(jià)的,由于二者地址相同。
解答:1定要注意a與&a是不1樣的,雖然二者地址相同,但意義不1樣,&a是全部數(shù)組對(duì)象的首地址,而a是數(shù)組首地址,也就是a[0]的地址,a的類型是int[5],a[0]的類型是int,因此&a+1相當(dāng)于a的地址值加上sizeof(int) * 5,也就是a[5],下1個(gè)對(duì)象的地址,已越界了,而a+1相當(dāng)于a的地址加上sizeof(int),即a[1]的地址。
如何將1個(gè)小數(shù)分解成整數(shù)部份和小數(shù)部份?
要記得利用頭文件中的庫(kù)函數(shù)modf,下面是函數(shù)原型(記住1些實(shí)用的庫(kù)函數(shù),避免自己重寫):
double modf(double num, double *i); // 將num分解為整數(shù)部份*i和小數(shù)部份(返回值決定)
可作為函數(shù)重載判斷根據(jù)的有:參數(shù)個(gè)數(shù)、參數(shù)類型、const修飾符;
不可以作為重載判斷根據(jù)的有:返回類型。
程序輸出題:
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *p = &(a + 1)[3];
printf("%d
", *p);
輸出:5
說(shuō)明:由于a+1指向a的第2個(gè)元素,[3]表示再向后移動(dòng)3個(gè)元素。
程序輸出題:
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char *str5 = "abc";
const char *str6 = "abc";
char *str7 = "abc";
char *str8 = "abc";
cout << (str1 == str2) << endl;
cout << (str3 == str4) << endl;
cout << (str5 == str6) << endl;
cout << (str7 == str8) << endl;
輸出:0 0 1 1
說(shuō)明:輸出str1~str8的地址為:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x23aa48
0x23aa40
0x23aa38
0x23aa30
輸出str1~str8內(nèi)容“abc”的存儲(chǔ)地址為:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x100403030
0x100403030
0x100403030
0x100403030
可以發(fā)現(xiàn)str1~str4中的內(nèi)容是存在棧上,地址各不相同,而str5~str8的內(nèi)容都是存儲(chǔ)在常量區(qū),所以地址都相同。
注意:
char *str = "abc";
printf("%p
", str1);
cout << &str1 << endl;
上面打印的是字符串 “abc”的地址,下面打印的是 str1 變量的地址。
C的結(jié)構(gòu)體和C++結(jié)構(gòu)體的區(qū)分
(1)C的結(jié)構(gòu)體內(nèi)不允許有函數(shù)存在,C++允許有內(nèi)部成員函數(shù),且允許該函數(shù)是虛函數(shù)。所以C的結(jié)構(gòu)體是沒(méi)有構(gòu)造函數(shù)、析構(gòu)函數(shù)、和this指針的。
(2)C的結(jié)構(gòu)體對(duì)內(nèi)部成員變量的訪問(wèn)權(quán)限只能是public,而C++允許public,protected,private3種。
(3)C語(yǔ)言的結(jié)構(gòu)體是不可以繼承的,C++的結(jié)構(gòu)體是可以從其他的結(jié)構(gòu)體或類繼承過(guò)來(lái)的。
以上都是表面的區(qū)分,實(shí)際區(qū)分就是面向進(jìn)程和面向?qū)ο缶幊趟悸返膮^(qū)分:
C的結(jié)構(gòu)體只是把數(shù)據(jù)變量給包裹起來(lái)了,其實(shí)不觸及算法。
而C++是把數(shù)據(jù)變量及對(duì)這些數(shù)據(jù)變量的相干算法給封裝起來(lái),并且給對(duì)這些數(shù)據(jù)和類不同的訪問(wèn)權(quán)限。
C語(yǔ)言中是沒(méi)有類的概念的,但是C語(yǔ)言可以通過(guò)結(jié)構(gòu)體內(nèi)創(chuàng)建函數(shù)指針實(shí)現(xiàn)面向?qū)ο笏枷搿?/p>
如何在類中定義常量成員并為其初始化?
解答:只能在初始化列表里對(duì)const成員初始化,像下面這樣:
class CBook {
public:
const double m_price;
CBook() :m_price(8.8) { }
};
下面的做法是毛病的:
class CBook {
public:
const double m_price;
CBook() {
m_price = 8.8;
}
};
而下面的做法雖未報(bào)錯(cuò),但有個(gè)warning,也不推薦:
class CBook {
public:
const double m_price = 8.8; // 注意這里若沒(méi)有const則編譯出錯(cuò)
CBook() { }
};
在定義類的成員函數(shù)時(shí)使用mutable關(guān)鍵字的作用是甚么?
解答:當(dāng)需要在const方法中修改對(duì)象的數(shù)據(jù)成員時(shí),可以在數(shù)據(jù)成員前使用mutable關(guān)鍵字,避免出現(xiàn)編譯出錯(cuò)。例子以下:
class CBook {
public:
mutable double m_price; // 如果不加就會(huì)出錯(cuò)
CBook(double price) :m_price(price) { }
double getPrice() const; // 定義const方法
};
double CBook::getPrice() const {
m_price = 9.8;
return m_price;
}
構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、析構(gòu)函數(shù)的調(diào)用點(diǎn)溫柔序問(wèn)題,以下面這個(gè)例子輸出是甚么?
class CBook {
public:
CBook() {
cout << "constructor is called.
";
}
~CBook() {
cout << "destructor is called.
";
}
};
void invoke(CBook book) { // 對(duì)象作為函數(shù)參數(shù),如果這里加了個(gè)&就不是了,由于加了&后是援用方式傳遞,形參和實(shí)參指向同1塊地
// 址,就不需要?jiǎng)?chuàng)建臨時(shí)對(duì)象,也就不需要調(diào)用拷貝構(gòu)造函數(shù)了
cout << "invoke is called.
";
}
int main() {
CBook c;
invoke(c);
}
解答:注意拷貝構(gòu)造函數(shù)在對(duì)象作為函數(shù)參數(shù)傳遞時(shí)被調(diào)用,注意是對(duì)象實(shí)例而不是對(duì)象援用。因此該題輸出以下:
constructor is called.
invoke is called.
destructor is called. // 在invoke函數(shù)調(diào)用結(jié)束時(shí)還要釋放拷貝構(gòu)造函數(shù)創(chuàng)建的臨時(shí)對(duì)象,因此這里還調(diào)用了個(gè)析構(gòu)函數(shù)
destructor is called.
引伸:拷貝構(gòu)造函數(shù)在哪些情況下被調(diào)用?
(1)函數(shù)的參數(shù)為類對(duì)象且參數(shù)采取值傳遞方式;
(2)將類對(duì)象做為函數(shù)的返回值。
C++中的explicit關(guān)鍵字有何作用?
解答:制止將構(gòu)造函數(shù)作為轉(zhuǎn)換函數(shù),即制止構(gòu)造函數(shù)自動(dòng)進(jìn)行隱式類型轉(zhuǎn)換。
例如CBook中只有1個(gè)參數(shù)m_price,在構(gòu)建對(duì)象時(shí)可使用CBook c = 9.8這樣的隱式轉(zhuǎn)換,使用explicit避免這類轉(zhuǎn)換產(chǎn)生。
在C++中,如果肯定了某1個(gè)構(gòu)造函數(shù)的創(chuàng)建進(jìn)程,在該構(gòu)造函數(shù)中如果調(diào)用了其它重載的構(gòu)造函數(shù),它將不會(huì)履行其它構(gòu)造函數(shù)的初始化列表部份代碼,而是履行函數(shù)體代碼,此時(shí)已退化成普通函數(shù)了。例子說(shuō)明以下:
class CBook {
public:
double m_price;
CBook() {
CBook(8.8);
}
CBook(double price) : m_price(price) { }
};
int main() {
CBook c;
cout << c.m_price << endl; // 此時(shí)其實(shí)不會(huì)輸出理想中的8.8
}
靜態(tài)數(shù)據(jù)成員只能在全局區(qū)域進(jìn)行初始化,而不能在類體中進(jìn)行(構(gòu)造函數(shù)中初始化也不行),且靜態(tài)數(shù)據(jù)成員不觸及對(duì)象,因此不受類訪問(wèn)限定符的限制。
例子說(shuō)明以下:
class CBook {
public:
static double m_price;
};
double CBook::m_price = 8.8; // 只能在這初始化,不能在CBook的構(gòu)造函數(shù)或直接初始化
C++中可以重載的運(yùn)算符:new/delete、new[]/delete[]、++等。
不可以重載的運(yùn)算符:、.、::、?:、sizeof、typeid、.、**、不能改變運(yùn)算符的優(yōu)先級(jí)。
引伸:重載++和
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)