C語(yǔ)言學(xué)習(xí)基礎(chǔ)知識(shí)分享
寫在前面
我們正式開始接觸到C語(yǔ)言,這是我在學(xué)習(xí)過(guò)C語(yǔ)言后重新寫的博客,我把之前的稍微優(yōu)化了一下,希望能用更加樸素的語(yǔ)言和大家分享,我希望給大家?guī)?lái)一個(gè)可以看的懂,理論和實(shí)踐并行的內(nèi)容.當(dāng)然里面也會(huì)存在一些錯(cuò)誤和不恰當(dāng)?shù)牡胤?還請(qǐng)諸位指正.
為何學(xué)習(xí)C語(yǔ)言
我想從兩個(gè)方面和大家分析學(xué)習(xí)C語(yǔ)言的必要性和好處.
語(yǔ)言層面
我們先來(lái)下一個(gè)結(jié)論 C生萬(wàn)物,編程之本, 很多人學(xué)習(xí)計(jì)算機(jī)都是從C語(yǔ)言開始的,它是長(zhǎng)遠(yuǎn)IT職業(yè)發(fā)展的首選,C語(yǔ)言是母體語(yǔ)言,是人機(jī)交互接近底層的橋梁 ,學(xué)會(huì) C語(yǔ)言,相當(dāng)于掌握技術(shù)核心 . IT行業(yè),一般每10年就有一次變革,40年間,在 TIOBE 排行榜中,C/C++位置長(zhǎng)期霸占前三名,沒(méi)有絲毫撼動(dòng),可謂經(jīng)典永不過(guò)時(shí)!
個(gè)人層面
在當(dāng)今社會(huì),技術(shù)不斷的發(fā)展和更新,語(yǔ)言更是層出不窮的出現(xiàn),C\++、Java、、python、go.語(yǔ)言實(shí)在是太多了,那么我們?yōu)楹芜€要學(xué)一門很老的語(yǔ)言,我們學(xué)習(xí)最新的語(yǔ)言不是可以更好的適應(yīng)當(dāng)前技術(shù)的迭代嗎?
每個(gè)人都有每個(gè)人的理解,首先我來(lái)說(shuō)一下自己的觀點(diǎn).和大多數(shù)人一樣,我接觸的第一門語(yǔ)言就是C語(yǔ)言,那時(shí)的我感覺(jué)內(nèi)容多,而且還很難理解,尤其是后面的指針一直在困擾著我,但是當(dāng)我在后面逐漸學(xué)習(xí)的其他語(yǔ)言后,C語(yǔ)言的很多理念出現(xiàn)在其中,尤其是一脈相承的C\++.C語(yǔ)言的學(xué)習(xí)可以大大提高我們學(xué)習(xí)其他語(yǔ)言的能力.
初識(shí)C語(yǔ)言
我想分為兩個(gè)博客的內(nèi)容和大家整體的過(guò)一下C語(yǔ)言的基本知識(shí),這樣我們看別人的代碼可以看的懂.我認(rèn)為大家對(duì)他有一個(gè)認(rèn)識(shí)是非常重要的,這樣即使我們深度不夠,也有往下探究的欲望.
什么是語(yǔ)言
在現(xiàn)實(shí)生活中我們可以很容易的知道人與人交流是通過(guò)語(yǔ)言來(lái)進(jìn)行交流的, 人和人可以用漢語(yǔ),英語(yǔ),俄語(yǔ)...進(jìn)行交流,那么人和計(jì)算機(jī)呢?或者說(shuō)計(jì)算機(jī)和計(jì)算機(jī)是通過(guò)什么語(yǔ)言交流的?這就是計(jì)算機(jī)語(yǔ)言. C語(yǔ)言是常見的一種計(jì)算機(jī)語(yǔ)言,每一個(gè)語(yǔ)言都有自己的優(yōu)點(diǎn),也有自己的缺點(diǎn),C語(yǔ)言同樣如此,相比較于其他的語(yǔ)言,C語(yǔ)言更加適合底層開發(fā), 注意C語(yǔ)言是適合底層開發(fā),不意味著只能干,我們也可以使用C語(yǔ)言做上層的業(yè)務(wù).
標(biāo)準(zhǔn)
什么事物要想發(fā)展要好,必須要有標(biāo)準(zhǔn).那么什么是標(biāo)準(zhǔn),在早期我們是通過(guò)二進(jìn)制編程的,,很多人要查手冊(cè),這里很難,所以那個(gè)時(shí)候一般研究這些的都是都是科學(xué)家.此時(shí)有很多科學(xué)家覺(jué)得我們使用二進(jìn)制是在是太麻煩了,受不了了,我們給二進(jìn)制序列起一個(gè)名字,例如張三和身份正好對(duì)應(yīng),我們把這些名字稱之為助記符,后面又發(fā)展成匯編語(yǔ)言,B語(yǔ)言,C語(yǔ)言和后面的很多語(yǔ)言.
C語(yǔ)言很優(yōu)秀,很多廠商會(huì)對(duì)C語(yǔ)言進(jìn)行定制,自己增加自己的語(yǔ)法,這個(gè)時(shí)候就出現(xiàn)了差異,這就是雜亂尺寸生,此時(shí)又權(quán)威的一些人提出了國(guó)際標(biāo)準(zhǔn),也就是K&R標(biāo)準(zhǔn),這就是標(biāo)準(zhǔn).后來(lái)標(biāo)準(zhǔn)進(jìn)行迭代,逐漸的迭代出其他的版本,例如流行的C89標(biāo)準(zhǔn),和后面的C90,C99.主流標(biāo)準(zhǔn)是C89和C90,C99之后都比較少一些,我們主要看C89的知識(shí)點(diǎn).
helloword
我們來(lái)認(rèn)識(shí)第一個(gè)代碼,這是我們幾乎每一個(gè)程序員都寫過(guò)的代碼.
#include <stdio.h> int main() { printf("hello,world\n"); return 0; }
main
如果你已經(jīng)嘗試了上面的代碼,覺(jué)得既新奇又飽含疑惑,那么下面我們先來(lái)簡(jiǎn)單的揭開它的面紗.注意,我們找個(gè)博客的目的是可以簡(jiǎn)單的上手C語(yǔ)言,會(huì)用就可以了,至于它的原理隨著我們學(xué)習(xí)的深入,我們都會(huì)逐漸明白的,所以說(shuō)不要著急.
<font color = red>我們規(guī)定main函數(shù)是程序的入口</font>,注意,這里標(biāo)準(zhǔn)直接這樣規(guī)定的,也就是說(shuō)我們啟動(dòng)一個(gè)程序時(shí),編譯器會(huì)自動(dòng)的找到main函數(shù),然后從上往下的開始執(zhí)行里面的代碼.
我們這里需要看一下main函數(shù)的大體框架,后面我們要嚴(yán)格按照這個(gè)格式來(lái)寫,至于為什么這里都等到函數(shù)那里去談.
int main() { // 代碼 return 0; }
在一些比較老的代碼規(guī)范里面,還存在下面的寫法,這里我們強(qiáng)烈不推薦.,他們實(shí)在是太老了,而且看著還很別扭.
void main() { }
printf
我們從main入口進(jìn)入了,現(xiàn)在我們開始在想,我們程序的目的是往屏幕上打印Hello World,所以我們調(diào)用了一個(gè)函數(shù),函數(shù)相關(guān)的細(xì)節(jié)我們會(huì)單獨(dú)分享.這個(gè)時(shí)候我告訴你在標(biāo)準(zhǔn)庫(kù)里面有一個(gè)printf函數(shù)可以幫助我們完成這個(gè)功能,我們要用這個(gè)函數(shù),這里需要引一個(gè)頭文件stdio.h,我們通過(guò)下面的做法來(lái)達(dá)到這個(gè)目的.
#include <stdio.h>
到這里解決我們大部分疑惑,也可以簡(jiǎn)單的上手寫一些代碼了.
#include <stdio.h> int main() { printf("我是C語(yǔ)言的初學(xué)者"); return 0; }
數(shù)據(jù)類型
我們都知道,我們可以從不同的角度來(lái)描述一個(gè)物體,假如說(shuō)這有一個(gè)箱子,我們可以這樣描述.
這里你會(huì)發(fā)現(xiàn)有不同的數(shù)據(jù)類型,存在整數(shù)和小數(shù),甚至名字是一串字符.我們計(jì)算機(jī)要模擬世界,那么肯定要提供這些類型,C語(yǔ)言就給我們內(nèi)置了很多的數(shù)據(jù)類型,我們先來(lái)見識(shí)一下.
數(shù)據(jù)類型 | 說(shuō)明 | 大小 |
char | 字符類型 | 1 字節(jié) |
short | 短整型 | 2 字節(jié) |
int | 整型 | 4 字節(jié) |
long | 長(zhǎng)整型 | 4 字節(jié) |
long long | 更長(zhǎng)的整形 | 8 字節(jié) |
float | 單精度浮點(diǎn)數(shù) | 4 字節(jié) |
double | 雙精度浮點(diǎn)數(shù) | 8 字節(jié) |
回答一下下面的問(wèn)題:
為什么要定義這么多類型?
我們的應(yīng)用場(chǎng)景是非常復(fù)雜的,不同應(yīng)用場(chǎng)景要求不同大小的空間,比如說(shuō),一個(gè)人的年齡、身高等變量可以定義成short型,定義成 int型就浪費(fèi)了空間。
這些類型的大小是什么意思?
根據(jù)不同的類型在內(nèi)存中開辟不同大小的一塊空間,每個(gè)類型開辟的空間是固定的,至于如何計(jì)算,這個(gè)我們下面談
byte & bit
在回答不同類型占據(jù)的空間前我們先來(lái)看一下計(jì)算機(jī)里面的一些單位.這里我們用一個(gè)宿舍樓來(lái)進(jìn)行舉例子.在一所高校中,我們把一棟宿舍樓分成很多個(gè)小宿舍,每一個(gè)小宿舍都有固定的床位.計(jì)算機(jī)同樣如此,在計(jì)算機(jī)中,一塊很大的內(nèi)存,我們把他分成很多個(gè)小空間,這個(gè)空間名字叫做字節(jié)(byte),這里我們首先要強(qiáng)調(diào)的是字節(jié)是內(nèi)存的基本單位.和每個(gè)小宿舍有這個(gè)固定床位一樣,每一個(gè)字節(jié)又會(huì)被分為八個(gè)區(qū)域,這個(gè)區(qū)域叫做比特位(bit),也就是一字節(jié)等于八個(gè)比特位.
sizeof
上面回答了內(nèi)存的基本單位,這里就理解不同的數(shù)據(jù)類型占據(jù)若干的字節(jié)是什么意思了.這個(gè)時(shí)候我們又在想,我們是不是可以驗(yàn)證一下,你在這里一直給我灌輸理論,總是感覺(jué)有點(diǎn)不踏實(shí).這里我們就要請(qǐng)出sizeof這個(gè)關(guān)鍵字.我們先來(lái)解釋一下什么是關(guān)鍵字.
我這里直接說(shuō)我的理解,所謂的關(guān)鍵字是C語(yǔ)言官方給我們提供的,這些關(guān)鍵字有著不同的功能,比如說(shuō)上面的int,我們可以很清楚的知道int代表的是一個(gè)整型.sizeof也是一個(gè)關(guān)鍵字,它的作用是計(jì)算占據(jù)內(nèi)存空間的大小,單位就是字節(jié).后面我們會(huì)遇到很多關(guān)鍵字,我們用一個(gè)談一個(gè).現(xiàn)在開始驗(yàn)證一下這些類型的大小,你會(huì)發(fā)現(xiàn)printf又出現(xiàn)了新的用法,這個(gè)后面會(huì)談到,先暫時(shí)這樣用著.
#include <stdio.h> int main() { printf("char %d\n", sizeof(char)); printf("short %d\n", sizeof(short)); printf("int %d\n", sizeof(int)); printf("long int %d\n", sizeof(long int)); printf("long long %d\n", sizeof(long long)); printf("float %d\n", sizeof(float)); printf("double %d\n", sizeof(double)); system("pause"); return 0; }
常量
生活中的有些值是不變的(比如:圓周率,性別(?),身份證號(hào)碼,血型等等),有些值是可變的(比如:年齡,體重,薪資)。 在C語(yǔ)言中,我們會(huì)學(xué)習(xí)到變量,常量,作用域,生命周期......等概念,我們不由得發(fā)出疑問(wèn),什么是變量,為什么要有變量?這些都是我們需要處理得疑惑.我先談?wù)劤A?,后面再說(shuō)說(shuō)變量。所謂的常量就是不可再次修改的數(shù)據(jù).它有下面的幾種分類.
數(shù)值常量 1,2,3...字符串常量 "abcd","defcbg"
這里面我重點(diǎn)談?wù)勛址A?在C語(yǔ)言中,存在一個(gè)字符串常量池,這個(gè)我們等到操作系統(tǒng)再談,像"abcd"就是其中的一部分,要是我們想要修改"abcd"變?yōu)?quot;bbcd",這是做不到的,有的人可能會(huì)感到疑惑,這不是很簡(jiǎn)單嗎,我們只需要把a(bǔ)修改成b不就完成了嗎?但是這只是象,"bbcd"也是字符串常量池的一部分,我們所謂的修改,就是更改指針?biāo)赶虻牡刂?指針后面談).
#include <stdio.h> int main() { char* pa = "abcd"; printf("%p\n", pa); pa = "bbcd"; printf("%p\n", pa); return 0; }
常量分類
上面的太籠統(tǒng) 這類簡(jiǎn)單的說(shuō)一下,在C語(yǔ)言中我們將學(xué)習(xí)不同的常量.
字面常量 就是字符const 修飾的常變量枚舉 后面談#define 定義得的標(biāo)識(shí)符常量
注意:const是一個(gè)關(guān)鍵字,這個(gè)關(guān)鍵字作用是很大的,我們后面會(huì)重點(diǎn)分析.
變量
簡(jiǎn)單得來(lái)說(shuō),變量就是可以修改得量.變量不同于常量,它可以被修改的\.例如int x = 10,x可以修改為20,但是我們不能把常量1修改成常量2.這就是變量定義.<font color = red>在計(jì)算機(jī)中,變量是一個(gè)在內(nèi)存中開辟特定大小的空間,用來(lái)保存數(shù)據(jù). </font>
定義變量
這倒是很簡(jiǎn)單,就是<font color = blue>類型 變量名 = 初始化的值</font>.這里我們需要談一下什么是變量名,前面我們描述箱子的時(shí)候,談到了長(zhǎng)度,我們用L表示,此時(shí)這里就可以認(rèn)為L(zhǎng)就是一個(gè)變量.
int a = 10; // 定義一個(gè)整型變量a 并初始化為 10 double b = 10.2; // 定義一個(gè)雙精度浮點(diǎn)數(shù)變量b 并初始化為 10
變量的分類
變量的分類主要分為兩大類,我們盡量不要使用全局變量.
- 全局變量
- 局部變量
局部變量
局部變量:包含在代碼塊中的變量叫做局部變量。局部變量具有臨時(shí)性。進(jìn)入代碼塊,自動(dòng)形成局部變量,退出代碼塊自動(dòng)釋放.(網(wǎng)上很多說(shuō)函數(shù)中的變量是局部變量,不能說(shuō)錯(cuò),但說(shuō)法是不準(zhǔn)確的),下面的a和d都是局部變量.
int main() { int a = 10; double d = 11.01; return 0; }
這里來(lái)個(gè)復(fù)雜的,這里就可以驗(yàn)證一下局部變量具有臨時(shí)性,這里的臨時(shí)性可以認(rèn)為對(duì)標(biāo)下面的作用域和生命周期.
#include <stdio.h> int main() { int a = 10; { int x = 20; printf("x = %d\n", x); } return 0; }
這里的臨時(shí)性就可以通過(guò)下面的代碼驗(yàn)證出來(lái)
#include <stdio.h> int main() { int a = 10; { int x = 20; printf("x = %d\n", x); } printf("x = %d\n", x); return 0; }
局部變量如果不進(jìn)行初始化,那么根據(jù)編譯器的不同,我們拿到的是隨機(jī)值,甚至嚴(yán)格的編譯器都不會(huì)讓我們使用.
我們?cè)跍y(cè)試一下gcc編譯器,這里看看有什么不同.看來(lái)gcc是沒(méi)有VS嚴(yán)格的,但是我們要按照最標(biāo)準(zhǔn)的來(lái),嚴(yán)格遵守變量被定義一定要初始化.
全局變量
這里我想和大家談?wù)勅肿兞?這個(gè)有一點(diǎn)重要.所謂的全局變量,全局變量具有全局性 , 我們可以認(rèn)為是在main函數(shù)外邊所定義的變量,一般按照<font color = bluee>g_變量名</font>的格式來(lái)走,當(dāng)然,也可以不按.
#include <stdio.h> int g_key = 20; //全局變量 double g_val = 10.00; int main() { printf("%d\n", g_key); printf("%d\n", g_val); return 0; }
上面我們談到了局部變量不進(jìn)行初識(shí)化是隨機(jī)值,那么全局變量呢?這是很簡(jiǎn)單的,我們直接給一個(gè)結(jié)論,全局變量定義起來(lái)即使我們不初始化,他也是固定值,是0.這里只驗(yàn)證VS.
int a; int main() { printf("%d\n", a); return 0; }
注意,如果你堅(jiān)持看我后面寫的博客,就會(huì)發(fā)現(xiàn)我們很少使用全局變量,它是有一定的缺陷的,等到后面我們會(huì)專門談的.
局部?jī)?yōu)先
大家看一下下面的代碼.<font color = red>如果全局變量和局部變量同名,編譯器優(yōu)先使用局部變量,這就是局部?jī)?yōu)先原則.</font>
#include <stdio.h> int a = 10; int main() { int a = 0; printf("a = %d\n", a); return 0; }
變量的使用
我們先來(lái)簡(jiǎn)單色的通過(guò)格式化輸入輸出來(lái)分析一下變量是如何被我門使用的,這些都是很簡(jiǎn)單的.
printf
這里我們需要再次談一下printf函數(shù),上面我們已經(jīng)使用過(guò)它的用法了,可能大家會(huì)有一些疑惑,這里需要具體的分析一下這個(gè)函數(shù).
printf()函數(shù)是我們經(jīng)常使用的的函數(shù)之一,他的作用就是將我們想要的數(shù)據(jù)輸出到指定位置,這里的指定位置包含屏幕,我們先使用一下
#include <stdio.h> int main() { int a = 10; printf("%d\n", a); return 0; }
這里我們可以看到,我們使用了printf()函數(shù)
printf("%d\n",a);
這里有幾點(diǎn)要說(shuō)一下
% 被稱為 "轉(zhuǎn)換說(shuō)明",所謂的轉(zhuǎn)換說(shuō)明就是將數(shù)據(jù)按指定的格式顯式出來(lái)%d是指將a的值以十進(jìn)制的形式打印來(lái),例如 %o :打印八進(jìn)制、%x 打印十六進(jìn)制.....
數(shù)據(jù)輸出的格式與很多,下面我列出一張表
X | 例子 | 說(shuō)明 |
d | %d | 打印int型,默認(rèn)1 |
f | %f | 打印float型,小數(shù)點(diǎn)后默認(rèn)6位 |
e | %e | 以科學(xué)計(jì)數(shù)法的形式打印,小數(shù)點(diǎn)后默認(rèn)6位 |
g | %g | 以科學(xué)計(jì)數(shù)法或者float型打印,方式看g的大小選擇 |
scanf
我們?cè)谙爰热蛔兞渴强梢宰兓?我們總不能把先要的值全部列出來(lái)吧,我們?nèi)绻謩?dòng)輸入該如何做到呢?這里給大家簡(jiǎn)紹一個(gè)scanf函數(shù).
和printf() 一樣,scanf()也是存在特定的格式讀入,這里先給出個(gè)例子,我們一起來(lái)看看
#include <stdio.h> int main() { int a = 0; scanf("%d", &a); printf("%d\n", a); return 0; }
作用域&生命周期
這個(gè)一直是一個(gè)比較容易模糊的點(diǎn),有很多人對(duì)他們的區(qū)別可能分不太清楚,一般我們能分辨清楚就可以了
作用域 變量可以被使用的地方,就是作用域生命周期 變量開始開辟空間 到 空間銷毀
這里我先給出點(diǎn)結(jié)論,適合大部分情況.局部變量的作用域和生命周期是在局部變量所在的代碼塊中,除了代碼塊就不可以了.全局變量的作用域和生命周期是整個(gè)程序.
到此這篇關(guān)于C語(yǔ)言學(xué)習(xí)基礎(chǔ)知識(shí)分享的文章就介紹到這了,更多相關(guān)C語(yǔ)言基礎(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++哈希應(yīng)用之位圖,哈希切分與布隆過(guò)濾器詳解
這篇文章主要為大家詳細(xì)介紹了C++哈希應(yīng)用中的位圖、哈希切分與布隆過(guò)濾器,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下2023-04-04C語(yǔ)言編程銀行ATM存取款系統(tǒng)實(shí)現(xiàn)源碼
這篇文章主要為大家介紹了C語(yǔ)言編程銀行ATM存取款系統(tǒng)實(shí)現(xiàn)的源碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11C++實(shí)現(xiàn)LeetCode(153.尋找旋轉(zhuǎn)有序數(shù)組的最小值)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(153.尋找旋轉(zhuǎn)有序數(shù)組的最小值),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之單鏈表存儲(chǔ)詳解
鏈表是一種物理存儲(chǔ)結(jié)構(gòu)上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的。本文將和大家一起聊聊C語(yǔ)言中單鏈表的存儲(chǔ),感興趣的可以學(xué)習(xí)一下2022-07-07C++實(shí)現(xiàn)LeetCode(199.二叉樹的右側(cè)視圖)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(199.二叉樹的右側(cè)視圖),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08