目錄
選擇題
單選
編程題
統(tǒng)計(jì)回文?
【題目解析】
【解題思路?- 窮舉】
【優(yōu)化】
連續(xù)最大和?
【題目解析】
【解題思路】
【空間優(yōu)化】
選擇題
單選
int x = 1;
do {
printf("%2d\n", x++);
} while (x--);




正確答案:
解析:
- do while循環(huán)是先執(zhí)行do再執(zhí)行while的條件判斷。
- x++:后置++,先使用x的值然后再x + 1,所以此處是輸出時(shí)可以說恒等于1,where判斷的時(shí)候x恒等于2進(jìn)行x--等于1,于是陷入死循環(huán)。
- 格式化輸出:
??????來源printf 函數(shù)轉(zhuǎn)換說明完整格式詳解-CSDN博客
精度:
- 對(duì)于整型數(shù)據(jù)類型(如:int、long、short),精度修飾符沒有任何作用,會(huì)被忽略。
- 對(duì)于浮點(diǎn)數(shù)數(shù)據(jù)類型(如:float、double),可以使用格式說明符%.nf來指定輸出的小數(shù)位數(shù)。例如:%.2f表示保留兩位小數(shù)。
- 對(duì)于字符型數(shù)據(jù)類型(如:char),精度修飾符也沒有任何作用,會(huì)被忽略。
- 對(duì)于字符串類型(如:char*),可以使用格式說明符%.ns來指定輸出的字符個(gè)數(shù)。例如:%.5s表示只輸出字符串的前五個(gè)字符。
數(shù)據(jù)長(zhǎng)度與字段寬度與精度的關(guān)系:
- 字符串:%m.ns
- 字符串長(zhǎng)度 >?n?>?m:此時(shí)m的作用失效,是只受n的控制。
const char* str = "abcdefg"; printf("%2.5s\n", str); //abcde
- m?>?n:是右對(duì)齊補(bǔ)空格。
const char* str = "abcdefg"; printf("%5.2s\n", str); // ab
- n?> 字符串長(zhǎng)度:作用與%s一樣。
const char* str = "abcdefg"; printf("%5.100s\n", str); //abcdefg
- 浮點(diǎn)數(shù):%m.nf
- m < 整數(shù)部分 + n:此時(shí)m的作用失效,是只受n的控制。
float number = 202383.1415; printf("%4.1f\n", number); //202383.1
- m >?整數(shù)部分 + n:是右對(duì)齊補(bǔ)空格。
float number = 202383.1415; printf("%10.1f\n", number); // 202383.1
- n?> 小數(shù)位數(shù):注意,在指定精度時(shí)要確保實(shí)際數(shù)據(jù)長(zhǎng)度大于精度才有意義,否則可能會(huì)導(dǎo)致不必要的錯(cuò)誤或者無法預(yù)料的結(jié)果。
float number = 202383.1415; printf("%20.10f\n", number); // 202383.1406250000
----------------------------------------------




正確答案:
?
解析:
- sizeof 求變量對(duì)應(yīng)類型所占字節(jié)數(shù):C語(yǔ)言字符串結(jié)尾最后會(huì)自動(dòng)補(bǔ)充一個(gè)'\0',所以為:9 + 1。
- strlen求字符串的有效長(zhǎng)度不包含 '\0' 在內(nèi):該字符串第5個(gè)字符為'\0',所以為:4。
----------------------------------------------
char p1[15] = "abcd", * p2 = "ABCD", str[50] = "xyz";
strcpy(str + 2, strcat(p1 + 2, p2 + 1));
printf("%s", str);




正確答案:
解析:
- char?p1[15] = "abcd";一維數(shù)組。
- char?* p2 = "ABCD"; 指向常量字符串,該字符串中的內(nèi)容是不能被修改的,存儲(chǔ)在代碼段。
- char str[50] = "xyz";一維數(shù)組。
字符串函數(shù)功能:
- strcpy(dest, src):將src字符串中的內(nèi)容拷貝到dest所在的空間中,最后返回dest。(注意:dest的空間大小一定要能夠存的下src中的字符總數(shù),否則程序會(huì)崩潰)
- strcat(dest, src):將src字符串中的內(nèi)容拼接在dest字符串之后,最終返回dest。(注意:dest空間一定要能夠容忍下src拼接進(jìn)來的字符,否則程序會(huì)崩潰)
strcat(p1 + 2, p2 + 1): "cd" 拼接 "BCD" 為 "cdBCD" 。
strcpy(str + 2, "cdBCD"):將 "cdBCD" 拷貝到str+2的位置為 "xycdBCD" 。
----------------------------------------------
#include<iosteam.h>
void main() {
int n[][3] = { 10,20,30,40,50,60 };
int(*p)[3];
p = n;
cout << p[0][0] << "," << *(p[0] + 1) << "," << (*p)[2] << endl;
}




正確答案:
解析:
????????二維數(shù)組的行可以省略,所以n是兩行三列的二維數(shù)組。
????????int(*p)[3]:是數(shù)組指針,本質(zhì)是一個(gè)指針,該指針只能指向具有3個(gè)int類型元素的一段連續(xù)空間。
? ? ? ? 數(shù)組名表示的就是數(shù)組搜元素的地址,此處二維數(shù)組n的每一個(gè)元素實(shí)際上就是一個(gè)一維數(shù)組int[3],n的二維數(shù)組中,首元素的地址就是int(*)[3]。
- p[0][0] == *(*(p + 0) + 0)
- *(p[0] + 1) ==?*(*(p + 0) + 1)
- (*p)[2] == *(*(p + 0) + 2)
????????所以,最后顯示的全是第0行,第一個(gè)元素,第二個(gè)元素。第三個(gè)元素。
----------------------------------------------



正確答案:
解析:
- main函數(shù)可以放在任何位置,只要不放在某一個(gè)函數(shù)的定義之內(nèi)即可。
- 在C / C++中,函數(shù)的定義是不能嵌套的。
----------------------------------------------
#include <iostream>
using namespace std;
char fun(char x, char y) {
if (x < y)
return x;
return y;
}
int main() {
int a = '1', b = '1', c = '2';
cout << fun(fun(a, b), fun(b, c));
return 0;
}




正確答案:
解析:
????????可以看出fun函數(shù)的算法是拿出x和y中的最小值。
----------------------------------------------




正確答案:
解析:
????????int* pa[5]:pa是一個(gè)指針數(shù)組,該數(shù)組中的每個(gè)元素都是 int* 類型的指針。
----------------------------------------------
struct One {
double d;
char c;
int i;
}
struct Two {
char c;
double d;
int i;
}




正確答案:
解析:
結(jié)構(gòu)體的大小計(jì)算遵循結(jié)構(gòu)體的對(duì)齊規(guī)則:
結(jié)構(gòu)體的第一個(gè)成員放在結(jié)構(gòu)體變量在內(nèi)存中存儲(chǔ)位置的0偏移處開始
從第2個(gè)成員往后的所有成員,都要放在一個(gè)對(duì)齊數(shù)(成員的大小和默認(rèn)對(duì)齊數(shù)的較小值)的整數(shù)的整數(shù)倍的地址處,VS中默認(rèn)對(duì)齊數(shù)為8
結(jié)構(gòu)體的總大小是結(jié)構(gòu)體的所有成員的對(duì)齊數(shù)中最大對(duì)齊數(shù)的整數(shù)倍。
如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的最大對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍
? ? ? ? #注:VS中的默認(rèn)對(duì)齊數(shù)為8,不是所有編譯器都有默認(rèn)對(duì)齊數(shù),當(dāng)編譯器沒有默認(rèn)對(duì)齊數(shù)的時(shí)候,成員變量的大小就是該成員的對(duì)齊數(shù)。(Linux中就沒有默認(rèn)對(duì)齊數(shù)概念)
補(bǔ)充:
#結(jié)構(gòu)體為什么要內(nèi)存對(duì)齊?
- 平臺(tái)原因(移植原因):
- 不是所有的硬件平臺(tái)都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。
- 性能原因:
- 數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。原因在于,為了訪問未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對(duì)齊的內(nèi)存訪問僅需要一次訪問。
總體來說:結(jié)構(gòu)體的內(nèi)存對(duì)齊是拿空間來?yè)Q取時(shí)間的做法。
----------------------------------------------




