13 重憶C 之 工程開發(fā)命令

pwd
返回了根目錄

這時候看到系統(tǒng)返回了一個 /,這個 / 被我們稱為系統(tǒng)的 根目錄(root)仁期,這個位置也就是我們現(xiàn)在在系統(tǒng)中的位置桑驱。

但是,我們要開展工作的位置的路徑為:

/home/user/project

所以跛蛋,我們要學會如何切換我們所在的位置:

輸入 cd 命令熬的,并在 cd 命令后加上空格,在此后輸入開展工作的位置的路徑:

cd /home/user/project

這就是一個層級化路徑赊级,其實其可以通過

cd home
cd user
cd project

逐次到達押框。

下載輸入 ls -l。
這里就有個old目錄理逊。

image.png
mv main.c old             //mv [選項] 源文件或目錄 目標文件或目錄

再使用移動操作:

移動文件

再創(chuàng)建新文件橡伞,通過命令

touch main.c 

創(chuàng)建新文件
這時候可以看見:

創(chuàng)建文件

old目錄下把key刪除

刪除```key```文件

更多相關(guān)命令的可附加參數(shù)及使用意義,可以通過 man [空格] [命令名]的方式進行進行進一步的查詢(查詢后退出只需敲擊鍵盤上的 q 即可)盒揉。

更多復雜的命令,點擊這里

多模塊程序

之前的課中兑徘,所有文件操作都是單文件進行刚盈。對于一個只完成一個特定的任務,只包含十幾個函數(shù)的程序來說挂脑,單文件的組織方式還算可以接受藕漱,但是當程序越來越長,程序?qū)崿F(xiàn)的功能越來越多最域,將他們?nèi)慷冀M織在一個文件里就會變得不那么容易讓人接受了谴分。

因此,我們需要學習如何在 C 語言中將不同功能在多個代碼文件中分別實現(xiàn)镀脂,然后將它們看作多個模塊組織在一起為同一個程序服務牺蹄。


關(guān)于gcc命令

原地址:gcc命令中參數(shù)c和o混合使用的詳解、弄清gcc test.c 與 gcc -c test.c 的差別

gcc命令使用GNU推出的基于C/C++的編譯器薄翅,是開放源代碼領(lǐng)域應用最廣泛的編譯器沙兰,具有功能強大,編譯代碼支持性能優(yōu)化等特點∏唐牵現(xiàn)在很多程序員都應用GCC鼎天,怎樣才能更好的應用GCC。目前暑竟,GCC可以用來編譯C/C++斋射、FORTRAN、JAVA但荤、OBJC罗岖、ADA等語言的程序,可根據(jù)需要選擇安裝支持的語言腹躁。

語法

gcc(選項)(參數(shù))

選項

-o:指定生成的輸出文件桑包;
-E:僅執(zhí)行編譯預處理;
-S:將C代碼轉(zhuǎn)換為匯編代碼纺非;
-wall:顯示警告信息哑了;
-c:僅執(zhí)行編譯操作,不進行連接操作烧颖。

參數(shù)

C源文件:指定C語言源代碼文件弱左。

實例
常用編譯命令選項

假設(shè)源程序文件名為test.c

無選項編譯鏈接

gcc test.c

test.c預處理、匯編炕淮、編譯并鏈接形成可執(zhí)行文件科贬。
這里未指定輸出文件,默認輸出為a.out

選項 -o

gcc test.c -o test

test.c預處理榜掌、匯編、編譯并鏈接形成可執(zhí)行文件test乘综。
-o選項用來指定輸出文件的文件名憎账。

選項 -E

gcc -E test.c -o test.i

將test.c預處理輸出test.i文件。

選項 -S

gcc -S test.i

將預處理輸出文件test.i匯編成test.s文件卡辰。
選項 -c

gcc -c test.s

將匯編輸出文件test.s編譯輸出test.o文件胞皱。

無選項鏈接

gcc test.o -o test

將編譯輸出文件test.o鏈接成最終可執(zhí)行文件test。

選項 -O

gcc -O1 test.c -o test

使用編譯優(yōu)化級別1編譯程序九妈。級別為1~3反砌,級別越大優(yōu)化效果越好,但編譯時間越長萌朱。

多源文件的編譯方法

