主要記錄我在《嗨翻C語(yǔ)言》中記錄的知識(shí)點(diǎn)社付,以備用時(shí)參考。
C語(yǔ)言入門(mén)
- gcc(GNU編譯器套件--GNU Compiler Collection)是個(gè)C編譯器疮绷。
Linux 直接存在
Mac 可使用Xcode
Windows 可用Cygwin(模擬Unix環(huán)境)或MinGw(僅運(yùn)行程序)
- 計(jì)算機(jī)僅理解機(jī)器代碼-->二進(jìn)制流还惠。
-
int main()
函數(shù)是程序中所有代碼的起點(diǎn)诊杆。 - 若要檢查程序的退出狀態(tài)(通常是int main()函數(shù)的返回值):
Windows下可在命令行輸入 echo %ErrorLevel%
Linux或Mac下輸入 echo $?
Note:Cygwin中輸入 echo $?
- 一條命令解決編譯和運(yùn)行,利用
&&
即可颈墅,eg:
gcc test.c -o test **&&** ./test
- 在類Unix(Linux/Mac)操作系統(tǒng)中章母,運(yùn)行程序必須指定程序所在目錄,除非該目錄位于PATH環(huán)境變量中。
- C語(yǔ)言中七婴,0為假祟偷,其他情況均為真。
- & | 與 && ||的異同:
同:都攜帶兩個(gè)條件
異:&&和||打厘,在特定條件下可以跳過(guò)第二個(gè)條件修肠。
&和|必須且總是計(jì)算兩個(gè)條件;而且可以對(duì)數(shù)字的某一位進(jìn)行布爾運(yùn)算户盯。
example1: A && B嵌施,若A為假,則B不必被計(jì)算莽鸭;A & B吗伤,無(wú)論A真或假,B都必須被計(jì)算硫眨;
example2: A || B足淆,若A為真,則B不必被計(jì)算礁阁;A | B巧号,無(wú)論A真或假,B都必須被計(jì)算姥闭。
- 部分函數(shù)丹鸿、關(guān)鍵字、語(yǔ)句舉例:
-
puts()
在命令提示符或終端顯示字符串泣栈。 -
scanf()
從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)卜高;可輸入多個(gè)字段;可輸入結(jié)構(gòu)化數(shù)據(jù)。
int x;
scanf("%d", &x);//fscanf(stdin, "%d", &x)
它在讀取數(shù)據(jù)時(shí)南片,遇到空格就停止掺涛,除非多個(gè)格式化占位符,eg:
#include <stdio.h>
int main()
{
char msg[21];
char phone[12];
scanf("%20s %11s", msg, phone);
printf("輸出\n");
printf("%s---------%s\n", msg, phone);
printf("%li %li\n", sizeof (msg), sizeof (phone));
msg[2] = '\0';
phone[7] = '\0';
printf("%s---------%s\n", msg, phone);
return 0;
}
運(yùn)行結(jié)果如下:
Liana 19996999999
輸出
Liana---------19996999999
21 12
Li---------1999699
*example1 ---- scanf()獲取數(shù): *
int num = -1;
scanf("%i", &num); /*scanf()需要的是變量地址*/
*example2 ---- scanf()獲取字符數(shù)組: *
char ex[11];
scanf("%10s", ex);
/ *ex字符數(shù)組設(shè)置大小為11疼进,但scanf獲取的長(zhǎng)度至多為10薪缆,
*因?yàn)镃語(yǔ)言中存在著標(biāo)志字符串結(jié)束的空字符'\0',
*與fgets()函數(shù)獲取字符數(shù)組內(nèi)容時(shí)有區(qū)別伞广。* /
-
fgets(變量, sizeof(變量), stdin)
拣帽,eg:
#include <stdio.h>
int main()
{
char msg[10];
fgets(msg, 10, stdin);
//char *msg = malloc(sizeof(char)*10);
//fgets(msg, 10, stdin);
printf("輸出\n");
printf("%s---------", msg);
printf("%li\n", sizeof (msg));
return 0;
}
運(yùn)行結(jié)果如下:
Liana
輸出
Liana
---------10
-
printf()
顯示格式化輸出;把數(shù)據(jù)發(fā)送到標(biāo)準(zhǔn)輸出嚼锄。
printf("i like cakes.\n")
//fprintf(stdout, "i like cakes.\n");
Note: <stdio.h> 包含能在終端讀寫(xiě)數(shù)據(jù)的接口减拭。
-
continue
可以跳過(guò)循環(huán)體其余部分,回到循環(huán)開(kāi)始(即永遠(yuǎn)跳至循環(huán)條件處)区丑。
example1 ---- while循環(huán)體:
/ *先判斷條件拧粪,條件滿足則再執(zhí)行語(yǔ)句塊
*重復(fù)上述步驟 * /
int i = 0;
while(i < 8)
{
printf("%d ", i);
if(i == 2)
{
i += 2;
continue;
}
++i;
}
這段代碼輸出結(jié)果如下:
0 1 2 4 5 6 7
example2 ---- do-while循環(huán)體:
/* Loop:先執(zhí)行一次語(yǔ)句塊判斷條件修陡,再判斷條件是否,滿足則重復(fù)上述步驟 */
int i = 0;
do {
++i;
printf("%d ", i);
if( i == 3)
{
i += 2;
continue;
}
} while(i < 7);
這段代碼輸出結(jié)果如下:
1 2 3 6 7
-
break
可以跳出循環(huán)語(yǔ)句塊和switch語(yǔ)句塊可霎,但不能從if語(yǔ)句塊中跳出魄鸦。
存儲(chǔ)器和指針(含字符串)
-
總線錯(cuò)誤:程序不能更新那一塊存儲(chǔ)空間。
段錯(cuò)誤abort trap <-- 緩沖區(qū)溢出 - C語(yǔ)言中癣朗,用雙引號(hào)定義的字符串叫做字符串字面值(string literal)拾因,是常量;而字符數(shù)組不是旷余。
example :
char a[] = "hello";
- 指針可以避免副本绢记、共享數(shù)據(jù)。
指針只是一個(gè)保存存儲(chǔ)器地址的變量荣暮,是進(jìn)程存儲(chǔ)器中真實(shí)編號(hào)的地址庭惜。
*
可以讀日肿ぁ(作為右值)或設(shè)置存儲(chǔ)器地址的內(nèi)容(作為左值)穗酥。 - 賦值語(yǔ)句也有返回值。
example 1 ---- 賦值:
int x, y;
y = (x = 4) /*等價(jià)于 y = x = 4;*/
//此時(shí)y的值為4
example 2 ---- 判等:
int x = 2;
int y = (x == 2);
//此時(shí)y的值為1
- 引用
int x = 4;
int *a = &x;//a指向變量x的地址
int k = *a;//*a作為右值惠遏,可以讀出a上存儲(chǔ)的地址(x的地址)中存儲(chǔ)的值(x的值)
//k = 4
-
sizeof()
是運(yùn)算符砾跃,而非函數(shù)。
程序在編譯時(shí)期將sizeof編譯為一串指令节吮,確定存儲(chǔ)空間的大小抽高,從而計(jì)算sizeof()
的值。
它在計(jì)算字符串字面值長(zhǎng)度時(shí)會(huì)包含空字符\0的長(zhǎng)度透绩,eg :
int k = sizeof ("haha");
printf("%d", k);
此處結(jié)果為:
5
- 數(shù)組變量也是個(gè)地址翘骂,eg :
int x = 3;
int a[2] = {3, 4};
printf("%p , %p\n", &x, a);
//%p 可用于格式化地址(十六進(jìn)制)
此處會(huì)打印兩個(gè)十六進(jìn)制地址值,eg:
0x7ffe11d245dc , 0x7ffe11d245e0
- 計(jì)算機(jī)會(huì)為每個(gè)進(jìn)程分配一個(gè)簡(jiǎn)版存儲(chǔ)器(存儲(chǔ)器是進(jìn)程的) 帚豪。
函數(shù)中聲明的變量通常保存于棧中碳竟,在main()
函數(shù)外部聲明的變量保存于全局變量中。
棧區(qū) <-存局部變量
堆區(qū) <-存全局變量
全局區(qū)
常量段(只讀存儲(chǔ)器) <-存字符串常量
代碼段
- 將指針強(qiáng)制轉(zhuǎn)化為一般數(shù)字狸臣,eg :
int x = 4;
int *p = &x;
long a = (long) p;
- 修改const修飾的變量莹桅,編譯期會(huì)報(bào)錯(cuò)。
- 關(guān)于數(shù)組的相關(guān)計(jì)數(shù)烛亦,
位置------------------從1開(kāi)始
索引诈泼、下標(biāo)-------------從0 開(kāi)始
- 數(shù)組可以當(dāng)指針用,
將數(shù)組傳遞給函數(shù)時(shí)煤禽,函數(shù)會(huì)將其作為指針變量铐达。
把數(shù)組變量傳給指針,會(huì)發(fā)生退化(長(zhǎng)度將未知)檬果,
example1:
#include <stdio.h>
void fun(char msg[])//實(shí)際為指針變量
{
printf("%s\n", msg);
printf("%li", sizeof (msg));//這里計(jì)算的大小是指針變量的大小瓮孙,而非字符串的大小贾节。
}
int main()
{
char *s="i am a cute, smart girl.";
fun(s);
printf("\n");
char ss[] ="i am a cute, smart girl.";
fun(ss);
return 0;
}
該程序運(yùn)行結(jié)果如下:
i am a cute, smart girl.
8
i am a cute, smart girl.
8
example2:
#include <stdio.h>
int main()
{
char *s1="i am a cute, smart girl.";
char ss1[] ="i am a cute, smart girl.";
printf("%s\n", s1);
printf("%li\n", sizeof (s1));
printf("%s\n", ss1);
printf("%li", sizeof (ss1));
return 0;
}
該程序運(yùn)行結(jié)果如下:
i am a cute, smart girl.
8
i am a cute, smart girl.
25
創(chuàng)建小工具
-
sed
流編輯器(stream editor) ---- 搜索、替換文本 -
標(biāo)準(zhǔn)輸入/輸出/錯(cuò)誤
標(biāo)準(zhǔn)輸入/輸出/錯(cuò)誤.png - 重定向
- 默認(rèn)情況下衷畦,標(biāo)準(zhǔn)輸出會(huì)發(fā)送到顯示器栗涂。可以借助
>
將標(biāo)準(zhǔn)輸出重定向到文件祈争。 - 默認(rèn)情況下斤程, 標(biāo)注輸入來(lái)從鍵盤(pán)讀取數(shù)據(jù)∑谢欤可以借助
<
將標(biāo)準(zhǔn)輸出重定向到文件忿墅。 - 標(biāo)準(zhǔn)錯(cuò)誤用于輸出錯(cuò)誤消息【谙浚可以借助
2>
重定向標(biāo)準(zhǔn)錯(cuò)誤疚脐。
Note:重定向最多可以寫(xiě)兩個(gè)文件, 一個(gè)標(biāo)準(zhǔn)輸出邢疙,一個(gè)標(biāo)準(zhǔn)錯(cuò)誤棍弄。
要同時(shí)輸出多個(gè)文件,則需要?jiǎng)?chuàng)建自己的數(shù)據(jù)流疟游,例如fopen()呼畸。
eg:
#include <stdio.h>
int main()
{
char word[10];
int i = 0;
while(scanf("%9s", word) == 1)
{
++i;
if(i % 2)
fprintf(stdout, "%s\n", word);
else
fprintf(stderr, "%s\n", word);
}
return 0;
}
//secret.txt的內(nèi)容如下:
//THE I GIRL'S AM NAME VERY IS CUTE LIANA.
在該程序中,將標(biāo)準(zhǔn)輸入重定向到文件secret.txt颁虐,并將標(biāo)準(zhǔn)輸出蛮原、標(biāo)準(zhǔn)錯(cuò)誤分別重定向到message.txt和message2.txt中:
gcc main.c -o test
./test < secret.txt > message.txt 2> message2.txt
運(yùn)行結(jié)果如下:
//message.txt 的內(nèi)容
THE
GIRL'S
NAME
IS
LIANA.
//message2.txt 的內(nèi)容
I
AM
VERY
CUTE
4.管道pipe |
能連接一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸入與另一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸出
A | B
系統(tǒng)同時(shí)運(yùn)行A和B兩個(gè)程序,并將A的輸出變成B的輸入
流水線:一連串相連的進(jìn)程另绩。
當(dāng)管道連接多個(gè)進(jìn)程時(shí)儒陨, < 會(huì)把文件內(nèi)容發(fā)送到流水線中第一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸入, > 會(huì)捕獲流水線中最后一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸出笋籽。
- 創(chuàng)建數(shù)據(jù)流/C語(yǔ)言中文件的使用
FILE *file = fopen(文件路徑, 模式);//打開(kāi)數(shù)據(jù)流
fclose(file);//關(guān)閉數(shù)據(jù)流
一個(gè)進(jìn)程能擁有的數(shù)據(jù)流是有限的蹦漠,所以用完應(yīng)及時(shí)關(guān)閉。
模式
w(寫(xiě)文件,write) r(讀文件,read) a(在文件末尾追加,append)
FILE *infile = fopen("input.txt", "r");
FILE *outfile = fopen("output.txt", "w");
fprintf(outfile, "你很%s", "好看");
char sentence[20];
fscanf(infile, "%19s", sentence);
fclose(infile);
fclose(outfile);
- 命令行小工具
ps -ae//顯示所有進(jìn)程干签,包括后臺(tái)運(yùn)行的進(jìn)程
tail -t 文件名//持續(xù)顯示文件末尾新添加的數(shù)據(jù)
- 修改程序工作方式
- 對(duì)于GUI程序:修改程序首選項(xiàng)
- 對(duì)于命令行程序:傳遞命令行參數(shù)
-
main函數(shù)
的兩種形式int main()
-
int main(int argc, char *argv[])
其中argv[0]為待運(yùn)行程序的名字津辩,argc記錄的是數(shù)組中元素的個(gè)數(shù)
Note:在處理上述函數(shù)的參數(shù)時(shí),可以由庫(kù)代勞容劳,使用時(shí)需要包含#include <unistd.h>喘沿。
getopt()每次調(diào)用都會(huì)返回命令行中下一個(gè)參數(shù),optarg變量指向選項(xiàng)后的那個(gè)參數(shù)竭贩,optind保存該函數(shù)從命令行讀取了幾個(gè)選項(xiàng)蚜印。
-
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *delivery = "";
int thick = 0;
int ch;
while ((ch = getopt(argc, argv, "d:t")) != EOF/*-1*/)
{
switch (ch)
{
case 'd':
delivery = optarg;
break;
case 't':
thick = 1;
break;
default:
fprintf(stderr, "Unknown option: '%s'\n", optarg);
return 1;
}
}
argc -= optind;
argv += optind;
if(thick) puts("Thick crust.");
if(delivery[0]) printf("To be delivered %s. \n", delivery);
puts("Ingredients: ");
for (int count = 0; count != argc; ++count)
puts(argv[count]);
return 0;
}
該程序結(jié)果如下:
gcc main.c -o order_pizza
./order_pizza Anchovies
Ingredients:
Anchovies
./order_pizza Anchovies Pineapple
Ingredients:
Anchovies
Pineapple
./order_pizza -d now Anchovies Pineapple
To be delivered now.
Ingredients:
Anchovies
Pineapple
./order_pizza -d now -t Anchovies Pineapple
Thick crust.
To be delivered now.
Ingredients:
Anchovies
Pineapple
./order_pizza -d
./order_pizza: option requires an argument -- 'd'
Unknown option: '(null)'