正確答案:
解析:
????????既然是要訪問用來引用,那肯定需要解引用,已知:a[1] == *(a + 1)。
- *(*(*(*(a+i)+j)+k)+l)? ==??*(*(*(a+i)+j)+k)[l]? ==? *(*(a+i)+j)[k][l]? ==? *(a+i)[j][k][l]? ==??a[i][j][k][l]
----------------------------------------------




正確答案:
解析:
知識(shí)鋪墊:
? ? ? ? 現(xiàn)在所使用的編譯器為滿足復(fù)雜的軟件開發(fā)需求,如:Linux下使用的GCC,是被稱為 編譯器套裝 ,是因?yàn)樗粌H僅包含了一個(gè)編譯器,而是由多個(gè)編譯器及相關(guān)工具組成的一個(gè)完整的編程環(huán)境。除了g++、gcc和gfortran等編譯器之外,GCC還包括了預(yù)處理器、匯編器、鏈接器等多個(gè)工具。這些工具協(xié)同工作,可以將源代碼轉(zhuǎn)換成可執(zhí)行文件或庫(kù)文件。?
????????因此,GCC被稱為編譯器套裝是因?yàn)樗峁┝送暾木幾g、鏈接和調(diào)試工具鏈,能夠滿足復(fù)雜的軟件開發(fā)需求。
(VS2019、DEV C++等,被稱作集成開發(fā)環(huán)境-IDE,其具備編輯、預(yù)處理、編譯、匯編、鏈接、調(diào)試、運(yùn)行)
階段:??
- 編輯(編輯器):將程序員 編寫源代碼 保存到文件中,并進(jìn)行必要的格式化處理。
- 預(yù)處理(編譯器):完成包含的?頭文件的展開?、?注釋刪除?、?define宏替換?、?條件編譯?等,最終形成?xxx.i 文件。頭文件是不參與編譯的,因?yàn)樵陬A(yù)處理階段已經(jīng)將頭文件展開了,編譯只對(duì)源文件進(jìn)行編譯。
? ? ? ? 鏈接之前每個(gè)源文件都是獨(dú)立的單元,它們之間并沒有直接的聯(lián)系。在鏈接階段,編譯器才會(huì)將這些獨(dú)立的目標(biāo)文件鏈接在一起,生成可執(zhí)行文件或者共享庫(kù)。
????????使用條件編譯和#pragma?once:能夠防止一個(gè)源文件內(nèi)多次包含同一個(gè)頭文件,即能夠確保在多個(gè)源文件下,各個(gè)源文件對(duì)于同一個(gè)頭文件各自只包含一次。
- 編譯(編譯器):完成 詞法分析 、 語(yǔ)法分析 、 語(yǔ)義分析 、 符號(hào)匯總 等(編譯器對(duì)源代碼語(yǔ)法規(guī)則進(jìn)行檢測(cè),如此才可以交付后續(xù)轉(zhuǎn)換為可執(zhí)行代碼),檢查無誤后將代碼翻譯成 匯編 指令,最終形成 xxx.s 文件。
匯編(編譯器):將 匯編 指令轉(zhuǎn)換成 二進(jìn)制 指令,形成 符號(hào)表 ,最終形成 xxx.o 文件。
鏈接(編譯器):將生成的各個(gè) xxx.o 文件進(jìn)行 鏈接 , 合并段表 、 符號(hào)表的合并和重定位 ,最終形成 .exe(.out) 可執(zhí)行程序。
運(yùn)行(計(jì)算機(jī)執(zhí)行):?.exe(.out) 可執(zhí)行程序會(huì)被加載到內(nèi)存中,并按照預(yù)定的邏輯進(jìn)行計(jì)算和處理。
各類階段錯(cuò)誤:
- 預(yù)處理錯(cuò)誤:程序編譯之前發(fā)生的錯(cuò)誤,這些錯(cuò)誤通常與頭文件、宏定義、條件編譯等相關(guān)。
- 找不到頭文件:當(dāng)程序中引用了不存在的頭文件時(shí),會(huì)發(fā)生找不到頭文件的錯(cuò)誤。
- 宏定義問題:當(dāng)程序中使用了未定義或重復(fù)定義的宏時(shí),會(huì)發(fā)生宏定義問題。
- 條件編譯問題:當(dāng)程序中使用了不正確的條件編譯語(yǔ)句時(shí),會(huì)發(fā)生條件編譯問題。
- 編碼格式問題:當(dāng)程序中出現(xiàn)了不支持的編碼格式時(shí),會(huì)發(fā)生編碼格式問題。
- 編譯錯(cuò)誤:編譯器會(huì)檢測(cè)代碼中存在的錯(cuò)誤。如有錯(cuò)誤,則會(huì)導(dǎo)致程序無法通過編譯,并給出相應(yīng)的錯(cuò)誤提示信息,指出哪一行代碼存在問題以及具體的錯(cuò)誤類型。
- 語(yǔ)法錯(cuò)誤(Syntax?Error):代碼中存在拼寫錯(cuò)誤、缺少分號(hào)、括號(hào)不匹配等語(yǔ)法問題。
- 未定義變量(Undefined?Variable?Error):在程序中引用了未定義的變量。
- 類型錯(cuò)誤(Type?Error):代碼中使用了不兼容的數(shù)據(jù)類型,例如:將字符串賦值給整數(shù)變量。
- 函數(shù)調(diào)用錯(cuò)誤(Function?Call?Error):函數(shù)調(diào)用參數(shù)數(shù)量不匹配、參數(shù)類型不正確等問題。
- 頭文件引用錯(cuò)誤(Header?File?Error):頭文件不存在或者路徑不正確等問題。
- 環(huán)境配置錯(cuò)誤(Environment?Configuration?Error):編譯器或者開發(fā)環(huán)境配置不正確導(dǎo)致編譯失敗。
- 內(nèi)存錯(cuò)誤(Memory?Error):程序訪問了無效的內(nèi)存地址,例如:空指針引用等。
- 重復(fù)定義(Redeclaration?Error):在同一作用域中重復(fù)定義變量、函數(shù)等。
- 編譯器警告(Compiler Warning):這種警告通常是編譯器發(fā)現(xiàn)了代碼中可能存在問題或潛在風(fēng)險(xiǎn),例如:未使用的變量、類型轉(zhuǎn)換可能會(huì)丟失精度等,出現(xiàn)在編譯階段。
- 鏈接錯(cuò)誤:也稱為連接錯(cuò)誤,鏈接器將多個(gè)目標(biāo)文件和庫(kù)文件合并成一個(gè)可執(zhí)行程序,并需要解決符號(hào)引用和符號(hào)定義之間的關(guān)系。如果檢測(cè)到錯(cuò)誤,鏈接器將停止鏈接并顯示錯(cuò)誤消息。
- 未定義符號(hào)(Undefined?Symbol?Error):使用未定義的函數(shù)或變量。
- 手誤拼寫了變量、函數(shù)或?qū)ο蟮拿Q。
- 沒有包含必要的頭文件。
- 在使用外部庫(kù)時(shí),沒有正確地鏈接庫(kù)文件。
- 在多個(gè)源文件中使用同一個(gè)全局變量,但只在其中一個(gè)源文件中進(jìn)行了定義。
- 重復(fù)定義符號(hào)(Duplicate?Symbol?Error):多次定義同一個(gè)函數(shù)或變量。
- 頭文件重復(fù)包含:如果多個(gè)源文件都包含同一個(gè)頭文件,并且該頭文件中定義了全局變量或函數(shù),那么在編譯時(shí)就會(huì)出現(xiàn)重復(fù)定義符號(hào)錯(cuò)誤。
- 全局變量重復(fù)定義:如果多個(gè)源文件中都定義了同名的全局變量,并且這些變量的作用域超出了各自的源文件范圍,那么在鏈接時(shí)就會(huì)出現(xiàn)重復(fù)定義符號(hào)錯(cuò)誤。
- 函數(shù)重復(fù)定義:如果多個(gè)源文件中都定義了同名的函數(shù),并且這些函數(shù)的作用域超出了各自的源文件范圍,那么在鏈接時(shí)就會(huì)出現(xiàn)重復(fù)定義符號(hào)錯(cuò)誤。
多文件 (嵌套文件包含) 編譯的重點(diǎn)問題 -> 解決方案 在頭文件中只聲明變量和函數(shù),而不要定義它們,在一個(gè)源文件中定義變量和函數(shù),并將其它源文件需要使用的聲明放在頭文件中。 使用?static?關(guān)鍵字來限制變量的作用域,避免在不同源文件中產(chǎn)生沖突。 使用?條件編譯 和 #pragma?once?預(yù)處理指令來避免頭文件被重復(fù)引用。 使用 命名空間 等技術(shù)來避免符號(hào)沖突問題。 - 缺少庫(kù)文件:使用未包含或版本不兼容的庫(kù)文件。
- 符號(hào)沖突:不同目標(biāo)文件包含具有相同名稱但實(shí)現(xiàn)不同的函數(shù)或變量。
- 重復(fù)定義變量或函數(shù)名:在程序中定義了兩個(gè)或多個(gè)同名的變量或函數(shù)。
- 重復(fù)定義標(biāo)簽:在程序中定義了兩個(gè)或多個(gè)同名的標(biāo)簽。
- 命名規(guī)則不規(guī)范:在程序中使用了與匯編器保留字相同的名稱,導(dǎo)致匯編器無法識(shí)別。
- 頭文件包含重復(fù)定義的內(nèi)容:頭文件中包含了與當(dāng)前程序中已有的變量、函數(shù)等同名的內(nèi)容。
- 模塊之間命名沖突:在一個(gè)大型項(xiàng)目中,不同模塊之間可能會(huì)出現(xiàn)命名沖突問題。
- 宏定義名稱重復(fù):在宏定義時(shí)使用了與已有宏定義相同的名稱。
- 數(shù)據(jù)對(duì)齊錯(cuò)誤:在不同的目標(biāo)文件中使用了不同的數(shù)據(jù)對(duì)齊方法。
- 訪問未對(duì)齊的地址:當(dāng)訪問一個(gè)未按照對(duì)齊方式對(duì)齊的內(nèi)存地址時(shí),會(huì)出現(xiàn)數(shù)據(jù)對(duì)齊錯(cuò)誤。
- 結(jié)構(gòu)體成員對(duì)齊不一致:結(jié)構(gòu)體成員在默認(rèn)情況下按照其自身大小進(jìn)行對(duì)齊,但可以通過編譯器指定結(jié)構(gòu)體成員的對(duì)齊方式。如果不同結(jié)構(gòu)體成員的對(duì)齊方式不一致,可能會(huì)導(dǎo)致數(shù)據(jù)對(duì)齊錯(cuò)誤。
- 指針類型不匹配:一個(gè)指針指向的內(nèi)存區(qū)域按照某種對(duì)齊方式進(jìn)行對(duì)齊時(shí),如果將該指針強(qiáng)制轉(zhuǎn)換成另一種類型的指針,而新類型的對(duì)齊方式與原先的不同,就可能會(huì)導(dǎo)致數(shù)據(jù)對(duì)齊錯(cuò)誤。例如:將一個(gè)按照8字節(jié)對(duì)齊方式進(jìn)行對(duì)齊的double類型數(shù)組強(qiáng)制轉(zhuǎn)換成int類型數(shù)組的指針,可能會(huì)導(dǎo)致數(shù)據(jù)對(duì)齊錯(cuò)誤。
- 編譯器優(yōu)化:編譯器在進(jìn)行優(yōu)化時(shí)可能會(huì)改變內(nèi)存布局,從而導(dǎo)致數(shù)據(jù)對(duì)齊錯(cuò)誤。
- 跨平臺(tái)移植:在跨平臺(tái)移植時(shí),由于不同平臺(tái)的字節(jié)順序、大小和對(duì)齊方式可能不同,需要特別注意數(shù)據(jù)對(duì)齊問題。
- 運(yùn)行錯(cuò)誤:程序在運(yùn)行時(shí)發(fā)生了異常或錯(cuò)誤,這種錯(cuò)誤可能會(huì)導(dǎo)致程序崩潰、停止工作或產(chǎn)生不正確的結(jié)果。
- 空指針引用:程序試圖訪問一個(gè)空指針時(shí),會(huì)發(fā)生空指針引用錯(cuò)誤。
- 沒有初始化指針變量就使用它。
- 對(duì)已經(jīng)釋放的內(nèi)存進(jìn)行操作。
- 函數(shù)返回了一個(gè)空指針,但沒有進(jìn)行檢查就使用它。
- 在結(jié)構(gòu)體中訪問了一個(gè)不存在的成員變量。
解決措施 使用指針變量之前,始終確保對(duì)其進(jìn)行初始化。 釋放內(nèi)存之后,將指針變量設(shè)置為?NULL。 使用函數(shù)返回值之前,始終檢查其是否為空指針。 訪問結(jié)構(gòu)體成員變量之前,始終檢查該成員是否存在。 - 數(shù)組越界:程序試圖訪問一個(gè)超出數(shù)組邊界的元素時(shí),會(huì)發(fā)生數(shù)組越界錯(cuò)誤。
- 內(nèi)存泄漏:程序分配了一塊內(nèi)存但沒有釋放時(shí),會(huì)發(fā)生內(nèi)存泄漏錯(cuò)誤。
- 忘記釋放動(dòng)態(tài)分配的內(nèi)存:通過 malloc 或 new 等函數(shù)動(dòng)態(tài)分配了內(nèi)存,但沒有及時(shí)釋放,會(huì)導(dǎo)致內(nèi)存泄漏。
- 指針操作不當(dāng):存在指針操作不當(dāng)?shù)那闆r,如:指針未初始化、指針越界、重復(fù)釋放等,會(huì)導(dǎo)致內(nèi)存泄漏。
- 異常處理不當(dāng):存在異常處理不當(dāng)?shù)那闆r,如:在拋出異常前未釋放資源等,也會(huì)導(dǎo)致內(nèi)存泄漏。
解決措施 在使用完動(dòng)態(tài)分配的內(nèi)存后及時(shí)調(diào)用free或delete等函數(shù)進(jìn)行釋放。 對(duì)于指針操作,要確保指針正確初始化,并且避免指針越界、重復(fù)釋放等情況。 在異常處理中及時(shí)進(jìn)行資源清理,并且避免在拋出異常前未釋放資源等情況。 使用智能指針等自動(dòng)化管理內(nèi)存的方式來減少手動(dòng)管理帶來的風(fēng)險(xiǎn)。 - 棧溢出:程序使用過多的棧空間時(shí),會(huì)發(fā)生棧溢出錯(cuò)誤。
- 遞歸調(diào)用:遞歸函數(shù)沒有正確終止條件或者遞歸深度太大,會(huì)導(dǎo)致棧溢出。
- 局部變量過多:函數(shù)中定義了太多的局部變量,會(huì)導(dǎo)致棧空間不足導(dǎo)致棧溢出。
- 緩沖區(qū)溢出:程序嘗試向緩沖區(qū)寫入超過其大小的數(shù)據(jù),會(huì)導(dǎo)致棧溢出。
- 函數(shù)調(diào)用嵌套過深:函數(shù)調(diào)用嵌套層數(shù)太多,會(huì)導(dǎo)致??臻g不足。
解決措施 確保遞歸函數(shù)有正確的終止條件,并且遞歸深度不會(huì)太大。 盡可能減少局部變量的數(shù)量,并且使用動(dòng)態(tài)內(nèi)存分配來代替數(shù)組等靜態(tài)分配方式。 對(duì)于緩沖區(qū)操作,要確保輸入數(shù)據(jù)不會(huì)超過緩沖區(qū)大小,并且使用安全的字符串處理函數(shù)(如:strcpy_s)來代替不安全的函數(shù)(如:strcpy)。 合理設(shè)計(jì)程序結(jié)構(gòu),避免函數(shù)嵌套層數(shù)過深。 - 除0錯(cuò)誤:程序試圖將一個(gè)數(shù)除以零時(shí),會(huì)發(fā)生除零錯(cuò)誤。
對(duì)于函數(shù)未定義的錯(cuò)誤:
????????函數(shù)未定義屬于鏈接錯(cuò)誤。在C++中,當(dāng)我們調(diào)用一個(gè)函數(shù)時(shí),編譯器會(huì)在當(dāng)前文件或外部文件中查找該函數(shù)的定義。如果找不到該函數(shù)的定義,編譯器就會(huì)報(bào) "未定義的引用" 錯(cuò)誤,并停止編譯。????????這時(shí),我們需要檢查是否正確包含了相關(guān)頭文件、是否正確鏈接了相關(guān)庫(kù)文件、是否正確實(shí)現(xiàn)了該函數(shù)等。
補(bǔ)充:
????????對(duì)于#include 引入源文件,一般情況下是不建議的,而是應(yīng)該包含對(duì)應(yīng)的頭文件。
- 引入源文件缺陷:
- 編譯時(shí)間增加:當(dāng)一個(gè)頭文件被多個(gè)源文件包含時(shí),每個(gè)源文件都需要重新編譯該頭文件,這會(huì)增加編譯時(shí)間。
- 命名空間污染:如果被包含的頭文件定義了全局變量或函數(shù),那么這些定義將出現(xiàn)在包含它的每個(gè)源文件中,可能導(dǎo)致命名沖突和意外行為。
- 不必要的依賴關(guān)系:當(dāng)一個(gè)頭文件被包含到多個(gè)源文件中時(shí),這些源文件之間就會(huì)出現(xiàn)不必要的依賴關(guān)系。如果修改了這個(gè)頭文件,所有依賴它的源文件都需要重新編譯。
- 應(yīng)該遵循規(guī)則:
- 只包含必要的頭文件。
- 在頭文件中使用前置聲明 (forward?declaration) 而不是包含其他頭文件來聲明類或函數(shù)。
- 使用命名空間避免全局命名沖突。
- 將常用的頭文件放在預(yù)編譯頭 (precompiled?header) 中以提高編譯速度。
---------------------------------------------
編程題
統(tǒng)計(jì)回文?
統(tǒng)計(jì)回文_??皖}霸_??途W(wǎng) (nowcoder.com)
【題目解析】
? ? ? ? 回文判斷:正讀和反讀都一樣的字符串。
【解題思路?- 窮舉】
#include<iostream>
#include<string>
using namespace std;
// 判斷是否是回文
bool IsCircle(const string& s)
{
size_t begin = 0;
size_t end = s.size() - 1;
while (begin < end)
if (s[begin++] != s[end--])
return false;
return true;
}
int main()
{
// 時(shí)間復(fù)雜度:O(n^2)
// 空間復(fù)雜度:O(n)
string str, sub;
getline(cin, str);
getline(cin, sub);
size_t count = 0;
for (size_t i = 0; i <= str.size(); ++i)
{
// 將字符串2插入到字符串1的每個(gè)位置,再判斷是否是回文
string tmp = str;
tmp.insert(i, sub);
if(IsCircle(tmp))
++count;
}
cout << count << endl;
return 0;
}
// 64 位輸出請(qǐng)用 printf("%lld")
【優(yōu)化】
????????使用暴力求解方式計(jì)算,使用拼接實(shí)現(xiàn)兩個(gè)字符串的插入合并,避免insert(其需要移動(dòng)),采取空間換時(shí)間,再將其進(jìn)行判斷是否符合回文。
#include <iostream>
#include <string>
using namespace std;
// 判斷是否為回文
bool IsCircle(const string& s)
{
size_t begin = 0;
size_t end = s.size() - 1;
while (begin < end)
if (s[begin++] != s[end--])
return false;
return true;
}
int main()
{
// 時(shí)間復(fù)雜度:O(n^2)
// 空間復(fù)雜度:O(n)
string str;
string sub;
getline(cin, str);
getline(cin, sub);
size_t count = 0;
string tmp;
for(size_t index = 0; index <= str.size(); index++) // index是sub插入的位置
{
// 拼接 - 避免insert(其需要移動(dòng)),采取空間換時(shí)間
tmp = str.substr(0, index);
tmp += sub;
tmp += str.substr(index);
// 驗(yàn)證是否為回文
if(IsCircle(tmp))
++count;
}
cout << count << endl;
return 0;
}
// 64 位輸出請(qǐng)用 printf("%lld")
連續(xù)最大和?
連續(xù)最大和_??皖}霸_??途W(wǎng) (nowcoder.com)
【題目解析】
????????本題是一個(gè)經(jīng)典的動(dòng)規(guī)問題,簡(jiǎn)稱dp問題。文章來源:http://www.zghlxwxcb.cn/news/detail-624297.html
【解題思路】
狀態(tài)方程式: max(dp[i]) = max(dp[i-1] + arr[i], arr[i]);
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
// 時(shí)間復(fù)雜度:O(n)
// 空間復(fù)雜度:O(n)
int n = 0;
cin >> n;
vector<int> nums;
nums.reserve(n);
while(n--)
{
int num;
cin >> num;
nums.push_back(num);
}
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
for(size_t i = 1; i < nums.size(); i++)
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
cout << *max_element(dp.begin(), dp.end()) << endl;
return 0;
}
// 64 位輸出請(qǐng)用 printf("%lld")
【空間優(yōu)化】
? ? ? ? 將一維數(shù)組變?yōu)橐粋€(gè)元素,并保證其內(nèi)部,在執(zhí)行中使用為執(zhí)行部分的最大值。文章來源地址http://www.zghlxwxcb.cn/news/detail-624297.html
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main()
{
// 時(shí)間復(fù)雜度:O(n)
// 空間復(fù)雜度:O(1)
int n = 0;
cin >> n;
vector<int> nums;
nums.reserve(n);
while(n--)
{
int num;
cin >> num;
nums.push_back(num);
}
int ret_max = -INT_MAX; // 取一個(gè)很小很小的值
int tmp_max = 0; // 對(duì)應(yīng)元素的最大值 - 第0個(gè)元素最大值為0
for(auto val : nums)
{
int next = tmp_max + val;
if(ret_max < next)
ret_max = next;
if(next < 0)
next = 0;
tmp_max = next;
}
cout << ret_max << endl;
return 0;
}
// 64 位輸出請(qǐng)用 printf("%lld")
到了這里,關(guān)于【C++刷題集】-- day5的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!