// 引入頭文件。裏面包含了重要的 printf。
#include <stdio.h>
// 入口函數。
// 參數一指輸入的參數個數,參數二保存了全部參數。
// 返回值爲 int 類型,通常 0 表明成功,負數表明失敗。
int main(int argc,char* argv[]){
printf("Hello World!\n");
return 0; // 表明執行成功。
}
複製代碼
經過指令的編譯與執行:linux
MAC 下的編譯使用 clang,Linux 下的編譯使用 gcc。數組
gcc/clang -g -o Hello xxx.c微信
-g 是 debug 模式,帶有調試信息的。markdown
-o 指明輸出文件的名字函數
xxx.c 源代碼oop
在 MAC 或 Linux 下使用 ./Hello 來執行ui
集成環境的運行,後臺其實也是這個步驟。編碼
short(短整型)、int(整型)、long(長整型)spa
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; // 表明執行成功。
}
複製代碼
枚舉能夠認爲它是一個有限制的整型。通常狀況下的使用,是在有必定數值範圍的,好比某個屬性的取值只能爲 一、二、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 語言中,它除了能夠存放普通的數值,還能夠存放另外一個內存的地址,這個值就是指針,經過這個值就能夠訪問到其它地址,而後就能夠取出這個地址所存放的數據。因此,這個值能夠有多重含義,具體跟業務邏輯相關。
指針的做用:
提高執行效率。
通常狀況下,將字符串傳入函數中,函數對字符串進行操做時,它是一個拷貝的過程,函數將字符串拷貝到本身的函數空間存放起來。屢次的拷貝會對整個 CPU 形成巨大的浪費。而指針,只須要向函數傳遞這個字符串所在的地址,函數經過指針訪問字符串。
更強的控制力。
由於它具備訪問地址的能力。像計算機的硬件實際到操做系統層都會有一個對應的映射地址,經過這個地址,C 語言就能訪問到硬件設備,並進行控制。C 語言是更底層的語言,它能夠訪問設備。
指針的操做:
一是對指針自己的操做。
實際就是對地址的操做。好比,當獲取某個空間的指針後,能夠對這個指針進行加減乘除的操做,對其加一,就指向了下一個空間。
二是對所指向的內容操做。
指針指向某一個內存地址時,能夠獲取其內容,能夠對這個內容進行加減乘除的操做。
指針的定義與使用:
type* var:
*var:表示獲取指針所指向的內容
堆內存的分配與釋放:
分配內存: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;
}
複製代碼
參考資料:
慕課網-音視頻基礎(李超)
歡迎關注微信公衆號:非也緣也