内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

C語(yǔ)言知識(shí)點(diǎn)匯總-創(chuàng)新互聯(lián)

C語(yǔ)言——只看這一篇就夠了!

C語(yǔ)言知識(shí)點(diǎn)保姆級(jí)總結(jié),這不得進(jìn)你的收藏夾吃灰?!
拖了很久的C語(yǔ)言所學(xué)知識(shí)的簡(jiǎn)單小結(jié),內(nèi)容有點(diǎn)多,第一次總結(jié)也可能有錯(cuò)誤或者不全面,歡迎隨時(shí)補(bǔ)充說明!

成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的武穴網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!數(shù)據(jù)類型

? 用不同數(shù)據(jù)類型所定義的變量所占空間大小不一樣,定義的變量不是保存于數(shù)據(jù)類型中,而是因?yàn)橹挥卸x了該數(shù)據(jù)類型的變量才能保存數(shù)據(jù)。

一、整型

? 1、整型(int) 四字節(jié),默認(rèn)有符號(hào)(-231-231-1),無(wú)符號(hào)加unsigned(0-232-1)(十位數(shù));

? 2、短整型(short int) ,兩字節(jié)(-215-215-1)(五位數(shù));

? 3、長(zhǎng)整型(long int) ,四字節(jié)(同int,在目前的操作系統(tǒng)中幾乎沒有區(qū)別);

? 4、長(zhǎng)長(zhǎng)整型(long long int), 八字節(jié)(-263-263-1),無(wú)符號(hào)(0-264-1);

二、浮點(diǎn)型

? 1、單精度浮點(diǎn)數(shù)(float),四字節(jié),保留小數(shù)點(diǎn)后6位

? 2、雙精度浮點(diǎn)數(shù)(double),八字節(jié),保留小數(shù)點(diǎn)后15位

int為一個(gè)32為的存儲(chǔ)單元,long long為64為的存儲(chǔ)單元

1 B/byte(字節(jié)) = 8 bit(比特)(位)

1 KB(千字節(jié)) = 1024 B/byte(字節(jié))

1 MB = 1024 KB

1 GB = 1024 MB

1TB =1024 GB

1 PB = 1024 TB

1 EB = 1024 PB

三、字符型

? char,用于儲(chǔ)存字符,和int很像,可用ASCII碼來(lái)儲(chǔ)存字符,
eg:

char grade=’A’;
 char grade=65;
'  '單引號(hào)為字符,eg:char a='a';

? " "雙引號(hào)為字符串,eg:char* a=“asd”;編譯器會(huì)自動(dòng)給字符串結(jié)尾添加’\0‘來(lái)作為字符結(jié)束標(biāo)識(shí),strlen函數(shù)中不統(tǒng)計(jì)\0,但是\0在內(nèi)存中占據(jù)空間。

? 除此之外,還有轉(zhuǎn)義字符,通過反斜杠來(lái)完成相關(guān)操作,如果要特殊字符轉(zhuǎn)字面字符需要另外添加反斜杠,轉(zhuǎn)義字符在字符串中占空間,但是只計(jì)算一個(gè)長(zhǎng)度,\0不計(jì)長(zhǎng)度。

?在這里插入圖片描述

四、變量和常量

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

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

在這里插入圖片描述

#includeint global = 2019;//全局變量
int main()
{
	int local = 2018;//局部變量
	return 0;
} 
分支及循環(huán)語(yǔ)句 一、分支語(yǔ)句

? 1、if語(yǔ)句

? 語(yǔ)法結(jié)構(gòu):

if(表達(dá)式)
語(yǔ)句;

if(表達(dá)式){
	語(yǔ)句列表1
}
else{
	語(yǔ)句列表2;
}

//多分支
if(表達(dá)式1){
	語(yǔ)句列表1;
}
else if(表達(dá)式2){
	語(yǔ)句列表2;
}
else{
	語(yǔ)句列表3;
}

? 表達(dá)式部分為真則執(zhí)行語(yǔ)句(0為假,非0為真),盡量在每個(gè)分支語(yǔ)句后都加{},否則只會(huì)執(zhí)行分支后第一條語(yǔ)句。

? else在沒有括號(hào)的情況下遵循就近原則所以在多重if語(yǔ)句嵌套使用情況下一定要加括號(hào)!

? 2、switch語(yǔ)句

? switch作為分支結(jié)構(gòu)常用于多分支的情況,可以簡(jiǎn)化多重if語(yǔ)句嵌套的情況。

? 語(yǔ)法結(jié)構(gòu)

switch(表達(dá)式A){
           case  常量表達(dá)式1:
                    語(yǔ)句1;
                    break;
           case  常量表達(dá)式2:
                    語(yǔ)句2;
                    break;
                    ……
           case  常量表達(dá)式n:
                    語(yǔ)句n;
                    break;
           default:
                    語(yǔ)句n+1; 
                     break;
}

? 其中

? 1、case后第一句不可定義變量,必須跟常量或者常量表達(dá)式,并且不可相同;

? 2、break在語(yǔ)句中可以起到劃分作用,不可省略,否則無(wú)法實(shí)現(xiàn)分支功能;

? 3、default語(yǔ)句不應(yīng)該省略,一般推薦位語(yǔ)句列表末尾;

? 4、switch語(yǔ)句結(jié)束條件:①遇到break;②執(zhí)行到語(yǔ)句列表末尾。

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

? 1、while語(yǔ)句

? 語(yǔ)法結(jié)構(gòu)

while(表達(dá)式){
	循環(huán)語(yǔ)句;
}

? 注:在循環(huán)語(yǔ)句中break的作用是停止后期所有循環(huán),continue的作用是終止本次循環(huán),開始下一次循環(huán)的判斷。

? 2、for語(yǔ)句

for(表達(dá)式1;表達(dá)式2;表達(dá)式3){
	循環(huán)語(yǔ)句;
}

? 表達(dá)式1為初始化部分,用于初始化循環(huán)變量,當(dāng)表達(dá)式1為空時(shí)直接進(jìn)入循環(huán);

? 表達(dá)式2 為條件判斷部分,用于判斷循環(huán)是否終止,當(dāng)表達(dá)式2為空時(shí)為死循環(huán);

? 表達(dá)式3為調(diào)整部分,用于循環(huán)條件的調(diào)整 。

? 注:建議使用“前閉后開”來(lái)限定區(qū)間范圍。

for(i=0; i<10; i++){
	a[i]=i;
}

? 3、do while語(yǔ)句

do{
	循環(huán)語(yǔ)句;
}while(表達(dá)式);

? 循環(huán)體至少執(zhí)行一次,while之后記得加分號(hào)。

? 二分查找函數(shù)循環(huán)實(shí)現(xiàn)范例:

int bin_search(int arr[], int left, int right, int key)
{
	int mid = 0;
	while(left<=right){
		mid = (left+right)>>1;
		if(arr[mid]>key)
		{
			right = mid-1;
		}
		else if(arr[mid]< key)
		{
			left = mid+1;
		}
		else
		{
			return mid;//找到了,返回下標(biāo)
		}
	}
	return -1;//找不到
}
函數(shù) 一、庫(kù)函數(shù)

? C語(yǔ)言基礎(chǔ)庫(kù)中的函數(shù),在添加頭文件后可直接調(diào)用。

二、自定義函數(shù) 1、函數(shù)組成

? 由函數(shù)名、返回值類型、函數(shù)參數(shù)以及函數(shù)體組成。

? 實(shí)參:真實(shí)的傳入函數(shù)的變量,**在被調(diào)用時(shí)會(huì)發(fā)生臨時(shí)拷貝,并非把原來(lái)的變量直接放入函數(shù)中,**只是把實(shí)參的數(shù)據(jù)拷貝給形參。

? 形參:函數(shù)名括號(hào)后的變量,因?yàn)樾螀⒅挥性诒徽{(diào)用的時(shí)候才被實(shí)例化并分配空間(形參實(shí)例化),**在被調(diào)用過后即被銷毀,只在該函數(shù)中有效(局部變量),**所以叫形參。

? 函數(shù)聲明,要滿足先聲明后使用的原則,由返回值類型、函數(shù)名與函數(shù)參數(shù)組成(需要加分號(hào)), 當(dāng)我們用到很多函數(shù)聲明的時(shí)候,為了方便我們的調(diào)用,我們可以創(chuàng)建一個(gè)頭文件.h(比如test.h),將函數(shù)聲明放在頭文件當(dāng)中 ,在寫頭文件時(shí),要注意加上#pragma once 。

//函數(shù)定義
double	Add(double x, double y){
	return x+y;
}
//函數(shù)聲明
double 	Add(double x, double y);
2、函數(shù)調(diào)用

? 分為傳值調(diào)用與傳址調(diào)用,其中傳址調(diào)用是把函數(shù)外部創(chuàng)建的內(nèi)存地址傳遞給函數(shù),可以真正與原值建立起聯(lián)系,直接操縱函數(shù)外部的變量。

? 函數(shù)也可以進(jìn)行嵌套調(diào)用以及鏈?zhǔn)皆L問。

? 嵌套調(diào)用樣例:

#includevoid new_line()
{
	printf("hehe\n");
}
void three_line()
{
	int i = 0;
	for(i=0; i<3; i++)
	{
		new_line();
	}
}
int main()
{
	three_line();
	return 0;
}

? 鏈?zhǔn)皆L問樣例:

#include#includeint main()
{
	char arr[20] = "hello";
	int ret = strlen(strcat(arr,"bit"));
	printf("%d\n", ret);
	return 0;
}
3、函數(shù)遞歸

? 程序自身調(diào)用被稱為遞歸,把復(fù)雜問題層層轉(zhuǎn)化為與原問題類似的小問題,函數(shù)在調(diào)用自身的情況下存在不合法遞歸(即無(wú)限次的遞歸導(dǎo)致棧溢出)。

? 所以在使用遞歸的時(shí)候一定要有遞歸出口,否則會(huì)陷入死循環(huán)導(dǎo)致棧溢出!

? **注:**棧結(jié)構(gòu)為電腦存儲(chǔ)的一部分,從高地址處向下開辟存儲(chǔ)空間,與用于開辟動(dòng)態(tài)存儲(chǔ)空間的堆相向開辟(堆為從低地址出向上開辟存儲(chǔ)空間),而函數(shù)調(diào)用將會(huì)形成棧幀,函數(shù)返回后自動(dòng)釋放棧幀結(jié)構(gòu),在此過程中,該函數(shù)定義的所有局部變量都在該函數(shù)的棧幀內(nèi)進(jìn)行空間開辟。

樣例:求n的階乘

int factorial(int n)
{
	if(n<= 1)
		return 1;
	else
		return n* factorial(n-1);
}

? 遞歸與迭代

? 遞歸在使用過程中由于頻繁進(jìn)行函數(shù)調(diào)用,且每次調(diào)用都需要時(shí)間成本以及空間成本,所以遞歸程序簡(jiǎn)單,但是可能導(dǎo)致遞歸效率變低的問題,而迭代方案通過對(duì)變量值進(jìn)行替換所以不會(huì)造成棧溢出,解決了效率低下的問題。

? 樣例(求斐波那契數(shù)列第n個(gè)的值):

//遞歸實(shí)現(xiàn)
int fibrec(int n){
	if(n<=2) retuen 1;
	else return fibrec(n-1)+fibrec(n-2);
}
//迭代實(shí)現(xiàn)
int fibite(int n){
	int fir=1,sec=1,thd=2;
	if(n<=2) return 1;
	else{
		while(n>2){
			fir=sec;
			sec=thd;
			thd=fir+sec;
			n--;
		}
		return thd;
	}
}
數(shù)組 一、一維數(shù)組的創(chuàng)建與初始化

? 創(chuàng)建數(shù)組時(shí)數(shù)組空間為整體開辟整體釋放,在內(nèi)存中是連續(xù)存放,在定義時(shí)就已經(jīng)確定數(shù)組大小(下標(biāo)不可為0),且不可被整體賦值。在數(shù)組的創(chuàng)建過程中,如果進(jìn)行了初始化則可不指定數(shù)組的大小,多維數(shù)組按照一維數(shù)組進(jìn)行理解。

? 數(shù)組傳參發(fā)生降維,降維成指向其(數(shù)組)內(nèi)部元素類型的指針。

? 數(shù)組名一般情況下都指的是首元素的地址,但如果sizeof()單獨(dú)出現(xiàn)以及&后跟數(shù)組名時(shí)表示的是整個(gè)數(shù)組

int s[5];
//表示數(shù)組首元素地址
printf("%d\n", sizeof(s+1));//結(jié)果為4/8,指針的具體大小根據(jù)編譯器的不同大小不同
//表示整個(gè)數(shù)組
printf("%d\n", sizeof(s));//結(jié)果為20
二、數(shù)組傳參(函數(shù))

? 由于在傳參過程中如果拷貝整個(gè)指針會(huì)導(dǎo)致效率大大降低甚至導(dǎo)致棧溢出,所以數(shù)組傳參要發(fā)降維問題,函數(shù)內(nèi)數(shù)組作為參數(shù)時(shí),實(shí)參為首元素地址,形參為指針。

? 在訪問結(jié)構(gòu)體成員時(shí)也同樣要發(fā)生類似的操作,用指向結(jié)構(gòu)體的指針來(lái)指代結(jié)構(gòu)體。

typedef struct node{
 int a;
 int b;
}point;

void pop(int* p){
	
}

int main(){
	point a;
	int* p=a;
	pop(p);
	return 0;
}

? 傳參樣例:

//用數(shù)組的形式傳遞參數(shù),不需要指定參數(shù)的大小,傳的只是數(shù)組首元素的地址。
void test(int arr[])
{}

//也可以傳入數(shù)組大小
void test(int arr[10])
{}

//數(shù)組降維,用指針進(jìn)行接收,傳的是數(shù)組首元素的地址
void test(int *arr)
{}

//二維數(shù)組傳參,第一個(gè)方括號(hào)可以空,但是第二個(gè)不可以空
void test(int arr[][5])
{}

void test(int arr[4][5])
{}

//傳過去的是二維數(shù)組的數(shù)組名,即數(shù)組首元素的地址,也就是第一行的地址,第一行也是個(gè)數(shù)組,用一個(gè)數(shù)組指針接收(比較少用)
void test(int (*arr)[5])
{}
三、字符數(shù)組
char a[]={'a','x','d'};
//此處由于結(jié)尾沒有'\0',strlen的機(jī)制是遇到'\0'即停止,所以在結(jié)尾沒有'\0'時(shí)為隨機(jī)數(shù)
//strlen(a)為隨機(jī)數(shù)
//sizeof(a)為3

char a[]={'a','x','d','\0'};
//strlen(a)為3
//sizeof(a)為4

char* a="axd";//或char a[]="axd"
//直接通過""定義字符串時(shí),會(huì)自動(dòng)在結(jié)尾補(bǔ)'\0',不需要自行補(bǔ)充,但'\0'依舊會(huì)占據(jù)一個(gè)字節(jié)
//strlen(a)為3
//sizeof(a)為4


char c[5]={'a', 'b', '\0', 'c', '\0'};
printf("%s", c);//結(jié)果為ab,因?yàn)樽址Y(jié)束標(biāo)志位'\0'
操作符 一、運(yùn)算優(yōu)先級(jí)

? 注:①++/–高于解引用;

? ②解引用高于±*/

? ③±*/高于位運(yùn)算;

? ④位運(yùn)算高于+=、-=、/=、*=;

%操作兩邊必須是整數(shù)。

二、二進(jìn)制中的操作符 1、位運(yùn)算基本介紹

與運(yùn)算:&

? 同1則1,否則為0;

或運(yùn)算:|

? 同0為0,否則為1

非運(yùn)算:~

? 1取0 0 取1

異或運(yùn)算:^

? 兩者相等為0,不等為1

移位運(yùn)算操作符:<< 左移 ; >>右移

? ①**<<左移:**左邊拋棄末尾補(bǔ)0;負(fù)數(shù)對(duì)反碼的補(bǔ)碼進(jìn)行移位操作;相當(dāng)于乘2;

? ②**>>右移:有符號(hào)的補(bǔ)符號(hào)位**,無(wú)符號(hào)的補(bǔ)0;相當(dāng)于除以2。

2、反碼與補(bǔ)碼

? **反碼:**正數(shù)的反碼為原碼本身,負(fù)數(shù)反碼符號(hào)位不變,剩余的數(shù)字位取反;

? **補(bǔ)碼:**正數(shù)的補(bǔ)碼為原碼本身,負(fù)數(shù)的補(bǔ)碼為反碼+1 。

三、隱式類型轉(zhuǎn)換

? 隱式類型轉(zhuǎn)換的原因:參與計(jì)算的數(shù)據(jù)如果類型不同無(wú)法直接進(jìn)行計(jì)算。

? 整型提升:有符號(hào)的補(bǔ)符號(hào)位,無(wú)符號(hào)的補(bǔ)0(符號(hào)位為最外面的那位)

? 樣例:

在這里插入圖片描述

? 例題,求循環(huán)次數(shù)

在這里插入圖片描述

? 解答:

? unsigned char 8位數(shù)據(jù)位,范圍在0-255,所以-2(11111110)時(shí),變成254;同理-1(11111111)時(shí),變成255;最后減到0時(shí),不滿足循環(huán)條件,for停止。剛好173次。 (7 4 1 ==>共(7-1)/3+1=3次,1-3=-2,即254,繼續(xù)循環(huán))
254 251 … 5 2 ==>共(254-2)/3+1=85次(2-3=-1,即255,繼續(xù)循環(huán))
255 252 … 6 3 ==>共(255-5)/3+1=85次(3-3=0,退出循環(huán)) 所以總共173次

指針

? 指針變量是個(gè)變量,指針本身是個(gè)地址,用于存放內(nèi)存單元的地址。

? 指針時(shí)用來(lái)存放地址的,指針類型的變量無(wú)論指向目標(biāo)是什么類型,指針本身在32位平臺(tái)所占大小都為4個(gè)字節(jié),在64位平臺(tái)是8個(gè)字節(jié) 。

#includeint main()
{
	int a = 10;//在內(nèi)存中開辟一塊空間,左值為空間,右值為內(nèi)容
	int *p = &a;//type* p
				//這里我們對(duì)變量a,取出它的地址,可以使用&操作符。
				//將a的地址存放在p變量中,p就是一個(gè)之指針變量。
	return 0;
}
一、指針的解引用

? 1、對(duì)指針的解引用只能看到sizeof(type)個(gè)字節(jié)的數(shù)據(jù);

? 2、按字節(jié)為單位,數(shù)據(jù)有高權(quán)值和低權(quán)值之分,地址有低地址和高地址之分;

? 3、數(shù)據(jù)低權(quán)值位在低地址處即為小端存儲(chǔ),反之則為大端存儲(chǔ)。
(“小小小”)

二、野指針 概念

? 指向的位置是不可知的指針。

規(guī)避

? 1、指針在定義時(shí)就進(jìn)行初始化;

? 2、避免指針越界(eg:注意循環(huán)時(shí)循環(huán)次數(shù)的限制);

? 3、指針使用完即進(jìn)行指針指向空間釋放;

? 4、避免返回局部變量的地址;

