天天看點

10W+字C語言硬核總結(一),值得閱讀收藏!

一. C語言概述

歡迎大家來到c語言的世界,c語言是一種強大的專業化的程式設計語言。

10W+字C語言硬核總結(二),值得閱讀收藏!

10W+字C語言硬核總結(三),值得閱讀收藏!

熬夜整理的C語言/C++萬字總結(四)

熬夜整理的C/C++萬字總結(五),檔案操作

程式員必備硬核資料,點選下載下傳

1.1 C語言的起源

貝爾實驗室的Dennis Ritchie在1972年開發了C,當時他正與ken Thompson一起設計UNIX作業系統,然而,C并不是完全由Ritchie構想出來的。它來自Thompson的B語言。

1.2 使用C語言的理由

在過去的幾十年中,c語言已成為最流行和最重要的程式設計語言之一。它之是以得到發展,是因為人們嘗試使用它後都喜歡它。過去很多年中,許多人從c語言轉而使用更強大的c++語言,但c有其自身的優勢,仍然是一種重要的語言,而且它還是學習c++的必經之路。

高效性。c語言是一種高效的語言。c表現出通常隻有彙編語言才具有的精細的控制能力(彙編語言是特定cpu設計所采用的一組内部制定的助記符。不同的cpu類型使用不同的彙編語言)。如果願意,您可以細調程式以獲得最大的速度或最大的記憶體使用率。

可移植性。c語言是一種可移植的語言。意味着,在一個系統上編寫的c程式經過很少改動或不經過修改就可以在其他的系統上運作。

強大的功能和靈活性。c強大而又靈活。比如強大靈活的UNIX作業系統便是用c編寫的。其他的語言(Perl、Python、BASIC、Pascal)的許多編譯器和解釋器也都是用c編寫的。結果是當你在一台Unix機器上使用Python時,最終由一個c程式負責生成最後的可執行程式。

1.3 C語言标準

1.3.1 K&R C

起初,C語言沒有官方标準。1978年由美國電話電報公司(AT&T)貝爾實驗室正式發表了C語言。布萊恩•柯林漢(Brian Kernighan) 和 丹尼斯•裡奇(Dennis Ritchie) 出版了一本書,名叫《The C Programming Language》。這本書被 C語言開發者們稱為K&R,很多年來被當作 C語言的非正式的标準說明。人們稱這個版本的 C語言為K&R C。

K&R C主要介紹了以下特色:結構體(struct)類型;長整數(long int)類型;無符号整數(unsigned int)類型;把運算符=+和=-改為+=和-=。因為=+和=-會使得編譯器不知道使用者要處理i = -10還是i =- 10,使得處理上産生混淆。

即使在後來ANSI C标準被提出的許多年後,K&R C仍然是許多編譯器的最準要求,許多老舊的編譯器仍然運作K&R C的标準。

1.3.2 ANSI C/C89标準

1970到80年代,C語言被廣泛應用,從大型主機到小型微機,也衍生了C語言的很多不同版本。1983年,美國國家标準協會(ANSI)成立了一個委員會X3J11,來制定 C語言标準。

1989年,美國國家标準協會(ANSI)通過了C語言标準,被稱為ANSI X3.159-1989 "Programming Language C"。因為這個标準是1989年通過的,是以一般簡稱C89标準。有些人也簡稱ANSI C,因為這個标準是美國國家标準協會(ANSI)釋出的。

1990年,國際标準化組織(ISO)和國際電工委員會(IEC)把C89标準定為C語言的國際标準,命名為ISO/IEC 9899:1990 - Programming languages -- C[5] 。因為此标準是在1990年釋出的,是以有些人把簡稱作C90标準。不過大多數人依然稱之為C89标準,因為此标準與ANSI C89标準完全等同。

1994年,國際标準化組織(ISO)和國際電工委員會(IEC)釋出了C89标準修訂版,名叫ISO/IEC 9899:1990/Cor 1:1994[6] ,有些人簡稱為C94标準。

1995年,國際标準化組織(ISO)和國際電工委員會(IEC)再次釋出了C89标準修訂版,名叫ISO/IEC 9899:1990/Amd 1:1995 - C Integrity[7] ,有些人簡稱為C95标準。

1.3.3 C99标準

1999年1月,國際标準化組織(ISO)和國際電工委員會(IEC)釋出了C語言的新标準,名叫ISO/IEC 9899:1999 - Programming languages -- C ,簡稱C99标準。這是C語言的第二個官方标準。

例如:

增加了新關鍵字 restrict,inline,_Complex,_Imaginary,_Bool

支援 long long,long double _Complex,float _Complex 這樣的類型

支援了不定長的數組。數組的長度就可以用變量了。聲明類型的時候呢,就用 int a[*] 這樣的寫法。不過考慮到效率和實作,這玩意并不是一個新類型。

二、記憶體分區

2.1 資料類型

2.1.1 資料類型概念

什麼是資料類型?為什麼需要資料類型? 資料類型是為了更好進行記憶體的管理,讓編譯器能确定配置設定多少記憶體。

我們現實生活中,狗是狗,鳥是鳥等等,每一種事物都有自己的類型,那麼程式中使用資料類型也是來源于生活。

當我們給狗配置設定記憶體的時候,也就相當于給狗建造狗窩,給鳥配置設定記憶體的時候,也就是給鳥建造一個鳥窩,我們可以給他們各自建造一個别墅,但是會造成記憶體的浪費,不能很好的利用記憶體空間。

我們在想,如果給鳥配置設定記憶體,隻需要鳥窩大小的空間就夠了,如果給狗配置設定記憶體,那麼也隻需要狗窩大小的記憶體,而不是給鳥和狗都配置設定一座别墅,造成記憶體的浪費。

當我們定義一個變量,a = 10,編譯器如何配置設定記憶體?計算機隻是一個機器,它怎麼知道用多少記憶體可以放得下10?

是以說,資料類型非常重要,它可以告訴編譯器配置設定多少記憶體可以放得下我們的資料。

狗窩裡面是狗,鳥窩裡面是鳥,如果沒有資料類型,你怎麼知道冰箱裡放得是一頭大象!

資料類型基本概念:

類型是對資料的抽象;

類型相同的資料具有相同的表示形式、存儲格式以及相關操作;

程式中所有的資料都必定屬于某種資料類型;

資料類型可以了解為建立變量的模具: 固定大小記憶體的别名;

10W+字C語言硬核總結(一),值得閱讀收藏!

2.1.2 資料類型别名

typedef unsigned int u32;

typedef struct _PERSON{

char name[64];

int age;

}Person;

void test(){

u32 val; //相當于 unsigned int val;

Person person; //相當于 struct PERSON person;

}

2.1.3 void資料類型

void字面意思是”無類型”,void* 無類型指針,無類型指針可以指向任何類型的資料。

void定義變量是沒有任何意義的,當你定義void a,編譯器會報錯。

void真正用在以下兩個方面:

對函數傳回的限定;

對函數參數的限定;

//1. void修飾函數參數和函數傳回
void test01(void){
 printf("hello world");
}
//2. 不能定義void類型變量
void test02(){
 void val; //報錯
}
//3. void* 可以指向任何類型的資料,被稱為萬能指針
void test03(){
 int a = 10;
 void* p = NULL;
 p = &a;
 printf("a:%d\n",*(int*)p);
 char c = 'a';
 p = &c;
 printf("c:%c\n",*(char*)p);
}
//4. void* 常用于資料類型的封裝
void test04(){
 //void * memcpy(void * _Dst, const void * _Src, size_t _Size);
}      

2.1.4 sizeof 操作符

sizeof 是 c語言中的一個操作符,類似于++、--等等。sizeof 能夠告訴我們編譯器為某一特定資料或者某一個類型的資料在記憶體中配置設定空間時配置設定的大小,大小以位元組為機關。

基本文法:

sizeof(變量);

sizeof 變量;

sizeof(類型);

sizeof 注意點:

sizeof傳回的占用空間大小是為這個變量開辟的大小,而不隻是它用到的空間。和現今住房的建築面積和實用面積的概念差不多。是以對結構體用的時候,大多情況下就得考慮位元組對齊的問題了;

sizeof傳回的資料結果類型是unsigned int;

要注意數組名和指針變量的差別。通常情況下,我們總覺得數組名和指針變量差不多,但是在用sizeof的時候差别很大,對數組名用sizeof傳回的是整個數組的大小,而對指針變量進行操作的時候傳回的則是指針變量本身所占得空間,在32位機的條件下一般都是4。而且當數組名作為函數參數時,在函數内部,形參也就是個指針,是以不再傳回數組的大小;

//1. sizeof基本用法
void test01(){
 int a = 10;
 printf("len:%d\n", sizeof(a));
 printf("len:%d\n", sizeof(int));
 printf("len:%d\n", sizeof a);
}
//2. sizeof 結果類型
void test02(){
 unsigned int a = 10;
 if (a - 11 < 0){
  printf("結果小于0\n");
 }
 else{
  printf("結果大于0\n");
 }
 int b = 5;
 if (sizeof(b) - 10 < 0){
  printf("結果小于0\n");
 }
 else{
  printf("結果大于0\n");
 }
}
//3. sizeof 碰到數組
void TestArray(int arr[]){
 printf("TestArray arr size:%d\n",sizeof(arr));
}
void test03(){
 int arr[] = { 10, 20, 30, 40, 50 };
 printf("array size: %d\n",sizeof(arr));
 //數組名在某些情況下等價于指針
 int* pArr = arr;
 printf("arr[2]:%d\n",pArr[2]);
 printf("array size: %d\n", sizeof(pArr));
 //數組做函數函數參數,将退化為指針,在函數内部不再傳回數組大小
 TestArray(arr);
}      

2.1.5 資料類型總結

資料類型本質是固定記憶體大小的别名,是個模具,C語言規定:通過資料類型定義變量;

資料類型大小計算(sizeof);

可以給已存在的資料類型起别名typedef;

資料類型的封裝(void 萬能類型);