• <output id="aynwq"><form id="aynwq"><code id="aynwq"></code></form></output>

    <mark id="aynwq"><option id="aynwq"></option></mark>
  • <mark id="aynwq"><option id="aynwq"></option></mark><label id="aynwq"><dl id="aynwq"></dl></label>
  • 學(xué)習(xí)啦 > 知識大全 > 知識百科 > 百科知識 > c語言中的指針是什么

    c語言中的指針是什么

    時間: 思行858 分享

    c語言中的指針是什么

      很多學(xué)習(xí)C語言的新手來說,指針無疑是一個難點(diǎn)。但是,我覺得指針也是C語言特別重要的一個特性。那么下面一起來看看學(xué)習(xí)啦小編為大家精心推薦的c語言中的指針是什么,希望能夠?qū)δ兴鶐椭?/p>

      為什么說指針是 C 語言的精髓?

      “指”是什么意思?其實(shí)完全可以理解為指示的意思。比如,有一個物體,我們稱之為A。正是這個物體,有了這么個稱謂,我們才能夠進(jìn)行脫離這個物體的實(shí)體而進(jìn)行一系列的交流。將一個物體的指示,是對這個物體的抽象。有了這種抽象能力,才有所謂的智慧和文明。所以這就是“指示”這種抽象方法的威力。

      退化到C語言的指針,

      指針是一段數(shù)據(jù)/指令(在馮諾易曼體系中,二者是相通,在同一空間中的)的指示。這是指示,也就是這段數(shù)據(jù)/指令的起始位置。但是數(shù)據(jù)/代碼是需要一個解釋的方法的。比如0x0001,可以作為一個整數(shù),也可以作為作為一串指令,也可以作為一串字符,總之怎樣解釋都可以。

      而C語言,在編譯階段,確定了這段數(shù)據(jù)/指令的“解釋方法”。

      例如,整型指針,表示的就是可以從這個指針p指向的位置開始解釋,解釋為一個整數(shù)。

      一個函數(shù)指針,表示的就是可以從這個指針p指向的位置開始解釋,解釋為一段指令,對應(yīng)的輸入和輸出以及返回值按照函數(shù)指針的類型,符合相應(yīng)的要求。

      綜上,C語言的精髓是指針,但指針不僅僅是C語言的精髓,它是抽象的精髓。各個語言中都有類似的東西,例如函數(shù),例如引用。

      (引用和指針的區(qū)別,我的理解,不可以進(jìn)行+/-偏移操作的指針,就是引用。隨意偏移,很容易使得目標(biāo)位置不符合其相應(yīng)的意義,從而造成解釋失敗,進(jìn)而崩潰。而增加了偏移功能的指針,好處是方便表述一堆具有相同類型的數(shù)據(jù)/指令,數(shù)組之類的就是這樣的實(shí)例。)

      同樣的void類型的指針,也是C語言的特色。void型的指針,就是去掉了指定類型的指針,從而使得可以以任意解釋方式,解釋指針,這就帶來了如上的潛在問題。但是也可以說,這個C語言的特有威力(我一般都把C語言的威力理解為這個)。這個帶來的好處非常之靈活。因為可以使用統(tǒng)一的類型來表述所有類型的數(shù)據(jù)。帶來的問題,和上面是類似的。就是如果解釋方法不當(dāng),就會造成災(zāi)難性的后果。C語言的強(qiáng)制類型轉(zhuǎn)換也是打破常規(guī)的指針解釋.也有可能帶來問題.

      給大家舉個例子

      一、指針

      1.指針就是存放地址的變量。在32位系統(tǒng)上,一個指針變量占用4個字節(jié)。在64位系統(tǒng)上,一個指針變量占用8個字節(jié)。

      2.指針類型、取地址、解引用

      1)指針類型

      int* pa;

      int *pa;

      int * pa;

      語義:pa是一個指針,該指針指向一個int型的數(shù)據(jù),即pa存放一個int型數(shù)據(jù)的地址。

      int* pa, pb; // pa是int*,pb是int

      int *pa, *pb;

      2)取地址——&

      int a;

      int* pa = &a; // pa指向a,a是pa的目標(biāo),pa是a的指針,pa中存放著a的地址。

      3)解引用(取目標(biāo))——*

      *pa = 100; // 將100賦值給pa的目標(biāo),即賦值給a

      3.指針的用法

      1)將指針作為函數(shù)的參數(shù),傳遞變量的地址,進(jìn)而在多個函數(shù)中訪問相同的內(nèi)存數(shù)據(jù)。

      2)指針也可以作為函數(shù)的返回值,但是不要返回指向局部變量的指針。因為函數(shù)返回以后,其局部變量所占用的內(nèi)存將隨函數(shù)棧一起被釋放,所得到的指針為野指針。

      int foo (void) {

      return 10;

      }

      a = foo ();

      int* foo (void) {

      ...

      return p;

      }

      int* foo (void); // 函數(shù)聲明,聲明一個沒有參數(shù),返回int*的foo反函數(shù)

      int (*foo) (void); // 函數(shù)指針

      void foo (void) {

      }

      沒有返回值的函數(shù)。

      解讀 C 語言中的指針

      一,基本概念

      關(guān)于指針的基本概念,我就不詳細(xì)介紹了,因為有許多書都介紹的很詳細(xì)。這里我只介紹一部分。指針指向一個地址,而指針本身在大多數(shù)系統(tǒng)上都是一個無符號整數(shù)(在32bit機(jī)上是4byte,在64bit機(jī)上是8byte)。下面用一個例子來說明其機(jī)制:

      在上面的例子中,先定義了一個指針p,它的類型是int,也就是說它只能指向一個int型的變量,而不能指向其他類型的變量。最后我們將a變量的地址賦給p。在這個過程中,涉及到兩個內(nèi)存塊,一個是存放指針p的內(nèi)存(用&p可得到內(nèi)存地址),一個是存放a的值的內(nèi)存塊(用&a可以得到內(nèi)存地址)。而第一個內(nèi)存存的p的值經(jīng)過賦值語句后也就是&a的值了。另外一個注意點(diǎn)是, *(星號)和變量類型以及變量名之間可以有任意個空格,也可以沒有。比如下面三種方式都是一樣的:

      int a = 10;

      int *p; //聲明一個指針,但未初始化,此時為野指針

      p = &a; //將a變量的地址賦給指針p

      在上面的例子中,先定義了一個指針p,它的類型是int,也就是說它只能指向一個int型的變量,而不能指向其他類型的變量。最后我們將a變量的地址賦給p。在這個過程中,涉及到兩個內(nèi)存塊,一個是存放指針p的內(nèi)存(用&p可得到內(nèi)存地址),一個是存放a的值的內(nèi)存塊(用&a可以得到內(nèi)存地址)。而第一個內(nèi)存存的p的值經(jīng)過賦值語句后也就是&a的值了。另外一個注意點(diǎn)是, *(星號)和變量類型以及變量名之間可以有任意個空格,也可以沒有。比如下面三種方式都是一樣的:

      int* a;

      int * a;

      int *a;

      解讀方法:

      首先從標(biāo)示符開始閱讀,然后往右讀,每遇到圓括號的右半邊就調(diào)轉(zhuǎn)閱讀方向。重復(fù)這個過程直到整個聲明解析完畢。需要注意的是,已經(jīng)讀過的部分在后續(xù)作為一個整體來看。

      看下面一個例子:

      int *a[3];

      //首先a右邊是[],說明a是一個具有3個元素的數(shù)組

      //右邊讀完,則讀左邊。a左邊是int*,說明a的元素是int類型的指針

      int (*a)[3]

      //首先,a右邊是圓括號的右半邊,轉(zhuǎn)向,左邊是一個*,說明a是一個指針

      //遇到括號,再轉(zhuǎn)向,是一個[],說明a是一個指向3個元素的數(shù)組的指針

      //左邊是int,說明元素類型是int

      //所以,a是一個指向具有3個整型元素的數(shù)組的指針

      int (*func)(int p);

      //相同的方法,func首先是一個指針

      //然后右邊是一個括號,說明(func)是個函數(shù),而func是指向這個函數(shù)的指針

      //這個函數(shù)具有int類型的參數(shù),返回值類型為int

      int (*func[3])(int p);

      //同理,func首先是一個具有3個元素的數(shù)組

      //其次,func左邊是一個*,說明func數(shù)組的元素是指針。要注意修飾的是func[3],而不是func。因為已經(jīng)讀過的部分在后面都作為一個整體來對待

      //跳出第一個圓括號,右邊又是一個圓括號,說明func數(shù)組的元素是函數(shù)類型的指針。這個函數(shù)具有int類型的參數(shù)和int型返回值

      二,數(shù)組首地址a,&a,&a[0]

      注:a,&a,&a[0]的含義雖然不同,但是他們?nèi)齻€的值是相等的!

      以int a[3]為例說明:

      a作為右值時,代表數(shù)組首元素的首地址,而非數(shù)組地址。 也就是a[0]的地址。int i = (a+1),這里a是右值,所以代表首元素的首地址,a+1代表下一個元素的首地址,即&a[1]。

      a是整個數(shù)組的名字。所以sizeof(a)的值為sizeof(int) * 3 = 40,代表整個數(shù)組的大小。

      &a即為取a的首地址,也即整個數(shù)組的首地址。所以sizeof(&a) = 4。 int p = (int)(&a+1)中的&a+1代表下一個數(shù)組的首地址,顯然是越界的。

      &a[0]代表首元素的首地址。 所以sizeof(&a[0]) = 4。

      &a[3],很顯然數(shù)組越界了,但它的sizeof是多少呢? 也是4,因為關(guān)鍵字sizeof求值是在編譯的時候,雖然并不存在a[3]這個元素,但是這里并沒有真正訪問a[3],而是根據(jù)數(shù)組元素類型來確定其值的。所以sizeof(a[3])不會出錯。

      a[-1]代表什么意思?首先要明白下標(biāo)的形式被編譯器解析成指針的形式,即a[1]被解析成(a+1)。那么,a[-1]被解析成*(a-1)。

      關(guān)于數(shù)組首元素的首地址和數(shù)組的首地址的區(qū)別:其實(shí),數(shù)組首元素的首地址和數(shù)組首地址的值是相同的,即&a[0]和a(以及&a)是相等的,但是而這含義不一樣。首元素的首地址加1后,是第二個元素的首地址(之所以一直說首地址,是因為有的類型存儲時會占多個地址),但數(shù)組的首地址加1后是“下一個數(shù)組的地址”,這里的下一個數(shù)組只是為了說明加1時加了整個數(shù)組的大小,而不是一個元素的大小。

      有一點(diǎn)比較容易混淆:a雖然代表整個數(shù)組,但(a+1)卻代表下一個元素的首地址,即和(&a[0]+1)一樣,下一個數(shù)組的形式為:(&a+1)。 下面以一個程序來說明:

      #include<stdio.h>

      int main()

      {

      int a[3] = {1, 2, 3};

      printf("%ld\n",sizeof(long unsigned int));

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

      printf("sizeof(a)=%ld\n", sizeof(a));

      printf("sizeof(&a[3])=%ld\n", sizeof(&a[3]));

      printf("a[-1]=%d\t*(a-1)=%d\n",a[-1],*(a-1));

      printf("a=%p\t&a=%p\t&a[0]=%p\n",a, &a,&a[0]);

      printf("a=%p\t(a+1)=%p\t(&a+1)=%p\n",a,(a+1),(&a+1));

      return 0;

      }

      輸出結(jié)果:

      8

      *(a+1)=2

      sizeof(a)=12

      sizeof(&a[3])=8

      a[-1]=0 *(a-1)=0

      a=0x7fffcb4cb980 &a=0x7fffcb4cb980 &a[0]=0x7fffcb4cb980

      a=0x7fffcb4cb980 (a+1)=0x7fffcb4cb984 (&a+1)=0x7fffcb4cb98c

      說明(下面的行數(shù)只計算main函數(shù)內(nèi)有代碼的行):

      程序第1行定義了一個具有3個元素的整型數(shù)組。

      第2行打印了long型的大小。因為我是64bit的,所以一個long是8byte。

      第3行打印了*(a+1)的值,結(jié)果和a[1]的值相等。說明a雖然代表整個數(shù)組,但作為右值時,的確代表首元素的首地址。

      第4行輸出值為12,是整個數(shù)組的大小。

      第5行打印了一個出界元素的大小,沒有報錯,驗證了上面第5條。

      第6行打印了a[-1]和*(a-1),輸出值相等。驗證了上面第6條。

      第7行打印了a和&a[0],值相等。說明數(shù)組的首地址和首元素的首地址是相等的。

      第8行打印了a,(a+1),(&a+1),由結(jié)果就可以看出首元素的首地址加1是加了一個數(shù)組元素的大小,而數(shù)組首地址加1是加了一個數(shù)組的大小。

      三,指針數(shù)組和數(shù)組指針

      指針數(shù)組: 首先它是一個數(shù)組,數(shù)組的元素是指針,也成為“存儲指針的數(shù)組”。

      數(shù)組指針: 首先它是一個指針,它指向一個數(shù)組,也可以理解為“數(shù)組的指針”。 也可以利用前面的“解讀方法”去分析。

      四,函數(shù)指針和指針函數(shù)

      函數(shù)指針: 指向函數(shù)的指針變量。

      指針函數(shù): 帶指針的函數(shù),也就是返回指針的函數(shù)。

      char * fun(char* a, char* b) //定義為指針函數(shù)

      {

      ...

      ...

      }

      int main()

      {

      char* (*p)(char* p1, char* p2); //定義函數(shù)指針

      p = &fun; //把函數(shù)地址賦給它

      //p = fun; //這樣寫也行

      (*p)("aa", "bb"); //使用函數(shù)指針

      return 0;

      }

      五,指針常量和常量指針

      const char* p1; //常量指針,指向常量的指針

      char const* p2; //同上

      char* const p3; //指針常量,指針是常量

      怎么記?

      可以先把類型名去掉,然后看const離誰近,就修飾誰。

      也可以const在*左邊的為常量指針,const在*右邊的為指針常量。

      三~五的萬能鑰匙

      其實(shí),關(guān)于“指針數(shù)組與數(shù)組指針、函數(shù)指針與指針函數(shù)、指針常量與常量指針”的判斷,有一個萬能鑰匙。那就是根據(jù)我們強(qiáng)大的中文語法:前邊是修飾詞,后邊才是主語。比如“指針數(shù)組”,前面的指針只是修飾詞,后面的數(shù)組才是主語,所以它是一個數(shù)組。

      六,野指針

      野指針指沒有確定指向的指針。造成野指針的情況有:

      1. 指針變量創(chuàng)建但沒有初始化。

      2. 指針p被free或者delete之后,沒有置為NULL。

      看了“c語言中的指針是什么”的人還看了:

    1.c語言中邏輯或的用法

    2.c語言中default的用法

    3.c語言中%s的用法

    4.c語言學(xué)習(xí)心得3篇

    5.c語言程序設(shè)計心得3篇

    6.c語言delay的用法

    7.c語言中g(shù)et的用法

    8.c語言實(shí)習(xí)心得

    1327672 主站蜘蛛池模板: 久久青草国产免费观看| 欧美a级v片在线观看一区| 性欧美成人免费观看视| 免费高清av一区二区三区| 亚洲激情成人网| ts人妖在线观看| 正在播放露脸一区| 国产精品久久免费视频| 久久久久人妻一区精品色| 青青青国产精品国产精品美女| 扒下老师的黑色丝袜桶她| 国产乱子伦在线观看| 一级毛片免费播放视频| 精品国产免费观看| 国产香蕉一区二区三区在线视频| 亚洲av无码片在线播放| 3d动漫h在线观看| 日日噜狠狠噜天天噜AV| 伊人久久精品线影院| sss欧美华人整片在线观看| 无码超乳爆乳中文字幕久久| 国产人妖tscd合集| xxxxx野外性xxxx| 欧美一区二区三区四区视频| 国产a级特黄的片子视频免费| AV无码精品一区二区三区宅噜噜 | 啊啊啊好大好爽视频| 99视频精品全部在线播放| 最近2018免费中文字幕视频| 国产成人精品一区二区秒拍| 亚洲国产精品一区二区成人片国内| 鲁啊鲁在线观看| 无套进入30p| 北条麻妃74部作品在线观看| 521色香蕉网站在线观看| 无码夫の前で人妻を侵犯| 亚洲精品15p| 亚洲国产老鸭窝一区二区三区| 成年在线网站免费观看无广告| 免费看大美女大黄大色| 99久久99久久精品免费观看|