溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在C語言中正確的使用指針

發(fā)布時間:2021-04-09 15:39:11 來源:億速云 閱讀:231 作者:Leah 欄目:編程語言

如何在C語言中正確的使用指針?相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

指針是什么? 

      指針本身是一個變量,它存儲的是數(shù)據(jù)在內(nèi)存中的地址而不是數(shù)據(jù)本身的值。

定義如下:

 int a=10,*p;  
 p=&a
 int a=10;
 int *p=&a;

       首先我們可以理解 int* 這個是要定義一個指針p,然后因為這個指針存儲的是地址所以要對a取地址(&)將值賦給指針p,也就是說這個指針p指向a。

      很多新手都會對這兩種定義方法感到迷惑,其實他倆的意思是一樣的。第一種定義方法定義了int型的變量a和指針p,然后將a的地址賦給p。第二種是在定義指針p的同時將a的地址賦給指針p。我們姑且理解為" int * "是定義指針的標(biāo)志。

指針有什么用?

   這樣我們就可以通過*p來找到指針?biāo)赶虻淖兞縜的地址,然后對地址中的值(值是10)進行操作。

//接著上面的代碼

printf("%p",p)   //結(jié)果是一個地址(p指向的變量a的地址)。
printf("%d",*p)  //結(jié)果是10,變量a的值。
printf("%d",&p)  //結(jié)果是一個地址(指針p的地址,因為指針也是一個變量自己也有地址的)

數(shù)組名和指針的區(qū)別?

  數(shù)組名是一個地址,它可以被理解為一個常指針(它只能指向本數(shù)組首元素的地址)。而指針可以指其他的變量等等。

int str[5]={1,2,3,4,5};
int *p=str;
printf("%d",*p);  //輸出為1,數(shù)組的首元素。
printf("%d",*str); //輸出為1,數(shù)組的首元素。
printf("%d",str[0]); //輸出為1,數(shù)組的首元素。
printf("%p",p); //輸出為地址,數(shù)組的地址。
printf("%p",str); //輸出為地址,數(shù)組的地址。
printf("%d",*(p+1)); //輸出為2,數(shù)組的第二個元素。
printf("%d",*(srt+1)); //輸出為2,數(shù)組的第二個元素。

對照代碼大家可以很清晰的看到數(shù)組名在對內(nèi)存中存儲的數(shù)據(jù)進行操作的方法和結(jié)果是一樣,但是數(shù)組名存儲自己數(shù)組本身的首地址。

什么是空指針,野指針?

      在函數(shù)內(nèi)部對指針進行賦值操作后,在函數(shù)執(zhí)行完畢后,該指針就成了一個空指針(變量從棧中彈出)。但是通過動態(tài)地址分配(堆空間)的指針不會有上述問題。

        free(p)后釋放內(nèi)存的指針為野指針。

關(guān)于const對于指針的限制問題

int a=10,b=20;
int * const p=&a;  //無法使p指向其他地址。
p=&b;          //這樣的操作是不允許的。
*p=20;          //可以這樣操作。

const int * p=&a;   //p可以指向其他地址。
p=&b;           //可以操作。
*p=10;           //操作不被允許。

const int * const p=&a  //p不能指向其他地址,也不能改變地址中的值。
p=&b;           //操作不被允許。
*p=20;           //操作不被允許。

       const在int的左邊那就是不能修改地址中的值,在右邊就是不能指向其他地址,左右都有那就是既不能修改地址的值也不能指向其他地址。 

       新手常出現(xiàn)的問題我個人總結(jié)了上述幾點,如果有錯誤的地方希望大家留言交流互相學(xué)習(xí)。后面會寫下多維數(shù)組的存儲方式和指針的問題。

下面簡單介紹下c語言指針的幾種用法。

1、指針指向變量:
下面有這樣一個代碼塊:

int main()
{int a=10;int b=15;test(a,b);printf("a=%d,b=%d\n",a,b);}
void test(int x,int y)
{int tmp;tmp=x;x=y;y=tmp;}

最后輸出的結(jié)果還是a=10,b=15。因為在函數(shù)調(diào)用時,實參和形參之間只是值傳遞。但我們使用指針結(jié)果就不一樣了,如:

int main()
{int a=10;int b=15;test(&a,&b);printf("a=%d,b=%d\n",a,b);return 0;}
void test(int * x,int *y)
{int tmp;tmp=*x;*x=*y;*y=tmp;}

輸出結(jié)果a=15,b=10。變量a和b的值發(fā)生了交換。這是因為我們利用指針訪問變量的存儲單元,間接修改變量的值。

2、指針指向數(shù)組:

定義一個數(shù)組并初始化,int array[5]={2,5,12,7,8},定義一個指針變量并把數(shù)組的地址賦給它,int *p=array,注意數(shù)組名就是數(shù)組的地址,而且數(shù)組的地址就是首元素的地址。因此我們的指針變量就指向了數(shù)組的首元素,*p=2。如果把(p+1),那么指針變量就指向了數(shù)組的下一個元素5,因此我們可以利用指針來遍歷數(shù)組的各個元素:

int main()
{int array[5]={2,5,12,7,8};int *p =array;for(int i=0;i<5;i++){printf("array[%d]=%d\n",i,*(p+i));}return 0;}

3、指針指向字符串:

我們都知道用數(shù)組存儲字符串,如char name[20]="jack",上面已經(jīng)簡單講述了指針指向數(shù)組,所以我們可以這樣做,char *name="jack",指針變量指向字符串的首個字符并可以依次訪問字符串的各個字符。

4,指針指向函數(shù):

我們需要知道怎樣表示一個指針指向函數(shù),說白了就是語法要正確,下面我也取一個代碼塊來說明一下:

int sum(int x,int y)
{return x+y;}
int main()
{int a=5;int b=6;int (*p)(int,int);p=sum;int result=(*p)(a,b);printf("The result is %d\n",result);return 0;}

不難發(fā)現(xiàn)上面代碼塊里語句(*p)(a,b)可以用p(a,b)來代替,因為p和sum就是一樣的,只是用前者可能更容易理解一點。而我們要知道怎樣定義一個指針指向函數(shù),int (*p)(int,int)這是固定寫法,前面的int是指針將來指向的函數(shù)的返回值的類型,如果沒有函數(shù)返回值,那就是void,后面括號里的兩個int 當(dāng)然就是指針將指向的函數(shù)的形參。指針指向函數(shù)用起來確實有點抽象,要想熟練運用的話就多去做一些這方面的練習(xí)吧!

5,指針指向結(jié)構(gòu)體:

我們首先首先定義一個結(jié)構(gòu)類型,

struct student
{
   char *name;
   int ages;
};

再根據(jù)類型定義結(jié)構(gòu)體變量 struct student stu={"Rose",15};定義一個指針指向結(jié)構(gòu)體類型,struct student *p;把結(jié)構(gòu)體變量stu的地址賦給指針變量p,p=&stu;我們可以有3種方式來訪問結(jié)構(gòu)體中的屬性ages:

stu.ages=15;(*p).ages=15;p->ages=15;不過第三種方式在C語言中只能用來指向結(jié)構(gòu)體。

看完上述內(nèi)容,你們掌握如何在C語言中正確的使用指針的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI