資料處理的核心問題:記憶及計算,這個問題會由資料型別用以描述這個資料如何儲存及計算。
電腦內部具有記憶體空間而該空間由Byte(8 bits)
所組成大多數情況下(實作定義)
任何資料型別的資料都是由0或1所組成,所以為何硬碟可以儲存照片、影音、word、PPT檔案等。
資料型別 | 名稱 | 大小(byte) | 例子 |
---|---|---|---|
短整數(short integer) | short int |
2* | 32 |
整數(integer) | int |
4* | 32 |
長整數(long integer) | long int |
4* | 32 |
字元(character | char |
1 | '3' |
單精度浮點數(single-precision floating points) | float |
4* | 3.2 |
倍精度浮點數(double-precision floating points) | double |
8* | 3.2 |
無 | void |
? |
*
代表為實作定義(表示不同編譯器會有不一樣的大小),如果想要知道其大小會使用 sizeof
這個運算子來去求出某個資料型別佔記憶體空間之大小。
表示我所使用的gcc
編譯器long int
的資料型別為8 byte
error
。(initalization)
Ex: int num=0;
資料型別 | 變數名稱 |
---|---|
int | num |
以下keyword保留其他功能使用不能當作變數名稱
不同資料型別的差異為
(int vs char)
(int vs float)
(short int vs long int)
(float vs double)
(int vs unsigned int)
數字的表示式:有號數及無號數
在計算機科學中會使用許多種數字型態的表示方法:有無號數、有號數、一補數、二補數等,其中無號數的缺點為不能用以計算負值,再來有號數的缺點為有可能會有溢位導致未定義行為情形發生,一補數是為了改進有號數數字表示法的缺點而去延伸出來的表示方式,編碼仍屬於阿貝爾群,一補數系統的缺點會是編碼時會產生 +0
和 -0
,後有了二補數這個編碼方式,並且成為計算機編碼最常見的方式,一補數系統仍常用通訊領域相關的用途。
IEEE 754
的浮點數表示法有單精度及雙精度表示法。
- 浮點數都表示約略之值
- 在使用一樣大小的記憶體空間下,浮點數可表示的範圍都大於整數
- 浮點數可以想成一種科學記號表示法:以
IEEE 754
為例:
- 有效數字越多表示值的精度越準確,但其佔用之記憶體空間會越大。
data type | Name | byte | Mantissa | exponent |
---|---|---|---|---|
single-precision floating point | float | 4* | 23* | 8* |
double-precision floating point | double | 8* | 52* | 11* |
long double | 8 | ?* | ?* |
printf
為內建的標準輸出的函式printf
使用必須給予想要印出之字串。 Ex: printf("Hello World !");
printf
輸出的字串可以用類似字元跳脫的方法,放置一些特定的格式符號來輸出特定的資料 Ex:int sum =10; printf("Sum is %d /n",sum);
scanf
是標準輸入的內建函式。//鍵盤輸入文字scanf
使用時要給予讀入資料格式及變數的記憶體位址 Ex: scanf("%d", &a);
&為取址運算子C
語言裡字元型別算是整數型別的特例:ASCII編碼C
語言編碼仍然是實作定義C
語言中字元型別有:char
(1 byte)和wchar_t
兩種型別,wchar_t
為寬字元表示式(expression): $3+4\times 2$
:其中3及4和2代表運算元(operand)
具有資料及型別 為運算子(operator)
對資料做運算,在進行運算時,因為運算有其優先順序,會產生暫時物件用以儲存運算結果,暫時物件也具有資料型別和值operator | int | float | ex | priority | Column 3 |
---|---|---|---|---|---|
+ | ok | ok | a+b | low | left to right |
- | ok | ok | a-b | low | left to right |
* | ok | ok | a*b | high | left to right |
/ | ok | ok | a/b | high | left to right |
% | ok | no | a%b | high | left to right |
註解:在除法時須注意資料型別不同所造成的結果不同如整數除以浮點數,若沒將其轉型會是以整數除法之值顯現
=
是賦值運算子(assign operator)
其用以會將右方的值複製給左方變數,不能寫成3=a
之類的,左方要放被改變的變數,在做賦值運算時會改變程式執行的狀態,所以改變變數之值為其的side effect
- 賦值運算的優先順序比大多運算子還低,順序為由右至左
C
語言內為表示式,真為條件成立,假為條件不成立C99
新增了_bool代表儲存true or false
的資料型別true
代表為1
,fasle
代表為0
C
語言中比較只能兩個兩個比較。and
替代&&
,則需要包含標頭檔<iso646.h>
程式是由每一個結構來去控制程式碼執行流程
if、for、while、do while
等程式碼。if、if-else、if-else if
等敘述。for、while、do-while
等敘述迴圈。def
: if{expression}{body}
若expression
成立則執行body
內的程式碼。
def
: if{expression}{body1}else{body2}
若expression
成立則執行body1
內的程式碼,不成立則執行body2
內的程式碼。
def
:switch(int){case (constant):body1;break; default:body2}
,用break
隔開不同case
的程式區塊。
def
:while(expression){body}
:若expression
成立則執行body
內的程式碼。
def
:do{body}while(expression)
:若expression
成立則執行body
內的程式碼(至少會做一次)。
def
:for(initial;expression;loop in/decrement){code body}
def
:(return_type) functio_name(var_type var_name,...){code body ... return return_value;}
1.變數名稱的宣告:
1.全域變數:
3.函式參數:
block
裡面。2.同一組區塊(block
)內同名稱變數只能有一個
3.變數名稱可視範圍
void
當作回傳值型態時,表示此函式無須回傳值且當函式型態為void
時,return
可以省略。int rand(void)
包含在stdlib
在使用rand
其給予亂數的序列都會相同,所以必須使用srand
來去給予亂數種:void srand(unsigned int seed)
def
:在函式定義裡,呼叫到所定義的函式,會達到類似無窮迴圈的概念,若回傳值定義不夠明確會一直占用記憶體空間程式會有非預期的結束(未定義行為)。
陣列是一群具有相同資料型態的元素集合的資料型態。
Array def
:element_type array_varname[element_num];
counter
、swap
等技巧,很重要。
arryprtf
的陣列與原本的陣列相同是直接拿來運算的C
語言中,函式傳遞時,陣列大小跟其是哪個陣列的資訊是分開的。 v[]
是指標的一種。C
語言的sizeof
運算子是實作定義上述程式中,在函式傳遞中v
並不是陣列型態。
N
至函式裡,可以使用保留值標記陣列長度。上述其中 i
是未初始化的區域變數會導致未定義行為。
上述其中 i
是全域變數會直接初始化為零。
Output
:1 1 1 1 1
若想讓印出的數字為:1 2 3 4 5
可以選擇將k
設置為全域變數。
static
表示這區域變數只會有一份並且只會初始化一次,得到類似全域變數的效果並且也不會在其餘函式中使用到。怎麼產生偽亂數?
char
) 可以儲存一個字元,但需要處理的文字通常是一串字元C
語言中並沒有替字串定義一個新的資料型別。
char[]
) 的形式來儲存。<string.h>
內提供各種處理字元陣列的函式實現對字串的操作行為。%zu
是C99
標準才有支援,若編譯器採用C89
、C90
實作需要改為%u
或%lu
。scanf
的回傳值判斷其成功讀入幾份資料。Pointer
)是C
語言的主要特性,是種儲存記憶體位址的資料型別。data_type *var_name
ex:swap
)。ex:array、string
)。 a[b]
運算等同於*(a+b)
,反之亦同。
- 在該陣列中從a開始往後移動b所在的陣列元素
- 當指標儲存某陣列第一個元素的記憶體位址,用起來與陣列相同。
Ex
:陣列歸零
const
修飾的變數在初始化之後不能再被賦值。
C
語言可以看待成唯讀的屬性。const char*
const char*
的形式。type*
可以轉型成const type*
q
是一個指標指向一個記憶體空間,空間有三個元素,每個元素都是int
。(int *[3])
像是陣列有三個元素每個都是(int *)
而 (int (*)[3])
才代表本身是個指標指向三個元素的整數陣列int (*q)[ ] =>int *(*q) => q
本身是個指標 指向一個整數的指標void
指標想像成泛用型別void
沒辦法被取值。電腦如何儲存指標?
malloc
函式動態配置記憶體<stdlib.h>
提供malloc
函式讓我們動態配置記憶體。
void malloc(size_t size);
。size
為非負整數型態(size_t
),表示要配置的記憶體空間大小(byte
)。sizeof
運算子來得知需要配置的記憶體空間。void
表示可以隱性轉型成其他資料型態的指標。larger
一樣是被視為自動變數會釋放記憶體空間,但被larger
使用malloc
配置所指向的記憶體空間不會被釋放。free
函式釋放動態配置的記憶體(Memory leak)
<stdlib.h>
提供free
函式來釋放動態配置的記憶體。
void free(void* ptr);
free
時的指標沒有明確指向記憶體空間,會產生未定義行為NULL pointer(空指標)
來去確定指標是否有指向記憶體位址,free
若是碰到NULL pointer(空指標)
會知道說喔喔沒有指向記憶體空間。realloc
函式重新配置記憶體大小<stdlib.h>
提供realloc
函式來複製記憶體內容。
void* realloc(void* ptr,size_t size);
。ptr
是要重新配置的記憶體空間開頭位址。malloc
或其他動態記憶體配置函式所配置。size
是重新配置後的記憶體空間大小(byte
)。函式與物件的異同
在C
語言中函式與物件是不同的概念但有些相似的地方。
&
)、獲得指標值(T*
)。T*
)儲存位址。T*
)進行間接運算(*
)可以取得該位置代表的特定物件或特定函式C
語言中函式都是使用函式指標進行呼叫的。op
必定指向必須要為函式。system()
函式可以執行其它程式(宣告於stdlib.h
)。int system(const char* command)
;system
會執行檔案路徑為command
的程式。system(hello.exe)
會執行同一個目錄為hello.exe
的執行檔(可以想成會呼叫hello.exe
的main
函式)system()
的回傳值就是所呼叫程式main
函式的回傳值。