? 5、指針使用前檢查其有效性。

三、指針運(yùn)算

? 1、指針±整數(shù),等價(jià)于±sizeof(type);

? 2、指針-指針,兩指針必須同一類型,一般用于數(shù)組與字符串求其兩地址間相隔的單元格數(shù),否則無(wú)效(指針+指針為非法操作);

? 3、指針的關(guān)系運(yùn)算。

? 4、指針和數(shù)組都可以用中括號(hào)或者解引用(二者互通)。

四、字符指針 1、字符指針

在指針的類型中我們知道有一種指針類型為字符指針 char* ;

一般使用方法

int main()
{
	char ch = 'w';
	char *pc = &ch;
	*pc = 'w';
	return 0;
}

用char*指針指向字符串

int main()
{
	const char* pstr = "hello bit.";
	printf("%s\n", pstr);
	return 0;
}
//上述代碼中把字符串hello bit.的首地址放入了指針中

需注意字符串可以以字符數(shù)組的形式給出,但是此時(shí)的字符數(shù)組附有存儲(chǔ)功能,而字符指針具有常量屬性,指向的是常量區(qū)的內(nèi)容,因此不可被修改,可以寫作:

const char* str="hello world";//從上圖表示不可被修改

? 也正因?yàn)檫@個(gè)原因 C/C++會(huì)把常量字符串存儲(chǔ)到單獨(dú)的一個(gè)內(nèi)存區(qū)域,當(dāng)幾個(gè)指針指向同一個(gè)字符串的時(shí)候,他們實(shí)際會(huì)指向同一塊內(nèi)存。但是用相同的常量字符串去初始化不同的數(shù)組的時(shí)候就會(huì)開辟出不同的內(nèi)存塊。

#includeint main()
{
	char str1[] = "hello world.";
	char str2[] = "hello world.";
	const char *str3 = "hello world.";
	const char *str4 = "hello world.";
	if(str1 ==str2)
		printf("str1 and str2 are same\n");
	else
		printf("str1 and str2 are not same\n");
	if(str3 ==str4)
		printf("str3 and str4 are same\n");
	else
		printf("str3 and str4 are not same\n");
	return 0;
}

在這里插入圖片描述

2、const知識(shí)點(diǎn)

? 在此說一下const的一些知識(shí)點(diǎn):

? ① const修飾的變量不能被直接修改,但是可以通過指針在進(jìn)行類型強(qiáng)轉(zhuǎn)來(lái)修改(只是可以但是完全沒必要);

? ② const修飾指針,表示不可以通過指針來(lái)修改所指目標(biāo);

? ③ const能用則用,會(huì)很好的保護(hù)數(shù)據(jù),

? const的作用:

? ① 寫給編譯器看,提前發(fā)現(xiàn)可能錯(cuò)誤的修改;

? ② 寫給程序員看,提示該變量不建議修改。

const int* p=&a;
*p = 20; //錯(cuò)誤,*p所指的值不可以修改
p = &n;//正確,*p的指向可以修改

int* const q = &m;
*q = 20;//正確,此時(shí)const修飾的是q,此時(shí)q所指向的值可以進(jìn)行修改
q = &t;//錯(cuò)誤,由于const修飾的是q,此時(shí)的q的指向不可以進(jìn)行修改

const int a=10; //若const a=10,編譯器也會(huì)默認(rèn)為a是int類型的
int *P=(int*)&a; //注意需要強(qiáng)制&a前需要加int*類型強(qiáng)制類型轉(zhuǎn)換(&a的原本類型為const int*)
*P=12;
五、指針數(shù)組

指針數(shù)組本質(zhì)上是數(shù)組,該類數(shù)組內(nèi)存放的的元素是指針。

int* arr1[10]; //整形指針的數(shù)組
char *arr2[4]; //一級(jí)字符指針的數(shù)組
char **arr3[5];//二級(jí)字符指針的數(shù)組
六、數(shù)組指針 1、數(shù)組指針定義

指針數(shù)組本質(zhì)上是指針,該類指針指向的是一個(gè)數(shù)組。

example:

int (*p)[10];
//解釋:p先和*結(jié)合,說明p是一個(gè)指針變量,然后指著指向的是一個(gè)大小為10個(gè)整型的數(shù)組。所以p是一個(gè)
指針,指向一個(gè)數(shù)組,叫數(shù)組指針
2、數(shù)組指針&數(shù)組

首先需要看的是數(shù)組名與&數(shù)組名(可以等價(jià)于數(shù)組指針)之間的關(guān)系

#includeint main()
{
	int arr[10] = { 0 };
	printf("arr = %p\n", arr);
	printf("&arr= %p\n", &arr);
	printf("arr+1 = %p\n", arr+1);
	printf("&arr+1= %p\n", &arr+1);
	return 0;
}

在這里插入圖片描述

根據(jù)上面的代碼我們發(fā)現(xiàn),其實(shí)&arr和arr,雖然值是一樣的,但是意義應(yīng)該不一樣的。實(shí)際上: &arr 表示的是數(shù)組的地址,而不是數(shù)組首元素的地址。(細(xì)細(xì)體會(huì)一下)本例中 &arr 的類型是: int(*)[10] ,是一種數(shù)組指針類型數(shù)組的地址+1,跳過整個(gè)數(shù)組的大小,所以 &arr+1 相對(duì)于 &arr 的差值是40

七、數(shù)組傳參,指針傳參 1、一維數(shù)組傳參

數(shù)組傳參會(huì)發(fā)生降維,最終傳入的是首元素的地址(指針),并利用此來(lái)訪問數(shù)組內(nèi)其他元素。

#includevoid test(int arr[])//ok
{}
void test(int arr[10])//ok
{}
void test(int *arr)//ok
{}
void test2(int *arr[20])//不ok
{}
void test2(int **arr)//不ok
{}
int main()
{
	int arr[10] = {0};
	int *arr2[20] = {0};
	test(arr);
	test2(arr2);
}
2、二維數(shù)組傳參

二維數(shù)組傳參,函數(shù)形參的設(shè)計(jì)只能省略第一個(gè)[]的數(shù)字。
因?yàn)閷?duì)一個(gè)二維數(shù)組,可以不知道有多少行,但是必須知道一行多少元素。

void test(int arr[3][5])//ok
{}
void test(int arr[][])//不ok
{}
void test(int arr[][5])//ok
{}
void test(int *arr)//不ok
{}
void test(int (*arr)[5])//ok
{}
void test(int* arr[5])//不ok
{}
void test(int **arr)//ok
{}
int main()
{
	int arr[3][5] = {0};
	test(arr);
}
3、一級(jí)指針傳參

需要傳入一個(gè)地址

#includevoid print(int *p, int size)
{
	int i = 0;
	for(i=0; i
4、二級(jí)指針傳參
#includevoid test(int** ptr)
{
	printf("num = %d\n", **ptr);
}
int main()
{
	int n = 10;
	int*p = &n;
	int **pp = &p;
	test(pp);
	test(&p);
	return 0;
}
八、函數(shù)指針

1、函數(shù)指針定義

? 函數(shù)指針是指指向函數(shù)而非指向?qū)ο蟮闹羔槨O衿渌羔樢粯?,函?shù)指針也指向某個(gè)特定的類型(特定的函數(shù)類型)。函數(shù)類型由其返回類型以及形參表確定,而與函數(shù)名無(wú)關(guān) 。

? 代碼在電腦中同樣占據(jù)內(nèi)存空間,所以具有存儲(chǔ)地址,而代碼部分在電腦中也是不可被修改的類似字符串常量。

? 在函數(shù)中,函數(shù)名單獨(dú)時(shí)即為函數(shù)的地址(eg:main=&main),所以在用指針調(diào)用函數(shù)時(shí),可以直接用指針調(diào)用不需要加*

Type (*pFunc)(datatype args);

    //pFunc為函數(shù)指針,Type為數(shù)據(jù)類型,參數(shù)(datatype args)可以有多個(gè),也可以沒有。

使用示例

bool max(int a, int b)
{
	if (a>b)
	{
		return a;
	}else{
		return b;
	}
}
 
void Test()
{
	bool (*pFunc)(int, double);
	pFunc = max;
	cout<< max(5, 10)<< endl;
}
九、函數(shù)指針數(shù)組

指針指向一個(gè)數(shù)組 ,數(shù)組的元素都是函數(shù)指針

使用方法: 把幾個(gè)相同類型的函數(shù)地址放到一個(gè)數(shù)組中,這個(gè)數(shù)組就是函數(shù)指針的數(shù)組。

十、回調(diào)函數(shù)

解釋:調(diào)用庫(kù)中函數(shù),但是庫(kù)中函數(shù)需要編寫程序時(shí)編寫一個(gè)調(diào)用函數(shù),該庫(kù)中的函數(shù)為回調(diào)函數(shù)。也就是說一個(gè)通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說這是回調(diào)函數(shù)。

? 回調(diào)函數(shù)必須在中間函數(shù)以及回調(diào)函數(shù)同時(shí)具備時(shí)才可以實(shí)現(xiàn)。

作者:no.body
鏈接:https://www.zhihu.com/question/19801131/answer/27459821
來(lái)源:知乎
//大佬在這個(gè)帖子里對(duì)于概念解釋的很好,可以做參考!

回調(diào)函數(shù)就是回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。

結(jié)構(gòu)體 1、基本定義

? **注:**①結(jié)構(gòu)體不可以自引用!但可以在結(jié)構(gòu)體內(nèi)定義該結(jié)構(gòu)體類型的指針!

? ②定義結(jié)構(gòu)體本質(zhì)是新增一種類型;

? ③結(jié)構(gòu)體傳參要傳結(jié)構(gòu)體地址(指針),以此提高效率。

