當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式云IOT技術(shù)圈
[導(dǎo)讀]C語言的設(shè)計哲學(xué): 一切工作程序員自己負(fù)責(zé)。 語言中的所有特性都不需要隱式的運行時支持。 程序員所做的都是對的。 程序員應(yīng)該知道自己在干什么,并保證自己的所作所為是正確的。 第1章-- C: 穿越時空的迷霧 小即是美。事物發(fā)展都有個過程,由簡入繁,不能一

C語言的設(shè)計哲學(xué):

一切工作程序員自己負(fù)責(zé)。
語言中的所有特性都不需要隱式的運行時支持。
程序員所做的都是對的。
程序員應(yīng)該知道自己在干什么,并保證自己的所作所為是正確的。

第1章-- C: 穿越時空的迷霧

小即是美。事物發(fā)展都有個過程,由簡入繁,不能一開始就想得太復(fù)雜,Multics, IBM的OS/360都是因此而失敗。

C語言的許多特性是為了方便編譯器設(shè)計者而建立的。----唉,怎么這個樣子

C語言的基本數(shù)據(jù)類型直接與底層硬件相對應(yīng)。----確實如此

register關(guān)鍵字,這個設(shè)計可以說是一個失誤,如果讓編譯器在使用各個變量時自動處理寄存器的分配工作,顯然比一經(jīng)聲明就把這類變量在生命周期內(nèi)始終保留在寄存器里要好,使用register關(guān)鍵字,簡化了編譯器,卻把包袱丟給了程序員。

C編譯器不曾實現(xiàn)的一些功能必須通過其他途徑實現(xiàn)----標(biāo)準(zhǔn)I/O庫和C預(yù)處理器。

在宏擴展中,空格會對擴展的結(jié)果造成很大的影響。宏后面不可加';',它不是C語句。宏最好只用于命名常量,并為一些適當(dāng)?shù)慕Y(jié)構(gòu)提供簡捷的記法。宏名應(yīng)該大寫這樣便很容易與函數(shù)調(diào)用區(qū)分開來。

const關(guān)鍵字原先如果命名為readonly就好多了。

const int *p;是指不能夠通過通過p來改變int的值,即:*p = 30和p[3] = 4都是錯誤,但p是可以改變。

const int *與int *是相容的,都是指向int的指針;const int **與int **不相容,前者是指向const int *的指針,int **是指向int *的指針。

盡量不要在你的代碼中使用無符號類型,以免增加不必要的復(fù)雜性。只有在使用位段和二進制掩碼時,才可以使用無符號數(shù)。應(yīng)該在表達(dá)式中使用強制類型轉(zhuǎn)換,使操作數(shù)均為有符號數(shù),或者無符號數(shù),這樣就不必由編譯器來選擇結(jié)果的類型。有個例子,在ANSI C中,-1 < (unsigned char)1為真,而-1 < (unsigned int)1 為假。

第2章-- 這不是Bug,而是語言特性

進步——是計算機軟件工程和編程語言設(shè)計藝術(shù)逐步發(fā)展的重要動因。這也是為什么C++語言令人失望的原因:它對C語言中存在的一些最基本問題沒有什么改進,而它對C語言最重要的擴展(類)卻是建立在脆弱的C類型模型上。

按照C語言的理念,程序員應(yīng)該知道自己在干什么,而且保證自己的所作所為是正確的。

多做之過:fall through作為switch的默認(rèn)行為是個失誤;相鄰的字符串自動合并成一個字符串;太多的缺省可見性,全局可見,一個大型函數(shù)一群“內(nèi)部”函數(shù)不得不在該函數(shù)的外部進行定義。沒有人會記得在它們之前加上static限定符,所以他們在缺省情況下是全局可見的。

誤做之過:

C語言中符號重載:static 在函數(shù)內(nèi)部,表示該變量的值在各個調(diào)用間一直保持延續(xù)性;在函數(shù)這一極,表示該函數(shù)只對文本文件可見。extern用于函數(shù)定義表示全局可見(屬于冗余),用于變量,表示它在其他地方定義。

運算符優(yōu)先級存在的問題:.優(yōu)先級高于*, p.f表示(p.f);函數(shù)()高于*;==和!=高于位運算符(val & mask != 0)表示val & (mask != 0);==和!=高于賦值符,c = getchar() != EOF表示c = (getchar() != EOF);算數(shù)運算符高于移位運算符 msb<<4 + lsb表示msb<<(4+lsb);逗號最低。

有些專家建議在C語言中記牢兩個優(yōu)先級就夠了:乘除先于加減,在涉及其他的操作符時一律加括號。

結(jié)合性,在幾個操作符具有相同優(yōu)先級時決定先執(zhí)行哪一個。

計算的次序之所以未定義,是想讓編譯器充分利用自身架構(gòu)的特點,或者充分利用存儲于寄存器的值。

如果對于堆棧的每次訪問之前都要檢查其大小和訪問權(quán)限,對于軟件來說代價太大了,根本不可行。

gets(char *s),不檢查緩沖區(qū)的空間,而fgets(char *s, int n, FILE *stream)可以對讀入的字符數(shù)設(shè)置一個上限n。fgets對緩沖大小進行限制的方式,更為安全。

少錯之過,標(biāo)準(zhǔn)參數(shù)的處理以及把lint程序錯誤的從編譯器中分離出來。

Lint Early, Lint Often Lint is your software conscience. It tells you when you are doing bad things. Always use lint. Listen to your conscience.gcc as lint,使用-Wall:enable a bunch of warning。gcc --help=warning查詢。

linux上可以使用splint。

讓充滿Bug的代碼快速通過編譯實在是不劃算。----我習(xí)慣于寫過代碼后用眼睛看一遍,確認(rèn)無誤后再編譯調(diào)試,看來以后可以在中間加上一步用lint檢查。

大型緩沖區(qū)如果閑置不用是非常浪費空間的。

如果程序員可以在同一代碼塊中同時進行malloc和free操作,內(nèi)存管理是最輕松的。

深刻教訓(xùn):即使可以保證你的編程語言100%可靠,你仍然可能成為算法中災(zāi)難的犧牲品。----確實如此,學(xué)好算法。

第3章-- 分析C語言的聲明

聲明器(declarator), 就是標(biāo)識符以及與它組合與它組合在一起的任何指針,函數(shù)括號,數(shù)組下標(biāo)等。以下形式: 標(biāo)識符

或 標(biāo)識符[下標(biāo)]

或 標(biāo)識符(參數(shù))

或 (聲明器)

----注意括號不能亂加,就兩個地方可以加括號

聲明格式:類型說明符 聲明器[,聲明器];

類型說明符: int char void等

存儲類型: extern static register auto

類型限定符: const volatile

理解C語言聲明的優(yōu)先級規(guī)則

A 聲明從它的名字開始讀取,然后按照優(yōu)先級順序依次讀取。

B 優(yōu)先級從高到底依次是:

B.1 聲明中被括號括起來的那部分

B.2 后綴操作符:

括()表示一個函數(shù),

[]表示這是一個數(shù)組。

B.3 前綴操作符:

*表示指向...的指針

C 如果const和(或)volatile關(guān)鍵字與類型說明符(如int,long等)相鄰,它作用于類型說明符;其他情況下const和(或)volatile關(guān)鍵字作用于它左邊緊鄰的指針*號。

用優(yōu)先級規(guī)則分析C語言聲明:

char * const *(*next)();
char *(* c[10])(int **p);

如果需要頻繁地對整個數(shù)組進行賦值操作,可以通過把它放入struct中。

在調(diào)用函數(shù)中,參數(shù)傳遞時首先盡可能地存放到寄存器中(追求速度)。

union也可以把同一個數(shù)據(jù)解釋成兩種不同的東西,不用強制類型轉(zhuǎn)換。

typedef和宏文本替換之間存在一個關(guān)鍵性的區(qū)別:typedef看成是一種徹底的"封裝"類型——在它聲明后不能再往里面增加別的東西。首先,可以用其他類型說明符對宏類型名進行擴展,但對typedef所定義的類型名稱不能這樣做。typedef int banana; unsigned banana i; /*錯誤!非法 */;其次連續(xù)幾個變量聲明。