如果有多個源文件宴树,基本上有兩種編譯方法:

假設(shè)有兩個源文件為test.ctestfun.c

  • 多個文件一起編譯

gcc testfun.c test.c -o test

testfun.ctest.c分別編譯后鏈接成test可執(zhí)行文件。

  • 分別編譯各個源文件晶疼,之后對編譯后輸出的目標文件鏈接酒贬。

gcc -c testfun.c

將testfun.c編譯成testfun.o

gcc -c test.c

將test.c編譯成test.o

gcc -o testfun.o test.o -o test

將testfun.o和test.o鏈接成test

以上兩種方法相比較,第一中方法編譯時需要所有文件重新編譯翠霍,而第二種方法可以只重新編譯修改的文件锭吨,未修改的文件不用重新編譯。


再來復習一下:

gcc -c a.c 編譯成目標文件a.o

gcc -o a a.o 生成執(zhí)行文件a.exe

gcc a.c 生成執(zhí)行文件a.exe

gcc -o a -c a.c 編譯成目標文件a

gcc -o a a.c 生成執(zhí)行文件a.exe

在a.c中引用test.c中的一個函數(shù)后:

gcc -c test.c 編譯成目標文件test.o

gcc -c a.c 編譯成目標文件a.o

gcc -o a test.o a.o 生成執(zhí)行文件a.exe

gcc -o a test.o a.c 生成執(zhí)行文件a.exe

gcc -o a test.c a.c 生成執(zhí)行文件a.exe

gcc -o a test.o a.c 生成執(zhí)行文件a.exe

總結(jié):只要參數(shù)中有-c寒匙,總是生成目標文件零如;只要參數(shù)中無-c而只有-o,則總是生成執(zhí)行文件锄弱。


在剛開始學習 C 語言的時候考蕾,我們曾經(jīng)學習過,當我們的程序只有一個main.c文件時棵癣,我們可以在命令行中通過

gcc -o program main.c

對單個代碼文件進行編譯辕翰,生成可執(zhí)行文件program,并且通過./program運行編譯生成的程序狈谊。在我們之前的課程中喜命,計蒜客的學習系統(tǒng)也幫你進行了這樣的操作。

相比于單個文件河劝、單一功能的程序壁榕,當程序有多個模塊時,問題就開始變得復雜了赎瞎。我們對每一個模塊會首先編譯出每個模塊對應的*.o目標代碼文件(relocatable object file)牌里,例如:

gcc -c -o set.o set.c

會將我們的一個set.c文件編譯成一個set.o的目標代碼文件。請注意,這里的-c表示生成目標代碼文件牡辽。-o與之前單文件的時候一樣喳篇,在它之后我們會寫明被生成的文件的名稱。

當我們完成了每一個獨立模塊的編譯并獲得它們的目標代碼文件后态辛,我們可以將我們的主程序的目標代碼文件與他們鏈接在一起麸澜。例如:

gcc -o program main.o set.o others.o

將目標代碼文件set.oothers.omain.o在鏈接在一起,并且輸出了 可執(zhí)行文件(excutable file)program奏黑。

我們依然可以通過./program運行編譯生成的程序炊邦。

當我們將一個程序?qū)懺诙鄠€文件中時,每一個文件中的變量和函數(shù)默認都是只有文件內(nèi)的部分才可以訪問的熟史。但是有一些特殊的全局變量馁害、類型定義、函數(shù)可能會需要在多個文件中被使用蹂匹。

這時候碘菜,我們可以將這類的內(nèi)容單獨寫成一個 頭文件(header file),并且將全局變量怒详、類型定義炉媒、函數(shù)聲明寫到頭文件中。

對于一個文件set.c昆烁,習慣上它的頭文件會被命名為set.h吊骤。在所有需要用set.h中全局變量、類型定義静尼、聲明的函數(shù)的文件中白粉,用

#include "set.h"

將對應的頭文件引入。在這里的引入頭文件方式和引入系統(tǒng)庫頭文件的方式很類似鼠渺,只不過這里用的是引號""而不是尖括號<>鸭巴。

