SlideShare a Scribd company logo
1 of 32
Download to read offline
++
  深度學習C



                Chapter 5

                  指標


深度學習 C++           1        指標
變數儲存位置
   敘述
    int         a = 3 ;                   0x4f223520
    double      b = 3.5 ;
                             0x3f441100

           名稱            a                        b
     位址         &a                          &b
     記憶體             3                        3.5
                4 bytes                      8 bytes


    a 的位址 = &a = 0x3f441100
    b 的位址 = &b = 0x4f223520

深度學習 C++                       2                       指標
位址運算子

   變數位址       :變數資料所佔用記憶空間
                的起始位址
   位址運算子 :變數名稱前使用 & 可取得
           變數位址

     int   foo = 3 ;
     cout << &foo ;        // 印出 foo 所佔用的起始位址。
                           // 位址是以十六進位表示的數字,
                           // 例如:0xbbffff6b

     double bar = 5.2 ;
     cout << &bar << endl ;
                                     address-of operator

深度學習 C++               3                            指標
指標資料型別
   指標資料型別:
    用來儲存某同型別資料所在記憶空間的位址
     int foo = 99 ;
     int *p ;       // 定義指標 p , 可以指向一整數位址
     p = &foo ;     // 將整數 foo 的位址存放到指標
                       // 變數 p 中

     上式程式碼二、三行可合併成                 int *p = &foo ;

    指標僅能指向同型別的變數位址
     double   bar = 2.2 ;
     // 錯誤
     int *p = &bar ;                             pointer

深度學習 C++                    4                        指標
指標 (一)
  指標定義:
     int* p ;          // p q 與 r 皆是整數指標
     int * q ;         // 皆可儲存整數位址
     int *r ;



     int *a , *b ;     // a 與 b 皆是整數指標
     int* c , d ;      // c 是整數指標,但 d 只是整數


   指標初值:
     int *p = 0 ;         // 指標 p 尚未指向任何位址
     const int NULL = 0 ;
     int *p = NULL ;

深度學習 C++                5                    指標
指標 (二)
      int   foo =      99 ;
      int* ptr1        ;            //   定義一整數指標變數 ptr1
      int * ptr2       ;            //   定義一整數指標變數 ptr2
      ptr1 = &foo      ;            //   將整數 foo 的位址存入指標變數 ptr1 內
      ptr2 = ptr1      ;            //   將指標變數 ptr1 內所存放的位址複製
                                    //   一份給 ptr2

 變數                           foo                         ptr2      foo

 資料                           99                                    99

 變數                                            ptr1

 資料
            int foo = 99                      int *ptr1 , int *ptr2
 變數                 ptr2      foo                         ptr2      foo

 資料                           99                          &foo      99

 變數      ptr1                                  ptr1

 資料      &foo                                  &foo

                ptr1 = &foo                           ptr2 = ptr1
深度學習 C++                                  6                               指標
指標與參照運算子
                                             foo
   空間儲存方式:
                                                   2
    int    foo = 2 ;
    int    *ptr = &foo ;
                               變數   ptr

                               資料     &foo



   ptr 指標內所儲存的資料為指標所指向變數的位址
   ptr 指標可用參照運算子(*)取得指標所指向的資料
   列印位址與資料
    cout << ptr << endl ; // 列印 foo 的位址
    cout << *ptr << endl ; // 列印 foo 的資料

深度學習 C++                   7                           指標
參照運算子

   指標之前使用參照運算子即可取得指標所指向位
    址之資料值
     int   foo = 2 ;
     int   *ptr = &foo ;                 // 指標 ptr 指向 foo
     cout << ”*ptr = ” << *ptr << endl ; // 列印:*ptr = 2
     *ptr += 1 ;                         // 將 ptr 所指向位址
                                         // 的資料加上 1
     cout << ”foo = ” << foo << endl ;   // 列印:foo = 3
     cout << ”square = ” << *ptr * *ptr // 列印:square = 9
          << endl ;

                                          dereference operator

深度學習 C++                   8                              指標
指標與常數 (一)
  指標變數可取得兩筆資料的記憶空間,可以使用常數保留
   字(const)來設定哪一個記憶空間的資料為常數

   int     foo = 30 ;

    // 不能透過 p 更改 foo 的值               p          foo
    // 但 p 可以改指向其它位址                  &foo             30
    const int *         p = &foo ;
                                                  常數
    // q 永遠指向 foo 的位址                 q          foo
    // 但 foo 的資料可透過 q 更動                  &foo     30
    int          * const q = &foo ;
                                          常數
    // r 永遠指向 foo 的位址                 r          foo
    // 且不能透過 r 改變 foo 的值                  &foo         30
    const int * const r = &foo ;
                                          常數       常數

深度學習 C++                     9                              指標
指標與常數 (二)
  三種指標常數:
   int foo = 1                    指標所在的記憶空間   指標指向的記憶空間
   const int * ptr = &foo              O         X
   int * const ptr = &foo              X         O
   const int * const ptr = &foo        X         X


   第一類型的常數指標是指不能透過指標來更改指向位址內
   所存放的資料,但不表示原擁有此記憶空間的變數本身不
   能更改其值
     int       foo = 30   ;
     const int * p = &foo ;
     *p = 50 ;              // 錯誤
     foo = 50 ;             // 可以

