C02 資訊儲存與運算
目錄
- 計算機記憶體
- 常量和變數
- 資料型別
- 運算子
- 計算機記憶體管理
計算機記憶體
資訊儲存概述
使用程式進行開發時,需要儲存各種資訊,這時候就需要用到變數。由於資訊型別不同,變數的型別也因此不盡相同。
同時,資訊的儲存除了用來記錄資訊之外,還會進行各種運算,因此這些運算就需要用到各種運算子。
記憶體
計算機記憶體可以分為實體記憶體和虛擬記憶體:
- 實體記憶體:高速主儲存器
- 虛擬記憶體:解決兩個問題:1、程式暫停,執行緒駐留在主儲存器中,可以把該程序轉移到虛擬儲存器中,提高主儲存器的使用效率;2,需要載入的程式比較大,實體記憶體容量不足。
Windows虛擬記憶體稱為:虛擬記憶體。Unix系統中稱為:(swap)交換空間。
記憶體管理
每個程式都希望程式程式碼和資料能夠更多的載入到記憶體,這樣可以提高計算機執行效率。
但是計算機都是多工系統,他需要對每個程式進行記憶體分配,這就涉及到作業系統對記憶體的管理。
常見的記憶體空間分配方式有以下三種:
分配方式 |
說明 |
特點 |
分頁式管理 |
記憶體被拆分成固定大小的儲存單位,每個單位4KB。程式申請使用記憶體時,按照4KB的倍數分配,分配區域不連續,隨機分配。 |
1. 頁面長度固定,分配方式簡單,記憶體利用率高。 2. 對一個程式來說,同一個邏輯模組可能被拆分為許多個頁面,不利於資訊保護和功能共享。 3. 程式在虛擬記憶體和實體記憶體之間轉移,按照4KB大小儲存單位進行轉移。 |
分段式管理 |
分段式管理主要依據程式的邏輯結構進行分段。程式邏輯結構一般分為主程式段和子程式段,主程式段必須在實體記憶體中執行,系統按照程式段的大小分配記憶體空間。段內的資料是連續的,虛擬記憶體和實體記憶體之間的轉移以段為單位進行轉移。 |
1. 段的長度不固定,分配空間時可能產生記憶體碎片,導致記憶體利用率不足。 2. 對一個程式來說,同一個邏輯模組連續存放,不僅提高了執行效率,也便於資訊的保護和功能共享。 |
段頁式管理 |
大多數計算機結合了分頁式儲存和分段式管理的優點,採用段頁式的管理。 |
1. 先將程式按邏輯模組分段,每個段再進行分頁,資訊傳遞以頁為單位。 2. 建立相關聯的段表、頁表,用來定位程式段、段內各業的儲存地址。 3. 通過分段提高了程式執行效率,通過分頁改善了記憶體空間的利用率。 |
常量和變數
C語言基本元素
1. 符號集(字符集)
C語言基本字符集分為源字符集(書寫C語言原始檔所用的字符集)和執行字符集(C語言程式執行期間解釋的字符集)。
源字符集包括大小寫字母(52)、數字(10)、格式符(4)、特殊字元(29)。
執行字符集在源字符集的基礎上還包括null字元(用做字串終止符)、警報(alert)、退格(backspace)、回車(carriage return)。為了在字母和字串中表示這些字元,輸入反斜槓\加對應的轉義序列(escape sequence)即可,例如,\0表示 null 字元(空字元),\a表示警報,\b表示退格,而\r表示回車。
源字符集中,格式符包括:空格、水平製表符(HT)、垂直製表符(VT)、換頁符(FF)。特殊字元如下29個:
! " # % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~ |
2. 關鍵字
也稱為保留字,是C語言中具有特定含義,專門用作語言特定成分的一類識別符號。ANSI標準定義32個關鍵字。
非常見:auto、register、volatile、goto。
儲存相關:const、extern、register、volatile、static、auto、signed、unsigned。
資料型別:char、short、int、float、long、double、struct、union、enum、void。
邏輯控制:if、else、for、while、do、break、continue、return、default、switch、case、goto。
特殊用途:sizeof、typedef
注意: 我們定義的識別符號不能是關鍵字;所有關鍵字小寫。
3. 識別符號
用來標記常量、變數、函式及檔名字的一串字元。(不包括關鍵字)。
識別符號命名規則:
1) 以字母(大小寫都可以)或下劃線開頭;
2) 後可跟若干個(包括0個)字母、數字、下劃線;
3) 識別符號的長度在各種編譯器和系統有所不同,建議不超過8個字元;
4) 識別符號與關鍵字不能相同。
問題?以下那些是合法的識別符號,哪些是非法的?
x |
y3 |
_imax |
ELSE |
X |
A_to_B |
7x |
int |
#NO |
bad one |
re-input |
aaaabbbbccc |
常量和變數
程式所操作的資訊需要儲存在記憶體中,所以需要定義常量和變數,常量和變數儲存所需操作的資訊。
1. 常量
常量:指在程式執行過程中,其值不變的量。在程式中不必對常量進行任何說明就可以使用。
例如:人的性別,一生下來就確定,不可以修改,即常量。
2. 變數
變數:指在程式執行過程中,其值可以被改變的量。
例如:人的姓名,或者小名,可以改變,即變數。
對於C語言來說,變數的值=該儲存空間裡的資料和資訊。
變數的定義
語法規則:
資料型別 識別符號1 [,識別符號2,…識別符號N ] ;
例如:
int a;
char b,c;
命名規則:與識別符號命名規則一致。
3. 常量與變數命名規範
1) 區分大小寫
2) 命名要見名知意
3) 先定義後使用
4) 符號常量名用大寫,變數小寫
4. 變數的賦值
1) 定義變數時初始化變數值
資料型別 變數名=初始值;
2) 先定義變數,然後為變數賦值
資料型別 變數名;
變數名=初始值;
5. 變數的輸入和輸出
scanf(“%d”,&a); printf(“%d”,a); |
6. 變數的使用
變數型別決定了變數在記憶體中的地址分配;變數名即變數在記憶體中的地址。
資料型別
C語言資料型別
c語言型別主要分為四類:
序號 |
型別與描述 |
1 |
基本型別: |
2 |
列舉型別: |
3 |
void 型別: |
4 |
派生型別: |
基本型別
基本型別資料如下:
型別 |
儲存大小 |
值範圍 |
char |
1 位元組 |
-128 到 127 或 0 到 255 |
unsigned char |
1 位元組 |
0 到 255 |
signed char |
1 位元組 |
-128 到 127 |
int |
2 或 4 位元組 |
-32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int |
2 或 4 位元組 |
0 到 65,535 或 0 到 4,294,967,295 |
short |
2 位元組 |
-32,768 到 32,767 |
unsigned short |
2 位元組 |
0 到 65,535 |
long |
4 位元組 |
-2,147,483,648 到 2,147,483,647 |
unsigned long |
4 位元組 |
0 到 4,294,967,295 |
1. 字元型資料
字元常量:用單引號包含的一個字元,只能包含一個字元。
例如:
‘a’ ‘A’ ‘$’ |
轉義字元:特殊的常量字元,詳細參考第一章介紹。
字元變數:字元型變數用來存放字元常量,只能存放一個字元。一個字元變數在記憶體中佔用一個位元組。
字元變數的定義和賦值:字元變數的賦值可以是直接賦值字元常量,或者整數(整數必須在ASCII表示範圍內)。如下示例所示:
字元資料在記憶體中的儲存
2. 整型資料
整型的儲存大小與系統位數有關,int資料型別的數值範圍與系統有關,16、32、64位系統對應預設整型資料的長度分別是16、32、64位。但目前通用的以64位系統為主。以下列出了32位系統與64位系統的儲存大小的差別(windows 相同):
使用 sizeof 運算子判斷具體平臺的儲存大小。表示式:sizeof(type) 得到物件或型別的儲存位元組大小。如下示例示例:
其中,%lu 為 32 位無符號整數。
整型變數在記憶體中的表示:以十進位制數13示例示例。
如何表示負數?C語言中負數是以補碼的形式進行儲存的。計算機中的符號數有三種表示方法,即原碼、反碼和補碼。三種表示方法均有符號位和數值位兩部分,符號位都是用0表示“正”,用1表示“負”,而數值位,三種表示方法各不相同:正整數的補碼是其二進位制表示,與原碼相同;負整數的補碼,將其對應正數二進位制表示所有位取反(包括符號位,0變1,1變0)後加1。
<<參考計算機補碼及運算>>
3. 浮點型別
型別 |
儲存大小 |
值範圍 |
精度 |
float |
4 位元組 |
1.2E-38 到 3.4E+38 |
6 位小數 |
double |
8 位元組 |
2.3E-308 到 1.7E+308 |
15 位小數 |
long double |
16 位元組 |
3.4E-4932 到 1.1E+4932 |
19 位小數 |
標頭檔案 float.h 定義了巨集,在程式中可以使用這些值和其他有關實數二進位制表示的細節。下面的例項將輸出浮點型別佔用的儲存空間以及它的範圍值:
%E 為以指數形式輸出單、雙精度實數。
void型別
void 型別指定沒有可用的值。它通常用於以下三種情況下:
序號 |
型別與描述 |
1 |
函式返回為空 |
2 |
函式引數為空 |
3 |
指標指向 void |
運算子
運算子是一種告訴編譯器執行特定的數學或邏輯操作的符號。C 語言內建了豐富的運算子,並提供了以下型別的運算子:
算術運算子
下表顯示了 C 語言支援的所有算術運算子。假設變數 A 的值為 10,變數 B 的值為 20,則:
運算子 |
描述 |
例項 |
+ |
把兩個運算元相加 |
A + B 將得到 30 |
- |
從第一個運算元中減去第二個運算元 |
A - B 將得到 -10 |
* |
把兩個運算元相乘 |
A * B 將得到 200 |
/ |
分子除以分母 |
B / A 將得到 2 |
% |
取模運算子,整除後的餘數 |
B % A 將得到 0 |
++ |
自增運算子,整數值增加 1 |
A++ 將得到 11 |
-- |
自減運算子,整數值減少 1 |
A-- 將得到 9 |
關係運算符
下表顯示了 C 語言支援的所有關係運算符。假設變數 A 的值為 10,變數 B 的值為 20,則:
運算子 |
描述 |
例項 |
== |
檢查兩個運算元的值是否相等,如果相等則條件為真。 |
(A == B) 不為真 |
!= |
檢查兩個運算元的值是否相等,如果不相等則條件為真。 |
(A != B) 為真 |
> |
檢查左運算元的值是否大於右運算元的值,如果是則條件為真。 |
(A > B) 不為真 |
< |
檢查左運算元的值是否小於右運算元的值,如果是則條件為真。 |
(A < B) 為真 |
>= |
檢查左運算元的值是否大於或等於右運算元的值,如果是則條件為真。 |
(A >= B) 不為真 |
<= |
檢查左運算元的值是否小於或等於右運算元的值,如果是則條件為真。 |
(A <= B) 為真 |
邏輯運算子
下表顯示了 C 語言支援的所有關係邏輯運算子。假設變數 A 的值為 1,變數 B 的值為 0,則:
運算子 |
描述 |
例項 |
&& |
稱為邏輯與運算子。如果兩個運算元都非零,則條件為真。 |
(A && B) 為假。 |
|| |
稱為邏輯或運算子。如果兩個運算元中有任意一個非零,則條件為真。 |
(A || B) 為真。 |
! |
稱為邏輯非運算子。用來逆轉運算元的邏輯狀態。如果條件為真則邏輯非運算子將使其為假。 |
!(A && B) 為真。 |
邏輯運算子&&和||存在短路運算,示例如下:
int main() { int a=10; int b=11; int c=0; if(a==b&&c++){
} printf("%d",c); return 0; } |
或者
int main() { int a=10; int b=10; int c=0; if(a==b||c++){
} printf("%d",c); return 0; } |
以上程式碼各輸出c的結果是?(輸出為:0)
位運算子
假設如果 A = 60,且 B = 13,現在以二進位制格式表示,它們如下所示:
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
位運算子作用於二進位制位,並逐位執行操作。&、 | 和 ^ 的真值表如下所示:
運算子 |
描述 |
例項 |
& |
按位與操作,按二進位制位進行"與"運算。運算規則: 0&0=0; 0&1=0; 1&0=0; 1&1=1; |
(A & B) 將得到 12,即為 0000 1100 |
| |
按位或運算子,按二進位制位進行"或"運算。運算規則: 0|0=0; 0|1=1; 1|0=1; 1|1=1; |
(A | B) 將得到 61,即為 0011 1101 |
^ |
異或運算子,按二進位制位進行"異或"運算。運算規則: 0^0=0; 0^1=1; 1^0=1; 1^1=0; |
(A ^ B) 將得到 49,即為 0011 0001 |
~ |
取反運算子,按二進位制位進行"取反"運算。運算規則: ~1=0; ~0=1; |
(~A ) 將得到 -61,即為 1100 0011,一個有符號二進位制數的補碼形式。 |
<< |
二進位制左移運算子。將一個運算物件的各二進位制位全部左移若干位(左邊的二進位制位丟棄,右邊補0)。 |
A << 2 將得到 240,即為 1111 0000 |
>> |
二進位制右移運算子。將一個數的各二進位制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。 |
A >> 2 將得到 15,即為 0000 1111 |
示例程式碼:
#include <stdio.h>
int main() { unsigned int a = 60; /* 60 = 0011 1100 */ unsigned int b = 13; /* 13 = 0000 1101 */ int c = 0;
c = a & b; /* 12 = 0000 1100 */ printf("Line 1 - c 的值是 %d\n", c );
c = a | b; /* 61 = 0011 1101 */ printf("Line 2 - c 的值是 %d\n", c );
c = a ^ b; /* 49 = 0011 0001 */ printf("Line 3 - c 的值是 %d\n", c );
c = ~a; /*-61 = 1100 0011 */ printf("Line 4 - c 的值是 %d\n", c );
c = a << 2; /* 240 = 1111 0000 */ printf("Line 5 - c 的值是 %d\n", c );
c = a >> 2; /* 15 = 0000 1111 */ printf("Line 6 - c 的值是 %d\n", c ); } |
輸出結果
賦值運算子
下表列出了 C 語言支援的賦值運算子:
運算子 |
描述 |
例項 |
= |
簡單的賦值運算子,把右邊運算元的值賦給左邊運算元 |
C = A + B 將把 A + B 的值賦給 C |
+= |
加且賦值運算子,把右邊運算元加上左邊運算元的結果賦值給左邊運算元 |
C += A 相當於 C = C + A |
-= |
減且賦值運算子,把左邊運算元減去右邊運算元的結果賦值給左邊運算元 |
C -= A 相當於 C = C - A |
*= |
乘且賦值運算子,把右邊運算元乘以左邊運算元的結果賦值給左邊運算元 |
C *= A 相當於 C = C * A |
/= |
除且賦值運算子,把左邊運算元除以右邊運算元的結果賦值給左邊運算元 |
C /= A 相當於 C = C / A |
%= |
求模且賦值運算子,求兩個運算元的模賦值給左邊運算元 |
C %= A 相當於 C = C % A |
<<= |
左移且賦值運算子 |
C <<= 2 等同於 C = C << 2 |
>>= |
右移且賦值運算子 |
C >>= 2 等同於 C = C >> 2 |
&= |
按位與且賦值運算子 |
C &= 2 等同於 C = C & 2 |
^= |
按位異或且賦值運算子 |
C ^= 2 等同於 C = C ^ 2 |
|= |
按位或且賦值運算子 |
C |= 2 等同於 C = C | 2 |
雜項運算子
下表列出了 C 語言支援的其他一些重要的運算子,包括 sizeof 和 ? :。
運算子 |
描述 |
例項 |
sizeof() |
返回變數的大小。 |
sizeof(a) 將返回 4,其中 a 是整數。 |
& |
返回變數的地址。 |
&a; 將給出變數的實際地址。 |
* |
指向一個變數。 |
*a; 將指向一個變數。 |
? : |
條件表示式 |
如果條件為真 ? 則值為 X : 否則值為 Y |
示例程式碼:
#include <stdio.h> int main() { int a = 4; short b; double c; int* ptr; /* sizeof 運算子例項 */ printf("Line 1 - 變數 a 的大小 = %lu\n", sizeof(a) ); printf("Line 2 - 變數 b 的大小 = %lu\n", sizeof(b) ); printf("Line 3 - 變數 c 的大小 = %lu\n", sizeof(c) ); /* & 和 * 運算子例項 */ ptr = &a; /* 'ptr' 現在包含 'a' 的地址 */ printf("a 的值是 %d\n", a); printf("*ptr 是 %d\n", *ptr); /* 三元運算子例項 */ a = 10; b = (a == 1) ? 20: 30; printf( "b 的值是 %d\n", b ); b = (a == 10) ? 20: 30; printf( "b 的值是 %d\n", b ); }
輸出結果:
運算子優先順序
運算子的優先順序確定表示式中項的組合。這會影響到一個表示式如何計算。某些運算子比其他運算子有更高的優先順序,例如,乘除運算子具有比加減運算子更高的優先順序。
例如 x = 7 + 3 * 2,在這裡,x 被賦值為 13,而不是 20,因為運算子 * 具有比 + 更高的優先順序,所以首先計算乘法 3*2,然後再加上 7。
下表將按運算子優先順序從高到低列出各個運算子,具有較高優先順序的運算子出現在表格的上面,具有較低優先順序的運算子出現在表格的下面。在表示式中,較高優先順序的運算子會優先被計算。
類別 |
運算子 |
結合性 |
字尾 |
() [] -> . ++ - - |
從左到右 |
一元 |
+ - ! ~ ++ - - (type)* & sizeof |
從右到左 |
乘除 |
* / % |
從左到右 |
加減 |
+ - |
從左到右 |
移位 |
<< >> |
從左到右 |
關係 |
< <= > >= |
從左到右 |
相等 |
== != |
從左到右 |
位與 AND |
& |
從左到右 |
位異或 XOR |
^ |
從左到右 |
位或 OR |
| |
從左到右 |
邏輯與 AND |
&& |
從左到右 |
邏輯或 OR |
|| |
從左到右 |
條件 |
?: |
從右到左 |
賦值 |
= += -= *= /= %=>>= <<= &= ^= |= |
從右到左 |
逗號 |
, |
從左到右 |