由于頭文件里也可以引入頭文件,因此我們可能事實上多次引入同一個文件拦盹,比如我們引1.h2.h鹃祖,且1.h也引入2.h,這時因為2.h被引入了兩次普舆,就有可能出現(xiàn)重復的聲明恬口。為了解決這個問題,我們2.h中定義一個宏沼侣,在2.h的最開始判斷這個宏是否被定義過祖能,如果被定義過,就跳過2.h整個文件的內(nèi)容蛾洛。

這里我們將會用到兩個新的預處理指令#ifndef xxx#endif养铸,它們成對出現(xiàn)且#ifndef在前,作用是如果這時并未已定義xxx宏,則這對#ifndef xxx, #endif之間的內(nèi)容有效钞螟。(其中xxx可以替換為任意宏名)

這樣```2.h```可以寫為類似于如下的內(nèi)容:
#ifndef xxx
#define xxx
typedef enum Status { Success, Fail };
typedef struct {
    char *name;
    int age;
} People;
Status go_to_Jisuanke(People);
#endif

細心的同學已經(jīng)發(fā)現(xiàn)兔甘,如果在程序中尚未引入2.h的位置定義了xxx宏,則#include "2.h"中的聲明并不會被引入鳞滨,因此我們不應該在此使用xxx這種平凡的名字裂明。實際上,我們一般會采用一個與頭文件名相關(guān)的名字來代替xxx太援,比如一個常用的代碼風格里,這個宏的名字形式為工程名_路徑名_文件名_H_扳碍。

總結(jié)的幾點

  • 某一代碼中定義的函數(shù)如果需要被其他代碼文件所使用提岔,應該將函數(shù)的聲明放入頭文件,并在其他代碼文件中引入這一頭文件笋敞。
  • 并不需要把每個函數(shù)單獨寫成一個模塊碱蒙,還是應該根據(jù)功能的劃分和實現(xiàn)去決定怎么抽出模塊。
  • 可以只有多個.c的文件夯巷,也并不一定非要都拆出.h文件赛惩。
  • #include可以被用于引入系統(tǒng)庫頭文件也可以被用于引入自己實現(xiàn)的頭文件。
  • 只不過在引入系統(tǒng)庫頭文件時趁餐,我們往往會使用尖括號<>喷兼,而在引入自己實現(xiàn)的頭文件時一般用引號""
  • gcc時后雷,-o之后寫的是生成可執(zhí)行文件的名稱季惯。-c的參數(shù)的使用會幫我們得到一個對象文件。
//-c和-o都是gcc編譯器的可選參數(shù)

//-c表示只編譯(compile)源文件但不鏈接臀突,會把.c或.cc的c源程序編譯成目標文件勉抓,一般是.o文件。
//-o用于指定輸出(out)文件名候学。不用-o的話藕筋,一般會在當前文件夾下生成默認的a.out文件作為可執(zhí)行程序。

//例如
gcc -c test.c          //將生成test.o的目標文件
gcc -o app test.c           //將生成可執(zhí)行程序app

gcc -c a.c -o a.o          //表示把源文件a.c編譯成指定文件名a.o的中間目標文件(其實在這里梳码,你把-o a.o省掉隐圾,效果是一樣的,因為中間文件默認與源文件同名边翁,只是后綴變化)翎承。

Makefile

在前面學習多模塊程序的時候,我們需要先把每個模塊的代碼都生成為目標代碼文件符匾,然后再將目標代碼文件聯(lián)編成一個可執(zhí)行文件叨咖。如果每一次編譯都要輸入這么多命令,是不是很復雜呢?如果每次修改一點點內(nèi)容就需要重新編譯整個工程甸各,是不是很浪費時間呢垛贤?

為了解決所遇到的問題,方便開發(fā)趣倾,我們使用一個叫做make的命令聘惦,它可以讀取Makefile文件,并且根據(jù)Makefile中的規(guī)則描述把源文件生成為可執(zhí)行的程序文件儒恋。

最基本的Makefile中包含了一系列形式如下的規(guī)則善绎。請注意,每一條規(guī)則的命令前诫尽,必須要有一個制表符\t禀酱。

目標: 依賴1 依賴2 ...
    命令

例如,可以寫一條規(guī)則:

array.o: array.c array.h
   gcc -c -o array.o array.c

