c語言kiss原則,KISS原則包括

本文目錄一覽:

大學本科研究生科目網路—軟體開發課程—軟體操作課程有哪些?(比如ps fl 之類的要說全哦

1. 計算機底層

這實際上就是兵哥哥說的《計算機組成原理》,我推薦的書是《深入理解計算機系統》,1000%的會比你的課本給你更多的東西。不管是寫程序做軟體還是搞科研發論文,不對底層有一個清晰的認識,你的整個前進道路都是模糊不清的。而只對體系結構的了解是遠遠不夠的,深挖才是歸途,為什麼現在很多解析內存CPU技術的博文博客火呢?因為大家都忽略啊!又因為大家都知道這是多麼有用啊!不做底層的分析,你怎麼去精準的定位問題呢?怎麼去寫出切合真實計算邏輯的簡單而又高效的優秀代碼呢?別鬧了。我同意一個觀點——讀優秀的代碼,從OS開始。讀這些就是你學習認知底層的過程,就是在站在巨人肩膀上遠眺的歷程。

2. 數學

過硬的數學功底使得你能看到一些新技術的出現而不茫然,看到的舊的技術能快速的跟進上手。這就是所謂「知識」和「技能」的關係,將工具運用到純熟的地步,你會發現別人遇到的很多問題在你這裡都不是問題了,看起論文來也得心應手啦,這就是潛移默化和下意識的作用。

3. C/C++

排在第三位是因為我覺得不是極其重要了。當然,C語言是基本功我就不在贅述。

一門語言對你的作用是認識到計算機的「思考方式」與人類的不同,想要更加精確簡單(KISS原則)的實現自己的想法,就要按照這個邏輯思路去執行。而選擇C語言是因為它是成熟的,是最為值得探究的語言,也是你今後可能進入Unix,Linux,嵌入式,甚至於IOS方向的基石。

4. 演算法設計

依託數學的知識,在演算法上的成績應該不會太次。《演算法導論》是要看的沒錯。如果時間少的話,《編程珠璣》《編程之美》《APUE》,這些書是要接觸的。

5. 英語/(日語)

不得不承認美帝和倭寇就是比我們先進。

學習英語的好處不言而喻,打破這層壁壘就會讓你感受到真正的世界的樣子,去那些純英文的編程網站,BBS,討論組,個人博客,增長見識的同時是你在逐步的認清這個世界,知道外面的人在做什麼在想什麼,現如今的潮流是什麼(為什麼不提媒體我覺得你應該懂得),更進一步你未來的發展方向是什麼,是否和大環境有衝突,這是你這一生究竟能達到多大成就的一個很重要的潛在因素,也是為你今後走出校園做一些非常必要的知識儲備和心理預備役。

日語的問題,是在英語之後的一個可選項,IT方面的日企非常多,待遇也非常好,我們懷抱著「師夷長技」的心態去學習就好了。

彙編問題

機器在存儲時不區分有符號數和無符號數,只是在做一些比較和位擴展時用到的寄存器和機器指令不相同

具體看《深入理解計算機系統》第二,三章節

一、只有一個標準!

在彙編語言層面,聲明變數的時候,沒有 signed 和 unsignde 之分,彙編器統統,將你輸入的整數字面量當作有符號數處理成補碼存入到計算機中,只有這一個標準!彙編器不會區分有符號還是無符號然後用兩個標準來處理,它統統當作有符號的!並且統統彙編成補碼!也就是說,db -20 彙編後為:EC ,而 db 236 彙編後也為 EC 。這裡有一個小問題,思考深入的朋友會發現,db 是分配一個位元組,那麼一個位元組能表示的有符號整數範圍是:-128 ~ +127 ,那麼 db 236 超過了這一範圍,怎麼可以?是的,+236 的補碼的確超出了一個位元組的表示範圍,那麼拿兩個位元組(當然更多的位元組更好了)是可以裝下的,應為:00 EC,也就是說 +236的補碼應該是00 EC,一個位元組裝不下,但是,別忘了「截斷」這個概念,就是說最後的結果被截斷了,00 EC 是兩個位元組,被截斷成 EC ,所以,這是個「美麗的錯誤」,為什麼這麼說?因為,當你把 236 當作無符號數時,它彙編後的結果正好也是 EC ,這下皆大歡喜了,雖然彙編器只用一個標準來處理,但是借用了「截斷」這個美麗的錯誤後,得到的結果是符合兩個標準的!也就是說,給你一個位元組,你想輸入有符號的數,比如 -20 那麼彙編後的結果是正確的;如果你輸入 236 那麼你肯定當作無符號數來處理了(因為236不在一個位元組能表示的有符號數的範圍內啊),得到的結果也是正確的。於是給大家一個錯覺:彙編器有兩套標準,會區分有符號和無符號,然後分別彙編。其實,你們被騙了。:-)