深度學習 C++                          10                      指標
指標基本運算 (一)
  使用指標交換兩變數 a 與 b 的數值
    int   a = 10 , b = 30 , tmp ;
    int *pa = &a , *pb = &b ; // 指標 pa 與 pb 分別指向 a 與 b

    tmp = *pa ;                  // 將指標 pa 所指的資料複製給 tmp
    *pa = *pb ;                  // 將指標 pb 所指的資料複製到 pa
                                 // 所指的位址
    *pb = tmp ;                  // 將 tmp 的資料複製到 pb 所指的
                                 // 位址

    // 列印 a = 30 , b = 10
    cout << ”a = ” << a << ”n”
         << ”b = ” << b << endl ;


深度學習 C++                    11                       指標
指標基本運算 (二)
 變數    tmp                     a               tmp               a

 資料                           10                                 10

 變數             b                              pb      b         pa
                30                             &b      30        &a
 資料
      int a=10, b=30, tmp                      int *pa=&a, *pb=&b

 變數    tmp                     a               tmp               a
 資料    10                     10               10                30
 變數    pb       b             pa               pb      b         pa
 資料    &b       30            &a               &b      30        &a

             tmp = *pa                               *pa = *pb

               變數        tmp                    a

               資料        10                     30

               變數        pb           b         pa
                         &b           10        &a
               資料
                                   *pb = tmp

深度學習 C++                               12                             指標
指標基本運算 (三)

   指標位址的指定

    int foo = 3 ;
    int *p , *q ;

    p = &foo ;      // 指標 p 指到 foo 的位址
    q = p ;         // 指標 p 的值存入指標 q,p 與
                    // q 兩指標同指向 foo




深度學習 C++               13                  指標
指標基本運算 (四)
  交換兩指標所指向的位址
   int a = 3 , b = 10 ;
   int *p = &a , *q = &b ; // 指標 p 指向 a,指標 q 指向 b

   // 輸出 p , q 所指向的值,即 *p = 3 , *q = 10
   cout << ”*p = ” << *p << ” ,”
        << ”*q = ” << *q << endl ;

   int *r = p ;   // 指標 r 指向 p 所指的位址
   p = q ;        // 指標 p 指向 q 所指的位址
   q = r ;        // 指標 q 指向 r 所指的位址

   // 輸出 p,q 所指向的值,即 *p = 10 , *q = 3
   cout << ”*p = ” << *p << ” , ”
        << ”*q = ” << *q << endl ;

深度學習 C++               14                      指標
指標基本運算 (五)
                                                         4 bytes
  移動指標所指向的位址                                            foo
                                                            3
   int      foo = 3 ;                         ptr
   int     *ptr = &foo ;                       &foo

                                      10個整數空間
   ptr = ptr + 10 ;                       = 40 bytes
                                      foo              4 bytes
                                         3     ‧‧‧
                           ptr
                           &foo+10

  移動後的指標所指向的位址可能不是程式所使
   用的空間,若將其資料更改,則可能引起程式
   在執行過程時中斷          run-time                                    error

深度學習 C++                         15                                指標
動態記憶空間配置

   為了靈活使用計算機內有限的記憶空間,C++可在
    程式執行當中,臨時向作業系統要取適當的記憶空
    間來使用,當程式不須再使用此記憶空間時,也可
    以立即將之歸還給作業系統供其他程式使用

   new    : 動態配置記憶空間

   delete: 動態歸還記憶空間


                        dynamical memory allocation