表示生成的文件是目標代碼文件array.o牧嫉,它依賴于array.carray.h剂跟。
當我們在命令行中執(zhí)行make array.o時,根據(jù)這一規(guī)則酣藻,如果array.o不存在或者array.carray.h至少之一比array.o更新曹洽,就會執(zhí)行gcc -c -o array.o array.c

我們把上述代碼保存為Makefile辽剧,與array.carray.h放在同一目錄送淆,在那個目錄里執(zhí)行make array.o就能看到效果。

注意:Makefile里的除當前目錄隱藏文件外的第一個目標會成為運行make不指定目標時的默認目標抖仅。

再看:

main: array.o main.o
    gcc -o main array.o main.o

main.o: main.c array.h
    gcc -c -o main.o main.c

array.o: array.c array.h
    gcc -c -o array.o array.c

Makefile有多條規(guī)則時坊夫,如果我們希望只生成其中一個,我們可以在make命令后加上需要生成的目標的名稱撤卢。例如环凿,在這里我們可以執(zhí)行make main.omake array.omake main放吩。當我們執(zhí)行make main時智听,make命令發(fā)現(xiàn)array.omain.o不存在,就會根據(jù)以它們?yōu)槟繕说囊?guī)則先生成它們渡紫。

很多時候到推,會需要將.o為后綴的目標代碼文件和可執(zhí)行的程序文件刪除,完全從頭進行編譯惕澎。那么我們可以寫一條clean規(guī)則莉测,例如:

clean:
    rm -f array.o main.o main

rm命令表示刪除文件,-f表示強制唧喉,因此rm -f array.o main.o main

按照預期捣卤,當我們執(zhí)行make clean就可以刪除array.o忍抽、main.omain了。事實真的這樣嗎董朝?

因為畢竟這時如果已經(jīng)存在clean文件鸠项,rm命令就不會執(zhí)行了。為了解決這個問題子姜,我們通過一個特殊的方法告訴make這個名為clean的規(guī)則在clean存在的時候仍然有效。

.PHONY: clean

clean:
    rm -f array.o main.o main

.PHONY用于聲明一些偽目標,偽目標與普通的目標的主要區(qū)別是偽目標不會被檢查是否存在于文件系統(tǒng)中而默認不存在且不會應用默認規(guī)則生成它。

在Makefile中我們還可以使用它的變量和注釋御蒲。

# 井號開頭的行是一個注釋
# 設(shè)置 C 語言的編譯器
CC = gcc

# -g 增加調(diào)試信息
# -Wall 打開大部分警告信息
CFLAGS = -g -Wall

# 整理一下 main 依賴哪些目標文件
MAINOBJS = main.o array.o

.PHONY: clean

main: $(MAINOBJS)
    $(CC) $(CFLAGS) -o main $(MAINOBJS)

array.o: array.c array.h
    $(CC) $(CFLAGS) -c -o array.o array.c

main.o: main.c array.h
    $(CC) $(CFLAGS) -c -o main.o main.c

clean:
    rm -f $(MAINOBJS) main

上面這個例子已經(jīng)是一個較為完整的Makefile了碧磅。以#開頭的是我們的注釋,我們在這里用注釋說明了我們定義的Makefile變量的用途。CC變量定義了編譯器,CFLAGS變量標記了編譯參數(shù)腾供,MAINOBJS變量記錄了main依賴的目標文件绒北。定義的變量可以直接通過$(變量名)進行使用脐往。

總結(jié)

  • 一個 Makefile 可以包含多個規(guī)則,我們既可以每次在make后說明執(zhí)行哪個功能岩调,也可以通過定義的all來執(zhí)行一系列的規(guī)則缰揪。
  • 在用gcc編譯時加上-Wall會顯示錯誤信息赞厕,Wall是用于顯示大部分警告信息的,編譯錯誤信息默認就會顯示浆西。
  • Makefile其實描述了一系列轉(zhuǎn)為對象文件抄肖、聯(lián)編的過程入客,不使用make也是可以完成的卓舵。
  • Makefile中的變量是用$()的方式來用噠膀钠。

Makefile體驗

(1)
→ ~/project ls -l                                                                                 
                                                                                                  
