-----------------------------------------------------------------------------------------
【開始】
1. 在Mac和Linux上寫C語言之前,首先要看看是否安裝了編譯器:
在終端下輸入gcc后回車進行檢測,如果安裝過,將提示 clang: error: no input files(沒有輸入文件);
如果沒有安裝,在Mac下根據提示安裝Xcode即可,或者Install gcc without xcode in maxOsX:http://osxdaily.com/2012/07/06/install-gcc-without-xcode-in-mac-os-x/ ( OSX命令行工具下載:https://developer.apple.com/downloads/ )
在CentOS下直接yum -y install gcc gcc-c++(-y表示將自動選擇y)
2. 現在開始愉快的寫代碼:
在Xcode里對新建的項目文件使用command+R就直接編譯運行你的c代碼了。
在Mac終端下,使用神器vim,如:vim test.c ,它不會幫你新建test.c,寫完c代碼后你需要command+s保存,然后:wq!退出,使用命令gcc test.c編譯,不指定編譯后的文件名,編譯文件名都將是a.out ,運行它使用./a.out
在Linux下,同樣使用vim,輸入vim test.c 的時候就在當前目錄新建了test.c文件,寫完c代碼直接:wq!保存退出,使用gcc test.c編譯,運行編譯文件./a.out ( gcc -o main.c main.o #生成.o文件 )
Sublime Text是一款值得使用的文本編輯器,如果裝好環境,使用cmd+B對代碼進行編譯,shift+cmd+B運行,但是Sublime只能運行一個程序,如果需要運行有輸入的程序,就必須離開Sublime進入到終端。
Windows環境下C/C++集成開發環境(IDE)推薦Dev-C++,這里不作過多介紹,下載地址在這里:http://sourceforge.net/projects/orwelldevcpp/?source=directory。
3. DEMO:
#include "stdio.h" /*
標准輸入流:鍵盤輸入
標准輸出流:終端輸出
標准錯誤流:錯誤輸出
stdin
stdout
stderr
*/ int main() { printf("nihao,shijie! \n"); //nihao, shijie
//內部實現:fprintf(stdout, "輸入一個數:");
int a;
scanf("%d", &a);
//內部實現:fscanf(stdin, "%d", &a);
if(a < 0) {
fprintf(stderr, "be sure: a > 0\n");
return 1;
} else {
printf("a > 0\n");
}
return 0; }
重定向: ./main.out >> m.txt #執行文件輸出結果追加寫入到m.txt ./main.out > m.txt #執行文件輸出結果覆蓋寫入到m.txt ./main.out < input.txt #輸入流重定向,input.txt作為輸入流 ./main.out 1>t.txt 2>f.txt < input.txt #輸出流寫入t.txt, 錯誤流寫入f.txt, 輸入流使用input.txt
管道: ls /usr/local/ | grep bin ps -e | grep ssh #將前一條命令的輸出流作為后面命令的輸入流
附:
【C語言編譯過程】
假如要編譯一個 1.c 程序為可執行文件 build,如何看到編譯器的處理過程呢,使用 gcc -v -o build 1.c
1. 預處理
cpp -o 1.i 1.c # 翻譯成.i文件
gcc -E
2. 編譯,系統用的是cc1
/usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -o build 1.c
我們可以直接用 gcc -S , 相當於幫我們執行上面的過程;
3. 匯編,系統用的是as
as -o build 1.c
我們可以直接用 gcc -c ,因為系統沒有辦法直接把c程序轉為匯編,所以相當於依次執行了編譯和匯編;
4. 鏈接,系統用的是collect2
/usr/lib/gcc/x86_64-linux-gnu/4.8/collect2 -o build 1.c
我們可以直接用 gcc -o ,同理,系統幫我們依次執行了編譯、匯編、鏈接。
示例:
gcc -E -o 1.i 1.c # 生成預處理文件1.i,將其中的include和define等替換成其它
gcc -S -o 1.s 1.c # 編譯成1.s 匯編碼文件,-o選項不能省,只是增加了-S選項
gcc -c -o 1.o 1.c # 編譯成1.o 二進制碼文件,給機器讀
由於include和define是預處理階段完成的替換,所以它們並不是關鍵字,關鍵字是編譯器處理的。
( 條件預處理 )
gcc -DABC 相當於 #define ABC , 用於調試中。
示例:
include <stdio.h> int main() { #ifdef ABC printf("%s", __FILE__); #endif printf("hello"); return 0; }
編譯時,gcc -DABC -o build 1.c ,-D選項后面直接加常量名,預處理會加入宏定義。
不用命令行定義 ARRAY_SIZE 時,值為3:
#include <stdio.h> int main() { #ifndef ARRAY_SIZE #define ARRAY_SIZE 3 #endif int array[ARRAY_SIZE] = {0}; printf("ARRAY_SIZE is %d\n", ARRAY_SIZE); perror("error msg"); return 0; }
gcc -o build 1.c -DARRAY_SIZE=2
( 宏展開下的#, ## )
# 字符串化
## 連接符號
#define ABC(x) #x // 宏體相當於字符串x,在宏中想賦值字符串的時候使用
#define ABC(x) day##x // 宏體相當於day連接x后的內容
示例:
include <stdio.h> #define FUNC(x) #x #define PAR(x) myparam##x int main() { int myparam1 = 10; int myparam2 = 20; printf(FUNC(abc\n)); // 輸出abc\n printf(PAR(1)); // 輸出10 printf(PAR(2)); // 輸出20 return 0; }
例2:內核中用例,傳入不同的后綴可以得到不同的值
#define ADM8211_SRAM(x) (priv->pdev->revision < ADM8211_REV_DB ? \ ADM8211_SRAM_A_ ## x : ADM8211_SRAM_B_ ## x) #define ADM8211_SRAM_INDIV_KEY 0x0000 #define ADM8211_SRAM_A_SHARE_KEY 0x0160 #define ADM8211_SRAM_B_SHARE_KEY 0x00c0 #define ADM8211_SRAM_A_SSID 0x0180 #define ADM8211_SRAM_B_SSID 0x00d4
Linux 下我們用man可以看到完整的手冊,如果想看一些常用選項,建議你用 `gcc --help`: