C语言重难点
C語(yǔ)言
編譯過(guò)程
GCC概述
GCC最初的全名是GNU C Compiler
隨著GCC支持的語(yǔ)言越來(lái)越多,它的名稱變成了GNU Compiler Collection
翻譯官 翻譯組織
文件后綴名 gcc
.c
gcc -o output
gcc -o 輸出的文件名 輸入文件名
gcc -v -o
c語(yǔ)言的編譯過(guò)程
預(yù)處理—編譯—匯編—鏈接
預(yù)處理: .I 文件 替換過(guò)程,沒(méi)有include define等
編譯: 匯編文件 .s
匯編: 生成目標(biāo)文件 .o
鏈接: 鏈接資源 build
gcc的語(yǔ)法所對(duì)應(yīng)的內(nèi)容
預(yù)處理:cpp -o a.i 001.c 【gcc -E】
編譯 :/usr/lib/gcc/i486-linux-gnu/4.4.3/cc1 -o a.s 001.c 【gcc -S】
匯編:as -o a.o a.s 【gcc -c】
鏈接:/usr/lib/gcc/i486-linux-gnu/4.4.3/collect2 -o build a.o+… 【gcc -o】 gcc -o build 001.c
【問(wèn)題】
define include是關(guān)鍵字嗎? 是預(yù)處理命令
預(yù)處理
Include
< > 尖括號(hào)是系統(tǒng)中的
" "是自定義的
#include 包含頭文件
#define 宏 替換 不進(jìn)行語(yǔ)法檢查
#ifdef #else #endif 條件預(yù)處理
#include <stdio> #define ABC int main(){#ifdef ABCprintf("=====%s=====",——FILE__);#endifprintf("hello world\n“);return 0; }發(fā)行版本不希望別人看到自己的代碼結(jié)構(gòu),可以設(shè)置#ifdef #else#endif ,來(lái)調(diào)節(jié)是否打印。
gcc -DABC == #define ABC
預(yù)定義宏(兩個(gè)下劃線)
_FUNCTION_ :函數(shù)名
_LINE_: 行號(hào)
_FILE_ : 文件名
宏體# ## 區(qū)別:
# 字符串化
## 連接符號(hào)
#include <stdio> #define ABC(x) #x #define DAY(x) myday##xint main() {int myday1 = 10;int myday2 = 20;printf(ABC(ab\n));printf("the day is %d\n",DAY(1));return 0; }結(jié)果:
ab
10
DAY(1)調(diào)用的是myday1,通過(guò)#連接myday
關(guān)鍵字
數(shù)據(jù)類型
硬件芯片操作的最小單位:
bit 1 0
軟件操作的最小單位: 8bit == 1B
網(wǎng)速之間的轉(zhuǎn)換:
? 4M 4Mbit Kbit/s KB/S
char
硬件芯片操作的最小單位: bit
軟件操作的最小單位: char
8bit = 1B
硬件處理的最小的單位: char
最大的是256
int
大小: 根據(jù)編譯器來(lái)決定。
編譯器最優(yōu)的處理大小:
系統(tǒng)一個(gè)周期,所能接受的最大處理單位 int
32bit的系統(tǒng),4B 恰好能接收int類型
16bit的系統(tǒng) , 2B int
300L 后面的L表示long類型的,可以表示一個(gè)很大的數(shù),
long short
特殊長(zhǎng)度
unsigned、signed
無(wú)符號(hào):數(shù)據(jù)
有符號(hào):數(shù)字
區(qū)別:內(nèi)存空間的最高字節(jié)是符號(hào)位還是數(shù)據(jù)
float、double
浮點(diǎn)數(shù)
float 代表 4B
double代表 8B
浮點(diǎn)型常量
1.0f 是float類型
1.1 是double 的類型
void
一般是聲明標(biāo)志,不是使用標(biāo)志
void fun() 表示函數(shù)不反悔。
自定義數(shù)據(jù)類型
C編譯器默認(rèn)定義的內(nèi)存分配不符合實(shí)際資源的形式(例如定義寄存器的大小)
struct 、union、enum、typedef
struct
元素之間的和
struct myabc{unsigned int a;unsigned int b;unsigned int c; }; struct myabc mybuf;在結(jié)構(gòu)體最后加分號(hào),abc的順序不同,可能結(jié)構(gòu)的大小也不相同(涉及字節(jié)對(duì)齊的問(wèn)題)
union
共用起始地址的一段內(nèi)存(共用體)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-o8qu2Rvm-1606119305231)(file:///C:/Users/15890/AppData/Local/Packages/Microsoft.Office.OneNote_8wekyb3d8bbwe/TempState/msohtmlclip/clip_image001.png)]
定義b,a可能發(fā)生改變。
enum
enumerate 一一列舉
被命名的整型常數(shù)的集合
#define MON 0 #define TUE 1 #define WED 2 /* 上述的宏可以表示為 */ enum abc{ MOD = 0,TUE,WED }enum 枚舉名稱{ 常量列表 };
#include <stdio.h>enum week{ Monday = 0 ,Tuesday =1 ,Wednesday = 2,Thursday,Friday,Saturday,Sunday }; int main() {enum weel a1; /* 定義了這樣的空間 */printf("the a1 is %lu\n",sizeof(a1));printf ("the %d\n",WED);return 0; }運(yùn)行結(jié)果:
4
2
枚舉變量就是個(gè)整數(shù),只是這個(gè)整數(shù)可以取這集合面所有的值
enum DAY{}day;定義枚舉類型同時(shí)定義枚舉變量;
enum {}day; 可以省略名稱,直接定義枚舉變量;
typedef
數(shù)據(jù)類型的別名
typedef int a_t; /* a是一個(gè)int類型的外號(hào) */ a_t mysize;雜項(xiàng)
Sizeof
它是關(guān)鍵字
編譯器給我們查看內(nèi)存空間容量的一個(gè)工具
return
:返回函數(shù)
邏輯結(jié)構(gòu)
cpu是順序執(zhí)行程序
PC 指針?lè)种?--> 選擇
代碼周期性的循環(huán),節(jié)約內(nèi)存。
條件選擇
if else 、switch、case、default、
循環(huán)
do、while(條件)、for(次數(shù))、
循環(huán)中的控制符
continue、break、goto(在同一個(gè)函數(shù)中可以跳)
switch(整形數(shù))
{case 整形數(shù)i:
}
類型修飾符
對(duì)內(nèi)存資源存放位置的限定
auto、register、static、const、extern、volatile
有的可讀可寫(xiě),有的可讀,有的可寫(xiě)
Auto
可讀可寫(xiě)的內(nèi)存空間 默認(rèn)平時(shí)就是 auto char a;如果放入大括號(hào)里,就是存放在棧里;
register
register int a;限定變量定義在寄存器上的修飾符; 寄存器速度快,內(nèi)存上面慢
編譯器會(huì)盡量的安排CPU的寄存器取存放這個(gè)a,如果寄存器不足,a還是放在存儲(chǔ)器中。
**&**這個(gè)符號(hào)對(duì)register不起作用;
內(nèi)存(存儲(chǔ)器) 寄存器
0x100 R0,R2
static
靜態(tài)變量
**修飾3種數(shù)據(jù):**函數(shù)內(nèi)部的變量;函數(shù)外部的變量;函數(shù)的修飾符;
修飾3種數(shù)據(jù):
1)、函數(shù)內(nèi)部的變量
2)、函數(shù)外部的變量
int a; ==> static int a; int fun() {}3)、函數(shù)的修飾符
int fun(); ==> static int fun();const
常量定義、只讀的變量,不能修改
可以通過(guò)指針的技巧去修改;
extern
外部申明;也是再全局變量中使用;
volatile
告知編譯器編譯不優(yōu)化
修飾變量的值的修改,不僅僅可以通過(guò)軟件,也可以通過(guò)其他方式(硬件外部的用戶)
int a = 100;while( a==100 );mylcd();[a] 表示 a 的地址
f1: LDR R0,[a] f2: CMP R0,#100 f3: JMPeq f1 ----> JMPEQ f2 f4: mylcd();修飾變量的值的修改,不僅僅通過(guò)軟件,也可以通過(guò)其他方式。例如: 如果外界接了鍵盤(pán)來(lái)鍵入a,則就會(huì)發(fā)生錯(cuò)誤;
運(yùn)算符
算術(shù)運(yùn)算符
+、-、*、/、%
* 、/ 大部分是不支持的。
CPU可以在一個(gè)周期處理+ ,但是 * 在一個(gè)周期處理不了,需要利用軟件進(jìn)行模擬實(shí)現(xiàn)乘法
% 取模,4%3 = 1; 1%3=1;
應(yīng)用場(chǎng)景:
任意一個(gè)N,我們模上M過(guò)后,得到M進(jìn)制的個(gè)位數(shù);
取一個(gè)范圍的數(shù);
? eg:給一個(gè)任意的數(shù),得到一個(gè)1到100以內(nèi)的數(shù):(m%100)+1
循環(huán)數(shù)據(jù)結(jié)構(gòu)的下標(biāo)。
邏輯運(yùn)算
真與假 返回結(jié)果為 1 和 0
|| 、 & 、
A || B ≠ \neq ?= B || A 不相等
#include <stdio.h> int main() {int a =10;int res;res = ((a==10) || printf("======\n"));printf("the res is %d\n",res);return 0; }結(jié)果:1
a若足,則不看式子后面的內(nèi)容了,若把a(bǔ) != 10,則會(huì)輸出 ====
< 、>= 、 <= 、 >、!、? :
位運(yùn)算
<< 、 >>
左移 : 乘法 *2 二進(jìn)制下的移位
m << 1; m × 2 \times2 ×2
m << n m × 2 n \times2^n ×2n
[數(shù)據(jù)、數(shù)字]
-1 *2 -2:
8bit (負(fù)數(shù)先取反,再加一)
1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0
1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 1 === -1 1 1 1 1 1 1 1 0 == -2
負(fù)數(shù)也滿足
右移:除以2
m >> n m/2^n
符號(hào)變量有關(guān) 有符號(hào)數(shù)整數(shù)填1,無(wú)符號(hào)數(shù)填0.
如果a為負(fù)數(shù),永遠(yuǎn)也不會(huì)為0;
如果a為正數(shù),可以為0;
& 、 |
A & 0 ----> 0
&: 屏蔽
int a = 0x1234;
a & 0xff00; 屏蔽低8bit,取出高8bit
&:取出
A & 1 —> A
&:清零器 clr
|
A | 0 = A
保留
A | 1 = 1
設(shè)置為高電平的方法,設(shè)置set
設(shè)置一個(gè)資源的bit5為高電平,其他位不變
int a;
a = (a | (0x1<<5)); =====> a | (0x1<<n)
清除第五位
int a;
a = a & 0 1 1 1 1 1 31 a & 31 31 : 32bit
~(0x1<<5)
a = a & ~(0x1<<5); =====> a = a & (~(0x1<<n));
我們想資源456bit設(shè)置為101?
^
相同位為假
a = a ^ b
b = a ^ b
a = a ^ b
可以交換 a ,b的值
內(nèi)存訪問(wèn)
( ) 限制符號(hào)
? 函數(shù)訪問(wèn)符號(hào)
[ ] 數(shù)組,內(nèi)存訪問(wèn)的 ID 符號(hào)
{ } 函數(shù)體的限制符
–> 地址訪問(wèn)
. 變量訪問(wèn)
C語(yǔ)言內(nèi)存空間的使用
指針
指針的概述
內(nèi)存類型資源地址、門(mén)牌號(hào)的代名詞
指針變量 : 存放指針這個(gè)概念的盒子
int a;
int *p;
char *p;
C語(yǔ)言編譯器對(duì)指針這個(gè)特殊的概念,有2個(gè)疑問(wèn)?
1、分配一個(gè)盒子,盒子要多大?
在32bit系統(tǒng)中,指針就4個(gè)字節(jié)
2、盒子里存放的地址 所指向 內(nèi)存的讀取方法是什么?
? 聲明,得到大小,一次讀多少字節(jié)。確定位置
指針指向內(nèi)存空間,一定要保證合法性
浮點(diǎn)數(shù)在內(nèi)存中表現(xiàn)形式很奇怪
浮點(diǎn)數(shù)讀取,指針定義為unsigned,無(wú)符號(hào)類型。
指針修飾符
const
常量、只讀【不能變】
雙引號(hào)就是常量,不可改變 const char型
內(nèi)存屬性:
1、內(nèi)存操作的大小
2、內(nèi)存的變化性,可寫(xiě)可讀
char *p;
const char *p; 【T】 字符串 “ hello world” “aaa”
char const *p;
指向的內(nèi)容不可以變,指針可以指向其他的地址 字符串
char * const p; 【T】 硬件資源 LCD
char *p const;
指向的內(nèi)容可以改變,指針不能指向別的地方 硬件資源 LCD
const char * const p ROM
第三種,都不可以變 ROM
volatile
防止優(yōu)化指向內(nèi)存地址
char *p;
volatile char *p ;*p == 0x10 與之前的相同:while( *p == 0x10 );xxxx;typedef
char *p;
什么類型 變量名稱;
xxx a;
int (*p[10])(int ,void (*p)(int));char *name_t : name_t是一個(gè)指針,指向了一個(gè)char類型的內(nèi)存 typedef char *name_t; name_t是一個(gè)指針類型的名稱,指向了一個(gè)char類型的內(nèi)存name_t abc;指針運(yùn)算符
++ 、–、+、-
int a = 100;
a+1
int *p = xxx [0x12]
p+1 [0x12 + 1*(sizeof(*p))]
指針的加法、減法運(yùn)算,實(shí)際上加的是一個(gè)單位,單位的大小可以使用sizeof(p[0])
int *p p+1
char *p p+1
p++ p-- : 更新地址
[ ]
變量名[ n ]
n:ID 標(biāo)簽
地址內(nèi)容的標(biāo)簽訪問(wèn)方式
取出標(biāo)簽里的內(nèi)存值
操作邏輯符
>= 、<= 、== 、 !=
int *p1;
int *p2;
p1 > p2
*p1 > *p2
--------- == !=
1、跟一個(gè)特殊值進(jìn)行比較 0x0 : 地址的無(wú)效值,結(jié)束標(biāo)志
if( p == 0x0)
NULL
2、指針必須是同類型的比較才有意義
char *
int *
多級(jí)指針
int **p;
存放地址的地址空間
char **p;
p[0] p[1] … p[n]
p[m] == NULL ----> 結(jié)束了
數(shù)組
數(shù)組的定義
內(nèi)存的一種分配形式
定義一個(gè)空間:
1、大小
2、讀取方式
數(shù)據(jù)類型 數(shù)組名[m] m 的作用域是在申請(qǐng)的時(shí)候
數(shù)組名是一個(gè)常量符號(hào),一定不要放到=的左邊 ,舉例。
char buf[100];
buf = “hello world”;
數(shù)組名不能 a++,數(shù)組名就是數(shù)組的常量標(biāo)簽。
int a[100];
越界
a[10]
數(shù)組空間的初始化
空間的賦值
按照標(biāo)簽逐一處理
int a[10]; [ 0 - 9 ]
a[0] = xx
a[1] = yy;
程序員這樣賦值,工作量比較大,能不能讓編譯器進(jìn)行一些自動(dòng)處理,幫助程序員寫(xiě)如上的程序
----》空間定義時(shí),就告知編譯器的初始化情況,空間的第一次賦值,初始化操作
int a[10] = 空間;
C語(yǔ)言本身,CPU內(nèi)部本身一般不支持空間和空間的拷貝
int a[10] = {10,20,30};
====> a[0] = 10; a[1] = 20; a[2] = 30; a[3]=0;
數(shù)組空間的初始化 和 變量的初始化 本質(zhì)不同,尤其在嵌入式的裸機(jī)開(kāi)發(fā)中,空間的初始化往往需要庫(kù)函數(shù)的輔助
char
char buf[10] = {‘a(chǎn)’,‘b’,‘c’}; 3個(gè)字節(jié)
buf當(dāng)成普通內(nèi)存來(lái)看,沒(méi)有問(wèn)題
buf當(dāng)成一個(gè)字符串來(lái)看,最后加上一個(gè)’\0’ 字符串的重要屬性,結(jié)尾一定有個(gè)’\0’
第二次內(nèi)存初始化,賦值?
逐一處理
buf[0] = ‘h’ buf[1] = ‘e’ … buf[n] = ‘d’, buf[n+1] = 0; (不要忘了0)
strcpy、strncpy
一塊空間,當(dāng)成字符空間,提供了一套字符拷貝函數(shù)
字符拷貝函數(shù)的原則:
內(nèi)存空間和內(nèi)存空間的逐一賦值的功能的一個(gè)封裝體
一旦空間中出現(xiàn)了0這個(gè)特殊值,函數(shù)就即將結(jié)束。
非字符串空間
字符空間
ASCII碼編碼來(lái)解碼的空間,----》給人看
%s abc ‘a(chǎn) ’ ‘b’ ’ c’
\0作為結(jié)束標(biāo)志
非字符空間
數(shù)據(jù)采集 0x00 - 0xff 8bit
開(kāi)辟一個(gè)存儲(chǔ)這些數(shù)據(jù)盒子
? char buf[10]; ----> string 字符
unsigned char buf[10];----> data 數(shù)據(jù)
buf = “abc”;
unsigned char *p = sensor_base;
只管逐一拷貝,結(jié)束在哪里?只能定義個(gè)數(shù)
拷貝三要素:
1、src
2、dest
3、個(gè)數(shù)
memcpy
int buf[10]; int sensor_buf[100];memcpy(buf,sensor_buf,10*sizeof(int));unsigned char buf1[10]; unsigned char sensor_buf[100];// 00 00 00 23 45 78 strncpy(buf,sensor_buf,10) memcpy(buf,sensor_buf,10*sizeof(unsigned char));指針數(shù)組
int a[100] char * a[100]; //100個(gè)地址sizeof(a) = 100 * 4;int b; sizeof(b)char **a; //地址里面還是地址多維數(shù)組
定義一個(gè)指針,指向int a[10]的首地址
定義一個(gè)指針,指向int b[5][6]的首地址
二維數(shù)組是一塊一塊讀的,
int *p1 = a; int **p2 = b; //無(wú)效的指針類型int *p; int *p[5];int a; int a[5];int *p[5]; //p是5個(gè)空間,5個(gè)空間里存int* 與我們定義的一塊一塊讀是不一樣的。 int (*p)[5]; //5個(gè)int指針 和int a[5] 相似結(jié)構(gòu)體
字節(jié)對(duì)齊
strcuct abc {char a; int b};1 + 4 = 5
效率,希望犧牲一點(diǎn)空間換取時(shí)間的效率
最終結(jié)構(gòu)體的大小一定是4的倍數(shù)
結(jié)構(gòu)體里成員變量的順序不一致,也會(huì)影響到他的大小
位域
內(nèi)存的分布圖
int a; 默認(rèn)方式
編譯 —》匯編 —》鏈接
*.o build
4G的大小
內(nèi)核空間 應(yīng)用程序不許訪問(wèn) (占用1G)
棧空間 局部變量 RW
運(yùn)行時(shí)的堆空間 malloc
全局的數(shù)據(jù)空間 (初始化的,未初始化) static RW data bss
只讀數(shù)據(jù)段 “hello world” 字符串常量 R TEXT
代碼段 code R TEXT
0x0 :
局部變量;
函數(shù)結(jié)束后就會(huì)“銷毀”失效了。
局部的都在棧上
全局未初始化—bss,初始化—data
static 的變量也在全局 ,但是出了大括號(hào)就沒(méi)用了(訪問(wèn)的局部變量),還是存在在全局變量的區(qū)域
生成可執(zhí)行文件,一般打包最后一個(gè)段中的內(nèi)容。 text在代碼段會(huì)代入build文件中,占據(jù)內(nèi)存,release版本會(huì)把字符進(jìn)行處理。
棧空間
運(yùn)行時(shí),函數(shù)內(nèi)部使用的變量,函數(shù)一旦返回,就釋放,生存周期是函數(shù)內(nèi)
堆空間
運(yùn)行時(shí),可以自由,自我管理的分配和釋放的空間,生存周期是由程序員來(lái)決定
分配:
malloc(),一旦成功,返回分配好的地址給我們,只需要接受,對(duì)于這個(gè)新地址的讀法,由程序員靈活把握,輸入?yún)?shù)指定分配的大小,單位就是B。
釋放:
free§;
只讀空間
靜態(tài)空間,整個(gè)程序結(jié)束時(shí)釋放內(nèi)存,生存周期最長(zhǎng)
C語(yǔ)言函數(shù)的使用
函數(shù)概述
一堆代碼的集合,用一個(gè)標(biāo)簽去描述它
函數(shù) 數(shù)組,函數(shù)具備3要素: int *p; int a[100];
1、函數(shù)名 (地址)
2、輸入?yún)?shù)
3、返回值
在定義函數(shù)時(shí),必須將3要素告知編譯器。
int fun(int,int,char)
{ xxx }
如何用指針保存函數(shù)那?
char *p;
char (*p)[10];
int (*p)(int,int,char);
定義函數(shù),調(diào)用函數(shù)
int fun(int a,char b) {xxxx } int main() {fun(10,2); }char buf[100]; buf[10];輸入?yún)?shù)
承上啟下的功能
調(diào)用者:
函數(shù)名(要傳遞的數(shù)據(jù)) //實(shí)參
被調(diào)者:
函數(shù)的具體實(shí)現(xiàn)
函數(shù)的返回值 函數(shù)名(接收的數(shù)據(jù)) //形參
{
xx xxx
}
實(shí)參 傳遞給 形參
傳遞的形式:
拷貝
值傳遞
特點(diǎn):
void fun(int a) {a = xx;a = sha md5 yy }int main() {int a = 20;fun(a);printf a ==? }上層調(diào)用者 保護(hù)自己空間值不被修改的能力
地址傳遞
上層,調(diào)用者 讓下層 子函數(shù) 修改自己空間值的方式,類似結(jié)構(gòu)體這樣的空間,函數(shù)與函數(shù)之間調(diào)用關(guān)系—> 連續(xù)空間的傳遞 (不傳地址的話,只是 拿來(lái)看一下,并不改變本身的值)
void fun(char a); int main() {char a = 'e';fun(a);a == 'c' } void fun(char *b);int a = 10;fun(&a);a ===? 10int a; scanf("%d",a); scanf("%d",&a)將a的值傳遞給函數(shù),不能保證a還為10
連續(xù)空間的傳遞
1、數(shù)組
數(shù)組名 — 標(biāo)簽
實(shí)參:
int abc[10];
fun(abc)
形參:
void fun(int *p) void fun(int p[10])
2、結(jié)構(gòu)體
結(jié)構(gòu)體變量
struct abc{int a;int b;int c;};
struct abc buf;
實(shí)參:
fun(buf); fun(&buf)
形參:
void fun(struct abc a1) void fun(struct abc *a2)
**" " —> 初始化const char *
承上啟下的功能
調(diào)用者:
函數(shù)名(要傳遞的數(shù)據(jù)) //實(shí)參
被調(diào)者:
函數(shù)的具體實(shí)現(xiàn)
函數(shù)的返回值 函數(shù)名(接收的數(shù)據(jù)) //形參
{
xx xxx
}
實(shí)參 傳遞給 形參
傳遞的形式:
拷貝
值傳遞
特點(diǎn):
void fun(int a) {a = xx;a = sha md5 yy }int main() {int a = 20;fun(a);printf a ==? }上層調(diào)用者 保護(hù)自己空間值不被修改的能力
地址傳遞
上層,調(diào)用者 讓下層 子函數(shù) 修改自己空間值的方式,類似結(jié)構(gòu)體這樣的空間,函數(shù)與函數(shù)之間調(diào)用關(guān)系—> 連續(xù)空間的傳遞 (不傳地址的話,只是 拿來(lái)看一下,并不改變本身的值)
void fun(char a); int main() {char a = 'e';fun(a);a == 'c' } void fun(char *b);int a = 10;fun(&a);a ===? 10int a; scanf("%d",a); scanf("%d",&a)將a的值傳遞給函數(shù),不能保證a還為10
連續(xù)空間的傳遞
1、數(shù)組
數(shù)組名 — 標(biāo)簽
實(shí)參:
int abc[10];
fun(abc)
形參:
void fun(int *p) void fun(int p[10])
2、結(jié)構(gòu)體
結(jié)構(gòu)體變量
struct abc{int a;int b;int c;};
struct abc buf;
實(shí)參:
fun(buf); fun(&buf)
形參:
void fun(struct abc a1) void fun(struct abc *a2)
" " —> 初始化const char *
char buf[10] —> 初始化char *
總結(jié)
- 上一篇: c语言爱心灯制作步骤,如何使用LED和5
- 下一篇: 不安全的文件上传基本原理(Unsafe