----由于typedef由編譯器解釋的,而宏是由預(yù)處理器解釋的

typedef void (*ptr_to_func)(int);//這樣來定義函數(shù)指針的別名。

不要為了方便起見對結(jié)構(gòu)使用typedef,這樣做唯一的好處是能使你不必書寫struct關(guān)鍵字,但這個關(guān)鍵字可以向你提示一些信息。

應(yīng)該始終在struct的定義中使用結(jié)構(gòu)標(biāo)簽,即使它并非必須。這種做法可以使代碼更為清晰。結(jié)構(gòu)標(biāo)簽的名字可以取一個以"_tag"結(jié)尾的名字。

C語言中存在多種名字空間:

  • 標(biāo)簽名(label name)
  • 標(biāo)簽(tag): 這個名字空間用于所有的結(jié)構(gòu)、枚舉和聯(lián)合
  • 成員名:每個結(jié)構(gòu)或聯(lián)合都有自身的名字空間
  • 其他

在同一個名字空間,任何名字必須具有唯一性。

----C中也有名字空間,沒注意啊。

第4章-- 令人震驚的事實:數(shù)組和指針并不相同

extern對象聲明告訴編譯器對象的類型和名字,對象的內(nèi)存分配則在別處進行。

X = Y;

在這個上下文環(huán)境里,符號X的含義是X所代表的地址。這被成為左值。

在這個上下文環(huán)境里,符號Y的含義是Y所代表的地址的內(nèi)容。這被稱為右值。

左值在編譯時可知,左值表示存儲結(jié)果的地方。

右值直到運行時才知。如無特別說明,Y的值是指右值。

數(shù)組名是個左值,但不是可修改的左值。

指針是間接尋址,數(shù)組名是直接尋址,這就是兩者在訪問數(shù)據(jù)時的區(qū)別。指針的值是運行時從內(nèi)存取得的,數(shù)名的值是編譯時已經(jīng)確定的。

專業(yè)的C程序員必須熟練的掌握malloc()函數(shù),并且學(xué)會用指針操縱匿名內(nèi)存。

第5章-- 對鏈接的思考

動態(tài)鏈接優(yōu)點:

  • 1.可執(zhí)行文件的體積小,節(jié)省磁盤空間和虛擬內(nèi)存。
  • 2.所有動態(tài)鏈接到某個特定函數(shù)庫的可執(zhí)行文件在運行時共享該函數(shù)庫在內(nèi)存中的一個單獨拷貝。

只使用動態(tài)鏈接。

gcc創(chuàng)建動態(tài)鏈接庫和使用

創(chuàng)建:gcc tomato.c -fPIC -shared -o libfruit.so

使用:gcc test.c -Wl,--rpath,. -L. -lfruit

這樣只要a.out和libfruit.so放在同一個目錄就可以了

與位置無關(guān)的代碼(position-independent code),對于共享庫顯得格外有用,因為每個使用共享庫的進程一般都會把它映射到不同的虛擬地址(盡管共享同一份物理拷貝),只要修改一下偏移量表就可以了。

grep很有用??!

始終將-l函數(shù)庫選項放在編譯命令行的最右邊。

警惕Interpositoning。缺省全局作用域。

準(zhǔn)則:不要讓程序中的任何符號成為全局的,除非有意把他們作為程序的接口之一。

ldd程序print shared library dependencies。

第6章-- 運動的詩章:運行時數(shù)據(jù)結(jié)構(gòu)

編程語言理論的經(jīng)典對立之一就是代碼和數(shù)據(jù)的區(qū)別。

代碼和數(shù)據(jù)的區(qū)別也可以是編譯時和運行時的分界線。編譯器的絕大部分工作都跟翻譯代碼有關(guān);必要的數(shù)據(jù)存儲管理的絕大部分都在運行時進行。

linux可執(zhí)行文件用文件第一個字節(jié)來標(biāo)注,7F開頭,緊跟后面的是"ELF",代表Executable and Linking Format.

可執(zhí)行文件由文本段、數(shù)據(jù)段和bss段組成,運行size a.out可查看各段大小。

bss段保存沒有值的變量,事實上只是,給出了運行時所需要的bss段大小。

運行時數(shù)據(jù)結(jié)構(gòu)有好幾種:堆棧,過程活動記錄,數(shù)據(jù),堆等。

堆棧有3個用處:

堆棧為函數(shù)內(nèi)部聲明的局部變量提供存儲空間。

進行函數(shù)調(diào)用時,堆棧存儲與此有關(guān)的一些維護信息。

堆棧也可以被看作暫時存儲區(qū)。比如計算表達(dá)式,存儲中間結(jié)果。

alloca()函數(shù)分配的內(nèi)存位于堆棧中,函數(shù)結(jié)束后自動銷毀。

發(fā)現(xiàn)數(shù)據(jù)段和文本段的位置,以及位于數(shù)據(jù)段中的堆,方法是聲明位于這些段的變量,并打印它們的地址。

過程活動記錄:局部變量,參數(shù),指向先前結(jié)構(gòu)的指針,返回地址。

Fedora上測了下,一個只有一個int參數(shù)的函數(shù)調(diào)用,要用32個字節(jié),參數(shù)4個,返回地址4,esp和ebp其他不知道。fame.h中是匯編,沒太看懂。

編譯器的設(shè)計者會盡可能地把過程活動記錄的內(nèi)容放到寄存器中,這樣可以提高速度。

static變量保存在數(shù)據(jù)段,而不是堆棧中。

auto關(guān)鍵字幾乎沒什么用處,因為它只能用于函數(shù)內(nèi)部,但是在函數(shù)內(nèi)部聲明的數(shù)據(jù)缺省就是這種分配。

setjmp和longjmp,在C++中變異為更普通的異常處理機制“catch”和“throw”。

對于如何在進程中支持不同的控制線程,只要簡單地為每個控制線程分配不同的堆棧即可。

有用的C語言工具:

indent 代碼縮進工具

默認(rèn)GNU風(fēng)格,使用-kr選項按K&R風(fēng)格。還有各種各樣選項,可以定制。

語法: indent [選項] [源文件列表]

indent [選項] [源文件] [-o 輸出文件]

ldd 用來查看程式運行所需的共享庫,常用來解決程式因缺少某個庫文件而不能運行的一些問題。

nm 打印目標(biāo)文件的符號表。

strace 工具trace system calls and signals

用法:strace [選項] command

gdb---哈哈,常用

time顯示程序所使用的實際時間和CPU時間

gprof列出程序的運行時分析圖。

標(biāo)準(zhǔn)的代碼優(yōu)化技巧包括:消除循環(huán),函數(shù)代碼就地擴展,公共子表達(dá)式消除,改進寄存器分配,省略運行時對數(shù)組邊界的檢查,循環(huán)不變量代碼移動,操作符長度削減(把指數(shù)操作轉(zhuǎn)變?yōu)槌朔ú僮?,把乘法操作轉(zhuǎn)變?yōu)橐莆徊僮骰蚣臃ú僮鳎┑取?/p>

第7章-- 對內(nèi)存的思考

內(nèi)存泄漏(leak)檢查工具:

mtrace

valgrind

malloc所分配的內(nèi)存通常會圓乘為下一個大于申請數(shù)的2的整數(shù)次方。

總線錯誤,幾乎都是由于未對齊的讀或?qū)懸鸬摹?---目前l(fā)inux好像不出現(xiàn)錯誤

段錯誤是由于MMU(內(nèi)存管理單元,負(fù)責(zé)支持虛擬內(nèi)存的硬件)的異常所致,而該異常通常是由于解除引用(查看指針?biāo)傅刂返膬?nèi)容)一個未初始化或非法值的指針引起的。

Keep it Simple, Stupid !

條件操作符簡潔,允許我們高高興興的在一行內(nèi)寫下代碼,而無需不必要的代碼膨脹。

最可能導(dǎo)致段錯誤的常見編程錯誤是:


  1. 壞指針的錯誤。free(p);后值空 p = NULL;

    1. 改寫錯誤。如數(shù)組越界。

    1. 指針釋放引起的錯誤。

    第8章-- 為什么程序員無法分清萬圣節(jié)和圣誕節(jié)

    很無厘頭的開始。

    類型提升:在任何表達(dá)式中,并不局限于涉及操作符和混合類型的操作數(shù)的表達(dá)式。

    char, 位段, enum, unsigned char, short, unsigned char -> int

    float -> double

    任何數(shù)組 -> 相應(yīng)類型的指針。----注意

    函數(shù)的參數(shù)也是表達(dá)式,所以也會發(fā)生類型提升。不用函數(shù)原型,會先提升再自動剪裁。

    如果使用了函數(shù)原型,缺省參數(shù)提升就不會發(fā)生,與實際類型相符合。----但數(shù)組到指針的提升仍會發(fā)生

    不需要按回車鍵就能得到一個字符,單字符I/O----用于游戲編程,這個我就不看了

    有限自動機(FSM)可以用作程序的控制結(jié)構(gòu)。它的基本思路是用一張表保存所有可能的狀態(tài),并列出進入每個狀態(tài)時可能執(zhí)行的所有動作,其中最后一個動作就是計算(通常在當(dāng)前狀態(tài)和下一次輸入字符的基礎(chǔ)上,另外再經(jīng)過一次表查詢)下一個應(yīng)該進入的狀態(tài)。你從一個“初始狀態(tài)”開始。在這一過程中,翻譯表可能告訴你進入了一個錯誤的狀態(tài),表示一個預(yù)期之外的或錯誤的輸入。你不停地在各種狀態(tài)間轉(zhuǎn)換,直到到達(dá)結(jié)束狀態(tài)。

    在C語言中,有好幾種方法可以用來表達(dá)FSM,但他們絕大多數(shù)都是基于函數(shù)指針數(shù)組。一個函數(shù)指針數(shù)組可以像下面這樣聲明:

    void (*state)MAX_STATES;

    debugging hooks

    調(diào)試器調(diào)試時可以調(diào)用函數(shù),比如gdb用call 函數(shù)名,對于復(fù)雜的數(shù)據(jù)結(jié)構(gòu)可以編寫一個函數(shù),用于遍歷數(shù)據(jù)結(jié)構(gòu)并打印出來。----時過境遷,現(xiàn)在強大的GUI調(diào)試器,這個已不怎么有用了。

    可調(diào)式性編碼

    可調(diào)式性編碼意味著把系統(tǒng)分成幾個部分,先讓程序總體結(jié)構(gòu)運行。只有基本的程序能夠運行之后你才能為那些復(fù)雜的細(xì)節(jié)完善、性能調(diào)優(yōu)和算法優(yōu)化進行編碼。

    有時候,花點時間把編程問題分解成幾個部分往往是解決它的最快辦法。----確實得花時間,動腦筋來分解。

    作者描寫其同事,寫散列表就是個例子啊。最初,使散列函數(shù)返回0,這樣所有元素都存儲于第0個位置后面的鏈表中。----這使得程序很容易調(diào)試

    復(fù)雜類型轉(zhuǎn)換,先寫一個對象的聲明,然后刪去標(biāo)識符,最后放在左面,如int (*compar)(int *)。

    不加類型說明符,聲明變量默認(rèn)是int;函數(shù)默認(rèn)返回值是int, 一般放在eax(第一個寄存器)中。int幾乎是C語言所有的默認(rèn)方式。應(yīng)該也是C最善于處理的數(shù)據(jù)類型。

    qsort函數(shù)原型:void qsort(void *base, size_t count, size_t size, int (*compar)(const void* element1, const void *element2));

    compar函數(shù)參數(shù)可以定義為(const void *)類型,這需要在compar函數(shù)內(nèi)部cast為所處理類型;也可以直接定義為所處理類型的指針,在調(diào)用qsort函數(shù)時需要將compar函數(shù)cast為(int (*)(const void *, constvoid *),一開始我以為這樣不正確(因為qsort函數(shù)內(nèi)部還是會調(diào)用compar的,這樣類型就不匹配了?。?,其實是正確的,因為這種類型檢查是編譯時做的(gcc 使用-c選項),鏈接時不做類型檢查,只要能找到那個函數(shù)名就行,運行時取參數(shù)更不管這些東西了,是用ebp+offset直接抓來的。

    第9章-- 再論數(shù)組

    數(shù)組的聲明就是數(shù)組,指針的聲明就是指針,兩者不能混淆。聲明與定義必須對應(yīng)。

    對于編譯器而言,一個數(shù)組就是一個地址,一個指針就是一個地址的地址。----左值

    什么時候數(shù)組和指針是相同的?

    C語言標(biāo)準(zhǔn)對此作了如下說明:

    • 規(guī)則1. 表達(dá)式中的數(shù)組名(與聲明不同)被編譯器當(dāng)作一個指向該數(shù)組第一個元素的指針。
    • 規(guī)則2. 下標(biāo)(subscript)總是與指針的偏移(an offset from a pointer相同
    • 規(guī)則3. 在函數(shù)參數(shù)的聲明中,數(shù)組名被編譯器當(dāng)作指向該數(shù)組的第一個元素的指針----這里數(shù)組是指一維數(shù)組

    指針有類型限制,是因為編譯器需要知道對指針進行解除引用時應(yīng)該取幾個字節(jié),以及每個下標(biāo)的步長。

    sizeof(數(shù)組名)結(jié)果是數(shù)組所占字節(jié)數(shù)(真正的數(shù)組,不是函數(shù)形參),由此可見是可以數(shù)組名包含了長度信息,并可以通過sizeof取得,所以C中檢查數(shù)組是否越界訪問是能夠做到的,但是很容易用指針避開,就像用指針可以修改const一樣。我覺得編譯器可以打開一個選項,是否檢查數(shù)組越界訪問。

    把作為形參的數(shù)組和指針等同起來是出于效率原因的考慮。在C語言中,所有非數(shù)組形式數(shù)據(jù)實參均以傳值形式。如果要copy整個數(shù)組,無論在時間上還是內(nèi)存空間上的開銷都可能是非常大的。

    int apricot[2][3][5]; // apricot 兩個[3][5]的數(shù)組,2*3個[5]的數(shù)組,2*3*5個int

    int (*p)[3][5] = apricot; // 步長 3 * 5

    int (*r)[5] = apricot[0]; // 步長 5

    int *t = apricot[0][0]; // 步長 1

    int u = apricot[0][0][0];

    指向數(shù)組第一個元素的指針與數(shù)組名等同。

    內(nèi)存中數(shù)組的布局

    C語言中,最右邊的下標(biāo)最先變化,這個約定被稱為"行主序"。

    只有字符串常量才可以初始化指針數(shù)組,因為可執(zhí)行文件中字符串常量是作為數(shù)據(jù)存儲。而161這樣的字面常量只出現(xiàn)在代碼中。

    數(shù)組與指針可交換性的總結(jié):


    1. 用a[i]這樣的形式對數(shù)組進行訪問總是被編譯器”改寫“或解釋為像*(a+i)這樣的指針訪問。

    1. 指針始終就是指針。它絕不可以改寫成數(shù)組。只是可以使用下標(biāo)形式訪問指針。

    1. 在特定上下文中,也就是指針作為函數(shù)的參數(shù)(也就只有這種情況--注意),一個數(shù)組的聲明可以看作是一個指針。作為函數(shù)參數(shù)的數(shù)組始終會被編譯器修改成為指向數(shù)組中第一個元素的指針。

    第10章-- 再論指針

    數(shù)組和指針參數(shù)是如何被編譯器修改的?

    “數(shù)組名被改寫成一個指針參數(shù)”規(guī)則并不是遞歸定義的。數(shù)組的數(shù)組會被改寫成“數(shù)組的指針”,而不是“指針的指針”。

    數(shù)組的數(shù)組 char c[8][10]; char (*c)[10]; 數(shù)組的指針

    指針數(shù)組 char *c[15]; char**c; 指針的指針

    指針的指針 char **c; char **c; 不改變----指針與指針不用修改

    數(shù)組的指針 char (*c)[64]; char (*c)[64]; 不改變----注意,指向一個長度為64的char數(shù)組的數(shù)組名的指針,訪問數(shù)組中元素這樣做:(*c)[0]。

    int a[20];

    int **p = &a; // 錯誤,指針的指針與數(shù)組的指針不兼容

    int (*t)[20] = &a; // 正確,t為由20個int的數(shù)組的指針。

    ----此處括號是必須的,因為[]的優(yōu)先級比*高

    Iliffe向量,創(chuàng)建一個一維數(shù)組,數(shù)組中的元素是指向其他東西的指針。

    例如main(int argc, char *argv[]),第二個參數(shù)會被改寫成char **。(注意,只有把二維數(shù)組改為一個指向向量的指針數(shù)組的前提下才可以這么做!)

    C語言中,傳遞多維數(shù)組必須提供除最左面一維以外的所有維的長度。

    可以放棄多維數(shù)組的形式,提供自己的下標(biāo)方式,如char_array[row_size*i + j] = ...

    模擬動態(tài)數(shù)組,當(dāng)表滿后,用realloc()對數(shù)組重新分配內(nèi)存,并確保realloc操作成功。

    重分配操作很可能把原先的整個內(nèi)存塊移到一個不同的位置,這樣表格中元素的地址便不再有效。為了避免麻煩,應(yīng)該使用下標(biāo)而不是元素的地址。----這也是STL中引入迭代器的一個原因吧

    “增加”和“刪除”操作都必須通過函數(shù)來進行,這樣才能維持表的完整性。

    第11章-- 你懂得C,所以C++不在話下

    類內(nèi)部定義的函數(shù)是inline函數(shù)

    重載是編譯時解析的。

    多態(tài)——運行時綁定。latebinding

    new和delete操作符,用于取代malloc()和free()函數(shù),能夠自動完成sizeof的計算工作,并會自動調(diào)用合適的構(gòu)造函數(shù)和析構(gòu)函數(shù)。new能真正的創(chuàng)建一個對象,malloc()函數(shù)只是分配內(nèi)存。

    C++的設(shè)計受限于嚴(yán)格的兼容性、內(nèi)部一致性和高效率。

    復(fù)用是軟件科學(xué)的一個崇高而又朦朧的目標(biāo)。----很多時候不如另起爐灶從頭開始

    管理和市場狀況是導(dǎo)致許多公司破產(chǎn)的原因,比單純的技術(shù)失敗更為常見。那些不時刻注意顧客需求的公司終究難以為繼,最能掌握這項藝術(shù)的公司往往能獲得成功。

    附錄A-- 程序員工作面試的秘密

    面試的關(guān)鍵在于正確理解問題!你需要仔細(xì)地聽,如果不理解問題或者覺得它的定義不清,可以要求一個更好的解釋。

    提供一種尋找可靠答案的好方法。

    鏈表環(huán)的檢測。

    mango[i++] += y; // i++僅執(zhí)行一次

    優(yōu)秀的程序員將會休息的更好,精力更加充沛,而蹩腳的程序員則很可能困得腦袋常常和桌子打架。

    人類的最高目標(biāo)是奮斗、尋求、創(chuàng)造。

    往期精彩

    學(xué)習(xí)嵌入式可以帶娃,不信你們看

    第10期 | ringbuff,通用FIFO環(huán)形緩沖區(qū)實現(xiàn)庫

    代碼寫得很牛逼但UI界面卻搞得很丑?來,楊工帶你!

    分享一個近期開源火爆全網(wǎng)的額溫槍方案(硬件+源碼)

    火爆全網(wǎng)開源額溫槍同平臺之華大HC32L136 SDK開發(fā)入門

    覺得本次分享的文章對您有幫助,隨手點[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。

    免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

    本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
    換一批
    延伸閱讀

    9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

    關(guān)鍵字: 阿維塔 塞力斯 華為

    加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

    關(guān)鍵字: AWS AN BSP 數(shù)字化

    倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

    關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

    北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

    關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

    8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

    關(guān)鍵字: 騰訊 編碼器 CPU

    8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

    關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

    8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

    關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

    要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

    關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

    北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

    關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

    北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

    關(guān)鍵字: BSP 信息技術(shù)
    關(guān)閉
    關(guān)閉