total 16                                                                                          
-rw-r--r-- 1 user user 304 Sep 15 16:46 array.c                                                   
-rw-r--r-- 1 user user  87 Sep 15 16:46 array.h                                                   
-rw-r--r-- 1 user user 297 Sep 15 16:46 main.c                                                    
-rw-r--r-- 1 user user   0 Sep 15 16:46 main.h                                                    
-rw-r--r-- 1 user user 419 Sep 15 16:46 Makefile                                                  
→ ~/project                                                                                       
→ ~/project cat Makefile                                                                          
                                                                                                  
# 設(shè)置 C 語言的編譯器                                                                             
CC = gcc                                                                                          
                                                                                                  
# -g 增加調(diào)試信息                                                                                 
# -Wall 打開大部分警告信息                                                                        
CFLAGS = -g -Wall                                                                                 
                                                                                                                   
# 整理一下 main 依賴哪些目標文件                                                                  
MAINOBJS = main.o array.o                                                                         
                                                                                                  
.PHONY: clean                                                                                     
                                                                                                  
main: $(MAINOBJS)                                                                                 
        $(CC) $(CFLAGS) -o main $(MAINOBJS)                                                       
                                                                                                  
array.o: array.c array.h                                                                          
        $(CC) $(CFLAGS) -c -o array.o array.c                                                     
                                                                                                  
main.o: main.c array.h                                                                            
        $(CC) $(CFLAGS) -c -o main.o main.c                                                       
                                                                                                  
clean:                                                                                            
        rm -f $(MAINOBJS) main                                                                    
→ ~/project                                                                                      
(2)
→ ~/project make                

gcc -g -Wall -c -o main.o main.c                                                  
gcc -g -Wall -c -o array.o array.c                                    
gcc -g -Wall -o main main.o array.o                                     
→ ~/project                               
(3)
→ ~/project ./main              
                                                             
1 2 3 4 5 6 7 8 9 0                                     
數(shù)組元素和為: 45                                             
數(shù)組元素平均值為: 4.5                                      
                                                      
→ ~/project                                                 
(4)
→ ~/project make clean                   
                                                        
rm -f main.o array.o main             

(5)
→ ~/project            
→ ~/project ls -l     
                         
total 16                                             
-rw-r--r-- 1 user user 304 Sep 15 16:46 array.c          

命令行參數(shù)

之前掏湾,main函數(shù)一般都沒參數(shù),對應在運行時肿嘲,一般就直接輸入可執(zhí)行的程序文件名(例如./main)忘巧。

但實際上main函數(shù)可以有參數(shù)。我們可以將任何過去無參數(shù)的main函數(shù)替換成下面這種有參數(shù)的main函數(shù)(不過考慮到我們并沒有利用睦刃,不寫是很正常的)。

int main(int argc, char **argv) {
    // ...
}

在這里十酣,main函數(shù)有兩個參數(shù)涩拙,第一個參數(shù)是整數(shù)型,會傳入命令行參數(shù)的個數(shù)耸采,程序運行時就可以接收到兴泥。第二個參數(shù)是char **,其中儲存了用戶從命令行傳遞進來的參數(shù)虾宇。

如果我們的程序可執(zhí)行文件名為main搓彻,則在命令行中輸入./main hello world我們會得到argc3argv[0]./main嘱朽,argv[1]hello旭贬,argv[2]world。如果有更多參數(shù)也可以以此類推搪泳。

命令行參數(shù)默認都是空格分隔稀轨,但是如果我們希望包含空格的一個字符串作為參數(shù),我們則需要在輸入?yún)?shù)時用引號將其包裹起來岸军。

如果我們的程序可執(zhí)行文件名為main奋刽,則在命令行中輸入./main "hello world" is my greet我們會得到argc5瓦侮,argv[0]./mainargv[1]hello world佣谐,argv[2]is肚吏,argv[3]myargv[4]greet狭魂。

任何被接收到的argv參數(shù)都可以被當做正常的字符串在代碼里使用罚攀。在很多程序的設(shè)計中,我們會需要根據(jù)接收到的參數(shù)來決定程序的執(zhí)行方式趁蕊,這時候坞生,學會使用argcargv就顯得很重要了。在之后的課程中掷伙,你也會需要運用這一塊的知識是己,一定要學明白喔。

一些總結(jié)

  • 命令行讀入的參數(shù)是從命令行鍵入的可執(zhí)行程序路徑開始計算任柜。
  • 在main函數(shù)中用于接收命令行參數(shù)的函數(shù)參數(shù)中卒废,第一個是命令行參數(shù)的個數(shù)。
  • 在int main(int argc, char **argv)中宙地,argc就固定為 2 了摔认,它取到的應該是命令行中鍵入的參數(shù)個數(shù)。

命令行參數(shù)

命令行參數(shù)是怎么獲取和使用的宅粥?

請先輸入 cat main.c 看一下我們當前所在目錄下的 main.c 文件参袱。

image.png

看到,在這個 main.c 的文件中秽梅,我們的 main 函數(shù)獲取了命令行參數(shù)的個數(shù) argc(整數(shù)型)和一系列參數(shù)(字符指針的指針抹蚀,可以用訪問數(shù)組的形式訪問)。

這個程序?qū)㈩A期輸出命令行參數(shù)的數(shù)量企垦,并且將每一個參數(shù)逐一列出环壤。
接下來讓我們 make 一下,完成對這個程序的編譯钞诡。

image.png

完成了 make郑现,就讓我們把它運行起來吧。請輸入 ./main 并運行起來這個程序荧降,并在之后隨意輸上一些空格分隔開的字符串接箫,例如:

./main I feel better after this

我們程序中的argc 接受到的參數(shù)一共是幾個,它們分別對應了我們在終端中輸入的哪一部分的內(nèi)容呢朵诫。

image.png

文件操作

之前課程中列牺,我們學習、設(shè)計的所有程序都是從標準輸入進行讀取拗窃、向標準輸出進行寫出的瞎领,操作系統(tǒng)為我們準備好了標準輸入泌辫、標準輸出的界面。在這節(jié)課中九默,我們將要學習如何從文件中進行讀取震放、如何向文件進行寫入。

在讀文件的時候我們需要先有一個可以讓我們訪問到文件的 文件指針(file pointer)驼修,它是一個FILE類型的指針殿遂。

我們可以通過下面的方式聲明一個文件指針。

FILE *fp;

這時候乙各,如果我們希望對一個文件進行操作墨礁,我們需要先使用

fp = fopen(文件路徑, 訪問模式);

將文件指針和文件關(guān)聯(lián)起來,其中第一個參數(shù)是一個字符串耳峦,對應了我們希望訪問的文件路徑恩静。第二個參數(shù)是訪問模式,它可以是表示只讀模式的"r"蹲坷,也可以是表示只寫模式的"w"驶乾,還可以是在文件末尾追加的"a"

當我們將文件指針和文件關(guān)聯(lián)起來后循签,我們就可以通過fgetc(fp);獲得當前指針之后位置的一個字符了级乐,每獲得一個字符,指針會向后移動一個字符(如果到達文件尾部則會返回EOF)县匠。

我們這時通過fputc('c', fp);的方式將字符'c'寫入到fp關(guān)聯(lián)的文件內(nèi)了风科。

了解到這些信息后,我們就可以實現(xiàn)將一個文件復制到另一個文件內(nèi)的函數(shù)了乞旦,例如:

void filecopy(FILE *in_fp, FILE *out_fp) {
    char ch;
    while ((ch = fgetc(in_fp)) != EOF) {
        fputc(ch, out_fp);
    }
}

這個函數(shù)接收的兩個參數(shù)都是文件指針贼穆。這個函數(shù)會通過一個可讀模式的文件指針逐字符地讀取,并且通過一個可寫模式的文件指針逐字符地將所有字符寫出杆查,從而起到復制文件內(nèi)容的作用。

你需要注意臀蛛,在給文件指針進行命名的時候亲桦,要避開 stdin、stdout 和 stderr 這三個名稱浊仆。因為這三個名稱其實已經(jīng)用于標準輸入客峭、標準輸出、標準錯誤的文件指針抡柿。

你可能會問了舔琅,那我們看到的 stdinstdoutstderr的這三個文件指針可以直接使用嗎洲劣?回答是肯定的备蚓。

我們是通過 fgetc(stdin);獲得來自標準輸入的字符课蔬,也可以通過fputc(ch, stdout);fputc(ch, stderr);將變量 ch中的字符輸出到標準輸出或標準錯誤中的。

