2.2 C語言的特性
A: c語言是一種底層語言
B: c 語言是一種小型語言
C: c 語言一種包容性語言,c語言假設用戶知道自己做什麼,
所以她提供了更爲廣闊的自由度。
優點:
高效
可移植性,c語言編譯器規模小,容易編寫。
功能強大
靈活
標準庫
與UNIX 系統結合緊密
缺點:
出錯率高
難理解
難以修改
3.2 gcc編譯器
Gcc( GNU Compiler Collection)
基本用法: gcc [options] [filenames]
-c 只編譯,生產.o 爲後綴的目標文件,通常用於編譯
不包含主程序的子程序文件。
-o output_filename 確定輸出文件的名稱爲
-g 產生符號調試工具gdb 所必要的符號資訊
-O 大寫哦 對程序進行優化編譯
-O2 比-o 更好的優化編譯
-std 例如: -std= c89 或者 -std=c99
4 變量和賦值
概念:
類型:每個變量都必須聲明她的類型。C可分爲基本數據類型和複合數據類型
聲明: 任何變量在使用之前必須進行聲明。如: 數據類型 變量名稱
初始化:
1. 自動變量未初始化的時候訪問,其數值是一個隨機數值。
例如:
#include <stdio.h>
Int main()
{
Int day;
Printf(“day = %d\n”,day);
Return 0;
}
標示符: 在編寫程序的時候,需要對變量, 函數,宏,以及其他實體進行命名,這些名稱成爲:標示符。
標示符有五條命名規則:
1. 以字母,下劃線開頭;
2. 可以包含字母,下劃線,數字
3. 大小寫敏感
4. 不能和關鍵字衝突
關鍵字:
特性:
有特殊含義的一串字符
全部小寫
標準庫中函數名全部小寫
格式化輸入/輸出
Printf( 格式字符串, 表達式1,表達式2,。。。。) //可變長參數
格式字符串可分爲兩個部分: 普通字符和 轉換說明
轉換說明包含以下幾部分:
完整格式: % - 0 m.n l或者h 格式字符
1. % 佔位符 不能省略
2. - 左對齊,省略 右對齊
3. 0 代表空位填0 省略代表空位不填
4. m 域寬 n 精度
5. l 整數long, 浮點數 double ; h爲 short;
6. i /d 輸出十進制整數
O 無符號的八進制整數
X 十六進制
u 無符號的十進制
c 輸出一個字符
s 輸出一個字符串
f 輸出一個浮點數
e 以指數的形式輸出浮點數
g 在f和e格式之間選擇一個較短格式輸出
P 輸出一個地址
2 %i%d
在printf裏面沒有區別
在scanf 有區別
%d 只匹配十進制
%i 八進制 十進制, 十六進制
3 如何輸出%
%%
4.4 scanf() 從鍵盤輸入
絕大數情況下,scanf 只包含轉換說明。
Scanf(格式字符串,地址列表);
例如: scanf(“%f%f%f”, &s1, &s2, &s3);
知識點級別:
Char 字符型
Sizeof 是c語言的一個關鍵字,不是函數。
Sizeof(變量的名字) 或者sizeof (類型)
整數在內存中的存儲? b*****b 【準確記憶】
整型在內存中的存儲是按照補碼形式存儲的。整數的補碼與源碼相同,
負數的補碼就是其絕對值的二進制形式按位取反,然後整個數值加 1.
進制轉換 【理解描述】
Sizeof 返回一個對象或者類型所佔的內存字節數
Sizeof 三種語法方式 b*****b 【準確記憶】
1. Sizeof(類型)
2. Sizeof(變量名)
3. Sizeof(表達式)
Int i=5;
Sizeof(i=10);
運算符
算符運算符
1. / 0不能做除數,兩個整數相除,取結果的整數部分。
2. % 要求操作數都爲整數,如果其中一個不是整數,編譯將無法通過。
賦值運算符
Int i,j;
複合賦值 += -= *= /= %=
自增、自減
比較運算符
==
推薦寫法: if(15 == data)
邏輯運算符的
短路特性 b*****b【準確描述】
&& || ?:
例子:
#include <stdio.h>
int main()
{
int i=0, j=0;
if(++i || ++j);
if(--i && ++j);
printf("i = %d,j = %d\n",i,j);
return 0;
}
位運算符
按位取反 ~3
按位與 &
用途: b***b 【記憶描述】
經常用來屏蔽某些二進制位(置0)。也可以知道某個二進制位是1還是0。
按位或 |
用途: b***b【記憶描述】
經常用來將某些二進制位 (置 1)。也可以知道某個二進制位是1還是0。
按位異或 ^
運算規則: b*****b 【準確記憶】
對應的二進制位上的數字相同則爲0,否則爲1。
例子: 判斷某個整數二進制格式倒數第三位是 0還是1?
If(data &4) ==4) 倒數第三位1
左移
規則: b*****b 【準確記憶】
左移的時候右邊的空位補零
右移
規則: b*****b 【準確記憶】
右移的時候左邊補上符號位。
取地址運算
條件運算符
表達式1?表達式2:表達式 3
語句
If else 語句
Switch 語句
結構 b*****b【準確記憶寫出】
Switch(控制表達式)
{
Case 常量表達式1 :語句1;
Case 常量表達式2 : 語句2;break;
....
Default: .....
}
注意:
控制表達式:計算結果是整型
常量表達式:不能包含變量或者函數調用,最終結果必須是整數。
例如: n+10 不是常量表達式(除非n是表示常量的宏),
每個分支中可以包含多條語句,可以不使用{}
循環語句
For(表達式1; 表達式2;表達式3)
{
語句;
}
【準確畫圖】
注意:可以這樣寫 for(;;){....}
For(i=0;i<10;i++){...}
C99 第一個表達式可以爲聲明例如:
For(int i=0; i<10; i++){....}
For(i=0,j=0;i<10; printf(),i++,j++){....}
For循環可以嵌套
C語言中兩種常用的無限循環(死循環)方式 【準確記憶】
1. While(1)語句
2. For(;;) 語句
do-while 循環
空語句 ;
緩衝區
輸入:
鍵盤->鍵盤緩衝區-> 輸入緩衝區-->程序
#include<stdio.h>
int main()
{
int data_1 = 0, data_2 = 0;
printf("請輸入兩個整數:");
scanf("%d",&data_1);
scanf("%d",&data_2);
printf("您輸入的兩個整數是:%d %d\n",data_1,data_2);
return 0;
}
Scanf 失敗的原因: 類型不匹配
改成如下:
#include<stdio.h>
int main()
{
int data_1 = 0, data_2 = 0;
printf("請輸入兩個整數:");
if(scanf("%d",&data_1) == 0)
{
scanf("%*[^\n]");
scanf("%*c");
}
if(scanf("%d",&data_2) == 0)
{
scanf("%*[^\n]"); //讀走\n之前的所有字符
scanf("%*c");//讀走\n
}
printf("您輸入的兩個整數是:%d %d\n",data_1,data_2);
return 0;
}
輸出緩衝區
程序-》輸出緩衝區-》屏幕
程序的輸出可以到達屏幕的條件: b*****b 【描述記憶】
1, \n
2. 程序結束
3. 輸出緩衝區滿(4kb)
4. 人工刷新(fflush)
例子:
#include <stdio.h>
int main()
{
printf("welcome!");
while(1);
}
結果:沒有輸出
#include <stdio.h>
int main()
{
printf("welcome!");
fflush(stdout); //新增加的人工刷新
while(1);
}
字符串
讀取一個字符串放到字符數組中,然後打印
Scanf(“%s”,&name);
Scanf 遇到空白字符結束
Gets(name)
從輸入設備讀取一行字符回來,放到name中
危險:gets 不會考慮name的大小,可能導致name的溢出。
Fgets(name,20,stdin);
Fgets會在整個字符串的後面添加\n
例子:
#include <stdio.h>
Int main()
{
Char name[20];
Pritnf(“請輸入您的姓名:”);
Scanf(“%s”,name);
Printf(“您輸入的姓名是:%s\n”,name);
Return 0;
}
操作字符串的庫函數
Strcpy
Strcat
Strncpy
Strncat
Strlen:
strcmp:
聚合類型: 數組和結構
一維數組初始化
Int a[5] = {1,2,3} ; //【可描述】如果初始化裏面常量表達式個數小於數組元素的個數,剩餘的元素初始化爲零。
指定初始化
Int a[30] = { [19] = 54, [9]=> 14, [29] = 45 };
Sizeof(數組)
#include <stdio.h>
int main()
{
int a[10];
printf("sizeof(a[0]) = %d\n",sizeof(a[0]));
printf("sizeof(a) = %d\n",sizeof(a));
char c[10];
printf("sizeof(c[0]) = %d\n",sizeof(c[0]));
printf("sizeof(c) = %d\n",sizeof(c));
return 0;
}
宏帶參數的宏:
#define sz(a) sizeof(a)/sizeof(a[0])
C99中的變長數組
Int n;
Scanf(“%d”, &n);
Int a[n]; //c99變長數組
函數的返回值
: 函數的返回值必須和return 返回值的類型一致
2. 如果函數沒有返回值 指定爲void
3. C語言的返回值類型可以省略默認爲 int
4.
隱式聲明: 如果函數在使用志氣沒有進行聲明,編譯器會創建一個隱式聲明,返回值類型爲int
值傳遞: c語言中實際參數和形式參數之間採用值傳遞的方式來傳遞數據。
#include <stdio.h>
void swap(int a,int b){
int t=a;
a=b;
b=t;
printf("swap:交換中:a = %d b=%d\n",a,b);
}
int main()
{
int x=5,y=7;
printf("main:交換之前:x= %d y= %d\n",x,y);
swap(x,y);
printf("main:交換之後:x= %d y= %d\n",x,y);
return 0;
}
在函數中測試一個參數數組的長度:
#include <stdio.h>
void len(int a[]){
printf("數組總的字節:%d\n",sizeof(a));
printf("傳入的數組的長度:%d\n",sizeof(a)/sizeof(a[0])
);
}
int main()
{
int a[20];
len(a);
return 0;
}
什麼時候使用const來修飾形參【描述記憶】
如果形參傳遞的是地址,又不希望在被調用函數更改地址上的內容 這個時候可以使用const 修飾形參。
例如:
Int test(const int r[],int len)
{
r[len-1] = 100;
}
變量的類別
c程序(小全)宏觀認識(代碼角度,和內存角度)
一個較爲完整的程序中,可以包含哪些部分 【描述記憶】
//系統頭文件
#include...
//宏定義
#define....
//全局變量
Int data = 1;
//自定義函數的聲明
Int main() //主函數
{
//局部變量 local
Int data=2;
For() //if switch while
{
//塊變量
Int data = 3;
}
}
//自定義函數
。。。。。
C程序在內存中的分佈
2.1 程序段
: 代碼段 存放程序代碼的一段區域, 程序段是隻讀的。
2.2 數據段
:存放已經初始化的全局變量。
2.3 bss段
:通常用來存放程序中未初始化的全局變量和靜態變量的一塊內存區域
2.4 堆
堆: 保存進程中被動態分配的內存
申請: malloc remalloc(new) OC(alloc new init)
釋放: free delete OC(release)
2.5 棧
棧: 存儲了程序中臨時創建的局部變量。
變量,生命週期,作用域
1.1 局部變量: 【準確記憶】
我們把在函數體中定義的變量叫做這個函數的局部變量。
Int main()
{
Int a,b,c,d........//局部變量
}
Int test()
{
Int a; //局部變量
}
局部變量的特點;
1 生命週期: 從定義這個局部變量的地方開始,到函數的結束。
2. 作用域(訪問範圍):在定義這個局部變量的函數內(定義這個變量的以下語句);
1.2 靜態局部變量
Static 修飾的局部變量:
特點 【描述記憶】
1 生命週期: 整個程序
2 作用域: 和普通變量一樣。
3. 值: 數值就是上一次函數調用結束之後的數值。
例子:
#include <stdio.h>
int test(){
static int i=0;
i++;
printf("i = %d\n",i);
return 0;
}
int main()
{
int i=0; //這裏的i和test裏面的i不一樣
for(;i<6;i++)
{
test();
}
return 0;
}
上個例子中去掉static後的效果:
1.3 全局變量
:定義在整個程序中的變量 稱爲全局變量
1. 生命週期 :整個程序的生命週期之內
2. 作用域(訪問範圍):整個程序的範圍內都可以訪問
3. 值:沒有初始化的全局變量的數值是0.
1.4 塊變量
:定義在語句塊裏面的變量叫做塊變量。
程序塊(語句塊): 使用{}括起來的一組語句。
塊變量的特性:
1. 生命週期: 定義變量的地方開始,程序塊結束的地方消失
2. 作用域(訪問範圍):程序塊內
For(......)
{
Int i = 0; //塊變量
}
If(......)
{
Int temp = i ; // 塊變量
}
變量優先級 : 局部優先原則
例子:
#include <stdio.h>
int data = 1;
int main()
{
printf("data = %d\n",data);
int data = 2; //局部變量
printf("data = %d\n",data);
if(1)
{
int data = 3; //塊變量
printf("data = %d\n",data);
}
return 0;
}
關鍵字修飾變量
Auto static register
Static 修飾全局變量
訪問範圍: 只能在本文件訪問。
即使在其他文件中使用extern聲明也不能使用
Static 修飾函數
訪問範圍:
這個函數只能在本文件中使用
什麼是自動變量: 【準確記憶】
普通局部變量(static 除外)都是 auto ,auto 一般省略。
Auto int i;
Register: 寄存器變量
:告訴編譯器這個變量會被頻繁的使用,請保存到寄存器中。
使用限制【描述記憶】
1. 必須能被cpu的寄存器接受(32位= 4個字節)
2. 不能對寄存器變量取地址 &
指針作爲返回值
注意:【描述記憶】
不要返回自動變量的地址。因爲自動變量在函數結束之後所使用的內存會被釋放。
指針作爲函數的參數
字符串
例子:
#include <stdio.h>
int main()
{
char str[5] = "abcde";
printf("str = %s\n",str);
char str1[6] = "abcde";
printf("str1 = %s\n",str1);
char *q = "abcde";
printf("*q = %s\n",q);
return 0;
}
字符串的三種表達方式的區別
1.字面值 。 存在於全局區,不可改變。在內存中只有一個。
2. Char 數組 存在於內存中函數棧,數值可以改變
Char str[] = “abcde”;
//賦值的時候
Str = “abcde”;
3.Char * 既可以指向字面值,也可以指向char 數組裏面的元素。
預處理
1.1 文件包含
#include <xxx.h>
#include “xxx.h”
區別:
<>到系統指定的路徑尋找 一般是: /usr/include
“” 優先從當前目錄開始,一般適用於自定義頭文件。
宏
1 簡單的宏
2. 帶參數的宏
//使用宏 判斷兩個整數中最大的那個
#define MAX(x,y) (x)>(y)?(x):(y)
注意:
參數不能是多次計算之後的數值
MAX(i++,j++) //這是錯誤的
應該在每個參數的外面加上()
在整個表達式的外面加上()
例子:
#include <stdio.h>
#define MUL(x,y) x*y
int main()
{
printf("結果:%d\n",MUL(3,5));
printf("結果:%d\n",MUL(1+2,2+3));
return 0;
}
8不對呀!
#define MUL(x,y) (x)*(y)
改成上面這樣就對了
Printf(“結果:%d\n”,30/MUL(3,5));
應該是 2結果是50;
還要改,改成下面:
#define MUL(x,y) ((x)*(y))
宏運算符 # 和 ##
1. #
2. ## 將兩個標識符粘貼在一起形成一個標識符
#define MAX(type) type max_##type()
MAX(float) 對應如下:
Float max_float()
預定義的宏
1 __LINE__
2 __FILE__
3 __DATE__
4 __TIME__
5 __STDC__ //判斷編譯器是否符合c 標準 返回0或者 1
1.5 條件編譯:
條件編譯就是根據預處理器的執行結果 來包含或者排除某一段程序。
#if #endif
Defined : 判斷一個宏 (有沒有定義過這個宏)
#define Debug
#ifdefined Debug
....
#endif
3 #ifdef // 等價於 #if defined
4 #else
#if ...
代碼
#elif ...
代碼
#else
代碼
#endif
爲什麼要用條件編譯?
【描述記憶】
1, 編寫多種硬件環境或者多操作系統上運行的可移植程序。
2,編寫用於不同編譯器的程序。
#if __STDC__
函數
#else
函數
#endif
3. 產品的調試與發佈
4. 爲宏提供定義
多源文件的程序編譯方法
1 首先對每一個源文件只編譯不連接
gcc -c .....
生成 xx.o 文件
2 連接成爲一個可執行程序
gcc *.o
自定義的頭文件
1.共享宏定義
2.全局變量的聲明
extern int r //告訴編譯器,該變量已經在其他文件
例子:
解決方法: 把test.c中的 添加一行 extern int speed;
3. 類型定義共享
重複包含一個頭文件,可能會導致編譯錯誤。怎麼做呢?
【描述記憶】
正確的自定義頭文件的編寫。
例如:
Test.h
#ifndef TEST_H
#define TEST_H
#include <stdio.h>
#define DISTANCE 1270
#define OIL 13
#endif
makefile
描述: makefile 由很多規則組成,一條規則可以分爲:
目標文件:依賴文件
命令 (生成目標文件所執行的指令,可以是多條)
typedef 與 #define的區別?
給結構起別名?
typedef struct
{
成員列表
} 別名;
使用結構指針作爲函數的參數和返回值的時候,可以使程序的效率提高!
結果替的對齊 與補齊?
結構體位段
位段/位域
struct s{
Int i:3; //指定i在內存中佔用3個二進制位。
Int b:1;
.....
}
例子:
#include <stdio.h>
//結構體類型的聲明
struct test
{
char c1:1;
char c2:2;
char c3:3;
};
int main()
{
printf("sizeof(struct test) = %d\n",sizeof(struct test));
return 0;
}
聯合
1, 可以有多個不同類型的成員的組成
2,通過成員的名字訪問成員
3,所有成員公用起始地址相同的一段內存
#include <stdio.h>
union
{
int i;
double d;
} test;
int main()
{
printf("sizeof(union test) = %d\n",sizeof(test));
return 0;
}
大端、小端 【準確記憶】
大端: 低字節存儲高位數據
小端: 低字節存儲低位數據
例子:判斷計算機是小端還是大端
#include <stdio.h>
int main()
{
union
{
int i;
char c;
}u;
u.i = 1;
printf("當前計算機:%s\n",u.c == 1? "小端" : "大端");
return 0;
}
枚舉類型
規則: enum 枚舉名{枚舉常量}; //枚舉常量之間使用逗號分隔
#include <stdio.h>
int main()
{
enum color {RED,BLUE,GREEN};
//本質上枚舉常量就是整數
enum color c;
c = 0; //僅限c語言中
c = BLUE;
printf("RED=%d BLUE=%d GREEN=%d\n",RED,BLUE,GREEN);
return 0;
}
內存與變量
自動變量 :內存都是操作系統維護的。
堆:自己申請 自己釋放
棧: 自動分配 自動釋放
動態分配內存 的函數 malloc calloc realloc
Malloc -- 分配內存塊,不會對分配的內存進行初始化
Calloc -- 分配內存塊,對內存進行清零
Realloc -- 調整先前已經分配的內存塊的大小
malloc :
Void * malloc(size_t size)
Malloc 分配size字節的內存,返回指向這塊內存的指針
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n = 0, i=0;
printf("請輸入數組的大小:");
scanf("%d",&n);
int *q = (int *)malloc(n*sizeof(int));
if(q == NULL)
{
//分配失敗
printf("error:分配失敗\n");
return 0;
}
for(;i<n;i++)
{
q[i] = i+1;
}
for(i=0; i<n; i++)
{
printf("%d ",q[i]);
}
printf("\n");
free(q); //釋放動態內存
q = NULL; //置爲空指針
return 0;
}
字符串的malloc分配
Char *q = (char *)malloc(n+1);
結構體的malloc分配
Struct employee *e = (struct employee *)malloc(sizeof(struct employee));
Void * calloc(size_t nmemb, size_t size);
Calloc 爲nmemb個 元素分配內存,每一個元素都是size 個字節大小,自動清零
realloc
:可以根據需求動態的 調整已經分配好的內存。
參數幾種情況:
1.內存擴張,realloc 不會初始化擴張的內存
2.失敗了,返回空指針,不會影響原來塊中的數據
3. 第一個參數 NULL, 相當於 malloc
4.第二個參數0,釋放原來的內存塊
指針數組
例子:
文件
文件指針: 就是指向FILE結構體的指針。
FILE * fp; //fp就是一個文件指針
文件的操作
fopen: 打開一個文件
fclose: 關閉一個文件
文件的讀寫
Int fputs() 將一個字符寫到文件中
fgetc(); //從文件中讀一個字符出來
例子:使用fgetc 實現:顯示指定文件的內容
#include <stdio.h>
int main(int argc ,const char *argv[])
{
FILE *fp = NULL;
if(argc<2 || argc>2)
{
printf("命令的格式不對\n");
printf("Useage:command filename\n");
return 0;
}
if((fp = fopen(argv[1],"r")) == NULL)
{
printf("文件打開失敗:%m\n");
return 0;
}
char c;
while(1)
{
c = fgetc(fp);
if(c==EOF)
break;
else
printf("%c",c);
}
fclose(fp);
return 0;
}
例子:fgetc, fputs文件的複製功能
/*文件複製*/
#include <stdio.h>
int main(int argc ,const char *argv[])
{
if(argc !=3)
{
printf("格式不對\n");
return 0;
}
FILE *fp1 = NULL;
FILE *fp2 = NULL;
if((fp1 = fopen(argv[1],"r")) == NULL)
{
printf("打開%s失敗\n",argv[1]);
return 0;
}
printf("成功打開%s文件\n",argv[1]);
if((fp2 = fopen(argv[2],"w")) == NULL)
{
printf("打開%s失敗\n",argv[2]);
fclose(fp1);
return 0;
}
printf("成功打開%s文件\n",argv[2]);
char c;
while(1)
{
c = fgetc(fp1);
if(c== EOF)break;
else
fputc( c,fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}
C語言提供的讀寫數據塊的函數
Size_t fread(buffer,size,count,fp)
Size_t fwrite(buffer,size,count,fp)
將fwrite寫到兩個整數到文件中
/*文件複製*/
#include <stdio.h>
int main(int argc ,const char *argv[])
{
int i=15, j=63;
FILE * fp = NULL;
if((fp = fopen("c.txt","w")) == NULL)
{
printf("fail to open the file:%m\n");
return 0;
}
printf("success to open the file\n");
fwrite(&i,sizeof(i),1,fp);
fwrite(&j,sizeof(i),1,fp);
fclose(fp);
return 0;
}
使用fread讀出來
/*文件複製*/
#include <stdio.h>
int main(int argc ,const char *argv[])
{
int i = 0,j = 0;
FILE *fp = NULL;
if((fp = fopen("c.txt","r")) == NULL)
{
printf("fail to open the file:%m\n");
return 0;
}
printf("success to open the file\n");
if(fread(&i,sizeof(i),1,fp)!=1)
{
printf("讀取失敗\n");
}
if(fread(&j,sizeof(j),1,fp)!=1)
{
printf("讀取失敗\n");
}
printf("i = %d j=%d\n",i,j);
fclose(fp);
return 0;
}
4.3.3 文件的定位rewind
Rewind 函數使位置指針回到文件的開頭。
Fseek 函數
Int fseek (FILE *stream,long offset, int whence)
Stream: 文件指針
Offset: 位移量
Whence: 起始點
文件開頭 0 SEEK_SET
當前位置 1 SEEK_CUR
文件末尾 2 SEEK_END
保存三個員工的信息(struct)--文件中,然後顯示出來
#include <stdio.h>
typedef struct
{
int ID;
char name[30];
float salary;
} employee;
int main(int argc ,const char *argv[])
{
employee e[3] = {{1, "趙志",500},{2,"月月",500.5},{3,"阿龍",600}};
FILE *fp = NULL;
if((fp = fopen("d.txt","w+")) ==NULL)
{
printf("fail to open the file:%m\n");
return 0;
}
printf("success to open the file\n");
int count = 0;
if((count = fwrite(e,sizeof(employee),3,fp))<3)
{
printf("write error:%m\n");
}
fseek(fp,-3*sizeof(employee),SEEK_CUR); //rewind
employee temp;
int i = 0;
for(;i<3;i++){
fread(&temp,sizeof(employee),1,fp);
printf("工號:%d 姓名:%s 薪資:%g\n",temp.ID,temp.name,temp.salar
y);
}
fclose(fp);
return 0;
}
文件讀寫的其他函數
Fgets fputs
從指定文件中讀取或者寫入一個字符串
Char str[500] //fgets(str,n,fp) n 爲指定讀取字符的個數,但是fp只能讀出 n-1 最後加’\0’
Fputs
Fprintf 和fscanf 格式化讀寫 注意:效率低,大量數據用 fread fwrite
標準庫
stdlib.h
無法劃歸到其他頭文件中的
字符串,數字,產生隨機數, 內存管理 系統通信 搜索排序等
參考: tarena課件
吊炸天c筆記