C語言 C語言基礎
C語言 C語言基礎
一、簡述
對於C語言基礎相關方面的表面理解,簡單介紹。
二、二進位制
生活中常用的是十進位制,基數0,1,2,3,4,5,6,7,8,9,。滿10進1。
時鐘60進位制。基數0,1,2...57,58,59。滿60進1。60秒為1分鐘,60分鐘為1小時。
計算機二進位制,基數0,1。滿2進1。高電平代表1,低電平代表0。計算機的指令和資料都是用0和1來表示的。
三、計算機部分組成
CPU+記憶體+外存。
CPU執行指令,CPU包括運算器、控制器。(包括多個暫存器)運算器負責邏輯運算,控制器包括對資料和指令的存取操作。
記憶體運行當前的程式(程式碼+資料),(程式碼可以看做是一系列的指令)記憶體可以劃分為很多個單元,每個單元一個位元組並對應一個編號。
外存可以簡單認為是硬碟。(存放東西的)
程式執行:程式test.exe放在硬碟,CPU將test.exe讀取到記憶體,然後逐條執行指令。
多工:有多個程式在同時執行,但是隻有一個CPU,採用時間片輪詢方式,簡單來說,假設A,B,C三個程式同時執行,CPU執行A程式的一條指令,然後再執行B程式的一條指令,在執行C程式的一條指令,再到A。CPU執行得很快,看起來是同時執行的。當然任務之間還有優先順序。
斷電資料丟失:在記憶體中的資料都是用電來表示的,斷電之後,這些資料就會丟失。
虛擬記憶體:假設每個應用獨佔4G記憶體。(實際並不是,虛擬記憶體經過一定的方式對映為實體記憶體)
記憶體4區:棧區,堆區,全域性區,程式碼區。
匯流排:計算機各部分通過匯流排連線。包括地址匯流排,資料匯流排,控制匯流排。地址匯流排:比如有32根地址匯流排,每一根線有高電平1,低電平兩種狀態0,那麼可以表示0x00000000~0xFFFFFFFF總共2的32次方這麼多個地址,一個地址可以表示一個記憶體單元。一般來說,地址匯流排越多,可以表示的地址越多。指標變數就是存放地址的,比如:int i = 10; int *p = &i;若i的地址為0x00800400;那麼p指標變數存放的值就是0x00800400,是一個有實際地址意義的整數。因為是32根地址匯流排,所以sizeof(p) = 4 (位元組)。資料匯流排:比如有8根資料線,那麼同時可以存取8位資料,一般來說資料匯流排越多,同時存取的資料越多,執行效率越高。控制匯流排:控制、協調計算機各部分工作,存取指令。一般來說匯流排還可以拓展。
四、變數
記憶體分為一個一個單元,一個單元一個位元組,並且一個單元對應一個地址編號。
在組合語言中,可以直接對記憶體地址進行操作,如:MOV AL,[2000H] ;將記憶體地址0x2000的內容送到AL暫存器中。
彙編中,直接將資料存放到某個記憶體地址,如將學生學號放到某個地址,學生姓名放到某個地址。到時候讀取的時候,直接讀取某個地址。這樣子固然程式執行效率高,但是如果資料一多,難免會記不住哪個資料對應哪個地址,看到一個地址,自己還得想一下之前這個地址(這一段記憶體)存放的是什麼資料,寫起程式碼也不方便。時間一長,就算是自己編寫的程式碼都要花很多時間才能看懂,而且維護起來也比較麻煩。
這樣我們將資料對應的一段記憶體起一個名字,這個名字就代表著一片記憶體,到時候直接操作著個名字就相當於操作這一片記憶體,這個名字就是我們所說的變數。起一個與資料相關的有意義的名字,方便我們程式設計。如:C語言中,我們可以將存放學生學號的那一段記憶體叫做id,將存放學生姓名的那一段記憶體叫做name。這樣我們就可以通過id,name這兩個變數名類讀取或儲存學生的id資訊和姓名資訊,到時候我們一看變數名name,我們就能想到這是存放姓名資訊的。
變數:對應一片記憶體,記憶體可以存放不同的資料,變數可變。變數的地址就是對應的那一片記憶體首地址。程式中定義一個變數就在記憶體中開闢一片記憶體空間(系統為程式分配一片記憶體空間)。
五、資料型別
為了方便,或者是為了執行效率,計算機採用了二進位制,通過低電平或斷電狀態表示0,通過 通電或高電平狀態表示1。這樣一來,計算機只認識0和1,也只能表示0和1。那麼我需要表示其他數字:2,3,4....字元:a,b,c...怎麼辦?我們可以使用多個0和1來代表其他數字和字元,並統一為一個表。
....... | ....... |
00110000 |
數字0 |
00110001 |
數字1 |
00110010 |
數字2 |
........ | ....... |
01000100 |
大寫字母D |
01000101 |
大寫字母E |
........ | ........ |
在記憶體中,表達整數0我們可以用 00110000,表達整數4億我們可以用 00111111100011000011110。
上面這樣子表示,我們可以知道這一段的0和1表示這整數0,那一段0和1表示4億,但是實際上我們“看”不到記憶體,我們不知道從這個位置開始,到哪裡結束表示著一個數據。我們需要明確規定多少個0和1表示一個整數,假設我們約定8位0和1表示一個整數,這樣我們知道了記憶體首地址,往後讀取8個0和1然後就可以讀取到一個數據(整數)。就像加密的電報一樣,"滴滴"表示1,“滴”表示0。按照多少個0和1代表一個字,才能正確的解密。
所以我們需要指定多少個0和1來表示一個數據。8個0和1可以表示2的8次方==〉256個數。要是有正負值,表示範圍為-128-127。比如在32位系統中,C語言的整型int用32位即4位元組表示,可以表示2的32次方==〉4294967296個數,有符號的表示範圍為-2147483648——2147483647。有一些資料範圍不大,只需幾十個,如果用32位表示一個數據就顯得浪費記憶體。有一些資料範圍很大,用32位表示又不夠表示,於是就有16位的short型別,64位的long long型別(不同的系統有可能型別的位數不一樣)。就像用盒子打包物品一樣,有一些物品比較小,有一些物品比較大。要是統一用一種尺寸的盒子裝,盒子過小,大的物品又裝不下,盒子過大,用來裝小的有顯得有點浪費,於是多種尺寸的盒子就產生了-多種資料型別。還有一個原因:就是在表達小數,或者是非常大的數時就算是64位也有點無能為力,但是如果改變儲存方式,同樣是64位,卻可以表示更大範圍的數。於是有了新的資料儲存方式,這是針對浮點數的。(如果將整數和浮點數採用同樣的儲存方式,計算機結構會更加複雜化,甚至會降低執行效率)
資料的大小範圍不一,整數,浮點數的儲存方式不一樣(讀取的時候解析的方式也不一樣),為了合理利用記憶體,提高執行效率,方便開發等原因,我們需要不同的資料型別。
不同的資料型別意味著資料的大小不同(多少位0和1表示一個數據,也就是這種資料型別佔多少個位元組),資料的儲存方式(資料的解析方式)不同。也就是說同一個記憶體首地址,按照不同的資料型別,即按照不同的位數解讀記憶體資料,就會讀取出不一樣的資料,按照不同的解析方式,也會讀取出不一樣的資料。就像加密電報一樣,按照不同的位數一樣的譯碼錶也會解讀出不一樣的譯文,按照一樣的位數不一樣的譯碼錶也會解讀出不一樣的資料。
定義不同資料型別的變數,系統根據資料型別分配相應的記憶體大小,程式填充資料時根據相應的儲存方式,讀取資料時按照相應的方式解析,不然讀取不到正確的資料。如float型別的資料,如果直接按照int型別資料讀取,那麼讀取出來的不是正確的資料。
六、修改記憶體資料
對於程式自己申請的記憶體,作為擁有者,可以對這一片記憶體進行讀取或修改資料,其他程式一般沒有許可權讀取或修改。但是可以通過一些方式可以進行修改。