欧美黑人XXXX高潮猛交,在线欧美国产精品,欧美日韩精品久久,亚洲电影一区二区三区

淺談C語(yǔ)言中的指針

欄目:技術(shù)專題 發(fā)布時(shí)間:2025-01-02
作者:翁財(cái)喜

                                             翁財(cái)喜

 

一、指針描述

很多人都說(shuō)指針是C語(yǔ)言的精髓,那什么是指針其實(shí)本質(zhì)上來(lái)講,指針就是地址,指針變量的值也就是地址的值。要搞清一個(gè)指針需要搞清指針的四方面的內(nèi)容:指針的類型、指針?biāo)赶虻念愋汀⒅羔樀闹?、指針本身所占?jù)的內(nèi)存區(qū)。

例如定義一個(gè)int *p,指針的類型是int*,指針?biāo)赶虻念愋褪莍nt,指針的值就是它所指向的內(nèi)存區(qū)或者說(shuō)地址。指針本身占據(jù)的內(nèi)存區(qū),在32位的平臺(tái)是占據(jù)了4個(gè)字節(jié),或者使用sizeof(指針的類型)就能知道大小。

二、指針的運(yùn)算符

指針的運(yùn)算需要知道兩個(gè)運(yùn)算符:&是取地址運(yùn)算符,*是間接運(yùn)算符。

例如:int a=1;  int *p;//定義一個(gè)變量a值為1,定義一個(gè)指針變量p

p=&a; //使p指向了a所在的地址

*p=2; //操作指針變量p賦值為2,這邊其實(shí)也是相當(dāng)于把a(bǔ)的值重新賦值為2

三、指針和數(shù)組的關(guān)系

舉例1:

int value;//定義一個(gè)變量

int a[20]={0};//定義一個(gè)大小為20的數(shù)組

int *p=a;//定義一個(gè)指針p指向數(shù)組a的首地址

value=*p;//這邊其實(shí)就是等于value=a[0]

value=*(p+3);//這邊其實(shí)就是等于value=a[3]

for(i=0;i<20;i++)

{

    (*p)++;//將指針指向的數(shù)組地址的值加1

    p++;//移動(dòng)指針的地址,就是將指針指向下一個(gè)數(shù)組單元地址

}

以上代碼實(shí)現(xiàn)將20個(gè)數(shù)組單元的值由0變成1,正常而言數(shù)組名a代表數(shù)組本身,類型是int[20]。但是如果將a看作為指針的話,他的類型是int*,是指向數(shù)組第0個(gè)單元的地址,也就是首地址。注意該指針是不能進(jìn)行修改的,也就是像a++這種操作是不行的。

舉例2:

char *p[2]={

    "Hello",

"BTZZ",

};//定義指針數(shù)組,里面存儲(chǔ)2個(gè)字符串

int (*pt)[10];//指向數(shù)組的指針,也就是行指針

p是一個(gè)三單元的數(shù)組,該數(shù)組的每個(gè)單元都是一個(gè)指針,這些指針各指向一個(gè)字符串。把指針數(shù)組名p當(dāng)作一個(gè)指針的話,它指向數(shù)組的第0號(hào)單元,它的類型是char **,它指向的類型是char *。

*p也是一個(gè)指針,它的類型是char *,它所指向的類型是char,它指向的地址是字符串"Hello!"的第一個(gè)字符的地址,即'H'的地址。注意:字符串相當(dāng)于是一個(gè)數(shù)組,在內(nèi)存中以數(shù)組的形式儲(chǔ)存,只不過(guò)字符串是一個(gè)數(shù)組常量,內(nèi)容不可改變,且只能是右值。如果看成指針的話,他即是常量指針,也是指針常量。

p+1也是一個(gè)指針,它指向數(shù)組的第1號(hào)單元,它的類型是char**,它指向的類型是char*。*(p+1)也是一個(gè)指針,它的類型是char*,它所指向的類型是char,它指向"BTZZ"的第一個(gè)字符’B’。

