欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:1. C語(yǔ)言之初識(shí)C語(yǔ)言

柚子快報(bào)激活碼778899分享:1. C語(yǔ)言之初識(shí)C語(yǔ)言

http://yzkb.51969.com/

文章目錄

前言一、什么是C語(yǔ)言二、第一個(gè)C語(yǔ)言程序三、數(shù)據(jù)類(lèi)型四、變量,常量1、變量1.1 變量的命名1.2 變量的分類(lèi)1.3 變量的使用1.4 變量的作用域和生命周期2、變量

五、字符串1. 概念2. 求解字符串的長(zhǎng)度【strlen】3. 轉(zhuǎn)義字符【含筆試題】

六、注釋七、選擇語(yǔ)句八、循環(huán)語(yǔ)句九、函數(shù)十、數(shù)組1、數(shù)組的定義2、數(shù)組的下標(biāo)3、數(shù)組的使用

十一、操作符1、算數(shù)運(yùn)算符2、移位操作符3、位操作符4、賦值操作符5、單目操作符6、關(guān)系操作符7、邏輯操作符8、條件操作符9、逗號(hào)表達(dá)式10、其他

十二、常見(jiàn)關(guān)鍵字1、前言2、有關(guān)數(shù)據(jù)存儲(chǔ)的底層原理3、typedef關(guān)鍵字4、static關(guān)鍵字4.1、static關(guān)鍵字修飾局部變量4.2、static關(guān)鍵字修飾全局變量4.3、static關(guān)鍵字修飾函數(shù)

十三、 #define 定義常量和宏十四、 指針1、引言2、內(nèi)存的概念和介紹3、指針變量的大小

十五、結(jié)構(gòu)體

前言

想必剛接觸C語(yǔ)言的同學(xué)們不知道C語(yǔ)言是什么?,有什么用,那么你來(lái)對(duì)了,本系列就會(huì)帶你入門(mén)C語(yǔ)言,從入門(mén)到“入土”,開(kāi)玩笑的,正如標(biāo)題所說(shuō),本教程首先對(duì)C語(yǔ)言有一個(gè)初步的認(rèn)識(shí),能夠看懂別人寫(xiě)的是什么,有一個(gè)大概的框架,那么,我要開(kāi)始講解了。 這一章主要是初始C語(yǔ)言的一個(gè)大綱。

一、什么是C語(yǔ)言

C語(yǔ)言是什么?

語(yǔ)言:漢語(yǔ),日語(yǔ),英語(yǔ)等。語(yǔ)言是一個(gè)自然語(yǔ)言,是人與人交流的語(yǔ)言。 計(jì)算機(jī)語(yǔ)言:類(lèi)比過(guò)來(lái),是人與計(jì)算機(jī)之間的交流。 C語(yǔ)言是一門(mén)通用計(jì)算機(jī)編程語(yǔ)言,廣泛應(yīng)用于底層開(kāi)發(fā)。C語(yǔ)言的設(shè)計(jì)目標(biāo)是提供一種能以簡(jiǎn)易 的方式編譯、處理低級(jí)存儲(chǔ)器、產(chǎn)生少量的機(jī)器碼以及不需要任何運(yùn)行環(huán)境支持便能運(yùn)行的編程語(yǔ) 言。 盡管C語(yǔ)言提供了許多低級(jí)處理的功能,但仍然保持著良好跨平臺(tái)的特性

二、第一個(gè)C語(yǔ)言程序

我們?cè)诹私馔闏語(yǔ)言是什么后,我們需要了解如何使用集成開(kāi)發(fā)環(huán)境去完成第一個(gè)C語(yǔ)言程序。

什么是集成開(kāi)發(fā)環(huán)境呢? 集成開(kāi)發(fā)環(huán)境(IDE,Integrated Development Environment )是用于提供程序開(kāi)發(fā)環(huán)境的應(yīng)用程序,一般包括代碼編輯器、編譯器、調(diào)試器和圖形用戶界面等工具。 像vscode就是一種編輯器,它不是集成開(kāi)發(fā)環(huán)境,但是它可以添加許多的插件來(lái)編輯代各種形式的代碼。 像vs2022就是一種集成開(kāi)發(fā)環(huán)境,在平時(shí)使用很方便,但是存儲(chǔ)空間比較大,畢竟有好有缺點(diǎn)嘛,不能兩者兼容。 但是我本人不太推薦使用那種上古編譯器比如VC++,DEV++…

接下來(lái)我們就開(kāi)始正式寫(xiě)第一個(gè)C語(yǔ)言程序

進(jìn)入官網(wǎng)下載VS2022,不要去別的地方下載那些盜版的?。?!點(diǎn)擊進(jìn)入官網(wǎng)

點(diǎn)擊個(gè)人免費(fèi)下載,學(xué)習(xí)下載這個(gè)完全夠用了。

打開(kāi)下載

打開(kāi)軟件,創(chuàng)建一個(gè)新項(xiàng)目

在C語(yǔ)言的學(xué)習(xí)中,大多數(shù)人的第一個(gè)程序就是hello word!,那么我們?cè)趺创蛴〕鰄ello word,開(kāi)始我們學(xué)習(xí)編程之旅,下面就跟著我來(lái)一起學(xué)習(xí)。

我們知道,C語(yǔ)言所有的字符,符號(hào),都是英文的。C語(yǔ)言中代碼是從main函數(shù)的第一行開(kāi)始的。main函數(shù)是程序的入口,一個(gè)工程中main函數(shù)有且只有一個(gè)。其中代碼中的printf是編譯器的頭文件引入的,可以直接使用。是頭文件,后綴為.c是源文件,后綴.h為頭文件。

#include

int main()

{

printf("hello world!\n");

return 0;

}

有人可能看到我這里寫(xiě)的是int main(){ ... return 0},通常就是這樣寫(xiě)的,也是最普遍的寫(xiě)法,還有一種就是void main(){ },這種寫(xiě)法比較古老,現(xiàn)在不會(huì)使用這種寫(xiě)法。

三、數(shù)據(jù)類(lèi)型

寫(xiě)出了我們的第一個(gè)C語(yǔ)言程序,接下來(lái)我們來(lái)說(shuō)一說(shuō)C語(yǔ)言中的數(shù)據(jù)類(lèi)型

在了解數(shù)據(jù)類(lèi)型前,我們先探究為什么要寫(xiě)程序?

是為了用程序解決生活中的一些問(wèn)題。在現(xiàn)實(shí)生活中,我們的各種數(shù)據(jù)有很多不同的類(lèi)型,為了更加豐富的表達(dá)生活中的各種值,所以在C語(yǔ)言程序中設(shè)置這么多數(shù)據(jù)類(lèi)型。

char //字符數(shù)據(jù)類(lèi)型

short //短整型

int //整形

long //長(zhǎng)整型

long long //更長(zhǎng)的整形

float //單精度浮點(diǎn)數(shù)

double //雙精度浮點(diǎn)數(shù)

每種類(lèi)型的字節(jié)大小是多少? 下圖所顯示的就是:

計(jì)算機(jī)中常見(jiàn)的單位:bit(比特),byte(字節(jié)),KB,MB,GB,TB,PB。

他們的單位換算為:

1 byte = 8 bit 1 KB = 1024 byte 1 MB = 1024 KB 1 GB = 1024 MB 1 TB = 1024 GB 1 PB = 1024 TB

四、變量,常量

在生活中有些值是不變的(比如:圓周率,性別,身份證號(hào)碼,血型等等),有些值是可變的(比如:年齡,體重,薪資等等),引入了變量和常量的概念。

首先,先講述一下變量:

1、變量

語(yǔ)法形式為:type + name。代碼如下:

int age = 150;

float weight = 45.5f; //浮點(diǎn)數(shù)默認(rèn)為雙精度浮點(diǎn)數(shù),在后面加個(gè)f,說(shuō)明是單精度浮點(diǎn)數(shù)類(lèi)型

char ch = 'w';

1.1 變量的命名

只能由字母(包括大小寫(xiě)),數(shù)字,下劃線組成。不能以數(shù)字開(kāi)頭。長(zhǎng)度不能超過(guò)63個(gè)字符。C語(yǔ)言是區(qū)分大小寫(xiě)的。變量名字不能以關(guān)鍵字命名字。變量的名字盡量有意義。

1.2 變量的分類(lèi)

變量分為局部變量和全局變量

#include

int global = 2019;//全局變量

int main()

{

int local = 2018;//局部變量

//下面定義的global會(huì)不會(huì)有問(wèn)題?

int global = 2020;//局部變量

printf("global = %d\n", global);

return 0;

}

總結(jié):

上面的局部變量global變量的定義其實(shí)沒(méi)有什么問(wèn)題的! 當(dāng)局部變量和全局變量同名的時(shí)候,局部變量?jī)?yōu)先使用。

1.3 變量的使用

了解了什么是變量,現(xiàn)在我們就要具體地去使用這個(gè)變量了,讓我們一起來(lái)看看

#include

int main()

{

int num1 = 0;

int num2 = 0;

int sum = 0;

printf("輸入兩個(gè)操作數(shù):>");

scanf("%d %d", &num1, &num2);

sum = num1 + num2;

printf("sum = %d\n", sum);

return 0;

}

在vs編譯時(shí)會(huì)發(fā)現(xiàn),我們?cè)谶@里會(huì)出現(xiàn)4996警告。

為什么會(huì)出現(xiàn)這個(gè)警告呢?

是因?yàn)樵趘s中輸入函數(shù),微軟有自己的定義scanf_s,而用scanf函數(shù)不安全。

如何消除這個(gè)警告呢?

第一種方法就是把scanf()改成scanf_s(),scanf()也是vs提供的,這種方式很簡(jiǎn)單,但是代碼的跨平臺(tái),可移植性就變差了,不推薦這種方法。第二種方法就是在.c文件中添加#pragma warning(disable:4996)這樣就不會(huì)提示這個(gè)告警了。跟著下圖一步一步的操作

首先下載everthing軟件,下載好點(diǎn)擊打開(kāi)搜索newc++file.cpp,打開(kāi)文件

把這行粘貼進(jìn)去#define _CRT_SECURE_NO_WARNINGS 1,后面還要加上個(gè)【1】不要忘了

這種方法一勞永逸,可以很好的解決我們的問(wèn)題~~

再次創(chuàng)建一個(gè).c文件,可以看到自動(dòng)就有那一行了

1.4 變量的作用域和生命周期

清楚了如果使用變量去編寫(xiě)程序,接下來(lái)我們來(lái)看一下變量的作用域和生命周期

作用域:

作用域(scope)是程序設(shè)計(jì)概念,通常來(lái)說(shuō),一段程序代碼中所用到的名字并不總是有效/可用的通常來(lái)說(shuō),一段代碼中所用到的變量名并不總是有效的,而限定這個(gè)名字的可用性的代碼范圍就是這個(gè)變量名的作用域。

了解了其基本概念,我們就到代碼中來(lái)演示一下

可以看到程序報(bào)錯(cuò)了,說(shuō)【未定義標(biāo)識(shí)符】,可以看出這個(gè)作用域具有限定范圍的

int main()

{

{

int a = 10;

printf("a = %d", a);

}

printf("a = %d", a);

return 0;

}

以上的話就是局部變量的作用域從下面代碼可以看出,完全沒(méi)有報(bào)出錯(cuò)誤,因?yàn)閷?duì)于全局變量的作用域,是從定義變量開(kāi)始到整個(gè)程序運(yùn)行結(jié)束,整個(gè)變量才會(huì)被銷(xiāo)毀,而這個(gè)變量a,則是在這個(gè)代碼塊結(jié)束之后便會(huì)銷(xiāo)毀,所以我們?cè)诤竺娌旁L問(wèn)不到這個(gè)變量

對(duì)于全局變量的作用域,還可以這樣使用,把這個(gè)b變量定義在add.c這個(gè)文件下,然后我們?cè)趖est.c這個(gè)文件定義一下這個(gè)變量b,用這個(gè)extern聲明一下即可

生命周期:

變量的生命周期指的是變量的創(chuàng)建到變量的銷(xiāo)毀之間的一個(gè)時(shí)間段

局部變量的生命周期是:進(jìn)入作用域生命周期開(kāi)始,出作用域生命周期結(jié)束。

全局變量的生命周期是:整個(gè)程序的生命周期

講完了變量,接下去我們來(lái)講講常量

2、變量

C語(yǔ)言中常量分為一下幾種:

字面常量const修飾的常變量#define 定義的標(biāo)識(shí)符常量枚舉常量

#include

//舉例

enum Sex

{

MALE,

FEMALE,

SECRET

};

//括號(hào)中的MALE,FEMALE,SECRET是枚舉常量

//#define的標(biāo)識(shí)符常量 演示

#define MAX 100

int main()

{

//字面常量演示

3.14;//字面常量

1000;//字面常量

//const 修飾的常變量

const float pai = 3.14f; //這里的pai是const修飾的常變量

pai = 5.14;//是不能直接修改的!

printf("max = %d\n", MAX);

//枚舉常量演示

printf("%d\n", MALE);//0

printf("%d\n", FEMALE);//1

printf("%d\n", SECRET);//2

//注:枚舉常量的默認(rèn)是從0開(kāi)始,依次向下遞增1的

return 0;

}

常量就是不變的量,所以叫常量

五、字符串

1. 概念

在講字符串之前,我們先來(lái)看看下面這個(gè),因?yàn)樵谟?jì)算機(jī)中存儲(chǔ)、表示的都是二進(jìn)制,所以我們打印出來(lái)的也會(huì)是一個(gè)二進(jìn)制首先定義一個(gè)char類(lèi)型的字符變量ch,然后分別以%c、%d、%s去打印出來(lái),可以看到,顯示的結(jié)果各不相同%c打印的就是一個(gè)字符,%d打印的則是這個(gè)字符在ASCLL碼表中的值,最后的%s,打印的就是ch這個(gè)字符串

然后開(kāi)始講一講字符串

概念:雙引號(hào)引起的一串字符叫做字符串

2. 求解字符串的長(zhǎng)度【strlen】

說(shuō)完了字符串了基本概念,了解了什么是字符串,接下去我們來(lái)看看如何入求解字符串的長(zhǎng)度

對(duì)于字符串,大家要知道,結(jié)束標(biāo)志是一個(gè) \0 的轉(zhuǎn)義字符,轉(zhuǎn)義字符我們下個(gè)模塊就講到,這個(gè)\0表示這個(gè)字符串已經(jīng)結(jié)束了。但是在計(jì)算字符串長(zhǎng)度的時(shí)候,這個(gè)\0是不計(jì)算在內(nèi)的也是說(shuō),求字符串的長(zhǎng)度統(tǒng)計(jì)的是字符串中\(zhòng)0之前出現(xiàn)多少個(gè)字

那我們?nèi)绾稳デ蠼庖粋€(gè)字符串的長(zhǎng)度呢?

這里我們需要使用到一個(gè)【string.h】頭文件里的一個(gè)函數(shù),叫做strlen(),可以計(jì)算一個(gè)字符串的長(zhǎng)度,也就是\0之前的長(zhǎng)度,這個(gè)函數(shù)我們后面會(huì)細(xì)講

printf("len = %d\n", strlen("abc"));

前面我們說(shuō)到過(guò)char類(lèi)型可以定義一個(gè)字符變量,不僅如此,在這里,我們還可以定義一個(gè)字符數(shù)組,什么是字符數(shù)組呢?就是這個(gè)數(shù)組中存放的都是字符,我們來(lái)看一個(gè)具體的定義

char arr[] = "abcdef";

以上就是字符數(shù)組的基本定義接著我們?cè)賮?lái)看一種,下面這一種也是字符數(shù)組的定義方式

char arr2[] = { 'a','b','c','d','e','f' };

可以看到,這兩個(gè)字符數(shù)組中的內(nèi)容是一樣,那他們打印出來(lái),以及計(jì)算出來(lái)的長(zhǎng)度是否是一樣的呢,我們一起來(lái)看一下

很明顯,從以上結(jié)果來(lái)看,是不一樣的,這是為什么呢?我們通過(guò)一張圖示來(lái)了解一下

從以上這張圖我們應(yīng)該可以很明顯地看出來(lái),為什么第二個(gè)arr2數(shù)組在打印的時(shí)候會(huì)出現(xiàn)【燙燙燙】這種東西呢,如果你自己去編譯器里試試的話應(yīng)該也是這樣因?yàn)榈诙€(gè)數(shù)組的內(nèi)容值給到了f,并不是一個(gè)完整的字符串,但是第一個(gè)數(shù)組給到的卻是一個(gè)完整的字符串,所以自動(dòng)擁有一個(gè)’\0’,第二個(gè)數(shù)組就沒(méi)了,所以后面打印出來(lái)的只會(huì)是一個(gè)隨機(jī)值,然后直至碰到一個(gè)\0為止,遍歷才會(huì)結(jié)束所以我們可以看到這個(gè)長(zhǎng)度也是受到了影響,arr1數(shù)組的長(zhǎng)度就是6,但是arr2數(shù)組的長(zhǎng)度卻是加上了一些隨機(jī)字符后的長(zhǎng)度,這就顯得不準(zhǔn)確了

3. 轉(zhuǎn)義字符【含筆試題】

那什么叫做轉(zhuǎn)義字符呢?我們通過(guò)代碼來(lái)看看

int main()

{

printf("abcndef");

printf("abc\ndef");

}

通過(guò)運(yùn)行結(jié)果我們可以看到,這個(gè)n,若是在其前面加上了一個(gè)\,則它的意思就發(fā)生了變化,在轉(zhuǎn)義字符里面就叫做【\n換行】,所以可以看到打印到【abc】就發(fā)生了換行,在后一行打印了def

然后我們?cè)賮?lái)看到一個(gè)打印一個(gè)test.c的路徑從運(yùn)行結(jié)果來(lái)看,并沒(méi)有真正地打印出來(lái)一個(gè)路徑,而是出現(xiàn)了很多空格細(xì)心的小伙伴應(yīng)該可以發(fā)現(xiàn)這個(gè)test的第一個(gè)字符t和路徑的\是同一個(gè)顏色,都淡化了,在轉(zhuǎn)義字符里,這個(gè)叫做【\t水平制表符】,也及時(shí)們鍵盤(pán)上的【Tab鍵】,敲一下就能空出4個(gè)空格

所以我們?cè)趐rintf輸出一個(gè)東西的時(shí)候,不要去寫(xiě)一些轉(zhuǎn)義字符,那C語(yǔ)言中有哪些轉(zhuǎn)義字符呢,我們一起來(lái)看一下

用一個(gè)表格給大家呈現(xiàn):

轉(zhuǎn)義字符釋義?在書(shū)寫(xiě)連續(xù)多個(gè)問(wèn)號(hào)時(shí)使用,防止他們被解析成三字母詞\ ’用于表示字符常量\“用于表示一個(gè)字符串內(nèi)部的雙引號(hào)\ \用于表示一個(gè)反斜杠,防止它被解釋為一個(gè)轉(zhuǎn)義序列符\a警告字符,蜂鳴\b退格符\f進(jìn)紙符\n換行\(zhòng)r回車(chē)\t水平制表符\v垂直制表符\dddddd表示1~3個(gè)八進(jìn)制的數(shù)字。如:\130X\xdddd表示2個(gè)十六進(jìn)制數(shù)字。 如:\x30 0

我們挑重點(diǎn)的說(shuō)一下

首先是二三兩個(gè),看第一行代碼,若你printf的是一個(gè)【‘’‘】,那么編譯器就會(huì)報(bào)錯(cuò),你本是想打印一個(gè)【’】,這個(gè)時(shí)候該怎么辦呢,你只需要在前面加上一個(gè)\,這就變成了一個(gè)轉(zhuǎn)義字符,然后就可以像運(yùn)行結(jié)果一樣輸出了然后第三個(gè)也是同理,這里便不做過(guò)多詳解

然后就是剛才我們所說(shuō)的打印路徑,要怎樣才能打印出這個(gè)路徑呢?沒(méi)錯(cuò),只需要再添加一個(gè)【\】就可以了,這就表示一個(gè)反斜杠,我們到代碼里看一下可以看到,這個(gè)路徑已經(jīng)被完全打印出來(lái)了

最后,我們?cè)賮?lái)講一下最后兩個(gè)有關(guān)八進(jìn)制和十六進(jìn)制的一樣,先給出運(yùn)行結(jié)果

有關(guān)【\ddd】,表示的就是八進(jìn)制,也就是通過(guò)八進(jìn)制去計(jì)算,如果用%d打印出來(lái)的就是計(jì)算的結(jié)果,如果使用%c打印出來(lái)的就是這個(gè)數(shù)字所對(duì)應(yīng)的ASCLL碼符號(hào) 對(duì)于十六進(jìn)制也是同理,/xdd值就是十進(jìn)制,然后看上面的打印也是同理 對(duì)于【\x3a】的話就是用a*160 然后我們來(lái)說(shuō)一道有關(guān)轉(zhuǎn)義字符的筆試題

printf("%d\n", strlen("c:\test\628\test.c"));

這個(gè)結(jié)果是什么呢?答案不盡相同而真正的答案是【14】,為什么呢?我們來(lái)看一下

分析

首先第一步,我們剛學(xué)了轉(zhuǎn)義字符,【\t】表示的一定是一個(gè)字符,所以18排除然后第二步,相信大家最疑惑的就是這個(gè)\628,這其實(shí)就是我們上面所說(shuō)的\ddd,但是這都能算嗎?這個(gè)時(shí)候你就要去想,八進(jìn)制能包含8嗎,八進(jìn)制就是0~7的數(shù)字,所以是不會(huì)有8,因此這個(gè)【\62】算一個(gè)轉(zhuǎn)義字符最后我們就可以得出答案為【14】

六、注釋

首先我們要先了解一下注釋是什么,它可以用來(lái)干嘛

注釋可以將你不需要或者還不想刪除地代碼暫時(shí)屏蔽起來(lái),在程序執(zhí)行的時(shí)候會(huì)直接跳過(guò)注釋的代碼,不會(huì)運(yùn)行如果在一些程序中有一些晦澀難懂的代碼,可能你寫(xiě)出來(lái)的代碼需要需要一些批注后面在閱讀你代碼的人才能知道這段代碼是什么意思,這個(gè)時(shí)候你就可以在這段代碼的上方或是下方寫(xiě)一些注釋,這樣后人就可以看懂你寫(xiě)的代碼

int main()

{

//下面是創(chuàng)建一個(gè)整型變量并賦值10

int a = 10;

int b = 100;

//C++ 注釋風(fēng)格 - C99

/* C語(yǔ)言的注釋風(fēng)格

int c = 10;

int d = 20;

printf("ff");

*/ // - 嵌套的話此處結(jié)束注釋

//不支持嵌套注釋

return 0;

}

我們來(lái)分析一下,對(duì)于雙斜杠//,這個(gè)是C99中對(duì)于C++的注釋風(fēng)格,那C語(yǔ)言的注釋風(fēng)格是怎樣的呢,就是/**/但是后面我還補(bǔ)充了一句話,就是對(duì)于C語(yǔ)言的這種注釋方法,不可以產(chǎn)生嵌套的,例如說(shuō)這里若是在外層加上一個(gè)/**/,這樣return 0;不會(huì)被注釋了,為什么呢?因?yàn)樯厦娴?*和return 0;上面的那個(gè)先匹配了,所以就不會(huì)到下面的

七、選擇語(yǔ)句

在C語(yǔ)言或是其他編程語(yǔ)言中,都有著三種結(jié)構(gòu)方式:【順序】、【選擇】和【循環(huán)】那這個(gè)選擇語(yǔ)句是什么呢?就是你有時(shí)候會(huì)面臨兩種或多種選擇,不同的選擇對(duì)應(yīng)的就是不同的結(jié)果

具體我們通過(guò)代碼來(lái)看一下

int main()

{

int input = 0;

printf("你要好好學(xué)習(xí)嗎(1/0)\n");

scanf("%d", &input);

if (input == 1)

{

printf("拿一個(gè)好offer\n");

}

else

{

printf("回家種田\n");

}

return 0;

}

上面這一段代碼,就是一個(gè)選擇語(yǔ)句,你可以在終端輸入你的選擇,問(wèn)你要不要好好學(xué)習(xí)。若你選擇的是1好好學(xué)習(xí),那么你就可以拿一個(gè)好offer;但若是你選擇0擺爛,那么就只能回家種田

八、循環(huán)語(yǔ)句

然后我們?cè)賮?lái)說(shuō)說(shuō)另一種形式,也就是循環(huán)語(yǔ)句

什么是循環(huán)呢?循環(huán)就是你一直不斷重復(fù)地做一件事,直到某個(gè)條件滿足時(shí)才會(huì)退出

然后我們通過(guò)一段代碼再來(lái)看一下

int main()

{

int line = 0;

printf("好好學(xué)習(xí)\n");

while (line < 20000)

{

printf("寫(xiě)代碼:%d\n", line);

line++;

}

if (line == 20000)

printf("好offer\n");

return 0;

}

然后對(duì)于循環(huán)的話,不僅僅是有while,還有do…while(),for這些,我們?cè)诤罄m(xù)都會(huì)講到

九、函數(shù)

函數(shù)其實(shí)就是將一個(gè)功能單獨(dú)封裝成為一個(gè)模塊,然后這個(gè)模塊可以被多次調(diào)用,以便來(lái)實(shí)現(xiàn)代碼的簡(jiǎn)化

我們先來(lái)看這么一段代碼這是一段兩數(shù)求和的代碼,輸入兩個(gè)數(shù)據(jù),然后輸出它們的和但是設(shè)想,若是我們要再求另外兩個(gè)數(shù)的和,那么就要再次輸入,然后求和的代碼就要再寫(xiě)一遍,這就徒增了代碼量,顯得整個(gè)程序很冗余,那要怎么簡(jiǎn)化呢?對(duì)就是使用函數(shù)。

int main()

{

int num1 = 0;

int num2 = 0;

int sum = 0;

printf("請(qǐng)輸入兩個(gè)操作數(shù)字:>");

scanf("%d %d", &num1, &num2);

sum = num1 + num2;

printf("sum = %d\n", sum);

return 0;

}

我們來(lái)看一下使用函數(shù)簡(jiǎn)化完之后是什么樣子這段代碼使用了三次求和,得到了三個(gè)求和結(jié)果

int Add(int m, int n)

{

return (m + n);

}

int main()

{

int sum1 = 0;

int sum2 = 0;

int sum3 = 0;

sum1 = Add(1, 2);

sum2 = Add(3, 4);

sum3 = Add(5, 6);

printf("sum1 = %d\n", sum1);

printf("sum2 = %d\n", sum2);

printf("sum3 = %d\n", sum3);

return 0;

}

十、數(shù)組

1、數(shù)組的定義

首先我們知道數(shù)字這個(gè)概念,但是當(dāng)我們需要一堆的數(shù)字,那么這個(gè)數(shù)字存到哪里去呢?沒(méi)錯(cuò),也就是用一個(gè)叫【數(shù)組】的東西存放起來(lái)那要怎么存放呢,我們來(lái)看一下

int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

首先需要先聲明這個(gè)數(shù)組是什么類(lèi)型的,是整型、字符型還是浮點(diǎn)型等,數(shù)組的話這些數(shù)據(jù)都是可以存儲(chǔ)的,然后在一個(gè)變量后面加上一個(gè)[],括號(hào)里可以寫(xiě)上你準(zhǔn)備為這個(gè)數(shù)組開(kāi)辟多大的空間,比如說(shuō)上面寫(xiě)的是10,那么這個(gè)數(shù)組中最多能存下的數(shù)據(jù)也就只有10個(gè),但是若你不寫(xiě)的話,就可以存多個(gè),后面會(huì)教大家一個(gè)方法去計(jì)算沒(méi)有給出數(shù)據(jù)具體大小如何去求這個(gè)數(shù)組的大小這里先給出,大家可以先看看,sizeof()是一種單目操作符,是用來(lái)計(jì)算你所使用的操作數(shù)所占的空間字節(jié)大小

int sz = sizeof(a)/sizeof(a[0]);

剛才說(shuō)過(guò),數(shù)組除了可以存放整數(shù)數(shù)據(jù)外,還可以存放字符型、浮點(diǎn)型的數(shù)據(jù)

char b[] = { 'a','b','c'};

double c[] = {2.5,6.9,7.7,1.5 }

2、數(shù)組的下標(biāo)

知道了數(shù)組怎么聲明,那我們聲明的這些數(shù)組怎么獲取到呢?

C語(yǔ)言規(guī)定:數(shù)組的每個(gè)元素都有一個(gè)下標(biāo),下標(biāo)是從0開(kāi)始的訪問(wèn)。下面就是我們通過(guò)下標(biāo)去訪問(wèn)的a數(shù)組中下標(biāo)為8的元素,打印出來(lái)的就會(huì)是9

//下標(biāo)訪問(wèn)數(shù)組元素

printf("%d\n", a[8]);

具體大家看圖示就能一目了然了 可以看到,這里arr數(shù)組的大小是10,那我們?nèi)ピL問(wèn)18這下標(biāo)會(huì)怎么樣呢,去編譯器里看看 從圖中可以看出,總共下標(biāo)也就只有9,你訪問(wèn)到了,那就會(huì)產(chǎn)生越界訪問(wèn),那么你訪問(wèn)到的就會(huì)是一個(gè)隨機(jī)值

3、數(shù)組的使用

看一下代碼。我們首先定義了一個(gè)大小而10的整型數(shù)組,然后將其內(nèi)容初始化為0,然后我們通過(guò)一個(gè)在while循環(huán)中通過(guò)scanf去輸入一些數(shù)據(jù),將其一一地通過(guò)下標(biāo)放入數(shù)組中。然后呢,還是一樣,通過(guò)循環(huán)去遍歷這個(gè)數(shù)組,調(diào)用printf去打印出里面的數(shù)據(jù)這就是數(shù)組的一種使用方法,其余的我們放到后面數(shù)組章節(jié)細(xì)講

int main()

{

int arr[10] = { 0 };

//0 ~ 9 - 輸入10個(gè)值給數(shù)組

int i = 0;

while (i < 10)

{

scanf("%d", &arr[i]);

i++;

}

i = 0;

while (i < 10)

{

printf("%d ", arr[i]);

i++;

}

return 0;

}

十一、操作符

C語(yǔ)言中操作符不少,這里我們做簡(jiǎn)要介紹,后續(xù)會(huì)詳細(xì)講解

1、算數(shù)運(yùn)算符

這里我們重點(diǎn)來(lái)講講【除】和【取余】首先來(lái)看這段代碼,結(jié)果會(huì)是多少?

int a = 7 / 2;

printf("%d\n", a);

運(yùn)行結(jié)果是3,因?yàn)檫\(yùn)算符的左右兩邊都是整數(shù),所以執(zhí)行的是整數(shù)除法,包括下面這段也是一樣,運(yùn)行結(jié)果都是3,只是因?yàn)閒loat浮點(diǎn)數(shù)的原因,小數(shù)點(diǎn)后多出6個(gè)0

float f = 7 / 2;

printf("%f\n", f);

那怎么將其變?yōu)楦↑c(diǎn)數(shù)除法,也就是得到3.5這個(gè)答案,你只需要將7或2任意一個(gè)數(shù)字改為浮點(diǎn)數(shù)即可,例如說(shuō)7.0/2.0,至少有一個(gè)操作數(shù)是浮點(diǎn)數(shù)執(zhí)行的才是浮點(diǎn)數(shù)除法

我們來(lái)看看結(jié)果

然后我們?cè)賮?lái)看看【取余】操作符

int main()

{

// % 取余操作符,關(guān)注的是除法后的余數(shù)

int a = 7 % 2; //商3余1

printf("%d\n", a);

return 0;

}

取到就是一個(gè)整數(shù)對(duì)另一個(gè)整數(shù)做除法后的余數(shù)

2、移位操作符

這一塊大家先了解一下,先不做細(xì)講,會(huì)在操作符章節(jié)細(xì)講

左移就是擴(kuò)大 右移就是縮小

3、位操作符

上面叫移位,這里叫位,區(qū)別大嗎?區(qū)別可大了,完全是兩個(gè)概念 這里也會(huì)在后面章節(jié)詳解

4、賦值操作符

有關(guān)賦值運(yùn)算符,第一個(gè)大家應(yīng)該不陌生,就是我們常見(jiàn)的賦值運(yùn)算,后面呢則是一些【加減乘除取余移位】這些復(fù)合而成的,你可以到編譯器里自己試試看

5、單目操作符

重點(diǎn)來(lái)說(shuō)一下單目運(yùn)算法

首先是這個(gè)取反操作,在C語(yǔ)言中呢,表示真假只有兩種,用0表示假,用非0表示真所以看下面的代碼,這個(gè)a就是【真】,所以會(huì)執(zhí)行“haha”語(yǔ)句,但若是你把a(bǔ)換成0,那么!a就是【真】,就會(huì)打印“hehe”語(yǔ)句

//C語(yǔ)言是如何表示真假的呢?

//0表示假,非0表示真

//-1 表示的就是真

int main()

{

//把假變成真,把真變成假

int a = 10;

if (a)

printf("haha\n");

if(!a) //這個(gè)不執(zhí)行

printf("hehe\n");

return 0;

}

然后【取正】【取負(fù)】很簡(jiǎn)單,看到下面代碼,會(huì)打印a的相反數(shù)

int a = -10;

printf("%d\n", +a);

printf("%d\n", -a);

然后對(duì)于取地址和星號(hào)運(yùn)算符,我們?cè)谙旅嬷羔樀牟糠纸榻B然后來(lái)看看sizeof()這個(gè)運(yùn)算符,sizeof()是一個(gè)函數(shù)嗎?不是的,sizeof是一個(gè)操作符

int a = 10;

char c = 'w';

int arr[10] = { 0 };

printf("%d\n", sizeof(a)); //4

printf("%d\n", sizeof(c)); //1

printf("%d\n", sizeof(arr)); //40

對(duì)于sizeof()這個(gè)運(yùn)算符呢,它是用來(lái)計(jì)算所占內(nèi)存空間的大小,單位是字節(jié),所以上面代碼的輸出分別為整型、字符型和一個(gè)數(shù)組所占內(nèi)存空間的大小因?yàn)檫@些變量都是用int、char這些變量類(lèi)型定義出來(lái)的,所以可以直接用sizeof()傳入這些變量的類(lèi)型,出來(lái)的結(jié)果也是一樣的

printf("%d\n", sizeof(a)); //4

printf("%d\n", sizeof(int)); //4

printf("%d\n", sizeof(c)); //1

printf("%d\n", sizeof(char)); //1

既然這是一個(gè)操作符,那干嘛要這個(gè)括號(hào)呢?直接去掉不就好了,不然引起歧義,就像下面這樣

printf("%d\n", sizeof int);

我們?cè)诰幾g器上跑一下可以看到,是不能運(yùn)行的~~這其實(shí)就更好地可以說(shuō)明sizeof是一個(gè)操作符,不是函數(shù),括號(hào)可以省略然后我們就可以得出結(jié)論:變量可去括號(hào),類(lèi)型不可取去括號(hào)

上面我們有提到過(guò),當(dāng)我們沒(méi)有對(duì)一個(gè)數(shù)組設(shè)定初始化元素個(gè)數(shù)時(shí),可以使用sizeof()去計(jì)算這個(gè)數(shù)組中有多少元素

就是下面這樣,sizeof(arr)就是整個(gè)數(shù)組的大小,sizeof(arr[0])便是一個(gè)元素的大小,當(dāng)然你也可以寫(xiě)成【sizeof(int)】,因?yàn)檎蛿?shù)組中一個(gè)元素的大小一定是4個(gè)字節(jié),也就是int所占的字節(jié)大小

printf("%d\n", sizeof(arr));;

int sz = sizeof(arr) / sizeof(arr[0]);

printf("%d\n", sz);

然后我們來(lái)說(shuō)一下 【前置、后置–】與【 前置、后置++】

這兩個(gè)其實(shí)是一樣的,我們先來(lái)看一下【 前置、后置++】對(duì)于前置++的話就是先++在賦值,所以下面的a會(huì)把++完之后的值給到b,然后自己也會(huì)++,因此最后輸出的便是11 11

int a = 10;

int b = ++a; //先++后賦值

// a = a + 1

// b = a

printf("%d %d\n", a, b); //11 11

對(duì)于后置++就不一樣了,剛好相反,就是c會(huì)先把自己的值給到d,然后自己再++,所以d得到的就是10,c后面++完后之后就是11

int c = 10;

int d = c++; //先賦值后++

// d = c;

// c = c + 1

printf("%d %d\n", c, d); //11 10

然后我們來(lái)說(shuō)【前置、后置–】,同理

int a = 10;

int b = --a; ///先--在賦值

printf("%d %d\n", a, b); //9 9

int c = 10;

int d = c--; ///先賦值后--

printf("%d %d\n", c, d); //9 10

然后這一段也是一樣,首先打印a–的一定是之前的值,然后打印的就是–之后的值,也就是9

int a = 10;

printf("%d\n", a--); //先使用,后--

printf("%d\n", a);

對(duì)于前置、后置的±,老是喜歡出一些面試題,把你搞暈,其實(shí)根本沒(méi)什么意義,我們來(lái)看看

int a = 1;

int b = (++a) + (++a) + (++a);

printf("%d\n", b);

從VS來(lái)看,這段代碼的運(yùn)行結(jié)果是12,但是在Linux的gcc編譯器中,運(yùn)行結(jié)果竟然是10 一段代碼在不同編譯器運(yùn)行結(jié)果不同,說(shuō)明這段代碼其實(shí)有問(wèn)題的,準(zhǔn)確的說(shuō)是存在歧義的 我們來(lái)講單目操作符的最后一個(gè),強(qiáng)制類(lèi)型轉(zhuǎn)換 首先來(lái)看這兩句代碼,你認(rèn)為這會(huì)輸出什么

int a = 3.14;

printf("%d\n", a);

因?yàn)?.14給到了一個(gè)整型變量a,所以只會(huì)保留整數(shù),這個(gè)時(shí)候大家看下面我用紅筆畫(huà)起來(lái)的一段Warning,說(shuō)這個(gè)【從“double”轉(zhuǎn)換到“int”】,可能會(huì)丟失數(shù)據(jù)這個(gè)時(shí)候應(yīng)該怎么辦呢?你可以在3.14前面加上一個(gè)(int),將這個(gè)數(shù)強(qiáng)制轉(zhuǎn)換成整型,也就是我上面注釋掉的一行代碼,這個(gè)時(shí)候你再去運(yùn)行試試,就不會(huì)報(bào)出Warning了

6、關(guān)系操作符

對(duì)于前面的四個(gè),直接用就可以了,和直觀地進(jìn)行一個(gè)比較。我們來(lái)講一下后面的兩個(gè)也就是比較兩個(gè)數(shù)是否相等與不等,這個(gè)要與【賦值運(yùn)算符】中的【=】做區(qū)別,一個(gè)是比較兩個(gè)數(shù)或是變量的,另一個(gè)則是進(jìn)行賦值運(yùn)算的,不混淆了

int a = 10;

int b = 20;

if (a == b)

printf("haha\n");

if(a != b)

printf("hehe\n");

那這個(gè)時(shí)候就有同學(xué)問(wèn)了,除了這個(gè)數(shù)字的比較,可以比較字符串嗎,我們來(lái)看看

char arr1[] = "abcdef";

char arr2[] = "abcdef";

if (arr1 == arr2)

printf("==\n");

else

printf("!=\n");

可以看到,兩個(gè)字符數(shù)組明明是一樣的,但是卻走了第二個(gè)分支,打印了【!=】,這里其實(shí)就出問(wèn)題了。為什么呢?這個(gè)我們后面會(huì)說(shuō)到,數(shù)組名是整個(gè)數(shù)組的首元素地址,其實(shí)【==】比較的是它們的地址對(duì)于字符串的比較,在C語(yǔ)言中有專門(mén)的函數(shù),叫做strcmp(),它和strlen()一樣都是屬于【string.h】頭文件里的,若比較的兩者相等的話,則會(huì)返回0,前者大于后者,返回 > 0的數(shù),后者大于前置,返回 < 0的數(shù),所以只需要去判斷一下去和0的大小即可

//兩個(gè)字符串不可以用“==”來(lái)判斷是否相等,使用strcmp(庫(kù)函數(shù))

char arr1[] = "abcdef";

char arr2[] = "abcdef";

if (strcmp(arr1,arr2) == 0)

printf("==\n");

else

printf("!=\n");

這樣的話結(jié)果就正確了

7、邏輯操作符

邏輯與【&&】是并且的意思,邏輯或【| |】是或者的意思。為真則為1,為假則為0對(duì)于邏輯與,只有兩個(gè)數(shù)均為1是才為1,只要有一個(gè)為0,結(jié)果即為0

int a = 5;

int b = 4;

int c = a && b;

printf("c = %d\n", c);

if (a && b)

printf("hehe\n");

從上述代碼和運(yùn)行結(jié)果可以看出,因?yàn)閍,b都不是0,因此它們的結(jié)果為1,才可以進(jìn)入下面那個(gè)if判斷,若是把a(bǔ),b其中任意一個(gè)改為0,則結(jié)果便為0,然后不會(huì)進(jìn)入下面的這個(gè)判斷對(duì)于邏輯或的話,只要其中有一個(gè)為1,則為1,只有兩個(gè)數(shù)均為0是,才為0所以下面的顯示結(jié)果是0,并且沒(méi)有進(jìn)入這個(gè)if條件的判斷

int a = 0;

int b = 0;

int c = a && b;

printf("c = %d\n", c);

if (a || b)

printf("hehe\n");

8、條件操作符

下面是一段簡(jiǎn)單的if分支判斷,然后給b賦值

int a = 10;

int b = 0;

if (a > 5)

b = 3;

else

b = -3;

printf("b = %d\n", b);

但是對(duì)于三目運(yùn)算符來(lái)說(shuō),不用這么麻煩,只需要這么一句就好了具體意思就是,判斷a是否大于5,若是,則將b賦值為3,若不是,則將b賦值為-3

a > 5 ? b = 3 : b = -3;

但是其還有更簡(jiǎn)便的寫(xiě)法,也是一樣去判斷,最后把得出來(lái)的值給到左邊的b即可

b = (a > 5 ? 3 : -3);

9、逗號(hào)表達(dá)式

我們先來(lái)說(shuō)一下其運(yùn)算規(guī)則:從左向右依次計(jì)算,整個(gè)表達(dá)式的結(jié)果是最后一個(gè)表示式的結(jié)果

列舉了一個(gè)逗號(hào)表達(dá)式,大家可以去自己試著計(jì)算一下,每過(guò)一個(gè)表達(dá)式參與運(yùn)算的變量都會(huì)改變,最后看打印出的a,b,c的值,也是發(fā)生了變化

int a = 3;

int b = 5;

int c = 0;

int d = (a += 2, b = b - c + a, c = a + b);

//a = 5 b = 10 c = 5 + 10 = 15

printf("d = %d\n", d);

printf("%d %d %d\n", a, b, c);

10、其他

【下標(biāo)引用操作符】

什么是下標(biāo)引用操作符呢?也就是這個(gè)[ ],我們?cè)诙x數(shù)組的時(shí)候指定的數(shù)組大小

int arr[10] = { 0 };

arr[4] = 5;

printf("%d\n", arr[4]);

對(duì)于上面這段代碼,我們稱arr4 是 [ ]的兩個(gè)操作符我們回憶一下【+】運(yùn)算符,這是一個(gè)雙目運(yùn)算符,比如說(shuō)2 + 3,那么就可以稱2 3 是 +的兩個(gè)操作符,對(duì)于我們來(lái)說(shuō)2 + 3可以寫(xiě)成3 + 2,既然雙目運(yùn)算符可以這么交換著來(lái)做,那【下標(biāo)引用操作符】可以嗎,答案是可以的?。。∩厦孢@段代碼,我們還可以寫(xiě)成這樣

int arr[10] = { 0 };

4[arr] = 5;

printf("%d\n", 4[arr]);

接下來(lái)的話是這個(gè)叫【函數(shù)調(diào)用】的操作符

int Add(int x, int y)

{

return (x + y);

}

int main()

{

int c = Add(2, 3); //()是函數(shù)調(diào)用操作符,操作數(shù)是:Add 2 3

printf("c = %d\n", c);

return 0;

}

很明確,就是函數(shù)外面的兩個(gè)小括號(hào),這個(gè)我們?cè)谏厦嬲f(shuō)到sizeof()操作符時(shí)也提到過(guò),對(duì)于sizeof(),雖然其有(),但是不可以把它認(rèn)為是一個(gè)函數(shù),它也會(huì)是一個(gè)操作符然后對(duì)于函數(shù)調(diào)用操作符的話,看到上面的Add函數(shù),()是操作符,那么操作數(shù)就是Add 2 3

十二、常見(jiàn)關(guān)鍵字

1、前言

了解了C語(yǔ)言中的常見(jiàn)運(yùn)算符,接下來(lái)我們來(lái)看看C語(yǔ)言中的關(guān)鍵字

首先對(duì)于關(guān)鍵字,我們要注意的兩點(diǎn)是 1、關(guān)鍵字是直接使用的,我們得了解 2、變量名不能是關(guān)鍵字 從下面這些可以看出,在C語(yǔ)言中,關(guān)鍵字還是蠻多的

首先單獨(dú)說(shuō)一下【auto】,它比較特殊,因?yàn)樵诰幾g器中,當(dāng)你定義一個(gè)變量的時(shí)候默認(rèn)就是存在的auto,翻譯過(guò)來(lái)就是自動(dòng)的,在C語(yǔ)言里指得是自動(dòng)變量,所有你定義的局部變量都是自動(dòng)創(chuàng)建、自動(dòng)銷(xiāo)毀的,所以局部變量都是auto修飾的就像下面這個(gè)整型變量a,你在int的前面加上或是不加auto 都是不會(huì)報(bào)錯(cuò)的, 原因就是所有局部變量都是auto

//auto int a = 10;

int a = 10; //auto可以省略

2、有關(guān)數(shù)據(jù)存儲(chǔ)的底層原理

有關(guān)寄存器這個(gè)東西,涉及到了數(shù)據(jù)存儲(chǔ),我們來(lái)詳細(xì)說(shuō)一下,讓大家先了解一下這個(gè)底層原理

首先你要知道在計(jì)算機(jī)中的數(shù)據(jù)是存放在哪里的

①內(nèi)存 ②硬盤(pán) ③高速緩存 ④寄存器

然后我們?cè)偻ㄟ^(guò)這張圖來(lái)了解一下

對(duì)于計(jì)算機(jī)中的寄存器,其實(shí)它所空間是很小的,單位只有字節(jié),但是它的讀寫(xiě)速度非??欤梢灾苯优cCPU【中央處理器】進(jìn)行交互 然后越往下這個(gè)空間越大,內(nèi)存的話現(xiàn)在普遍都是8G,16G這樣,大一點(diǎn)有32G,不會(huì)像很早之前的只有2MB這樣;對(duì)于硬盤(pán)的話,我們?nèi)ナ袌?chǎng)上買(mǎi)也是500G,1個(gè)T這樣的大小 我們的寄存器,因?yàn)樗淖x取速度很快,因此CPU直接到寄存器里面拿數(shù)據(jù),但這個(gè)時(shí)候寄存器內(nèi)存不夠大了怎么辦呢?裝不過(guò)這么多,這個(gè)時(shí)候我們所知道的高速緩存,也就是Cache,會(huì)給寄存器提供內(nèi)存,那高速緩存里又不夠了,這個(gè)時(shí)候就繼續(xù)讓內(nèi)存給它提供。這樣的話整體地提高了計(jì)算機(jī)的運(yùn)行效率 下面就是【register】這個(gè)關(guān)鍵字的用法,在定義這個(gè)變量b的時(shí)候加上了這個(gè)關(guān)鍵字,就是【建議】編譯器把這個(gè)變量放到寄存器中,這里要注意,只是建議,而不是直接放入 具體再如何使用大家可以去查閱一些資料,這里不做過(guò)多詳解

//建議把b放到寄存器中

register int b = 10;

3、typedef關(guān)鍵字

首先就是這個(gè)【typedef】,這個(gè)關(guān)鍵字的話是用來(lái)重命名的,用在結(jié)構(gòu)體上會(huì)比較多

typedef struct Linknode{

int data[MaxSize];

struct Linknode* next;

}LNode;

當(dāng)然它不止應(yīng)用在結(jié)構(gòu)體上,對(duì)于一些數(shù)據(jù)類(lèi)型也是可以重命名的,例如下面這個(gè)【unsigned int】,后面你在使用【uint】定義變量的時(shí)候就和【unsigned int】一樣

typedef unsigned int uint;

int main()

{

unsigned int num1 = 0;

uint num2 = 0; //與num1一樣

return 0;

}

4、static關(guān)鍵字

最后再來(lái)說(shuō)一下這個(gè)static關(guān)鍵字

這里是來(lái)說(shuō)說(shuō)C語(yǔ)言中的static關(guān)鍵字,首先你要了解static關(guān)鍵字可以用來(lái)修飾什么,它主要是可以用來(lái)修飾下面三個(gè)

修飾局部變量修飾全局變量修飾函數(shù)

4.1、static關(guān)鍵字修飾局部變量

首先我們來(lái)看看static對(duì)于局部變量的修飾

void test()

{

int a = 3;

a++;

printf("%d ", a);

}

int main()

{

int i = 0;

while (i < 10)

{

test();

i++;

}

return 0;

}

你認(rèn)為上面這段程序會(huì)輸出什么??吹街鞒绦?,使用while循環(huán)來(lái)控制i變量,當(dāng)i = 10的時(shí)候邊不會(huì)進(jìn)入循環(huán),所以是會(huì)循環(huán)10次,然后看內(nèi)部的test()函數(shù),每次循環(huán)調(diào)用這個(gè)函數(shù)的時(shí)候都會(huì)定義一個(gè)變量a,然后++之后變?yōu)?,然后輸出所以這段程序的運(yùn)行結(jié)果是會(huì)輸出10個(gè)4

然后我們修改一下這個(gè)定義的變量a,將其設(shè)置為靜態(tài)變量,也就是在int前面加上一個(gè)static修飾那這個(gè)時(shí)候你認(rèn)為上面那段程序會(huì)打印出什么呢?

static int a = 3;

首先你要了解靜態(tài)變量的特性以及其余普通變量之前的區(qū)別

①普通的局部變量是放在內(nèi)存的棧區(qū)上的,進(jìn)入局部范圍,變量創(chuàng)建,出了局部范圍變量銷(xiāo)毀 ②當(dāng)static修飾局部變量時(shí),局部變量是在靜態(tài)區(qū)開(kāi)辟空間的,這時(shí)的局部變量,出了作用域變量不銷(xiāo)毀,下次進(jìn)去作用域,使用的是上一次遺留的數(shù)據(jù)(改變了存儲(chǔ)位置,由棧區(qū)–>靜態(tài)區(qū),使得變量的生命周期發(fā)生了變化)

知道了這些,你應(yīng)該清楚這個(gè)打印結(jié)果是多少了,4~13,每一次進(jìn)入這個(gè)test()函數(shù)時(shí),這個(gè)變量a將不再被執(zhí)行,也就是只會(huì)在第一次進(jìn)入這個(gè)函數(shù)的時(shí)候定義,之后就會(huì)一直存在,知道這個(gè)程序結(jié)束時(shí)它才會(huì)被銷(xiāo)毀,所以這個(gè)變量a每次保留的便是上一次++后的結(jié)果

看到了上面的結(jié)果,對(duì)于靜態(tài)變量修飾成員相信你也有了一個(gè)初步的了解,對(duì)于普通的局部變量,是存儲(chǔ)在棧區(qū)上的。但是對(duì)于靜態(tài)變量,你知道它是存儲(chǔ)在什么地方的嗎?沒(méi)錯(cuò),就靜態(tài)區(qū),我們通過(guò)下面這張圖再來(lái)了解一下在計(jì)算機(jī)內(nèi)存中變量到底是如何存儲(chǔ)的

4.2、static關(guān)鍵字修飾全局變量

add.c:

int g_val = 2022;

test.c:

extern int g_val; //聲明外部符號(hào)

int main()

{

printf("%d\n", g_val);

return 0;

}

以上的這種全局變量聲明,以及【extern】關(guān)鍵字調(diào)用,是聲明一個(gè)變量,但是若這個(gè)g_val變量被定義成了靜態(tài)變量,會(huì)怎么樣呢?我們來(lái)看看

可以看到,這個(gè)外部命令無(wú)法被解析 全局變量是具有外部鏈接屬性的,如果全局變量被static修飾,外部鏈接屬性就變成了內(nèi)部鏈接屬性,其他源文件就沒(méi)法再通過(guò)鏈接找到這個(gè)符號(hào) 所以可以得出結(jié)論,static修飾后的局部變量只能在自己所在的.c文件內(nèi)部使用~

4.3、static關(guān)鍵字修飾函數(shù)

其實(shí)這個(gè)理念也是一樣的,若你不使用static修飾,那你可以用extern關(guān)鍵字做一個(gè)引入,那它就是一個(gè)外部鏈接,但若是你使用static修飾,那么這個(gè)函數(shù)就只能本源文件使用,不可以給到外部的文件使用,這就是一個(gè)內(nèi)部鏈接了

可以看到,也是同理,這是一個(gè)內(nèi)部鏈接,外部是訪問(wèn)不到的,即使是有這個(gè)extern關(guān)鍵字

十三、 #define 定義常量和宏

首先來(lái)說(shuō)說(shuō)這個(gè)#define去定義常量

#define MAX 100

int main()

{

printf("%d\n", MAX);

int a = MAX;

int arr[MAX] = { 0 };

printf("%d\n", a);

return 0;

}

看到如上代碼,我使用#define定義了一個(gè)MAX常量,并且其值為100,在main函數(shù)中,你就可以直接使用這個(gè)常量,對(duì)它進(jìn)行打印、賦值 當(dāng)然除了定義整型數(shù)據(jù)常量,其他類(lèi)型也是可以的,例如字符串也可以

#define STR "abcdef"

printf("%s\n", STR);

講完使用#define去定義常量,我們?cè)賮?lái)說(shuō)說(shuō)宏定義,它也是利用#define去聲明的

下面有一個(gè)求和的函數(shù)以及宏定義求和的寫(xiě)法

//函數(shù)

int Add(int x, int y)

{

return x + y;

}

//宏

#define ADD(x,y) ((x) + (y)) //為了保持整體性

除了求和的功能外,其實(shí)你還可以定義其他功能,例如說(shuō)比較兩個(gè)數(shù)的較大值,就可以像下面這么去寫(xiě),使用一個(gè)三目運(yùn)算符即可

#define MAX(x,y) ((x) > (y) ? (x) : (y))

十四、 指針

1、引言

對(duì)于指針這一塊,很多同學(xué)在剛開(kāi)始學(xué)習(xí)C語(yǔ)言的時(shí)候就聽(tīng)別人說(shuō)起過(guò),說(shuō)指針很難很難,訪問(wèn)內(nèi)存、取地址這些操作,既危險(xiǎn)又難搞

2、內(nèi)存的概念和介紹

對(duì)于指針這一塊的話,是直接和計(jì)算機(jī)中的內(nèi)存發(fā)生關(guān)系的,所以我們先來(lái)講講內(nèi)存相關(guān)的知識(shí),帶大家先行了解一下底層的知識(shí) 對(duì)于內(nèi)存,大家在日常生活中應(yīng)該也有聽(tīng)到過(guò),例如我們?yōu)殡娔X、筆記本買(mǎi)的內(nèi)存條,以及我們手機(jī)的內(nèi)存,對(duì)于這個(gè)內(nèi)存來(lái)說(shuō),一般都是8G或是16個(gè)G,與內(nèi)存相對(duì)應(yīng)的,那就是硬盤(pán),一般的話都是500G或是1個(gè)T這樣 在計(jì)算機(jī)中,內(nèi)存是一塊連續(xù)的存儲(chǔ)空間,但是這樣就無(wú)法分配到每一個(gè)部分進(jìn)行使用,這個(gè)時(shí)候呢就將內(nèi)存分成了一塊塊小的內(nèi)存單元,那為了能夠有效的訪問(wèn)到內(nèi)存的每個(gè)單元,就給內(nèi)存單元進(jìn)行了編號(hào),這些編號(hào)就被稱為該內(nèi)存單元的地址

從上面這張圖示,就可以很直觀地看出內(nèi)存在計(jì)算機(jī)中到底是如何存儲(chǔ)的,每一個(gè)內(nèi)存單元的大小都是一個(gè)字節(jié),然后為它們都進(jìn)行了編號(hào),這樣在外界需要訪問(wèn)時(shí),就可以根據(jù)這個(gè)內(nèi)存編號(hào)去指定進(jìn)行一個(gè)訪問(wèn),這個(gè)一個(gè)個(gè)編號(hào)其實(shí)就被稱為是地址

知曉了地址的基本概念后,我們?cè)賮?lái)到編譯器中去看看這個(gè)地址究竟是怎樣分部的

首先我們來(lái)看最簡(jiǎn)單的一句代碼,就是定義一個(gè)變量a,我們都知道int整型的變量在內(nèi)存中是占4個(gè)字節(jié)的,我們?cè)谶@句代碼上打個(gè)斷點(diǎn)進(jìn)入內(nèi)存窗口一看究竟

int main()

{

int a = 4;

}

輸入這個(gè)【&a】,就可以看到內(nèi)存中為變量a開(kāi)辟的4個(gè)內(nèi)存單元,首地址就是從【0x00CFF814】開(kāi)始,整型變量占4個(gè)字節(jié),看我框起來(lái)的這4個(gè)就是,對(duì)于每一個(gè)字節(jié)它都有自己的一個(gè)編號(hào), &a呢就是取到第一個(gè)字節(jié)的地址

那我們要怎么使用代碼去獲取這個(gè)地址呢

&a // 拿到的值第一個(gè)字節(jié)的地址

我們通過(guò)調(diào)試窗口再來(lái)看一下。很明顯,得到了我們想要的結(jié)果

或者你不想到調(diào)試窗口中去看的話,也是可以的我們直接printf打印出來(lái)即可,可以看到,這里使用的是%p,這是專門(mén)對(duì)于地址訪問(wèn)的,如果你是%d,出來(lái)的就是格式化后的數(shù)字了

講完了內(nèi)存,講完了地址,接下去才是真正的指針,但其實(shí)對(duì)于地址來(lái)說(shuō),它就是指針,指針是地址的一個(gè)別名,下面就來(lái)看一下指針是如何去定義的

int a = 4;

int* pa = &a;

可以看到,在int類(lèi)型后我加上了一個(gè)【*】星號(hào),這就說(shuō)明這是一個(gè)指針類(lèi)型的變量,這個(gè)pa就是【指針變量】,因?yàn)樯厦嬲f(shuō)過(guò)指針是地址的別名,所以這個(gè)等式是成立的,pa這個(gè)指針變量可以去接收a的地址,也存放了a的地址

既然這個(gè)指針變量存放了變量的地址,那么可不可以通過(guò)這個(gè)指針變量去訪問(wèn)到這個(gè)地址并且把它打印出來(lái)呢?答案是可以的,這就是涉及到我們的下一個(gè)知識(shí)點(diǎn),就是指針的解引用 利用【*】這個(gè)操作符

*pa

上面定義了,pa就是一個(gè)指針變量,*pa其實(shí)就是通過(guò)pa中存放的地址,找到這個(gè)地址所存放的空間,這個(gè)時(shí)候取到的其實(shí)就是變量a,因?yàn)槿〉搅诉@個(gè)地址,這塊空間上所存放的起始就是a變量的內(nèi)容,我們通過(guò)運(yùn)行來(lái)看一下

小結(jié)

①指針其實(shí)就是地址,地址就是內(nèi)存單元的編號(hào) ②把地址進(jìn)行存儲(chǔ)的時(shí)候,就可以放到一個(gè)變量中,這個(gè)變量就是【指針變量】 ③我們說(shuō)的指針,實(shí)際上在專業(yè)術(shù)語(yǔ)中叫做【指針變量】 ④【*】星號(hào)解引用可以通過(guò)存放變量的地址快速訪問(wèn)到那個(gè)變量在內(nèi)存中所存放的位置,繼而獲取內(nèi)容

3、指針變量的大小

求一個(gè)變量的大小就是用sizeof()這個(gè)關(guān)鍵字

int a = 10;

printf("%d\n",sizeof(a));

printf("%d\n",sizeof(int));

上面這段代碼的打印就是4 4,那請(qǐng)問(wèn)下面這段呢?

int a = 10;

int* pa = &a;

printf("%d\n",sizeof(pa));

printf("%d\n",sizeof(int*));

很明顯,也是4 4

在編譯器的偏左上角,有一個(gè)x64和x86,這個(gè)東西叫做【運(yùn)行環(huán)境】,x64代表你在64位OS的環(huán)境下運(yùn)行代碼,x86代表的就是32位,剛才我選擇的是32位,現(xiàn)在我把它改成64位,

很明顯,一樣的代碼,但是在不同的運(yùn)行環(huán)境下所產(chǎn)生的值卻不同,

指針變量存放的就是地址,所以指針變量的大小取決于存儲(chǔ)一個(gè)地址需要多大的空間

要看到不是地址,其實(shí)是存儲(chǔ)的地址線,沒(méi)錯(cuò),就是硬件上的地址線

我們所用的電腦,其實(shí)就是硬件,是硬件的話就需要通電,那在我們的電腦上其實(shí)就存在著這么一種【地址線】,我們上面所說(shuō)的32位與64位,也可以對(duì)應(yīng)到這個(gè)地址線中,因?yàn)樵?2位的環(huán)境下,是32根地址線;64位環(huán)境下就是64根地址線當(dāng)我們是32根地址線時(shí),在通電之后就會(huì)有一個(gè)電信號(hào),這個(gè)電信號(hào)就是0/1,那這些電信號(hào)具體是怎樣的呢,我們來(lái)看一下

就是0101這樣的存儲(chǔ)方式,然后根據(jù)二進(jìn)制的逢二進(jìn)一去羅列出這32根地址線可以存儲(chǔ)下多少地址,這里告訴你,一共是有232個(gè)地址可以存儲(chǔ)那這其實(shí)就可以得出結(jié)論了,32個(gè)0或者1組成得的地址序列,需要32個(gè)bit,也就是4個(gè)byte去存放,而這4個(gè)字節(jié)也就對(duì)應(yīng)著我們指針變量的大小,因此就可以得出為什么指針變量的大小是4個(gè)字節(jié)了然后來(lái)解釋一下為什么在64位環(huán)境下這個(gè)指針變量就變成了8個(gè)字節(jié),這其實(shí)你自己也可以去推導(dǎo),32個(gè)0或1組成的地址序列需要32個(gè)比特位,那么這里便需要64個(gè)比特位,根據(jù)1B = 8bit,所以就需要8個(gè)byte去存放,這也可以得出在64位環(huán)境下指針變量的大小是8個(gè)字節(jié)

了解了上面這些,知道了指針變量的大小取決于地址的大小,下面我們來(lái)看看這些指針變量的大小是多少,我是在32位環(huán)境下運(yùn)行的

printf("%d\n", sizeof(short*));

printf("%d\n", sizeof(long*));

printf("%d\n", sizeof(long long*));

printf("%d\n", sizeof(float*));

printf("%d\n", sizeof(double*));

是1 4 8 4 8 嗎,如果是這個(gè)答案的話請(qǐng)你再回去仔細(xì)看一下上面的推導(dǎo)過(guò)程我們來(lái)看一下運(yùn)行結(jié)果

可以看到,均為4,它們都是指針變量,指針變量求它的大小看的是什么,看到就是地址的大小,上面說(shuō)了,我是在32位環(huán)境下運(yùn)行的,因此就是32根地址線,需要32個(gè)bit,也就是4個(gè)byte去存放 可以看到,報(bào)了很多Warning,這是為什么呢,明明這個(gè)代碼就是可以運(yùn)行的,而且還可以出結(jié)果這里報(bào)了一個(gè)【符號(hào)不匹配】的問(wèn)題,為什么呢?這里明確說(shuō)一下,sizeof()計(jì)算數(shù)據(jù)字節(jié)大小的時(shí)候默認(rèn)返回的類(lèi)型是unsigned int,也就是無(wú)符號(hào)整型,但%d是用來(lái)打印整型變量的,所以這里才會(huì)出現(xiàn)【符號(hào)不匹配】的問(wèn)題

應(yīng)該將其修改問(wèn)%zu去打印才對(duì),你只要記住它是專門(mén)用來(lái)打印sizeof()的返回值的就行了,不行深入了解也沒(méi)關(guān)系修改如下,可以看到,已經(jīng)一個(gè)Warning都沒(méi)有了

十五、結(jié)構(gòu)體

對(duì)于結(jié)構(gòu)體,也是C語(yǔ)言中比較重要的一個(gè)部分,因?yàn)镃語(yǔ)言是一門(mén)面向過(guò)程的語(yǔ)言,它不像C++、Java那樣面向?qū)ο?,具有?lèi),可以在類(lèi)內(nèi)定義成員變量和成員方法,所以C中就有了結(jié)構(gòu)體這一個(gè)東西,可以用來(lái)描述復(fù)雜對(duì)象

我們都去書(shū)店買(mǎi)過(guò)書(shū),知道書(shū)它有書(shū)名、出版社、作者,這些都可以定義為字符類(lèi)型,但是還有書(shū)的價(jià)格,怎么定義呢,難道也定義成字符類(lèi)型嗎,當(dāng)然不是,依舊是定義成浮點(diǎn)類(lèi)型,除了這些,其實(shí)還有很多種類(lèi)需要去定義但是對(duì)于這么多的類(lèi)型,都要分開(kāi)嗎,這肯定不行,這樣這本書(shū)就不是一個(gè)整體了,如果你有面向?qū)ο蟮乃季S就知道,它的屬性和行為都是定義在這一個(gè)類(lèi)中,都是封裝好的,這就是類(lèi)的封裝在C語(yǔ)言中,我們也可以實(shí)現(xiàn)封裝,那就是用結(jié)構(gòu)體

我們以學(xué)生類(lèi)型來(lái)做一個(gè)封裝

可以看到,我們使用到了struct這個(gè)關(guān)鍵字,這個(gè)就是在關(guān)鍵字那一模塊所屬要留在這里講解的關(guān)鍵字,stu就是student的簡(jiǎn)寫(xiě)??梢钥吹剑锩嬗兄N類(lèi)型,分別是姓名、年齡和成績(jī),因?yàn)橐粋€(gè)學(xué)生都具備這三種屬性,這是他們共同的屬性,所以可以將他們封裝在一起

struct stu {

char name[20]; //姓名

int age; //年齡

float score; //成績(jī)

};

那對(duì)于結(jié)構(gòu)體這種復(fù)合類(lèi)型怎么去定義變量進(jìn)行初始化呢,我們來(lái)看看其實(shí)和普通變量也是一樣的,你要把【struct stu】看做是一個(gè)類(lèi)型,用這個(gè)類(lèi)型定義出來(lái)的變量就叫做【結(jié)構(gòu)體變量】,對(duì)于每個(gè)結(jié)構(gòu)體變量的初始化,都需要使用一對(duì)大括號(hào){},里面去一一按照順序去初始化你在結(jié)構(gòu)體中定義的變量溫馨提示:這里的float成績(jī)類(lèi)型后面加上f與double類(lèi)型作為區(qū)分

struct stu s1 = { "zhangsan",20,80.5f };

struct stu s2 = { "lisi",25,90.5f };

那初始化了這些變量后如何將他們打印出來(lái)呢,也就訪問(wèn)到每一個(gè)同學(xué)的信息

這里就要使用到【.】點(diǎn)操作符,這個(gè)也是我們前面留下的,這個(gè)操作符可以去通過(guò)結(jié)構(gòu)體聲明出來(lái)的變量訪問(wèn)當(dāng)前這個(gè)變量所具有的信息,代碼如下:

//格式:結(jié)構(gòu)體變量.結(jié)構(gòu)體成員

printf("%s %d %f\n", s1.name, s1.age, s1.score);

printf("%s %d %f\n", s2.name, s2.age, s2.score);

好,初識(shí)C語(yǔ)言就到這里結(jié)束了!

柚子快報(bào)激活碼778899分享:1. C語(yǔ)言之初識(shí)C語(yǔ)言

http://yzkb.51969.com/

參考閱讀

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/13760208.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