二、存在兩套指令!

第一點說明彙編器只用一個方法把整數字面量彙編成真正的機器數。但並不是說計算機不區分有符號數和無符號數,相反,計算機對有符號和無符號數區分的十分清晰,因為計算機進行某些同樣功能的處理時有兩套指令作為後備,這就是分別為有符號和無符號數準備的。但是,這裡要強調一點,一個數到底是有符號數還是無符號數,計算機並不知道,這是由你來決定的,當你認為你要處理的數是有符號的,那麼你就用那一套處理有符號數的指令,當你認為你要處理的數是無符號的,那就用處理無符號數的那一套指令。加減法只有一套指令,因為這一套指令同時適用於有符號和無符號。下面這些指令:mul div movzx … 是處理無符號數的,而這些:imul idiv movsx … 是處理有符號的。

舉例來說:

內存里有 一個位元組x 為:0x EC ,一個位元組 y 為:0x 02 。當把x,y當作有符號數來看時,x = -20 ,y = +2 。當作無符號數看時,x = 236 ,y = 2 。下面進行加運算,用 add 指令,得到的結果為:0x EE ,那麼這個 0x EE 當作有符號數就是:-18 ,無符號數就是 238 。所以,add 一個指令可以適用有符號和無符號兩種情況。(呵呵,其實為什麼要補碼啊,就是為了這個唄,:-))

乘法運算就不行了,必須用兩套指令,有符號的情況下用imul 得到的結果是:0x FF D8 就是 -40 。無符號的情況下用 mul ,得到:0x 01 D8 就是 472 。(參看文後附錄2常式)

三、可愛又可怕的c語言。

為什麼又扯到 c 了?因為大多數遇到有符號還是無符號問題的朋友,都是c裡面的 signed 和 unsigned 聲明引起的,那為什麼開頭是從彙編講起呢?因為我們現在用的c編譯器,無論gcc 也好,vc6 的cl 也好,都是將c語言代碼編譯成彙編語言代碼,然後再用彙編器彙編成機器碼的。搞清楚了彙編,就相當於從根本上明白了c,而且,用機器的思維去考慮問題,必須用彙編。(我一般遇到什麼奇怪的c語言的問題都是把它編譯成彙編來看。)