深度學習 C++         16                           指標
new 與 delete (一)
  取得一個單位的記憶空間
    int    *ptr ;
    ptr = new int ;    // 向作業系統要一個整數空間,並
                       // 將此空間的位址存入 ptr 指標
    *ptr = 10 ;        // 指標 ptr 所指向存入 10
    *ptr += 1 ;        // 指標 ptr 所指向位址的資料加 1
    cout << *ptr ;     // 輸出指標 ptr 所指向位址的資料,即 11
    // 程式碼前三行可以使用
    int *ptr = new int(10);

   歸還記憶空間                     new “ß delete f/ aÉv—ÿY‡gœNu(
                               deleteÿRG’£PzzŁfiNgm‹Y1

    delete ptr ;       // 歸還指標 ptr 所指向的動態記憶空間
                       // 回作業系統,但指標 ptr 變數仍存在
深度學習 C++                  17                                    指標
new 與 delete (二)
   圖表表示

  變數   ptr                         ptr

  資料                               &□

  變數                                                    □

  資料
             int *ptr                    ptr = new int


  變數   ptr                         ptr

  資料   &□                          &□

  變數                     □

  資料                     10

             *ptr = 10                   delete   ptr



深度學習 C++                      18                            指標
new 與 delete (三)
   取得 n 個單位的連續記憶空間
    int i , n ;
    cin >> n ;
    int *ptr = new int [n] ;  // ptr 指標指向 n 個連續整數空間的
                              // 首位整數位址
    for( i = 0 ; i < n ; ++i ) *(ptr+i) = (i+1)*(i+1) ;
                                      ‧‧‧
       1      4         9      16     ‧‧‧        n2
     ptr    ptr+1     ptr+2   ptr+3          ptr+(n-1)

    以上的 *(ptr+i) 可以使用 ptr[i] 取代,因此之前迴圈可簡化成
     for( i = 0 ; i < n ; ++i ) ptr[i] = (i+1)*(i+1) ;

   歸還一整塊記憶空間
    delete [] ptr ;    // 歸還指標 ptr 所指向的一整塊動態記憶空間,
                       // 但指標 ptr 仍會存在

深度學習 C++                        19                        指標
new 與 delete (四)
  由 new 取得的記憶空間會持續存在。當程式執行 delete
   時,作業系統才會將指標所指向的記憶空間取回重新使用

  由 new 取來的動態空間要隨時有指標記得這些動態空間的位
   址。若程式執行中,造成這些記憶空間的位址失去聯繫,這種
   現象被稱為記憶空間流失 (memory leak)
  當程式執行結束後,所有使用的動態記憶空間( 包含流失
   的記憶空間 )都會全部退還給系統重新使用

   int foo = 3 ;
   int *ptr = new int(5) ; // 指標 ptr 指向一動態空間,內存有整數 5
   cout << *ptr << endl ; // 列印指標 ptr 所指向的資料值 5
                   記憶空間流失
   ptr = &foo ;             // 指標 ptr 改指向 foo 變數
   cout << *ptr << endl   ; // 列印指標 ptr 所指向的資料值 3
深度學習 C++                    20                      指標
指標與結構資料型別

   指標可以使用 -> 來讀取結構資料型別的資料
    struct Complex {
        double re, im ;
    };

    Complex foo ;                // 定義一複數變數
    Complex *ptr = &foo ;        // 讓一複數指標指到此複數變數

    ptr -> re = 2 ;              // 利用指標來設定實數資料
    ptr -> im = 5 ;              // 利用指標來設定虛數資料

   也可以使用以下方式
   (*ptr).re = 2 ;
   (*ptr).im = 5 ;

深度學習 C++                    21                      指標
指標的指標 (一)
  指標內所儲存的資料也可以是另一個指標的位址
    int       foo = 5      ;
    int        *p = &foo   ;            // 整數指標 p 指向整數 foo

    int       **q = &p ;                // 指標的指標 q 指向整數指標 p


      q                           p                      foo
          &p                      &foo                      5
          q                     p <=> *q            foo <=> *p <=> **q


   cout << ”foo = ”            << foo        << endl      // 都輸出 5
        << ” *p = ”            << *p         << endl
        << ” **q = ”           << **q        << endl ;


深度學習 C++                                22                               指標
指標的指標 (二)
  利用雙層指標將指標所指到的位址對調

    int foo   = 5    , bar = 10  ;
    int *a    = &foo , *b = &bar ;     // a 指向 foo , b 指向 bar

    int *tmp ;
    int **c = &a , **d = &b ;          // c 指向 a , d 指向 b
    cout << ” **c ” << **c << ’n’    // 印出 c,d在雙層指標運作後所
         << ” **d ” << **d << ”nn”; // 指向的資料值,分別為 5 和 10

    tmp = *c ;                         // tmp 指向 c 所指向的位址
    *c = *d ;                          // c 指向 d 所指向的位址
    *d = tmp ;                         // d 指向 tmp 所指向的位址
    cout << ” **c ” << **c << ’n’
         << ” **d ” << **d << endl ;   // 印出 10 和 5


深度學習 C++                        23                          指標
指標的指標 (三)
      bar             foo                 bar   tmp    foo
 變數
       10              5                   10           5
 資料
                                                 a            b
 變數
                                                &foo         &bar
 資料
           int foo=5, bar=10            int *a=&foo, *b=&bar, *tmp
      bar      tmp    foo      d          bar   tmp    foo    d
 變數
       10              5    &b             10   &foo    5    &b
 資料
       c        a              b           c     a            b
 變數
       &a      &foo         &bar           &a   &foo         &bar
 資料
           int **c=&a, **d=&b                   tmp = *c
      bar      tmp    foo      d          bar   tmp    foo    d
 變數
       10      &foo    5    &b             10   &foo    5    &b
 資料
       c        a              b           c     a            b
 變數
       &a      &bar         &bar           &a   &bar         &foo
 資料
               *c = *d                          *d = tmp


深度學習 C++                           24                                指標
雙層指標與動態矩陣 (一)
  雙層指標可以指向動態產生的矩陣
    int    n   =   10 ;
    // 指標 ptr1 ptr2       … ptrm 分別指向 n 個動態整數記憶空間的起始位址
    int *ptr1 = new       int[n] ;
    int *ptr2 = new       int[n] ;
    ‧‧‧
    int *ptrm = new       int[n] ;

  將 m 個指標合併使用
     // 指標的指標 ptr 指向 m 個動態指標記憶空間的起始位址
     int ** ptr = new int*[m] ;

     // 讓每個 ptr[i] 指標指向 n 個動態整數記憶空間的起始位址
     for( int i = 0 ; i < m ; ++i )       ptr[i] = new int[n] ;


深度學習 C++                             25                           指標
雙層指標與動態矩陣 (二)
int**        int*                                  int
 ptr        ptr[0]
                             ptr[1][0]     ptr[1][1]     …   ptr[1][n-1]

            ptr[1]

            ptr[2]
                             ptr[0][0]     ptr[0][1]     …   ptr[0][n-1]
              …

              …
                              ‧‧‧‧‧‧

           ptr[m-1]          ptr[m-1][0]   ptr[m-1][1]   …   ptr[m-1][n-1]



 int **ptr = new int*[m] ;          for ( i = 0 ; i < m ; ++i )
                                        ptr[i] = new int[n] ;


深度學習 C++                          26                                  指標
雙層指標與動態矩陣 (三)

   使用雙層指標設定矩陣元素
     // 將矩陣每一個元素歸零
     int r , c ;
     for ( r = 0 ; r < m ; ++r ) {
           for ( c = 0 ; c < n ; ++c ) ptr[r][c] = 0 ;
     }


   歸還動態矩陣記憶空間

    for ( int r = 0 ; r < m ; ++r ) delete [] ptr[r] ;
    delete [] ptr ;


深度學習 C++                  27                             指標
九九乘法表:指標版
 輸出:
 1x1=   1   2x1= 2   3x1= 3   4x1= 4   5x1= 5   6x1= 6   7x1= 7   8x1= 8   9x1= 9
 1x2=   2   2x2= 4   3x2= 6   4x2= 8   5x2=10   6x2=12   7x2=14   8x2=16   9x2=18
 1x3=   3   2x3= 6   3x3= 9   4x3=12   5x3=15   6x3=18   7x3=21   8x3=24   9x3=27
 1x4=   4   2x4= 8   3x4=12   4x4=16   5x4=20   6x4=24   7x4=28   8x4=32   9x4=36
 1x5=   5   2x5=10   3x5=15   4x5=20   5x5=25   6x5=30   7x5=35   8x5=40   9x5=45
 1x6=   6   2x6=12   3x6=18   4x6=24   5x6=30   6x6=36   7x6=42   8x6=48   9x6=54
 1x7=   7   2x7=14   3x7=21   4x7=28   5x7=35   6x7=42   7x7=49   8x7=56   9x7=63
 1x8=   8   2x8=16   3x8=24   4x8=32   5x8=40   6x8=48   7x8=56   8x8=64   9x8=72
 1x9=   9   2x9=18   3x9=27   4x9=36   5x9=45   6x9=54   7x9=63   8x9=72   9x9=81




                                 程式          輸出



深度學習 C++                                28                                     指標
彈珠臺模擬
  彈珠碰到滾輪後會等機會
   地往左右兩方滾下,求彈
   珠在各底層位置的機率?

  作法:
   假設有 M 個彈珠,利用亂
   數函式決定彈珠在撞到滾     A|B|C|D|E|F
   輪後往左或往右的方向,      滾 輪 彈 珠 台 n=5
   統計各位置的彈珠數量,
   除以 M 即為機率         程式     輸出


深度學習 C++      29                    指標
向量相乘 (一)
            a0
            a1
  ab =      .
            .        b0,b1,‧‧‧,bn-1
            .
           an-1

                  a0b0 , a0b1 ,       ‧‧‧ , a0bn-1
                  a1b0 , a1b1 ,       ‧‧‧ , a1bn-1
     =
              an-1b0 , an-1b1 , ‧‧‧ , an-1bn-1

                  M0,0   , M0,1   ,   ‧‧‧ , M0,n-1
                  M1,0   , M1,1   ,   ‧‧‧ , M1,n-1
     =                                                 = M
                  Mn-1,0 , Mn-1,1 ,   ‧‧‧ , Mn-1,n-1



深度學習 C++                                  30                 指標
向量相乘 (二)

   由使用者輸入長度,在程式中以 new 向系統取
    得 n2 個同型別記憶空間,如下圖:

      M0,0   M0,1   M0,2   ‧‧‧   M1,0   M1,1   ‧‧‧   Mn-1,n-1




    這 n2 個動態記憶空間在計
                                          程式     輸出
     算機記憶體中是連續排列的




深度學習 C++                    31                              指標
矩陣分解

           A   B         S      :nxn 方陣
   S =                   A B C D:mxm 方陣
           C   D
                         n = 2m

  S = {si,j} , A = {ai,j} , B = {bi,j} …
 則
       ai,j = si,j       0 <= i , j < m

       bi,j = si,j+m
       ci,j = si+m,j                  程式   輸出
       di,j = si+m,j+m
深度學習 C++                 32                     指標

More Related Content

What's hot

17第十七讲(第七章中)(2)
17第十七讲(第七章中)(2)17第十七讲(第七章中)(2)
17第十七讲(第七章中)(2)
何青青 Clare
 

What's hot (20)

系統程式 - 第二章
系統程式 - 第二章系統程式 - 第二章
系統程式 - 第二章
 
Ptyhon 教學 003 函數
Ptyhon 教學 003 函數Ptyhon 教學 003 函數
Ptyhon 教學 003 函數
 
17第十七讲(第七章中)(2)
17第十七讲(第七章中)(2)17第十七讲(第七章中)(2)
17第十七讲(第七章中)(2)
 
第4章函数
第4章函数第4章函数
第4章函数
 
C python 原始碼解析 投影片
C python 原始碼解析 投影片C python 原始碼解析 投影片
C python 原始碼解析 投影片
 
系統程式 -- 第 3 章 組合語言
系統程式 -- 第 3 章 組合語言系統程式 -- 第 3 章 組合語言
系統程式 -- 第 3 章 組合語言
 
第5章数组
第5章数组第5章数组
第5章数组
 
系統程式 -- 第 5 章 連結與載入
系統程式 -- 第 5 章 連結與載入系統程式 -- 第 5 章 連結與載入
系統程式 -- 第 5 章 連結與載入
 
Ppt 145-149
Ppt 145-149Ppt 145-149
Ppt 145-149
 
系統程式 -- 第 4 章
系統程式 -- 第 4 章系統程式 -- 第 4 章
系統程式 -- 第 4 章
 
系統程式 -- 第 2 章
系統程式 -- 第 2 章系統程式 -- 第 2 章
系統程式 -- 第 2 章
 
Ch1 c++總複習
Ch1 c++總複習Ch1 c++總複習
Ch1 c++總複習
 
Ch9
Ch9Ch9
Ch9
 
竞赛中C++语言拾遗
竞赛中C++语言拾遗竞赛中C++语言拾遗
竞赛中C++语言拾遗
 
Python speed up with numba
Python speed up with numbaPython speed up with numba
Python speed up with numba
 
Ch9 教學
Ch9 教學Ch9 教學
Ch9 教學
 
第三章
第三章第三章
第三章
 
Ch10 範例
Ch10 範例Ch10 範例
Ch10 範例
 
Python basic - v01
Python   basic - v01Python   basic - v01
Python basic - v01
 
Appendix B 教學
Appendix B 教學Appendix B 教學
Appendix B 教學
 

Viewers also liked

Kitchen3
Kitchen3Kitchen3
Kitchen3
Benera
 
Ud com podem ajudar als nostres boscos1
Ud com podem ajudar als nostres boscos1Ud com podem ajudar als nostres boscos1
Ud com podem ajudar als nostres boscos1
UIB
 
Sosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir Araştırma
Sosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir AraştırmaSosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir Araştırma
Sosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir Araştırma
Ayşe Vergen
 
실수만발 김대리 It로_위기극복
실수만발 김대리 It로_위기극복실수만발 김대리 It로_위기극복
실수만발 김대리 It로_위기극복
JongHwa Hyun
 
Repoblam
RepoblamRepoblam
Repoblam
UIB
 

Viewers also liked (9)

Studio1
Studio1Studio1
Studio1
 
Kitchen3
Kitchen3Kitchen3
Kitchen3
 
Ud com podem ajudar als nostres boscos1
Ud com podem ajudar als nostres boscos1Ud com podem ajudar als nostres boscos1
Ud com podem ajudar als nostres boscos1
 
Baska
BaskaBaska
Baska
 
La moral kantiana
La moral kantianaLa moral kantiana
La moral kantiana
 
Ch 6
Ch 6Ch 6
Ch 6
 
Sosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir Araştırma
Sosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir AraştırmaSosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir Araştırma
Sosyal Paylaşım Sitelerinde Üye Bağlılığı Üzerine Bir Araştırma
 
실수만발 김대리 It로_위기극복
실수만발 김대리 It로_위기극복실수만발 김대리 It로_위기극복
실수만발 김대리 It로_위기극복
 
Repoblam
RepoblamRepoblam
Repoblam
 

Ch 5

  • 1. ++ 深度學習C Chapter 5 指標 深度學習 C++ 1 指標
  • 2. 變數儲存位置  敘述 int a = 3 ; 0x4f223520 double b = 3.5 ; 0x3f441100 名稱 a b 位址 &a &b 記憶體 3 3.5 4 bytes 8 bytes a 的位址 = &a = 0x3f441100 b 的位址 = &b = 0x4f223520 深度學習 C++ 2 指標
  • 3. 位址運算子  變數位址 :變數資料所佔用記憶空間 的起始位址  位址運算子 :變數名稱前使用 & 可取得 變數位址 int foo = 3 ; cout << &foo ; // 印出 foo 所佔用的起始位址。 // 位址是以十六進位表示的數字, // 例如:0xbbffff6b double bar = 5.2 ; cout << &bar << endl ; address-of operator 深度學習 C++ 3 指標
  • 4. 指標資料型別  指標資料型別: 用來儲存某同型別資料所在記憶空間的位址 int foo = 99 ; int *p ; // 定義指標 p , 可以指向一整數位址 p = &foo ; // 將整數 foo 的位址存放到指標 // 變數 p 中 上式程式碼二、三行可合併成 int *p = &foo ;  指標僅能指向同型別的變數位址 double bar = 2.2 ; // 錯誤 int *p = &bar ; pointer 深度學習 C++ 4 指標
  • 5. 指標 (一)  指標定義: int* p ; // p q 與 r 皆是整數指標 int * q ; // 皆可儲存整數位址 int *r ; int *a , *b ; // a 與 b 皆是整數指標 int* c , d ; // c 是整數指標,但 d 只是整數  指標初值: int *p = 0 ; // 指標 p 尚未指向任何位址 const int NULL = 0 ; int *p = NULL ; 深度學習 C++ 5 指標
  • 6. 指標 (二) int foo = 99 ; int* ptr1 ; // 定義一整數指標變數 ptr1 int * ptr2 ; // 定義一整數指標變數 ptr2 ptr1 = &foo ; // 將整數 foo 的位址存入指標變數 ptr1 內 ptr2 = ptr1 ; // 將指標變數 ptr1 內所存放的位址複製 // 一份給 ptr2 變數 foo ptr2 foo 資料 99 99 變數 ptr1 資料 int foo = 99 int *ptr1 , int *ptr2 變數 ptr2 foo ptr2 foo 資料 99 &foo 99 變數 ptr1 ptr1 資料 &foo &foo ptr1 = &foo ptr2 = ptr1 深度學習 C++ 6 指標
  • 7. 指標與參照運算子 foo  空間儲存方式: 2 int foo = 2 ; int *ptr = &foo ; 變數 ptr 資料 &foo  ptr 指標內所儲存的資料為指標所指向變數的位址  ptr 指標可用參照運算子(*)取得指標所指向的資料  列印位址與資料 cout << ptr << endl ; // 列印 foo 的位址 cout << *ptr << endl ; // 列印 foo 的資料 深度學習 C++ 7 指標
  • 8. 參照運算子  指標之前使用參照運算子即可取得指標所指向位 址之資料值 int foo = 2 ; int *ptr = &foo ; // 指標 ptr 指向 foo cout << ”*ptr = ” << *ptr << endl ; // 列印:*ptr = 2 *ptr += 1 ; // 將 ptr 所指向位址 // 的資料加上 1 cout << ”foo = ” << foo << endl ; // 列印:foo = 3 cout << ”square = ” << *ptr * *ptr // 列印:square = 9 << endl ; dereference operator 深度學習 C++ 8 指標
  • 9. 指標與常數 (一)  指標變數可取得兩筆資料的記憶空間,可以使用常數保留 字(const)來設定哪一個記憶空間的資料為常數 int foo = 30 ; // 不能透過 p 更改 foo 的值 p foo // 但 p 可以改指向其它位址 &foo 30 const int * p = &foo ; 常數 // q 永遠指向 foo 的位址 q foo // 但 foo 的資料可透過 q 更動 &foo 30 int * const q = &foo ; 常數 // r 永遠指向 foo 的位址 r foo // 且不能透過 r 改變 foo 的值 &foo 30 const int * const r = &foo ; 常數 常數 深度學習 C++ 9 指標
  • 10. 指標與常數 (二)  三種指標常數: int foo = 1 指標所在的記憶空間 指標指向的記憶空間 const int * ptr = &foo O X int * const ptr = &foo X O const int * const ptr = &foo X X 第一類型的常數指標是指不能透過指標來更改指向位址內 所存放的資料,但不表示原擁有此記憶空間的變數本身不 能更改其值 int foo = 30 ; const int * p = &foo ; *p = 50 ; // 錯誤 foo = 50 ; // 可以 深度學習 C++ 10 指標
  • 11. 指標基本運算 (一)  使用指標交換兩變數 a 與 b 的數值 int a = 10 , b = 30 , tmp ; int *pa = &a , *pb = &b ; // 指標 pa 與 pb 分別指向 a 與 b tmp = *pa ; // 將指標 pa 所指的資料複製給 tmp *pa = *pb ; // 將指標 pb 所指的資料複製到 pa // 所指的位址 *pb = tmp ; // 將 tmp 的資料複製到 pb 所指的 // 位址 // 列印 a = 30 , b = 10 cout << ”a = ” << a << ”n” << ”b = ” << b << endl ; 深度學習 C++ 11 指標
  • 12. 指標基本運算 (二) 變數 tmp a tmp a 資料 10 10 變數 b pb b pa 30 &b 30 &a 資料 int a=10, b=30, tmp int *pa=&a, *pb=&b 變數 tmp a tmp a 資料 10 10 10 30 變數 pb b pa pb b pa 資料 &b 30 &a &b 30 &a tmp = *pa *pa = *pb 變數 tmp a 資料 10 30 變數 pb b pa &b 10 &a 資料 *pb = tmp 深度學習 C++ 12 指標
  • 13. 指標基本運算 (三)  指標位址的指定 int foo = 3 ; int *p , *q ; p = &foo ; // 指標 p 指到 foo 的位址 q = p ; // 指標 p 的值存入指標 q,p 與 // q 兩指標同指向 foo 深度學習 C++ 13 指標
  • 14. 指標基本運算 (四)  交換兩指標所指向的位址 int a = 3 , b = 10 ; int *p = &a , *q = &b ; // 指標 p 指向 a,指標 q 指向 b // 輸出 p , q 所指向的值,即 *p = 3 , *q = 10 cout << ”*p = ” << *p << ” ,” << ”*q = ” << *q << endl ; int *r = p ; // 指標 r 指向 p 所指的位址 p = q ; // 指標 p 指向 q 所指的位址 q = r ; // 指標 q 指向 r 所指的位址 // 輸出 p,q 所指向的值,即 *p = 10 , *q = 3 cout << ”*p = ” << *p << ” , ” << ”*q = ” << *q << endl ; 深度學習 C++ 14 指標
  • 15. 指標基本運算 (五) 4 bytes  移動指標所指向的位址 foo 3 int foo = 3 ; ptr int *ptr = &foo ; &foo 10個整數空間 ptr = ptr + 10 ; = 40 bytes foo 4 bytes 3 ‧‧‧ ptr &foo+10  移動後的指標所指向的位址可能不是程式所使 用的空間,若將其資料更改,則可能引起程式 在執行過程時中斷 run-time error 深度學習 C++ 15 指標
  • 16. 動態記憶空間配置  為了靈活使用計算機內有限的記憶空間,C++可在 程式執行當中,臨時向作業系統要取適當的記憶空 間來使用,當程式不須再使用此記憶空間時,也可 以立即將之歸還給作業系統供其他程式使用  new : 動態配置記憶空間  delete: 動態歸還記憶空間 dynamical memory allocation 深度學習 C++ 16 指標
  • 17. new 與 delete (一)  取得一個單位的記憶空間 int *ptr ; ptr = new int ; // 向作業系統要一個整數空間,並 // 將此空間的位址存入 ptr 指標 *ptr = 10 ; // 指標 ptr 所指向存入 10 *ptr += 1 ; // 指標 ptr 所指向位址的資料加 1 cout << *ptr ; // 輸出指標 ptr 所指向位址的資料,即 11 // 程式碼前三行可以使用 int *ptr = new int(10);  歸還記憶空間 new “ß delete f/ aÉv—ÿY‡gœNu( deleteÿRG’£PzzŁfiNgm‹Y1 delete ptr ; // 歸還指標 ptr 所指向的動態記憶空間 // 回作業系統,但指標 ptr 變數仍存在 深度學習 C++ 17 指標
  • 18. new 與 delete (二)  圖表表示 變數 ptr ptr 資料 &□ 變數 □ 資料 int *ptr ptr = new int 變數 ptr ptr 資料 &□ &□ 變數 □ 資料 10 *ptr = 10 delete ptr 深度學習 C++ 18 指標
  • 19. new 與 delete (三)  取得 n 個單位的連續記憶空間 int i , n ; cin >> n ; int *ptr = new int [n] ; // ptr 指標指向 n 個連續整數空間的 // 首位整數位址 for( i = 0 ; i < n ; ++i ) *(ptr+i) = (i+1)*(i+1) ; ‧‧‧ 1 4 9 16 ‧‧‧ n2 ptr ptr+1 ptr+2 ptr+3 ptr+(n-1)  以上的 *(ptr+i) 可以使用 ptr[i] 取代,因此之前迴圈可簡化成 for( i = 0 ; i < n ; ++i ) ptr[i] = (i+1)*(i+1) ;  歸還一整塊記憶空間 delete [] ptr ; // 歸還指標 ptr 所指向的一整塊動態記憶空間, // 但指標 ptr 仍會存在 深度學習 C++ 19 指標
  • 20. new 與 delete (四)  由 new 取得的記憶空間會持續存在。當程式執行 delete 時,作業系統才會將指標所指向的記憶空間取回重新使用  由 new 取來的動態空間要隨時有指標記得這些動態空間的位 址。若程式執行中,造成這些記憶空間的位址失去聯繫,這種 現象被稱為記憶空間流失 (memory leak)  當程式執行結束後,所有使用的動態記憶空間( 包含流失 的記憶空間 )都會全部退還給系統重新使用 int foo = 3 ; int *ptr = new int(5) ; // 指標 ptr 指向一動態空間,內存有整數 5 cout << *ptr << endl ; // 列印指標 ptr 所指向的資料值 5 記憶空間流失 ptr = &foo ; // 指標 ptr 改指向 foo 變數 cout << *ptr << endl ; // 列印指標 ptr 所指向的資料值 3 深度學習 C++ 20 指標
  • 21. 指標與結構資料型別  指標可以使用 -> 來讀取結構資料型別的資料 struct Complex { double re, im ; }; Complex foo ; // 定義一複數變數 Complex *ptr = &foo ; // 讓一複數指標指到此複數變數 ptr -> re = 2 ; // 利用指標來設定實數資料 ptr -> im = 5 ; // 利用指標來設定虛數資料 也可以使用以下方式 (*ptr).re = 2 ; (*ptr).im = 5 ; 深度學習 C++ 21 指標
  • 22. 指標的指標 (一)  指標內所儲存的資料也可以是另一個指標的位址 int foo = 5 ; int *p = &foo ; // 整數指標 p 指向整數 foo int **q = &p ; // 指標的指標 q 指向整數指標 p q p foo &p &foo 5 q p <=> *q foo <=> *p <=> **q cout << ”foo = ” << foo << endl // 都輸出 5 << ” *p = ” << *p << endl << ” **q = ” << **q << endl ; 深度學習 C++ 22 指標
  • 23. 指標的指標 (二)  利用雙層指標將指標所指到的位址對調 int foo = 5 , bar = 10 ; int *a = &foo , *b = &bar ; // a 指向 foo , b 指向 bar int *tmp ; int **c = &a , **d = &b ; // c 指向 a , d 指向 b cout << ” **c ” << **c << ’n’ // 印出 c,d在雙層指標運作後所 << ” **d ” << **d << ”nn”; // 指向的資料值,分別為 5 和 10 tmp = *c ; // tmp 指向 c 所指向的位址 *c = *d ; // c 指向 d 所指向的位址 *d = tmp ; // d 指向 tmp 所指向的位址 cout << ” **c ” << **c << ’n’ << ” **d ” << **d << endl ; // 印出 10 和 5 深度學習 C++ 23 指標
  • 24. 指標的指標 (三) bar foo bar tmp foo 變數 10 5 10 5 資料 a b 變數 &foo &bar 資料 int foo=5, bar=10 int *a=&foo, *b=&bar, *tmp bar tmp foo d bar tmp foo d 變數 10 5 &b 10 &foo 5 &b 資料 c a b c a b 變數 &a &foo &bar &a &foo &bar 資料 int **c=&a, **d=&b tmp = *c bar tmp foo d bar tmp foo d 變數 10 &foo 5 &b 10 &foo 5 &b 資料 c a b c a b 變數 &a &bar &bar &a &bar &foo 資料 *c = *d *d = tmp 深度學習 C++ 24 指標
  • 25. 雙層指標與動態矩陣 (一)  雙層指標可以指向動態產生的矩陣 int n = 10 ; // 指標 ptr1 ptr2 … ptrm 分別指向 n 個動態整數記憶空間的起始位址 int *ptr1 = new int[n] ; int *ptr2 = new int[n] ; ‧‧‧ int *ptrm = new int[n] ;  將 m 個指標合併使用 // 指標的指標 ptr 指向 m 個動態指標記憶空間的起始位址 int ** ptr = new int*[m] ; // 讓每個 ptr[i] 指標指向 n 個動態整數記憶空間的起始位址 for( int i = 0 ; i < m ; ++i ) ptr[i] = new int[n] ; 深度學習 C++ 25 指標
  • 26. 雙層指標與動態矩陣 (二) int** int* int ptr ptr[0] ptr[1][0] ptr[1][1] … ptr[1][n-1] ptr[1] ptr[2] ptr[0][0] ptr[0][1] … ptr[0][n-1] … … ‧‧‧‧‧‧ ptr[m-1] ptr[m-1][0] ptr[m-1][1] … ptr[m-1][n-1] int **ptr = new int*[m] ; for ( i = 0 ; i < m ; ++i ) ptr[i] = new int[n] ; 深度學習 C++ 26 指標
  • 27. 雙層指標與動態矩陣 (三)  使用雙層指標設定矩陣元素 // 將矩陣每一個元素歸零 int r , c ; for ( r = 0 ; r < m ; ++r ) { for ( c = 0 ; c < n ; ++c ) ptr[r][c] = 0 ; }  歸還動態矩陣記憶空間 for ( int r = 0 ; r < m ; ++r ) delete [] ptr[r] ; delete [] ptr ; 深度學習 C++ 27 指標
  • 28. 九九乘法表:指標版 輸出: 1x1= 1 2x1= 2 3x1= 3 4x1= 4 5x1= 5 6x1= 6 7x1= 7 8x1= 8 9x1= 9 1x2= 2 2x2= 4 3x2= 6 4x2= 8 5x2=10 6x2=12 7x2=14 8x2=16 9x2=18 1x3= 3 2x3= 6 3x3= 9 4x3=12 5x3=15 6x3=18 7x3=21 8x3=24 9x3=27 1x4= 4 2x4= 8 3x4=12 4x4=16 5x4=20 6x4=24 7x4=28 8x4=32 9x4=36 1x5= 5 2x5=10 3x5=15 4x5=20 5x5=25 6x5=30 7x5=35 8x5=40 9x5=45 1x6= 6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 7x6=42 8x6=48 9x6=54 1x7= 7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 8x7=56 9x7=63 1x8= 8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 9x8=72 1x9= 9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81 程式 輸出 深度學習 C++ 28 指標
  • 29. 彈珠臺模擬  彈珠碰到滾輪後會等機會 地往左右兩方滾下,求彈 珠在各底層位置的機率?  作法: 假設有 M 個彈珠,利用亂 數函式決定彈珠在撞到滾 A|B|C|D|E|F 輪後往左或往右的方向, 滾 輪 彈 珠 台 n=5 統計各位置的彈珠數量, 除以 M 即為機率 程式 輸出 深度學習 C++ 29 指標
  • 30. 向量相乘 (一) a0 a1 ab = . . b0,b1,‧‧‧,bn-1 . an-1 a0b0 , a0b1 , ‧‧‧ , a0bn-1 a1b0 , a1b1 , ‧‧‧ , a1bn-1 = an-1b0 , an-1b1 , ‧‧‧ , an-1bn-1 M0,0 , M0,1 , ‧‧‧ , M0,n-1 M1,0 , M1,1 , ‧‧‧ , M1,n-1 = = M Mn-1,0 , Mn-1,1 , ‧‧‧ , Mn-1,n-1 深度學習 C++ 30 指標
  • 31. 向量相乘 (二)  由使用者輸入長度,在程式中以 new 向系統取 得 n2 個同型別記憶空間,如下圖: M0,0 M0,1 M0,2 ‧‧‧ M1,0 M1,1 ‧‧‧ Mn-1,n-1  這 n2 個動態記憶空間在計 程式 輸出 算機記憶體中是連續排列的 深度學習 C++ 31 指標
  • 32. 矩陣分解 A B S :nxn 方陣 S = A B C D:mxm 方陣 C D n = 2m  S = {si,j} , A = {ai,j} , B = {bi,j} … 則 ai,j = si,j 0 <= i , j < m bi,j = si,j+m ci,j = si+m,j 程式 輸出 di,j = si+m,j+m 深度學習 C++ 32 指標