除了fgetc和fputc之外郊尝,我們還可以使用fscanf和fprintf函數(shù)二跋。這兩個函數(shù)都很像我們已經(jīng)很熟悉的scanf和printf函數(shù),只是不過流昏,scanf和printf 可以被看作 fscanf和fprintf 的特例扎即。

我們使用 fscanf 從文件指針in_fp進行讀取時,可以寫成:

fscanf(in_fp, "%c", &a);

而如果我們寫

fscanf(stdin, "%c", &a);

這將完全與下面直接使用 scanf 的方式等價况凉。

scanf("%c", &a);

類似地谚鄙,我們使用fprintf向文件指針out_fp進行寫出時,可以寫成:

fprintf(out_fp, "%c", a);

而如果我們寫

fprintf(stdout, "%c", a);

這將完全與下面直接使用 printf的方式等價刁绒。

printf("%c", a);

在使用文件并且確定不再繼續(xù)使用后闷营,我們要通過下面所示的方式將文件指針fp與文件的關(guān)聯(lián)斷開。你可以將它視為和fopen相反的一個操作膛锭。

fclose(fp);

如果你不在程序中使用fclose粮坞,程序正常結(jié)束時,程序會為所有打開的文件調(diào)用fclose初狰。

stdin莫杈、stdout其實也是被打開的文件指針,如果你覺得用不到的話奢入,其實也是可以使用fclose將他們關(guān)閉掉的筝闹。你可以自己試一試,關(guān)閉 stdin腥光、stdout 會對我們以前寫過的程序帶來什么樣的影響呢关顷?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市武福,隨后出現(xiàn)的幾起案子议双,更是在濱河造成了極大的恐慌,老刑警劉巖捉片,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件平痰,死亡現(xiàn)場離奇詭異,居然都是意外死亡伍纫,警方通過查閱死者的電腦和手機宗雇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莹规,“玉大人赔蒲,你說我怎么就攤上這事。” “怎么了舞虱?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵欢际,是天一觀的道長。 經(jīng)常有香客問我砾嫉,道長幼苛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任焕刮,我火速辦了婚禮舶沿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘配并。我一直安慰自己括荡,他們只是感情好绪钥,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布年堆。 她就那樣靜靜地躺著垮耳,像睡著了一般缸废。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上名船,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天戳寸,我揣著相機與錄音刨仑,去河邊找鬼梧油。 笑死苫耸,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的儡陨。 我是一名探鬼主播褪子,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼骗村!你這毒婦竟也來了嫌褪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤胚股,失蹤者是張志新(化名)和其女友劉穎笼痛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體琅拌,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡缨伊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了财忽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片倘核。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡泣侮,死狀恐怖即彪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤隶校,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布漏益,位于F島的核電站,受9級特大地震影響深胳,放射性物質(zhì)發(fā)生泄漏绰疤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一舞终、第九天 我趴在偏房一處隱蔽的房頂上張望轻庆。 院中可真熱鬧,春花似錦敛劝、人聲如沸余爆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛾方。三九已至,卻和暖如春上陕,著一層夾襖步出監(jiān)牢的瞬間桩砰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工释簿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亚隅,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓辕万,卻偏偏與公主長得像枢步,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子渐尿,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理醉途,服務發(fā)現(xiàn),斷路器砖茸,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 動態(tài)鏈接隘擎,在可執(zhí)行文件裝載時或運行時,由操作系統(tǒng)的裝載程序加載庫凉夯。大多數(shù)操作系統(tǒng)將解析外部引用(比如庫)作為加載過...
    小5筒閱讀 5,504評論 0 3
  • linux資料總章2.1 1.0寫的不好抱歉 但是2.0已經(jīng)改了很多 但是錯誤還是無法避免 以后資料會慢慢更新 大...
    數(shù)據(jù)革命閱讀 12,161評論 2 33
  • 1.簡介 GCC 的意思也只是 GNU C Compiler 而已货葬。經(jīng)過了這么多年的發(fā)展,GCC 已經(jīng)不僅僅能支持...
    Leon_Geo閱讀 713評論 0 4
  • 動態(tài)調(diào)用動態(tài)庫方法c/c++linuxwindows 關(guān)于動態(tài)調(diào)用動態(tài)庫方法說明 一劲够、 動態(tài)庫概述 1震桶、 動態(tài)庫的...
    KINGZ1993閱讀 13,911評論 0 10