四、指針和結(jié)構(gòu)類型的關(guān)系

舉例:

struct MyStruct

{

    int a;

    int b;

    int c;

};

struct MyStruct ss={20,30,40}; //聲明了結(jié)構(gòu)對(duì)象ss,并把ss 的成員初始化為2030和40。

struct MyStruct *ptr=&ss; //聲明了一個(gè)指向結(jié)構(gòu)對(duì)象ss的指針,它的類型是 MyStruct *,它指向的類型是MyStruct。

這邊會(huì)用到一個(gè)指向運(yùn)算符->,指針ptr通過(guò)使用指向運(yùn)算符來(lái)對(duì)結(jié)構(gòu)體成員進(jìn)行訪問(wèn),例如:ptr->a;ptr->b;ptr->b。

五、指針和函數(shù)的關(guān)系

舉例1:

void fun(int *a, int *b)//使用*接收地址

{

int temp;

temp = *a;

*a = *b;

*b =temp;

}

void main(void)

{

int a =10, b = 20;

fun2(&a, &b); //將ab的地址作為參數(shù)傳過(guò)去

}

以上代碼實(shí)現(xiàn)a和b值互換,函數(shù)fun將形參保存的地址內(nèi)容進(jìn)行ab值互換操作,那么實(shí)參的值也會(huì)進(jìn)行改變。

舉例2:

void fun(char **p) //要使用**進(jìn)行接收

{

*p = "BTZZ";

 }

void main(void )

{

char *p = "hello";

fun(&p);    //傳實(shí)參地址

}

以上代碼將指針p指向了字符串BTZZ,因?yàn)閭鬟f的實(shí)參是一個(gè)一級(jí)指針,所以地址傳參的時(shí)候需要形參是一個(gè)二級(jí)指針,也就是使用**來(lái)進(jìn)行接收。

舉例3:

int add(int x, int y)

{

return x + y;

}

int process(int (*p)(int, int), int a, int b)//回調(diào)函數(shù),使用函數(shù)指針p指向add函數(shù)

{

int c;

c= (*p)(a, b); //調(diào)用add函數(shù)

return c;

}

void main(void)

{

int num;

num = process(add, 2 ,3); //將add函數(shù)作為參數(shù)傳遞給另一個(gè)函數(shù)

}

以上代碼實(shí)現(xiàn)num等于5,add函數(shù)是已經(jīng)事先封裝好的函數(shù),但是函數(shù)的2個(gè)參數(shù)沒(méi)有先知道所以,這種時(shí)候可以采用回調(diào)函數(shù)。

六、其他

1、int *f(void)和int (*f)(void)的區(qū)別

*f沒(méi)加括號(hào)本質(zhì)是一個(gè)函數(shù),返回值是一個(gè)int*的類型。加括號(hào)主要為了保存函數(shù)的首地址,通過(guò)函數(shù)指針變量來(lái)替換函數(shù)名的使用。

2、空類型指針(void *)

void * 通用指針,任何類型的指針都可以給void*類型的指針變量賦值,主要也是用在函數(shù)的參數(shù)和返回值的位置。

3、野指針

例如int *p;*p=10; 這種情況就屬于野指針,是有問(wèn)題的因?yàn)橹羔樧兞坑殖跏蓟?,所以指針?biāo)赶虻牡刂肥请S機(jī)的值,解引用的時(shí)候也會(huì)造成訪問(wèn)了一個(gè)不確定的值。

4、越界訪問(wèn)

指針指向的空間不合理,比如一個(gè)10個(gè)元素整型的數(shù)組,指針指向了第11個(gè)單元,那么第十一個(gè)元素的值就是隨機(jī)值了。

5、動(dòng)態(tài)內(nèi)存分配

使用 malloc、calloc 和 realloc 等函數(shù)進(jìn)行動(dòng)態(tài)內(nèi)存分配時(shí),需要確保在不再需要內(nèi)存時(shí)使用 free 函數(shù)釋放它,否則會(huì)導(dǎo)致內(nèi)存泄漏。