精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

二級指針和多級指針的定義形式

C語言編程學習基地 ? 來源:C語言編程學習基地 ? 作者:C語言編程學習基地 ? 2022-10-18 16:38 ? 次閱讀

二級指針 (多級指針)

指針變量作為一個變量也有自己的存儲地址,而指向指針變量的存儲地址就被稱為指針的指針,即二級指針。依次疊加,就形成了多級指針。指針可以指向一份普通類型的數據,例如 int、double、char 等,也可以指向一份指針類型的數據,例如 int *、double *、char * 等。如果一個指針指向的是另外一個指針,我們就稱它為二級指針,或者指向指針的指針。,我們先看看二級指針,它們關系如下:

int a =100;//一個普通變量
int *p1 = &a;//一個一級指針p1指向a變量的地址
int **p2 = &p1;//一個二級指針p2指向p1指針的地址
//  p2   ->   p1   ->   a
//  &p1       &a       100


/*規律:
一級指針 指向變量的地址
二級指針 指向一級指針的地址
三級指針 指向二級指針的地址
依次類推....

指針變量也是一種變量,也會占用存儲空間,也可以使用&獲取它的地址。C語言不限制指針的級數,每增加一級指針,在定義指針變量時就得增加一個星號*。p1 是一級指針,指向普通類型的數據,定義時有一個*;p2 是二級指針,指向一級指針 p1,定義時有兩個*。

多級指針的話就是:

int ***p3 = &p2;//三級指針
int ****p4 = &p3;//四級指針
int *****p5 = &p4;//五級指針


//實際開發中會經常使用一級指針和二級指針,幾乎用不到高級指針。

想要獲取指針指向的數據時,一級指針加一個*,二級指針加兩個*,三級指針加三個*關系如下:

#include 
int main() {


  int a = 100;
  int *p1 = &a;
  int **p2 = &p1;
  int ***p3 = &p2;


  printf("%d, %d, %d, %d
", a, *p1, **p2, ***p3);//他們的值都是一樣的
  printf("&p2 = %#X, p3 = %#X
", &p2, p3);//所指向的地址也是一樣的
  printf("&p1 = %#X, p2 = %#X, *p3 = %#X
", &p1, p2, *p3);
  printf(" &a = %#X, p1 = %#X, *p2 = %#X, **p3 = %#X
", &a, p1, *p2, **p3);


  return 0;
}
//以三級指針 p3 為例來分析上面的代碼。***p3等價于*(*(*p3))。*p3 得到的是 p2 的值,
  也即 p1 的地址;*(*p3) 得到的是 p1 的值,也即 a 的地址;經過三次“取值”操作后,*(*(*p3)) 
  得到的才是 a 的值。

指針數組、指向函數的指針、指向二維數組的指針

指針數組:

指針變量和普通變量一樣,也能組成數組,如果一個數組中的所有元素保存的都是指針,那么我們就稱它為指針數組。指針數組的定義形式一般為:

數據類型 * 名字 [數組長度];
這里注意 [ ]的優先級比 * 來得高
int *a [10];
這里說明a是一個數組,包含了10個元素,每個元素的類型為int *。

除了每個元素的數據類型不同,指針數組和普通數組在其他方面都是一樣的,下面是一個簡單的例子:

#include
int main(void) {


  int a = 1;
  int b = 2;
  int c = 3;


  //定義一個指針的數組
  int *an[3] = { &a,&b,&c };//由于里邊每一個元素都是指針,所以利用取地址符&,指向abc三個變量


  //這里定義一個指向指針數組的指針,由于數組已經是指針了,所以要用到二級指針
  int **p = an;//由于數組本身就是表示一個地址所以不用取地址符&


  printf("%d %d %d
", *an[0], *an[1], *an[2]);
  printf("%d %d %d
", **(p + 0) , **(p + 1), **(p + 2));


  return 0;
}


//arr 是一個指針數組,它包含了 3 個元素,每個元素都是一個指針,在定義 arr 的同時,
我們使用變量 a、b、c 的地址對它進行了初始化,這和普通數組是多么地類似。


    parr 是指向數組 arr 的指針,確切地說是指向 arr 第 0 個元素的指針,
它的定義形式應該理解為int *(*parr),括號中的*表示 parr 是一個指針,
括號外面的int *表示 parr 指向的數據的類型。arr 第 0 個元素的類型為 int *,
所以在定義 parr 時要加兩個 *。

指針數組還可以和字符串數組結合使用:

#include 
int main(){


    char *str[3] = {  //定義一個字符串數組 長度為3
        "c.biancheng.net",
        "C語言中文網",
        "C Language"
    };


    printf("%s
%s
%s
", str[0], str[1], str[2]);//依次輸出每個字符串
    return 0;
}

指向函數的指針:

一個函數總是占用一段連續的內存區域,函數名在表達式中有時也會被轉換為該函數所在內存區域的首地址,這和數組名非常類似。我們可以把函數的這個首地址(或稱入口地址)賦予一個指針變量,使指針變量指向函數所在的內存區域,然后通過指針變量就可以找到并調用該函數。這種指針就是函數指針。

數據類型 *指針名 (數據類型 參數);


數據為函數返回值類型,指針名稱,括號里邊為函數參數列表。參數列表中可以同時給出參數的類型和名稱,
也可以只給出參數的類型,省略參數的名稱,這一點和函數原型非常類似。

注意( )的優先級高于*,第一個括號不能省略,如果寫作returnType *pointerName(param list);就成了函數原型,它表明函數的返回值類型為returnType *

用指針來實現對函數的調用:

#include 


//返回兩個數中較大的一個
int max(int a, int b){
    return a>b ? a : b;
}
int main(void){


    int x, y, maxval;
    //定義指向函數指針*pmax
    int (*pmax)(int, int) = max;  //也可以寫作int (*pmax)(int a, int b)
            //要注意的是定義必須和函數形式一致
    printf("Input two numbers:");
    scanf("%d %d", &x, &y);


    maxval = (*pmax)(x, y);//將函數調用并指針賦值
    printf("Max value: %d
", maxval);


    return 0;
}


 // maxval 對函數進行了調用。pmax 是一個函數指針,在前面加 * 就表示對它指向的函數進行調用。
   注意( )的優先級高于*,第一個括號不能省略。

指向二維數組的指針:

(復盤一下二維數組的知識)二維數組在概念上是二維的,有行和列,但在內存中所有的數組元素都是連續排列的,它們之間沒有“縫隙”。以下面的二維數組 a 為例:

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


a就是像一個矩陣:
0   1   2   3
4   5   6   7
8   9  10  11


但在內存中,a 的分布是一維線性的,整個數組占用一塊連續的內存:
【0】【1】【2】【3】【4】【5】【6】【7】【8】【9】【10】【11】

C語言中的二維數組是按行排列的,也就是先存放 a[0] 行,再存放 a[1] 行,最后存放 a[2] 行;每行中的 4 個元素也是依次存放。數組 a 為 int 類型,每個元素占用 4 個字節,整個數組共占用 4×(3×4) = 48 個字節。

C語言把一個二維數組分解成多個一維數組來處理。對于數組 a,它可以分解成三個一維數組,即 a[0]、a[1]、a[2]。每一個一維數組又包含了 4 個元素,例如 a[0] 包含`a[0][0] 、a[0][1]、a[0][2]、a[0][3]。

為了更好的理解指針和二維數組的關系,我們先來定義一個指向 a 的指針變量 p:

int (*p)[4] = a;
//括號中的*表明 p 是一個指針,它指向一個數組,數組的類型為int [4],
  這正是 a 所包含的每個一維數組的類型。

[ ]的優先級高于*,( )是必須要加的,如果赤裸裸地寫作int *p[4],那么應該理解為int *(p[4]),p 就成了一個指針數組,而不是二維數組指針。

對指針進行加法(減法)運算時,它前進(后退)的步長與它指向的數據類型有關,p 指向的數據類型是int [4],那么p+1就前進 4×4 = 16 個字節,p-1就后退 16 個字節,那么這正好是數組 a 所包含的每個一維數組的長度。也就是說,p+1會使得指針指向二維數組的下一行,p-1會使得指針指向數組的上一行。

按照上面的定義,我們來看看代碼:

#include 
int main(void){


    int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
    int (*p)[4] = a;


    printf ( "%d
",  sizeof(*(p+1))  );//這里輸出是16
    return 0;
}

*(p+1)+1表示第 1 行第 1 個元素的地址:*(p+1)單獨使用時表示的是第 1 行數據,放在表達式中會被轉換為第 1 行數據的首地址,也就是第 1 行第 0 個元素的地址,因為使用整行數據沒有實際的含義,編譯器遇到這種情況都會轉換為指向該行第 0 個元素的指針;就像一維數組的名字,在定義時或者和 sizeof、& 一起使用時才表示整個數組,出現在表達式中就會被轉換為指向數組第 0 個元素的指針。

*(*(p+1)+1)表示第 1 行第 1 個元素的值。很明顯,增加一個 * 表示取地址上的數據:**

規律:
a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)




#include
int main(void) {
  int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
  int i, j;
  int(*p)[4] = a;//定義一個指向二維數組的指針p
          
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 4; j++) {


      printf("%d ", *(*(p+i)+j));//利用二級指針就可以訪問到i行j列的元素
    }      //*(p+i):一維數組
    printf("n");    //*(*(p+i)+j)  二維數組
  }


  return 0;


}


/*輸出:
1 2 3 4
5 6 7 8
9 10 11 12




數組名 a 在表達式中也會被轉換為和 p 等價的指針!

指針數組和二維數組指針在定義時非常相似,但是括號的位置不同所表示的意思也就天壤之別:

int *(p1[5]);  //指針數組,可以去掉括號直接寫作 int *p1[5];
int (*p2)[5];  //二維數組指針,不能去掉括號

指針數組和二維數組指針有著本質上的區別:

指針數組是一個數組,只是每個元素保存的都是指針,以上面的 p1 為例,在32位環境下它占用 4×5 = 20 個字節的內存。二維數組指針是一個指針,它指向一個二維數組,以上面的 p2 為例,它占用 4 個字節的內存。

至于多維數組和二維數組沒有本質的區別,但是復雜度倒是高了許多。一般不常用。

結束語:

程序在運行過程中需要的是數據和指令的地址,變量名、函數名、字符串名和數組名在本質上是一樣的,它們都是地址的助記符:在編寫代碼的過程中,我們認為變量名表示的是數據本身,而函數名、字符串名和數組名表示的是代碼塊或數據塊的首地址;程序被編譯和鏈接后,這些名字都會消失,取而代之的是它們對應的地址。指針就是存放地址的一種變量。

常見的的指針:

d2db0a1a-4eb8-11ed-a3b6-dac502259ad0.png

1、 指針變量可以進行四則運算。指針變量的加減運算并不是簡單的加上或減去一個整數,而是跟指針指向的數據類型與地址有關。

2、給指針變量賦值時,要將一份數據的地址賦給它,不能直接賦給一個整數,例如int *p = 1000;是沒有意義的,使用過程中一般會導致程序崩潰。

3、使用指針變量之前一定要初始化,否則就不能確定指針指向哪里,如果它指向的內存沒有使用權限,程序就崩潰了。對于暫時沒有指向的指針,直接賦值NULL讓它變為空指針。

4、數組也是有類型的,數組名的本意是表示一組類型相同的數據。在定義數組時,或者和 sizeof、& 運算符一起使用時數組名才表示整個數組,表達式中的數組名會被轉換為一個指向數組的指針。

指針的用法暫時就這些,C指針大法這些才是入門!繼續加油咯~

審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲
    +關注

    關注

    13

    文章

    4266

    瀏覽量

    85686
  • 函數
    +關注

    關注

    3

    文章

    4308

    瀏覽量

    62445
  • 指針
    +關注

    關注

    1

    文章

    480

    瀏覽量

    70512
  • 數組
    +關注

    關注

    1

    文章

    416

    瀏覽量

    25913

原文標題:【零基礎學C語言】知識總結十:二級指針、指針數組和指向函數的指針

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    詳解C語言二級指針三種內存模型

    二級指針相對于一指針,顯得更難,難在于指針和數組的混合,定義不同類型的
    發表于 11-02 09:35 ?386次閱讀

    嵌入式C語言二級指針

    二級指針相對于一指針,顯得更難,難在于指針和數組的混合,定義不同類型的
    發表于 11-04 10:08 ?581次閱讀

    C語言中多級指針的概念和使用方法

    多級指針在C語言中是一種特殊的指針類型,它可以指向其他指針指針。
    發表于 08-16 16:16 ?993次閱讀

    嵌入式軟開的二級指針輸出的程序是怎樣的

    嵌入式軟開的指針是什么意思?嵌入式軟開的二級指針輸出的程序是怎樣的?
    發表于 12-24 06:38

    C51指針定義和應用小結

    一. 指針變量的定義指針變量定義與一般變量的定義類似,其形式如下:數據類型 [存儲器類型1] *
    發表于 06-07 17:52 ?3335次閱讀

    函數指針指針函數定義

    函數指針指針函數,C語言學習中最容易混淆的一些概念,好好學習吧
    發表于 01-11 16:44 ?0次下載

    c語言函數指針定義,指針函數和函數指針的區別

     往往,我們一提到指針函數和函數指針的時候,就有很多人弄不懂。下面就由小編詳細為大家介紹C語言中函數指針指針函數和函數指針之間的區別。
    發表于 11-16 15:18 ?3619次閱讀

    C語言中的“二級指針”該如何理解

    在討論C語言指針時,我一直在強調“將指針看作普通數據類型”,要是讀者能夠記住這一點,在看到二級指針時,將其與其他普通數據類型對比分析,會發現其實二級
    發表于 07-31 16:58 ?1.2w次閱讀
    C語言中的“<b class='flag-5'>二級</b><b class='flag-5'>指針</b>”該如何理解

    C語言二級指針的用法與原理

    提到指針,我們都知道指針是用來存儲一個變量的地址。所以,當我們定義了一個指向指針指針的時候(pointer to pointer),我們也
    發表于 07-02 14:52 ?3789次閱讀
    C語言<b class='flag-5'>二級</b><b class='flag-5'>指針</b>的用法與原理

    C進階技巧:二級指針問題

    這里重點看看一、二級,畢竟二級指針與我們的維數據結合使用,維素組在圖形、矩陣、算法等等方面還是使用非常廣泛的。
    的頭像 發表于 09-08 15:00 ?1849次閱讀
    C進階技巧:<b class='flag-5'>二級</b><b class='flag-5'>指針</b>問題

    C語言中的指針(重點)超詳細

    - 指針4.3、指針的運算關系5、指針和數組6、二級指針7、指針數組1、
    發表于 01-13 14:10 ?11次下載
    C語言中的<b class='flag-5'>指針</b>(重點)超詳細

    維數組與數組指針以及指針數組

    維數組與數組指針以及指針數組
    的頭像 發表于 08-16 09:02 ?2587次閱讀

    指針長度簡述

    我們使用這樣的方式來定義一個指針: Type *p; 我們說 p是指向type類型的指針 ,type可以是任意類型,除了可以是char,short, int, long等基本類型外,還可以是
    的頭像 發表于 09-29 18:42 ?4036次閱讀
    <b class='flag-5'>指針</b>長度簡述

    C語言中一指針、二級指針和三指針

    指針的用法其實是取數據的地址,以此類推,二級指針就是取一指針的地址,也可以表示一
    發表于 05-19 17:30 ?1884次閱讀
    C語言中一<b class='flag-5'>級</b><b class='flag-5'>指針</b>、<b class='flag-5'>二級</b><b class='flag-5'>指針</b>和三<b class='flag-5'>級</b><b class='flag-5'>指針</b>

    面試???1:函數指針指針函數、數組指針指針數組

    在嵌入式開發領域,函數指針指針函數、數組指針指針數組是一些非常重要但又容易混淆的概念。理解它們的特性和應用場景,對于提升嵌入式程序的效率和質量至關重要。一、
    的頭像 發表于 08-10 08:11 ?720次閱讀
    面試常考+1:函數<b class='flag-5'>指針</b>與<b class='flag-5'>指針</b>函數、數組<b class='flag-5'>指針</b>與<b class='flag-5'>指針</b>數組