struct node1{
	int  a;
	int  b;
};

typedef struct node2 {
	int c;
	int d;
}node2;//通過typedef為結(jié)構(gòu)體變量定義一個(gè)別名node2,在以后使用中可以使用別名以此提高編寫效率

int main(){
	struct node1 s;//用結(jié)構(gòu)體定義變量
	node2  q;//用別名定義變量
}

? **注:**結(jié)構(gòu)體不可以自引用!但可以在結(jié)構(gòu)體內(nèi)定義該結(jié)構(gòu)體類型的指針!

struct Node
{
	int data;
	struct Node next;
};//錯(cuò)誤

struct Node
{
	int data;
	struct Node* next;
};//正確

typedef struct Node
{
	int data;
	struct Node* next;
}Node;//正確
2、結(jié)構(gòu)體變量的定義和初始化
struct Point1
{
	int x;
	int y;
}p1; //聲明類型的同時(shí)定義變量p1
struct Point p2; //定義結(jié)構(gòu)體變量p2

typedef struct Point2
{
	int x;
	int y;
}p;
p p1;
p p2;

在定義結(jié)構(gòu)體變量時(shí),可以在初始化的部分定義其內(nèi)容,也可以在之后定義。

typedef struct Point2
{
	int x;
	int y;
}p;
p p1;
p1.x=1;
p1.y=2;//可以直接用結(jié)構(gòu)體類型的變量進(jìn)行定義

typedef struct Point2
{
	int x;
	int y;
}p;
p* p2=(p*)malloc(sizeof(p));
p2->x=1;
p2->y=2;//定義一個(gè)指向結(jié)構(gòu)體的指針并為其分配空間即可進(jìn)行定義
3、結(jié)構(gòu)體的內(nèi)存對(duì)齊(結(jié)構(gòu)體的占用大小的計(jì)算)

結(jié)構(gòu)體內(nèi)存空間占用的大小并不是單純的元素相加,而是通過浪費(fèi)一定量的空間來(lái)?yè)Q取目標(biāo)數(shù)據(jù)讀取速度的加快

計(jì)算方式:

① 第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處。

② 其他成員變量要對(duì)齊到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處。

? (起始偏移量要能整除該成員的對(duì)齊數(shù))

對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù) 與 該成員大小的較小值。

? VS中默認(rèn)的值為8

③ 結(jié)構(gòu)體總大小為大對(duì)齊數(shù)(每個(gè)成員變量都有一個(gè)對(duì)齊數(shù))的整數(shù)倍。

④ 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的大對(duì)齊數(shù)的整數(shù)倍處(即結(jié)構(gòu)體大?。Y(jié)構(gòu)體的整

體大小就是所有大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍。

樣例:

struct S1
{
    char a;
    int b;
    char C;
};
printf("%d\n", sizeof(struct S1));

char 為1個(gè)字節(jié), int 為4個(gè)字節(jié);
char a 從0偏移開始,占用一個(gè)字節(jié);偏移量為1,接下來(lái)存放 int b,偏移量1不是對(duì)齊數(shù)4 的整數(shù)倍,所以向后繼續(xù)偏移一直到4,4是對(duì)齊數(shù)4的整數(shù)倍,所以將int b存放在偏移地址為4處,占用4個(gè)字節(jié);偏移量變?yōu)?,存放 char c ,占一個(gè)字節(jié),偏移量9不是大對(duì)齊數(shù)4的整數(shù)倍,所以向后繼續(xù)偏移直到偏移處為12的地方。

圖示如下:

在這里插入圖片描述

自主設(shè)置默認(rèn)對(duì)齊數(shù)

#pragma pack(a)//通過該指令可設(shè)置默認(rèn)對(duì)齊數(shù)為a
位斷

位段的聲明和結(jié)構(gòu)是類似的,有兩個(gè)不同:
1.位段的成員必須是 int、unsigned int 、signed int或者char(同屬于整型家族);
2.位段的成員名后邊有一個(gè)冒號(hào)和一個(gè)數(shù)字。

struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
};

注: ① 位段的成員可以是 int unsigned int signed int 或者是 char (屬于整形家族)類型;

② 位段的空間上是按照需要以4個(gè)字節(jié)( int )或者1個(gè)字節(jié)( char )的方式來(lái)開辟的;

③ 位段涉及很多不確定因素,位段是不跨平臺(tái)的,注重可移植的程序應(yīng)該避免使用位段;

④位斷不需要考慮內(nèi)存對(duì)齊問題所以較為節(jié)省空間。

總而言之, 跟結(jié)構(gòu)相比,位段可以達(dá)到同樣的效果,但是可以很好的節(jié)省空間,但是有跨平臺(tái)的問題存在。

枚舉

即一一列舉

enum Day//星期
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun   //最后一個(gè)不加逗號(hào)
};
enum Sex//性別
{
	MALE,
	FEMALE,
	SECRET
};