C 是可愛的,因為c符合kiss 原則,對機器的抽象程度剛剛好,讓我們即提高了思維層面(比彙編的機器層面人性化多了),又不至於離機器太遠 (像c# ,java之類就太遠了)。當初KR 版的c就是高級一點的彙編……:-)

C又是可怕的,因為它把機器層面的所有的東西都反應了出來,像這個有沒有符號的問題就是一例(java就不存在這個問題,因為它被設計成所有的整數都是有符號的)。為了說明c的可怕特舉一例:

#include stdio.h

#include string.h

int main()

{

int x = 2;

char * str = “abcd”;

int y = (x – strlen(str) ) / 2;

printf(“%d\n”,y);

}

結果應該是 -1 但是卻得到:2147483647 。為什麼?因為strlen的返回值,類型是size_t,也就是unsigned int ,與 int 混合計算時類型被自動轉換了,結果自然出乎意料。。。

觀察編譯後的代碼,除法指令為 div ,意味無符號除法。

解決辦法就是強制轉換,變成 int y = (int)(x – strlen(str) ) / 2; 強制向有符號方向轉換(編譯器默認正好相反),這樣一來,除法指令編譯成 idiv 了。我們知道,就是同樣狀態的兩個內存單位,用有符號處理指令 imul ,idiv 等得到的結果,與用無符號處理指令mul,div等得到的結果,是截然不同的!所以牽扯到有符號無符號計算的問題,特別是存在討厭的自動轉換時,要倍加小心!(這裡自動轉換時,無論gcc還是cl都不提示!!!)

為了避免這些錯誤,建議,凡是在運算的時候,確保你的變數都是 signed 的。

彙編遇到奇怪的問題

你的問題有誤。

並不是在執行了 mov bx, 0指令「以後」出現問題,而是在執行它「以前」。也就是說,只要mov sp, 10h執行了,問題就出現了。

出現這個現象的原因,是你在「調試」。如果不用單步方式調試,而是直接運行,或者用設置在後面較遠的適當位置的斷點方式調試,結果是不一樣的。

DOS下調試一個程序,所有對寄存器、內存數據的修改,是真實的CPU寄存器和內存修改。它不是用一個隔離過的虛擬環境外部控制。

單步調試,靠的是 INT 01H內部單步中斷。

每執行一條指令,就會發生一次 int 01h中斷。

而中斷,是需要用堆棧的(保存斷點現場)。

所以,你設置的堆棧區的數據,在單步調試過程中,就被改寫了。

其實,將堆棧設置到關鍵數據區或關鍵代碼區,正是防止跟蹤破解的技巧之一。這樣設置,可以讓程序正常運行不受影響,但用單步調試進行跟蹤就不行。

解決辦法:

堆棧單獨設置。

考慮到中斷(包括調試中斷和隨機出現的硬體中斷)會改變堆棧中內容,要保護重要數據區的安全,堆棧的設置要避開它們。

在涉及利用堆棧進行的操作中途不要用斷點或單步方式調試,調試時使用斷點方式,斷點設置在堆棧操作開始前或全部完成後,堆棧操作開始前關中斷(用CLI指令),完成後開中斷(用STI指令)。

C語言:用extern和不用extern聲明方法有什麼區別?

在C語言中,修飾符extern用在變數或者函數的聲明前,用來說明「此變數/函數是在別處定義的,要在此處引用。

1.

extern修飾變數的聲明。舉例來說,如果文件a.c需要引用b.c中變數int v,就可以在a.c中聲明extern int

v,然後就可以引用變數v。這裡需要注意的是,被引用的變數v的鏈接屬性必須是外鏈接(external)的,也就是說a.c要引用到v,不只是取決於在a.c中聲明extern

int

v,還取決於變數v本身是能夠被引用到的。這涉及到c語言的另外一個話題--變數的作用域。能夠被其他模塊以extern修飾符引用到的變數通常是全局變數。還有很重要的一點是,extern

int v可以放在a.c中的任何地方,比如你可以在a.c中的函數fun定義的開頭處聲明extern int

v,然後就可以引用到變數v了,只不過這樣只能在函數fun作用域中引用v罷了,這還是變數作用域的問題。對於這一點來說,很多人使用的時候都心存顧慮。好像extern聲明只能用於文件作用域似的。

2.

extern修飾函數聲明。從本質上來講,變數和函數沒有區別。函數名是指向函數二進位塊開頭處的指針。如果文件a.c需要引用b.c中的函數,比如在b.c中原型是int

fun(int mu),那麼就可以在a.c中聲明extern int fun(int mu),然後就能使用fun來做任何事情。就像變數的聲明一樣,extern

int fun(int

mu)可以放在a.c中任何地方,而不一定非要放在a.c的文件作用域的範圍中。對其他模塊中函數的引用,最常用的方法是包含這些函數聲明的頭文件。使用extern和包含頭文件來引用函數有什麼區別呢?extern的引用方式比包含頭文件要簡潔得多!extern的使用方法是直接了當的,想引用哪個函數就用extern聲明哪個函數。這大概是KISS原則的一種體現吧!這樣做的一個明顯的好處是,會加速程序的編譯(確切的說是預處理)的過程,節省時間。在大型C程序編譯過程中,這種差異是非常明顯的。

3.

此外,extern修飾符可用於指示C或者C++函數的調用規範。比如在C++中調用C庫函數,就需要在C++程序中用extern

「C」聲明要引用的函數。這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規範來鏈接。主要原因是C++和C程序編譯完成後在目標代碼中命名規則不同

C語言問題 在線等

以下合法的一組常量是

A. 1.24e3 08211 0xFF 12L //合法

B. 38.00e8f 12UL 01777777 『X』 // 38.00e8f 不合法

C. 20FA 07321 0xffff 」A「 //20Fa不合法

D. 3.14E2.3 0x32768 -27 1UL // 3.14E2.3 不合法

2. 以下常量合法的一組是

A. 1L 0380 1.2e2.3 『S』 // 1.2e2.3 不

B. 3.8e3 1.8f 反斜杠ff 」x「 // 反斜杠ff 不

C. 『反斜杠反斜杠』 0732 反斜杠xFFL 363u // 反斜杠xFFL

D. 01000 12.34 12UL 2AF0 \\2AFo 不

第二題應該是沒有答案。。

為什麼包含初始化式的extern聲明不能位於函數內

extern定義的變數必須是全局的,這樣才可能在其他文件中使用,所以,不能再語句塊里定義。位於函數內的變數是局部變數。

變數只能定義一次,所以,不管怎樣,只能有一個extern int i=1這樣的定義。

extern可置於變數或者函數前,以表示變數或者函數的定義在別的文件中,提示編譯器遇到此變數或函數時,在其它模塊中尋找其定義。另外,extern也可用來進行鏈接指定。

在子程序中定義的變數稱為局部變數,在程序的一開始定義的變數稱為全局變數。

全局變數作用域是整個程序,局部變數作用域是定義該變數的子程序。

當全局變數與局部變數同名時:

在定義局部變數的子程序內,局部變數起作用;在其它地方全局變數起作用。

參考:

謝謝你讓學到一點知識。

原創文章,作者:ACOE,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/139724.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ACOE的頭像ACOE
上一篇 2024-10-04 00:22
下一篇 2024-10-04 00:22

相關推薦

  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演著非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • Python語言設計基礎第2版PDF

    Python語言設計基礎第2版PDF是一本介紹Python編程語言的經典教材。本篇文章將從多個方面對該教材進行詳細的闡述和介紹。 一、基礎知識 本教材中介紹了Python編程語言的…

    編程 2025-04-28
  • Python語言實現人名最多數統計

    本文將從幾個方面詳細介紹Python語言實現人名最多數統計的方法和應用。 一、Python實現人名最多數統計的基礎 1、首先,我們需要了解Python語言的一些基礎知識,如列表、字…

    編程 2025-04-28
  • Python作為中心語言,在編程中取代C語言的優勢和挑戰

    Python一直以其簡單易懂的語法和高效的編碼環境而著名。然而,它最近的發展趨勢表明Python的使用範圍已經從腳本語言擴展到了從Web應用到機器學習等廣泛的開發領域。與此同時,C…

    編程 2025-04-28
  • Python基礎語言

    Python作為一種高級編程語言擁有簡潔優雅的語法。在本文中,我們將從多個方面探究Python基礎語言的特點以及使用技巧。 一、數據類型 Python基礎數據類型包括整數、浮點數、…

    編程 2025-04-28

發表回復

登錄後才能評論