C 語言基礎
// 引入頭檔案,里面包含了重要的 printf,
#include <stdio.h>
// 入口函式,
// 引數一指輸入的引數個數,引數二保存了所有引數,
// 回傳值為 int 型別,一般 0 代表成功,負數代表失敗,
int main(int argc,char* argv[]){
printf("Hello World!\n");
return 0; // 代表執行成功,
}
————————
通過指令的編譯與執行:
MAC 下的編譯使用 clang,Linux 下的編譯使用 gcc,
gcc/clang -g -o Hello xxx.c
● -g 是 debug 模式,帶有除錯資訊的,
● -o 指明輸出檔案的名字
● xxx.c 源代碼
在 MAC 或 Linux 下使用 ./Hello 來執行
集成環境的運行,后臺其實也是這個步驟,
一、常用基本型別
short(短整型)、int(整型)、long(長整型)
float(單精度浮點型,一般情況使用 float,)、double(雙精度浮點型,精度高,適用于科學計算等,)
char(字符)、char*(字串)
void(對型別不關心時)
二、基本運算
+、-、*、/、%
int main(int argc,char* argv[]) { int a = 10; float b = 12.5; // 列印結果;a+b=22.500000 (float 型別) printf("a+b=%f\n",a+b); // 列印結果;... , a*b=125.000000 (float 型別) printf("a+b=%f\n,a*b=%f\n",a+b,a*b); char c = 'a'; // 列印結果;c=f(c 為字符 a,c 加數字可以變為另一個字符,c+1=b,c+2=c,...) printf("c=%c\n",c+5); // 列印結果;c=102(f 的實際編碼的值就是 102) printf("c=%d\n",c+5); int d = 10; int e = d % 6; // 取余 int f = d / 6; // 取商 // 列印結果;e=4,f=1 printf("e=%d\n,f=%d\n",e,f); return 0; // 代表執行成功, }
三、變數與常量
● int a = 0; // 變數,可以再賦值,可以不賦值初始值,
變數在計算機中的物理意義,就是一個暫存器,暫存器是臨時存盤資料的,它的速度非常快,從記憶體中取一塊資料時,首先存盤到暫存器,當改變這個值時,重繪的是暫存器,可擦除,這樣可以加快程式的執行速度,
● const int len = 265; // 常量,不可改變,需要賦值初始值,
在編譯程式時,程式中設定了一段靜態緩沖區,靜態緩沖區是受保護的,通過正常途徑是不可修改的,但如果知道記憶體的具體物理地址,也是可以改變的,
四、陣列
陣列是有序的元素序列(C 語言的陣列存放的是同一種型別的元素,索引從 0 開始),C 語言中定義陣列需要告訴編譯器陣列的長度,C 語言中陣列的定義; char c[2], int arr[10]
int main(int argc,char* argv[]) { // int arr[10]; // arr[0] = 1; // arr[1] = 2; // printf("%d,%d\n",arr[0],arr[1]); int arr[10] = {1,2,3,}; // 列印結果;1,2,3,0(默認情況下,不賦值的情況下,陣列會初始化為 0,) printf("%d,%d,%d,%d\n",arr[0],arr[1],arr[2],arr[3]); float f[2] = {1,2}; // 列印結果;1.000000,2.000000 printf("%f,%f\n",f[0],f[1]); return 0; }
五、結構體
// 它是沒有保護的概念的(如 private 等) struct st { int a; // 成員 a int b; // 成員 b };
// 結構體可以理解為它是一個類 struct st{ int a; float f; }; int main(int argc,char* argv[]){ struct st ss; ss.a = 12; ss.f = 10.2; // 列印結果;struct:12, 10.200000 printf("struct:%d, %f\n",ss.a,ss.f); return 0; // 代表執行成功, }
六、列舉型別
列舉可以認為它是一個有限制的整型,一般情況下的使用,是在有一定數值范圍的,比如某個屬性的取值只能為 1、2、3,
enum em { red_color = 0, // 值為 0,如果值為 1 green_color, // 值為 1,則值為 2 black_color // 值為 2,則值為 3 };
enum em { red_color = 5, green_color, black_color = 10, yellow_color }; int main(int argc,char* argv[]){ enum em ee; ee = green_color; // 列印結果;enum:6 printf("enum:%d\n",ee); ee = yellow_color; // 列印結果;enum:11 printf("enum:%d\n",ee); return 0; // 代表執行成功, }
七、指標
指標就是存放記憶體地址的變數,地址空間內的存的值,在 C 語言中,它除了可以存放普通的數值,還可以存放另一個記憶體的地址,這個值就是指標,通過這個值就可以訪問到其它地址,然后就可以取出這個地址所存放的資料,所以,這個值可以有多重含義,具體跟業務邏輯相關,
1、指標的作用:
● 提升執行效率,
一般情況下,將字串傳入函式中,函式對字串進行操作時,它是一個拷貝的程序,函式將字串拷貝到自己的函式空間存放起來,多次的拷貝會對整個 CPU 造成巨大的浪費,而指標,只需要向函式傳遞這個字串所在的地址,函式通過指標訪問字串,
● 更強的控制力,
因為它具有訪問地址的能力,像計算機的硬體實際到作業系統層都會有一個對應的映射地址,通過這個地址,C 語言就能訪問到硬體設備,并進行控制,C 語言是更底層的語言,它可以訪問設備,
2、指標的操作:
● 對指標本身的操作,
實際就是對地址的操作,比如,當獲取某個空間的指標后,可以對這個指標進行加減乘除的操作,對其加一,就指向了下一個空間,
● 對所指向的內容操作,
指標指向某一個記憶體地址時,可以獲取其內容,可以對這個內容進行加減乘除的操作,
3、指標的定義與使用:
● type* var:type 指型別,比如 int、void 等,
而 * 代表這個變數是一個指標,可以靠近型別 type 寫,表示這種型別的指標,關注指標是什么型別的,也可以靠近變數 var 寫,表示這個變數是一個指標,而對型別不關注,這兩種寫法對編譯器是沒有區別的,但在撰寫代碼時,最好統一風格,
● *var:表示獲取指標所指向的內容
4、堆記憶體的分配與釋放:
● 分配記憶體:void* mem = malloc(size);
● 釋放記憶體:free(mem);
#include <stdio.h> #include <stdlib.h> // malloc() 需要的頭檔案 int main(int argc,char* argv[]){ // malloc() 一般回傳的是 void* 型別, // malloc() 在 <stdlib.h> 頭檔案中, char* p = (char*)malloc(10); // 分配十個字符的空間 *p = 'a'; // 第一個字符的位置 *(p+1) = 'b'; // 第二個字符的位置 // 將記憶體分配的地址告訴 printf, // printf 將 p 地址所指向的空間的內容以字串的形式列印出來, printf("%s\n",p); // 列印結果;ab // 將 p 所指向的空間釋放掉 // 系統管理層將記憶體又還給了堆空間 free(p); *p = 'd'; // 即使把空間釋放掉,但因為仍然掌握此空間的位置,知道 p 的指向, // 所以即使被釋放掉了,還是可以對其操作, printf("%s\n",p); // 列印結果;db // 所以為了不讓再訪問這個地址,要將其指向 NULL,設定為無效地址, p = NULL; // *p = 'e'; // crash return 0; }
八、常見的記憶體空間
● 堆疊空間:堆疊的機制,后進先出,最大的特點是,在 C 語言中寫的函式,在函式內所分配的所有變數都是在堆疊空間分配的,當從函式退出時,從堆疊空間分配的資源會被自動釋放,
分配的資源是有限的,默認每個函式堆疊空間的大小是 8兆,
● 堆空間:需要明確的使用 malloc() 函式來分配資源,使用完記憶體后,要通過 free() 函式將資源釋放回堆空間,這樣別人使用時還能從堆空間分配資源,
分配的資源幾乎可以認為是無限的,適合需要大空間的時候,
● 記憶體映射:像一些動態庫一般都是將它直接匯入記憶體映射區,也是一段專門的空間,
比如將某個檔案直接映射到記憶體中,檔案的內容與記憶體形成映射關系,當改變記憶體中的值時,會直接在系統內部自動更新到檔案中,
● Linux 記憶體地址的劃分:4G 32 位系統

0 ~ 0x08048000:這段是受保護空間,我們的行程是不能訪問的,
code:存放的是行程所要執行的代碼段,
堆空間的增長是從下向上,堆疊空間是從上向下,每次分配空間是向下走的,堆空間與堆疊空間這樣的劃分是為了減少沖突,
共享庫,或者叫記憶體映射區,當想通過記憶體改變檔案時,就可以將檔案映射到 mmap 這段空間中,
● 記憶體泄漏:
? 不斷的向系統申請記憶體,
? 申請的記憶體不用,也不釋放,
● 野指標:占用別人的記憶體稱為野指標,
九、條件判斷與回圈
比較運算:
>、<、>=、<=、==、!=
if/else 陳述句:
if( a> b){ ? ... }else{ ? ... }
for 陳述句:
for(int i =0; i<100; i++){ ? ... }
while 陳述句:
#include <stdio.h>
#include <unistd.h> // usleep() 需要的頭檔案
int main(int argc,char* argv[]){
while (1) { // 死回圈
printf("while...\n"); // 一秒鐘列印一次
usleep(1000000); // 微秒
}
return 0;
}
十、函式
C 語言中的命名一般以 Linux 的風格,單詞與單詞用下劃線連接,單詞一般都是縮寫,
// void 回傳型別
// func 函式名稱
// int a 形參
void func(int a){
... // 函式不能太大,一般不超過 50 行,
}
● 函式指標:指向函式的指標變數,通過 C 語言的函式指標可以實作 C++ 中的多型,就是定義的函式指標既可以指向 a 函式,也可以指向 b 函式,對外層來說,只需要呼叫這個函式指標就可以了,(多型就是指一個函式可以有不同的含義)
● 函式指標的格式:回傳值型別 (*指標變數名) ([形參串列]);
————————
int func(int x); // 宣告一個函式 int (*f)(int x); // 宣告一個函式指標,回傳型別和形參必須與指定的函式一致, f = func; // 將 func 函式的首地址賦值給指標 f,然后呼叫 f 即可, ———————— #include <stdio.h> int func(int a){ printf("a=%d\n",a); return 0; } int func1(int b){ printf("b=%d\n",b+5); return 0; } int main(int argc,char* argv[]){ int (*f)(int); // 在 C++ 中這就是多型, // 對上層來講,呼叫的都是 f 這個函式指標,但在底層回傳的是不同的結果, f=func; f(2); f=func1; f(3); // 列印結果;a=2 b=8 return 0; }
十一、檔案操作
● 檔案型別:FILE* file; (FILE* 在 Linux 下叫指標,在 Windows 下叫句柄,)
● 打開檔案:FILE* fopen(path,mode);
● 關閉檔案:fclose(FILE*);
#include <stdio.h> void createfile(char* filename){ // open/create file FILE* file = fopen(filename,"w"); if (!file) { printf("Failed to create file (%s)\n",filename); return; } // 向創建好的檔案內寫入內容, // 引數一指寫入的字串,引數二指字串中的每一項多大,引數三指一共有幾項,引數四指寫到哪個檔案 size_t len = fwrite("aaaaa", 1, 5, file); if (len !=5) { // size_t 使用的列印為 %zu, printf("Failed to write file,(%zu)",len); fclose(file); return; } printf("Successed to write file\n"); fclose(file); printf("Successed to create file\n"); } void read_data(char* filename){ FILE* file = fopen(filename,"r"); if (!file) { printf("Failed to create file (%s)\n",filename); return; } // 定義為 1k 大小,并初始化為 0, char buffer[1024] = {0,}; // 引數:讀出的資料存放位置,長度,讀多少,從哪讀, size_t len = fread(buffer, 1, 10, file); if (len <= 0) { printf("Failed to read file!\n"); fclose(file); return; } printf("read_data:%s\n",buffer); fclose(file); return; } int main(int argc,char* argv[]){ // create file // createfile("/Users/jianghouren/Downloads/1.txt"); // read file read_data("/Users/jianghouren/Downloads/1.txt"); return 0; }

最后,不管你是轉行也好,初學也罷,進階也可,如果你想學編程~
【值得關注】我的 C/C++編程學習交流俱樂部!【點擊進入】
問題答疑,學習交流,技術探討,還有超多編程資源大全,零基礎的視頻也超棒~
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/253798.html
標籤:C