與宏定義相比枚舉的優(yōu)點(diǎn):
① 增加代碼的可讀性和可維護(hù)性;
② 和#define定義的標(biāo)識(shí)符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn);
③ 防止了命名污染(封裝);
④ 便于調(diào)試;
⑤ 使用方便,一次可以定義多個(gè)常量 。

聯(lián)合體

聯(lián)合也是一種特殊的自定義類型
這種類型定義的變量也包含一系列的成員,特征是這些成員公用同一塊空間(所以聯(lián)合也叫共用體), 聯(lián)合的成員是共用同一塊內(nèi)存空間的,這樣一個(gè)聯(lián)合變量的大小,至少是大成員的大小(因?yàn)槁?lián)合至少得有能力保存大的那個(gè)成員)。

//聯(lián)合類型的聲明
union Un
{
	char c;
	int i;
};
//聯(lián)合變量的定義
union Un un;

**注:**聯(lián)合體需要考慮內(nèi)存對(duì)齊,要求為大內(nèi)存數(shù)的整數(shù)倍。

動(dòng)態(tài)內(nèi)存管理

? 程序開始運(yùn)行后在堆上開辟大量空間(數(shù)組之類的空間開辟在棧上進(jìn)行),而在堆上開辟的空間使用完畢后需要在使用完成后由free函數(shù)進(jìn)行釋放,然后令指向該空間的指針指空,如果只申請(qǐng)不釋放會(huì)造成內(nèi)存泄漏問題。

動(dòng)態(tài)申請(qǐng)空間主要涉及三個(gè)函數(shù):malloc函數(shù),calloc函數(shù),relloc函數(shù)。

void* malloc (size_t size);

? 只申請(qǐng)空間,不對(duì)空間進(jìn)行初始化,傳入的參數(shù)size為要開辟的空間大小;

void* calloc (size_t num, size_t size);

? 申請(qǐng)空間,與malloc唯一的不同之處在于calloc會(huì)初始化為0,傳入的參數(shù)size為單個(gè)空間的大小,參數(shù)a為所需要的單個(gè)空間的數(shù)量;

void* realloc (void* ptr, size_t size);

將分配size個(gè)大小的空間,然后在調(diào)整原內(nèi)存空間大小的基礎(chǔ)上,將原來(lái)內(nèi)存中的數(shù)據(jù)移動(dòng)到新的空間,返回值為調(diào)整之后的內(nèi)存起始位置。

由于realloc可能會(huì)申請(qǐng)失敗返回NULL所以不建議直接用原指針接收返回地址,正確使用方法為:

int* ptr = (int*)malloc(100);
int* p = NULL;
p = realloc(ptr, 1000);
if (p = !NULL) {
	ptr = p;
}

內(nèi)存釋放操作

int* p=(int*)malloc(100);
......
free(p);
p = NULL;
柔性數(shù)組 1、定義

? 在結(jié)構(gòu)體內(nèi)大小為0(a[0])或空(a[])的數(shù)組(必須為結(jié)構(gòu)體內(nèi)最后一個(gè)元素且不能是唯一元素)

這樣可以在結(jié)構(gòu)體內(nèi)具有一個(gè)變長(zhǎng)數(shù)組包含柔性數(shù)組成員的結(jié)構(gòu)用malloc ()函數(shù)進(jìn)行內(nèi)存的動(dòng)態(tài)分配,并且分配

的內(nèi)存應(yīng)該大于結(jié)構(gòu)的大小,以適應(yīng)柔性數(shù)組的預(yù)期大小 ,sizeof 返回的這種結(jié)構(gòu)大小不包括柔性數(shù)組的內(nèi)存 。

2、使用方法
typedef struct st_type
{
	int i;
	int a[0];//柔性數(shù)組成員
}type_a;
printf("%d\n", sizeof(type_a));//輸出的是4
//初始化
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
p->i = 100;
for(i=0; i<100; i++)
{
	p->a[i] = i;
}
free(p);

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

新聞標(biāo)題:C語(yǔ)言知識(shí)點(diǎn)匯總-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)鏈接:http://www.rwnh.cn/article36/csjppg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、網(wǎng)站制作、動(dòng)態(tài)網(wǎng)站、網(wǎng)站排名、網(wǎng)站建設(shè)、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

石泉县| 青铜峡市| 鄂温| 临潭县| 云梦县| 上高县| 陆丰市| 汪清县| 句容市| 徐水县| 敦煌市| 方山县| 天气| 称多县| 同仁县| 乌兰县| 呼和浩特市| 泾源县| 南岸区| 龙陵县| 遂平县| 临武县| 攀枝花市| 溧水县| 通州市| 乐亭县| 开封市| 炉霍县| 扬中市| 宜君县| 淄博市| 临泉县| 东乌珠穆沁旗| 绵竹市| 龙岩市| 凤庆县| 射阳县| 中卫市| 慈溪市| 大丰市| 六盘水市|