SlideShare une entreprise Scribd logo
1  sur  61
第六章 陣列與指標




            1
陣列 Arrays

    陣列 : 由一連續且相同資料型態的元素所組成 .
    1. 所謂“連續”指的是元素是循序地儲存在記憶體裡 .
    陣列的宣告方式 datatype name [constant-size]
    1.   constant-size 不可以是變數 , 只能是常數且是一個正整數 , 例如 :
    2.           #define MAX_SIZE        16
    3.           ...
                                            a[0] 5
    4.           int list[MAX_SIZE + 1];
                                                a[1]   -2
    陣列的初始化 :
                                                a[2]   17

    1. 如 int a[3] = {5, -2, 17};
    2. 陣列元素若未進行初始化 , 其每個元素的值都是 garbage value
         • 註 : 對於 global 和 static 陣列其元素會初始為 0
    1. 陣列初始最後一個元素後 , 其它未初始化元素都會設為 0
         • int b[5] = {5,-2};




2
陣列 Arrays (cont.)

    若未明確指定 constant-size, 則編譯器會依列示的初始
    值個數來計算陣列所需的元素個數
         • int q[] = {1, 2, 3}; 等同於
           int q[3] = {1, 2, 3};
    陣列大小無法再更動
    C 陣列索引由 0 開始 , 因此 int a[3]; 為表示有 3 個
    int, 分別為 a[0], a[1] 和 a[2]
    1. 小心別存取 a[3].
    字串 (String) 的宣告可以是為字元陣列加上一個空字
    元 (NULL character), 如下 :
    1.            char str1[] = {'a', 'b', 'c', '0'};
                  char str2[] = "abc";




3
陣列 Arrays (cont.)

    extern int a[]; 此非陣列宣告 , 而是明確表示陣
    列 a 為外部參考 .(External Reference), 即陣列 a
    是定義在其他檔案 (file scope) 或任何函數外
    (global variable)
    const int a[3] = {5, -2, 17}; const 關鍵字可以使陣
    列元素只能讀無法修改 .




4
範例 -1D 陣列

    #include <stdio.h>
     #include <stdio.h>
    #define SIZE 33
     #define SIZE
    #define SHOW_1D(X,Y) for ((X)=0;(X)<(Y);(X)++) 
     #define SHOW_1D(X,Y) for ((X)=0;(X)<(Y);(X)++)
      printf("a[%d]=%-5d <--%pn",(X),a[(X)],&a[(X)]);
       printf("a[%d]=%-5d <--%pn",(X),a[(X)],&a[(X)]);
    int main()
     int main()
    {{
      int i=0;
       int i=0;
      int a[SIZE]={5,-2,17};
       int a[SIZE]={5,-2,17};
      SHOW_1D(i,SIZE);
       SHOW_1D(i,SIZE);
      a[1]=100;
       a[1]=100;
      SHOW_1D(i,SIZE);
       SHOW_1D(i,SIZE);

     return 0;
       return 0;
    }}



5
要讓程式當掉其實很容易


void fun(void)
{
 char a[4] ;
 a[4] = 0 ; // crash!
}

void fun(void)
{
 char a[3] ;

 a[3] = 0 ;         // may be still alive! Why?
}




6
隨堂練習

Please implement this function:
float D2A(int Digital_value) ;

-10bit AD (0-1023)
-對應電壓 0~3.3V
-每次取樣 10 筆,過濾掉最大與最小值,取平均
-傳入 Digital 值 ( 八筆平均 ) ,傳回電壓值

test.c – 使用者輸入 AD 值,呼叫 AD 模組的功能,傳回正確的電壓
值。
AD.c – AD 模組的實現
AD.h – AD 模組相關的宣告

7
D2A Converter



      Digital : 0~1023
      Voltage: 0 ~ 3.3V
                                3.3V


      Input Digital value = X     ?




1023             X
            =                      0   X   1023
3.3               V

       V = 3.3 * X / 1023

      8
指標 Pointer
指標

     指標 : 目的是用來指向其他變數 .
     1. 本身亦為一個變數 ,
     2. 指標內容為”所指向變數之記憶體位址” .
     和指標有關的二個運算子 (Operator)
     1. & 傳回變數的位址
     2. * Redirect operator( 間接存取運算子 ) 提取
        (dereferences) 被指標所指向的位置裡所儲存之值




10
範例

     int i,i,j;j;
       int
     int **p;
       int p;          /* pointer to `int' */
                        /* pointer to `int' */
     i i= 6;
         = 6;
     pp= &i;
          = &i;        /* set `p' to address of `i' */
                        /* set `p' to address of `i' */
     j j= *p;
         = *p;         /* set `j' to 66(value of `i') */
                        /* set `j' to (value of `i') */
     *p = 5;
       *p = 5;         /* set `i' to 55*/
                        /* set `i' to */



                    i 0xba04
                                 6 5
                    j 0xba08    6



                                                 *p

                    p 0xba18    0xba04




11
範例

     #include <stdio.h>
      #include <stdio.h>
     int data[2] = {100, 200};
      int data[2] = {100, 200};
     int moredata[2] = {300, 400};
      int moredata[2] = {300, 400};
     int main(void)
      int main(void)
     {{
       int **p1, **p2, **p3;
        int p1, p2, p3;

      p1 = p2 = data;
       p1 = p2 = data;
      p3 = moredata;
       p3 = moredata;
      printf(" *p1 = %d, *p2 = %d, *p3 = %dn",
       printf(" *p1 = %d, *p2 = %d, *p3 = %dn",
             *p1 , , *p2 , , *p3);
              *p1      *p2     *p3);
      printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %dn",
       printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %dn",
           *p1++ , ,*++p2 , ,(*p3)++);
            *p1++      *++p2    (*p3)++);
      printf(" *p1 = %d, *p2 = %d, *p3 = %dn",
       printf(" *p1 = %d, *p2 = %d, *p3 = %dn",
             *p1 , , *p2 , , *p3);
              *p1      *p2     *p3);
      return 0;
       return 0;
     }}


12
data[1] = 200

            data[0] = 100
data




            moredata[0]=400
                              *p1 = 100, *p2 = 100,   *p3 = 300
            moredata[0]=300
moredata




                  P3
                  P2
                  P1




       13
data[1] = 200

            data[0] = 100
data




            moredata[0]=400
                                    *p1++ = 100
moredata
            moredata[0]=300   301             access (*p1)
                                              p1++

                                    *++p2 = 200
                                              p2++
                                              access (*p2)
                  P3
                  P2                (*p3)++ = 300
                                               access *p3
                  P1                           (*p3) = (*p3) + 1




       14
data[1] = 200

            data[0] = 100
data




            moredata[0]=400
                                    *p1 = 200, *p2 = 200,   *p3 = 301
moredata
            moredata[0]=300   301




                  P3
                  P2
                  P1




       15
算我求求你們,
千萬別寫出 *++p2 這樣的鬼東西!

對軟體團隊而言,程式的可讀性與可維護性,
 其重要性超過一切!




16
指標 (cont.)

     null pointer : 指標內容為 0 (NULL)
     1. if (ptr) statement ;
     2. if ( ptr!= 0) statement ;
     指標不可以指向
     1. 常數值 (constants) 如 3, 因為 3 並沒有一個固定的記
        憶體位址 .
     2. 暫存器 (register) 變數 , 因為暫存器變數的內容並不
        是放在記憶體 , 因此沒有記憶體位址 .
     3. 運算式 (expressions) 如 8 * k , 運算式的結果即如同常
        數值 , 一樣沒有一個固定的記憶體位址 .




17
陣列與指標 (cont.)

     指標與陣列的關聯
     1. 陣列的存取是直接存取 (direct addressing), 而指標的存取是間接
        存取 (indirect addressing)
     2. 陣列名稱 arr 為一個常數值 , 代表陣列元素的起始位址 , 而指標
        p 的內容為 arr 陣列起始位址
     3. &arr[0]==arr
     4. arr[i]==*(arr+i)
     5. arr++; 是錯誤的 ( 提醒 :++ 和—運算子的對象是變數 )
     6. sizeof 運算子
       • sizeof(arr) 傳回陣列所佔記憶體空間
       • sizeof(p) 傳回指標變數所佔記憶體空間




18
陣列與指標 (cont.)

     1. & 運算子
       • &array == arrary == &arrary[0]
       • &pointer 傳回指標變數的位址 .
     1. 字串常數
       • 字串常數儲存在一個唯讀的記憶位置 .
       • char arr[] = "abc"
           陣列 arrary 其第一個元素至第 4 個元素為別被設為 'a', 'b',
           'c', '0'
           如同 strcpy(arr,”abc”)
       • char *ptr = "abc"
       • ptr 指向字串常數所在記憶體位址


                       “abc” 到底儲存在哪裡?

19
範例 -1D 陣列

     #include <stdio.h>
      #include <stdio.h>
     #define SIZE 3
      #define SIZE 3
     void show_1d(int *ar,int size);
      void show_1d(int *ar,int size);
     int main()
      int main()
     {{
        int i=0;
         int i=0;
        int a[3]={5,-2,17};
         int a[3]={5,-2,17};
        show_1d(a,SIZE);
         show_1d(a,SIZE);
        a[1]=100;
         a[1]=100;
        show_1d(&(a[0]),SIZE);
         show_1d(&(a[0]),SIZE);
       return 0;
        return 0;
     }}
     void show_1d(int *ar,int size)
      void show_1d(int *ar,int size)
     {{
        int i=0;
         int i=0;
        for (;i<size;i++) printf("ar[%d]=%-5d <--%pn",i,ar[i],&ar[i]);
         for (;i<size;i++) printf("ar[%d]=%-5d <--%pn",i,ar[i],&ar[i]);
     }}
20
#include <stdio.h>
      #include <stdio.h>
     #define SIZE 3
      #define SIZE 3
     void show_1d(int *start, int *end);
      void show_1d(int *start, int *end);
     int main()
      int main()
     {{
        int i=0;
         int i=0;
        int a[3]={5,-2,17};
         int a[3]={5,-2,17};
        show_1d(a,a+SIZE);
         show_1d(a,a+SIZE);
        a[1]=100;
         a[1]=100;
        show_1d(&a[0],a+SIZE);
         show_1d(&a[0],a+SIZE);
       return 0;
        return 0;
     }}
     void show_1d(int *start, int *end)
      void show_1d(int *start, int *end)
     {{ int i i= 0 ;;
         int = 0
        for (;stasrt<end;start++,i++)
         for (;stasrt<end;start++,i++)
           printf(“start[%d]=%-5d <-- %pn",i,*start, start);
            printf(“start[%d]=%-5d <-- %pn",i,*start, start);
     }}

21
陣列與指標 (cont.)

     千萬別存取一個未初始化的指標
     1. int *pt; // an uninitialized pointer
     2. *pt=4; // a terrible error
     3. 使用指標前 , 必須先讓指標指向一個已存在的變數的
        記憶體位址




22
指標的運算

     ptr++ 或 ptr=ptr+1 會使指標的數值增加一個單位 . 此
     單位大小由指標所指向資料型態的大小而定
     例如 ptr 指向位址 0xff00:
     1. 若 ptr char 的指標 , 則 ptr++ 將使 ptr 成為 0xff01
     2. 若 ptr 是一個指向 int (4 bytes) 的指標 , 則 ptr++ 將使 ptr 成為
        0xff04
     若 ptr1 指向 a[0] 且 ptr2 指向 a[3], 則
     1.   ptr2 > ptr1 的結果為真
     2.   ptr2 - ptr1 的結果 3 ( 和 a 陣列的資料型態無關 )




23
指標的運算 (cont.)

     若 ptr1 指向 a[0] 且 ptr2 指向 b[3], 則
     1. 無法確定 ptr2 > ptr1 或 ptr2 < ptr1 的結果 , 唯一能確
        定的只有 ptr2 != ptr1




24
指標的指標




int **p2; // a pointer to a pointer
 int **p2; // a pointer to a pointer
     int *p1;
      int *p1;
     int arr[3]={3,6,9};
      int arr[3]={3,6,9};
     p1=arr+2;
      p1=arr+2;
     p2=&p1;
      p2=&p1;
     **p2= 100;
      **p2= 100;




25
多維陣列

     宣告一個二維陣列如 float m[3][2];
     m 陣列的 6 個元素 , 分別為 m[0][0], m[0][1],
     m[1][0], m[1][1], m[2][0], m[2][1]




26
範例 -2D 陣列


     #include <stdio.h>
      #include <stdio.h>
     #define ROW 33
      #define ROW
     #define COL 22
      #define COL
      int main()
       int main()
     {{
        int i,j;
         int i,j;
       int m[ROW][COL]={{100,200},{300,400},{500,600}};
        int m[ROW][COL]={{100,200},{300,400},{500,600}};

       m[1][1]=900;
        m[1][1]=900;
       for (i=0;i<ROW;j=0,i++)
        for (i=0;i<ROW;j=0,i++)
          for (j=0;j<COL;j++)
           for (j=0;j<COL;j++)
             printf("m[%d][%d]=%-5d <--%pn",i,j,m[i][j],&m[i][j]);
              printf("m[%d][%d]=%-5d <--%pn",i,j,m[i][j],&m[i][j]);

     return 0;
      return 0;
     }}

27
多維陣列 (cont.)


     多維陣列即為多個”陣列的陣列” (of arrays of arrays...)
     宣告一個二維陣列如 float m[3][2]; //array of 3 array of 2
     floats
     1. m 是一個 float 型態的陣列其可儲存 3 項資料而每一項
         又具有 2 個元素 (2-int 資料型態單位的陣列 )
     2. float m[3][2]; // m is an array of 3 somethings
     3. float m[3][2]; // an array of 2 floats         (*m)[2]
     4. m[3][2] 是一個以 2-int 資料型態為單位的陣列
                 m[0]      m[0][0]        m[0][0]

                 m[1]      m[0][0]        m[0][0]

 pointer array   m[2]      m[0][0]        m[0][0]
28
An array of arrays

  zippo               the address of the first 2-int element
  zippo+2             the address of the third 2-int element
  *(zippo+2)          the third element, a 2-int array, hence the address of its first
                      element, an int
  *(zippo+2) + 1      the address of the second element of the 2-int array, also an int
  *(*(zippo+2) + 1)   the value of the second int in the third row (zippo[2][1])




                                                zippo[m][n] == *(*(zippo + m) + n)

29
Pointers to Multi-Dimensional Arrays

     int (* pz)[2]; // pz points to an array of 2 ints

     pz=zippo;
     pz[m][n] == *(*(pz + m) + n)




30
Example


     #include <stdio.h>

     int main(void)
     {
        int zippo[4][2] = { {2,4} , {6,8} , {1,3} , {5, 7} };

         printf(" zippo = %p, zippo + 1 = %pn",
                  zippo,      zippo + 1);
         printf("zippo[0] = %p, zippo[0] + 1 = %pn",
               zippo[0],     zippo[0] + 1);
         printf(" *zippo = %p, *zippo + 1 = %pn",
                 *zippo,      *zippo + 1);
         printf("zippo[0][0] = %dn", zippo[0][0]);
         printf(" *zippo[0] = %dn", *zippo[0]);
         printf(" **zippo = %dn", **zippo);
         printf("    zippo[2][1] = %dn", zippo[2][1]);
         printf("*(*(zippo+2) + 1) = %dn", *(*(zippo+2) + 1));   return 0;
     }

31
Pointer to const data

     int * p1;
     const int * p2;
     const int ** pp2;
     p1 = p2; // not valid -- assigning const to non-const
     p2 = p1; // valid -- assigning non-const to const
     pp2 = &p1; // not valid -- assigning non-const to const
      const int **pp2;
       int *p1;
      const int n = 13;
       pp2 = &p1; // not allowed, but suppose it were
      *pp2 = &n; // valid, both const, but sets p1 to point at n *p1
      *p1= 10; // valid, but changes const n


32
Constant pointer

      ch6/const_ptr.c
     #include <stdio.h>
     int main()
     {
       const int a=10;
       int b=20;
       const int * const ptr=&a;
       *ptr=100;
       ptr=&b;


      return 0;
     }
33
Functions and Multidimensional Arrays

     #define ROWS 3
      #define ROWS 3
     #define COLS 4
      #define COLS 4
     void sum_rows(int ar[][COLS], int rows);
      void sum_rows(int ar[][COLS], int rows);
     int main() {{
      int main()
     int junk[3][4] = {{
      int junk[3][4] =      {2,4,5,8} ,,
                             {2,4,5,8}
                            {3,5,6,9} ,,
                             {3,5,6,9}
                            {12,10,8,6}
                             {12,10,8,6}
                        };
                         };

           sum_rows(junk, ROWS);
            sum_rows(junk, ROWS);
           return 0;
            return 0;
     }}


34
void sum_rows(int ar[][COLS], int rows)
      void sum_rows(int ar[][COLS], int rows)
     {{
        int r;
         int r;
        int c;
         int c;
        int tot;
         int tot;

          for (r = 0; rr < rows; r++)
           for (r = 0; < rows; r++)
          {{
             tot = 0;
              tot = 0;
             for (c = 0; c < COLS; c++)
              for (c = 0; c < COLS; c++)
                 tot += ar[r][c];
                  tot += ar[r][c];
             printf("row %d: sum = %dn", r, tot);
              printf("row %d: sum = %dn", r, tot);
          }}
     }}
35
Lab #6 - Homework



      矩陣相乘 – 除了影像處理或加解密…等,我不認
      為你 在嵌入式系統裡會碰 到更複雜的陣列運算了
      !
     (http://zh.wikipedia.org/zh-hk/ 矩陣乘法 )


      早晚你 要碰 到的 – 泡泡排序法。




36
37
Bubble Sort

#include <stdio.h> /* Bubble Sort */

void main(void)
{
 int data[50];
 int i,j,n,temp;

printf("Please input integer number you want to sort:");
scanf("%d" ,&n);
printf("n");

if (n > 49)
{
              printf("number should be less than 49n");
              return;
}

for (i = 1;i <= n;i++)
{
               printf("input data[%d]=", i);
               scanf("%d", &data[i]);
}




38
                                                           38
Sorting

for (i=1; i <= n; i++)
 {
            for (j = n; j > i; j--)
            {
                         if (data[j-1] > data[j])
                         {
                                     temp = data[j-1];
                                     data[j-1] = data[j];
                                     data[j] = temp;
                         }
            }
 }

 printf("nSorting result: n");
 for(i = 1; i <= n; i++)
             printf("%d ", data[i]);
}

39
                                                            39
矩陣相乘

1. 輸入矩陣 row, column
2. 輸入矩陣所有元素
3. 矩陣相乘




40
矩陣相乘 (1)

#include <stdio.h>

// Matrix A : m x n (row = m, column = n)
// Matrix B : n x p
// A x B = C (C should be m x p)
//
#define m 3
#define n 2
#define p 2




41
矩陣相乘 (2)
void main()
{
              int A[m+1][n+1], B[n+1][p+1], C[m+1][p+1];
              int i, j, k;

              printf("Please input Matrix A:");
              for (i =1 ; i<= m; i++)
              {
              for(j=1;j<=n;j++)
                            scanf("%d",&A[i][j]);
              }/*end for*/


              printf("Please input Matrix B:");
              for (i =1 ; i<= n; i++)
              {
              for(j=1;j<=p;j++)
                            scanf("%d",&B[i][j]);
              }/*end for*/




  42
矩陣相乘 (3)

     for (i=1; i<=m; i++)
     {
     for (j=1; j<=p; j++)
                  {
                  C[i][j]=0;
                  for(k = 1; k <= n; k++)
                              {
                              C[i][j] = C[i][j] +A[i][k] * B[k][j];
                  }
                  printf("%d ", C[i][j]);
     }
     printf("n");
     }
}




43
How to access CPU registers?


       CPU Internal Registers
       Memory Mapping Registers




  44
CPU Internal Registers




  45
/*
      透過一般暫存器 R4 ,設定 Stack Point ( SP )暫存器的值
           (通常特殊暫存器都不允許直接設值 , 必須透過一般暫存器)
     */
        asm("xld.w %r4,0x20000");
        asm("ld.w %sp,%r4");


     /*
      假設第 0 個 bit 代表 IE bit ( Interrupt Enable ),值為 1 時表示允許中
     斷產生
      以下的程式會令 CPU 允許中斷發生
     */
        asm("ld.w %r8, 0x000001"); // Set PSR to interrupt enable
        asm("ld.w %psr, %r8");




 GCC-Inline-Assembly-HOWTO
     Reference-2

46
Memory Mapping Registers




47
“volatile”




             這兩個程式等價嗎?
48
使用 C 語言開發驅動程式 (1)

     Volatile 變數
volatile unsigned int * xxx_register = 0x300024 ;

// 對暫存器 0x300024 連續設值,因為變數形態設定為 volatile
// 所以對 xxx_register 的操作不會被最佳化
//
*xxx_register = 0x00ABCDEF ;
*xxx_register = 0x12345678 ; ;


// 0x300021 是 CPU 的 memory mapping Register
// 以下的運算是將 bit 4 設為 1
//
 *((volatile unsi gned char *)0x300021) |= 0x10;



 *((volatile unsigned char *)0x300021) =
                        *((volatile unsi gned char *)0x300021) | 0x10 ;


49
volatile unsigned char data ;

data = *((volatile unsigned char *)0x300021) ;

data = data | 0x10 ;               // set bit 4 as 1

*((volatile unsi gned char *)0x300021 = data ;




50
IF FPSHIFT-mask-enable
     set to 16bpp and color mode
ELSE
     set LCD-panel-data-width to 4-bit mode




51
動態記憶體配置



void * malloc(int size) ;
void free(void * ptr) ;




52
main()
     {
      int A_array[20] ;

     int * B_array ;
     int array_no ;

     int i ;

     for(i=0;i<20;i++)
                    A_array[i] = 0 ;

     printf("please input size of array B: ") ;
     scanf("%d",&array_no) ;

     B_array = (int *)malloc(array_no * sizeof(int)) ;
     if(B_array != NULL)
     {
                    for(i=0;i<array_no;i++)
                                   B_array[i] = 0 ;
     }

      free(B_array ) ;
     }




53
Lab #6-2

使用 malloc/free 修改 homework1 (多項式)程
式,
使其可以處理超過 10 項的多項式。




54
Lab #6-3

     4 個學生的四科成績




     求全部平均



     求第 n 位學生的平均



55                 Page:97
記憶體測試


     記憶體會出問題的機會比想像的多, e.g.
     1.   電路設計或 Layout 錯誤
     2.   Chip Select 選錯
     3.   SDRAM controller 設定錯誤
     4.   Timing 設定



     基本的硬體測試 - 把各個記憶體的每 一個 byte 都測
     過,確定讀寫 ( 如果能寫的話 ) 都沒問題


56                                Copyright © 2007
                                   FITPI. All rights
Lab #6-4


1.   Allocate Memory as SRAM
2.   write(address,value)
3.   verify(address,value)
4.   calculate_checksum(address,size)




57
嵌入式系統標準函式庫的效能考量

      memcpy()                          void memcpy(void * dest, void * src, int n)
                                        {
                                         // 這個 function 也有可能是用 assembly 實現的 , 但算法基本上一樣
                                         //
                                         int i ;
                                         char *Dest = (char *)dest ;
                                         char *Src = (char *)src ;

                                         for(i=0;i<n;i++)
                                                      Dest[i] = Src[i] ;
                                                                                 安全的作法
                                                                                 安全的作法
                                        }


     void my_memcpy(void * dest, void * src, int n)
     {
      // for Video-RAM copy only
      //

                                                                           加速版
      int i ;
      long *Dest = (long *)dest ;                                          加速版
      long *Src = (long *)src ;

      for(i=0;i<(n>>2);i++)                      // 往右移兩個 bit  n/4
                   Dest[i] = Src[i] ;
     }

58
                                                                                         58
59
60
61

Contenu connexe

Tendances

オペアンプとアナログ計算機
オペアンプとアナログ計算機オペアンプとアナログ計算機
オペアンプとアナログ計算機Toshiyuki Masui
 
ブートストラップ法とその周辺とR
ブートストラップ法とその周辺とRブートストラップ法とその周辺とR
ブートストラップ法とその周辺とRDaisuke Yoneoka
 
統計的学習の基礎 5章前半(~5.6)
統計的学習の基礎 5章前半(~5.6)統計的学習の基礎 5章前半(~5.6)
統計的学習の基礎 5章前半(~5.6)Kota Mori
 
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明MITSUNARI Shigeo
 
用十分鐘學會字串處理的那些事兒!
用十分鐘學會字串處理的那些事兒!用十分鐘學會字串處理的那些事兒!
用十分鐘學會字串處理的那些事兒!鍾誠 陳鍾誠
 
はじめてのShiny
はじめてのShinyはじめてのShiny
はじめてのShinyKazuya Wada
 
ARMアーキテクチャにおけるセキュリティ機構の紹介
ARMアーキテクチャにおけるセキュリティ機構の紹介ARMアーキテクチャにおけるセキュリティ機構の紹介
ARMアーキテクチャにおけるセキュリティ機構の紹介sounakano
 
ハイパースレッディングの並列化への影響
ハイパースレッディングの並列化への影響ハイパースレッディングの並列化への影響
ハイパースレッディングの並列化への影響Hiroshi Watanabe
 
Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜
Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜
Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜Takahiro Inoue
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013Ryo Sakamoto
 
Rにおける大規模データ解析(第10回TokyoWebMining)
Rにおける大規模データ解析(第10回TokyoWebMining)Rにおける大規模データ解析(第10回TokyoWebMining)
Rにおける大規模データ解析(第10回TokyoWebMining)Shintaro Fukushima
 
C程式-函式與巨集
C程式-函式與巨集C程式-函式與巨集
C程式-函式與巨集艾鍗科技
 
78th Tokyo.R Radiantによるデータ分析入門
78th Tokyo.R Radiantによるデータ分析入門78th Tokyo.R Radiantによるデータ分析入門
78th Tokyo.R Radiantによるデータ分析入門ケンタ タナカ
 
アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法nitoyon
 
性能測定道 実践編
性能測定道 実践編性能測定道 実践編
性能測定道 実践編Yuto Hayamizu
 
Rでのtry関数によるエラー処理
Rでのtry関数によるエラー処理Rでのtry関数によるエラー処理
Rでのtry関数によるエラー処理wada, kazumi
 
汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mcl汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mclMITSUNARI Shigeo
 

Tendances (20)

オペアンプとアナログ計算機
オペアンプとアナログ計算機オペアンプとアナログ計算機
オペアンプとアナログ計算機
 
ブートストラップ法とその周辺とR
ブートストラップ法とその周辺とRブートストラップ法とその周辺とR
ブートストラップ法とその周辺とR
 
R高速化
R高速化R高速化
R高速化
 
統計的学習の基礎 5章前半(~5.6)
統計的学習の基礎 5章前半(~5.6)統計的学習の基礎 5章前半(~5.6)
統計的学習の基礎 5章前半(~5.6)
 
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
レベル2準同型暗号の平文バイナリ制約を与えるコンパクトな非対話ゼロ知識証明
 
Python入門
Python入門Python入門
Python入門
 
用十分鐘學會字串處理的那些事兒!
用十分鐘學會字串處理的那些事兒!用十分鐘學會字串處理的那些事兒!
用十分鐘學會字串處理的那些事兒!
 
はじめてのShiny
はじめてのShinyはじめてのShiny
はじめてのShiny
 
ARMアーキテクチャにおけるセキュリティ機構の紹介
ARMアーキテクチャにおけるセキュリティ機構の紹介ARMアーキテクチャにおけるセキュリティ機構の紹介
ARMアーキテクチャにおけるセキュリティ機構の紹介
 
ハイパースレッディングの並列化への影響
ハイパースレッディングの並列化への影響ハイパースレッディングの並列化への影響
ハイパースレッディングの並列化への影響
 
Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜
Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜
Map Reduce 〜入門編:仕組みの理解とアルゴリズムデザイン〜
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
 
Rにおける大規模データ解析(第10回TokyoWebMining)
Rにおける大規模データ解析(第10回TokyoWebMining)Rにおける大規模データ解析(第10回TokyoWebMining)
Rにおける大規模データ解析(第10回TokyoWebMining)
 
C程式-函式與巨集
C程式-函式與巨集C程式-函式與巨集
C程式-函式與巨集
 
計算量
計算量計算量
計算量
 
78th Tokyo.R Radiantによるデータ分析入門
78th Tokyo.R Radiantによるデータ分析入門78th Tokyo.R Radiantによるデータ分析入門
78th Tokyo.R Radiantによるデータ分析入門
 
アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法アルゴリズムイントロダクション15章 動的計画法
アルゴリズムイントロダクション15章 動的計画法
 
性能測定道 実践編
性能測定道 実践編性能測定道 実践編
性能測定道 実践編
 
Rでのtry関数によるエラー処理
Rでのtry関数によるエラー処理Rでのtry関数によるエラー処理
Rでのtry関数によるエラー処理
 
汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mcl汎用性と高速性を目指したペアリング暗号ライブラリ mcl
汎用性と高速性を目指したペアリング暗号ライブラリ mcl
 

Similaire à C程式-陣列與指標

Similaire à C程式-陣列與指標 (20)

第6章指针
第6章指针第6章指针
第6章指针
 
17第十七讲(第七章中)(2)
17第十七讲(第七章中)(2)17第十七讲(第七章中)(2)
17第十七讲(第七章中)(2)
 
第5章数组
第5章数组第5章数组
第5章数组
 
Ch 6
Ch 6Ch 6
Ch 6
 
Python入門:5大概念初心者必備
Python入門:5大概念初心者必備Python入門:5大概念初心者必備
Python入門:5大概念初心者必備
 
Python learn guide
Python learn guidePython learn guide
Python learn guide
 
C语言学习100例实例程序
C语言学习100例实例程序C语言学习100例实例程序
C语言学习100例实例程序
 
第4章函数
第4章函数第4章函数
第4章函数
 
竞赛中C++语言拾遗
竞赛中C++语言拾遗竞赛中C++语言拾遗
竞赛中C++语言拾遗
 
Ch2 教學
Ch2 教學Ch2 教學
Ch2 教學
 
Arduino程式快速入門
Arduino程式快速入門Arduino程式快速入門
Arduino程式快速入門
 
Ch2
Ch2Ch2
Ch2
 
Ppt 1-50
Ppt 1-50Ppt 1-50
Ppt 1-50
 
Python 入門
Python 入門 Python 入門
Python 入門
 
Ch9 教學
Ch9 教學Ch9 教學
Ch9 教學
 
Chapter 5 array and struct
Chapter 5 array and structChapter 5 array and struct
Chapter 5 array and struct
 
Ch9
Ch9Ch9
Ch9
 
Ch4 教學
Ch4 教學Ch4 教學
Ch4 教學
 
Ch4
Ch4Ch4
Ch4
 
ncuma_串列.pptx
ncuma_串列.pptxncuma_串列.pptx
ncuma_串列.pptx
 

Plus de 艾鍗科技

TinyML - 4 speech recognition
TinyML - 4 speech recognition TinyML - 4 speech recognition
TinyML - 4 speech recognition 艾鍗科技
 
Appendix 1 Goolge colab
Appendix 1 Goolge colabAppendix 1 Goolge colab
Appendix 1 Goolge colab艾鍗科技
 
Project-IOT於餐館系統的應用
Project-IOT於餐館系統的應用Project-IOT於餐館系統的應用
Project-IOT於餐館系統的應用艾鍗科技
 
02 IoT implementation
02 IoT implementation02 IoT implementation
02 IoT implementation艾鍗科技
 
Tiny ML for spark Fun Edge
Tiny ML for spark Fun EdgeTiny ML for spark Fun Edge
Tiny ML for spark Fun Edge艾鍗科技
 
2. 機器學習簡介
2. 機器學習簡介2. 機器學習簡介
2. 機器學習簡介艾鍗科技
 
5.MLP(Multi-Layer Perceptron)
5.MLP(Multi-Layer Perceptron) 5.MLP(Multi-Layer Perceptron)
5.MLP(Multi-Layer Perceptron) 艾鍗科技
 
心率血氧檢測與運動促進
心率血氧檢測與運動促進心率血氧檢測與運動促進
心率血氧檢測與運動促進艾鍗科技
 
利用音樂&情境燈幫助放鬆
利用音樂&情境燈幫助放鬆利用音樂&情境燈幫助放鬆
利用音樂&情境燈幫助放鬆艾鍗科技
 
IoT感測器驅動程式 在樹莓派上實作
IoT感測器驅動程式在樹莓派上實作IoT感測器驅動程式在樹莓派上實作
IoT感測器驅動程式 在樹莓派上實作艾鍗科技
 
無線聲控遙控車
無線聲控遙控車無線聲控遙控車
無線聲控遙控車艾鍗科技
 
最佳光源的研究和實作
最佳光源的研究和實作最佳光源的研究和實作
最佳光源的研究和實作 艾鍗科技
 
無線監控網路攝影機與控制自走車
無線監控網路攝影機與控制自走車無線監控網路攝影機與控制自走車
無線監控網路攝影機與控制自走車 艾鍗科技
 
Reinforcement Learning
Reinforcement LearningReinforcement Learning
Reinforcement Learning艾鍗科技
 
人臉辨識考勤系統
人臉辨識考勤系統人臉辨識考勤系統
人臉辨識考勤系統艾鍗科技
 
智慧家庭Smart Home
智慧家庭Smart Home智慧家庭Smart Home
智慧家庭Smart Home艾鍗科技
 

Plus de 艾鍗科技 (20)

TinyML - 4 speech recognition
TinyML - 4 speech recognition TinyML - 4 speech recognition
TinyML - 4 speech recognition
 
Appendix 1 Goolge colab
Appendix 1 Goolge colabAppendix 1 Goolge colab
Appendix 1 Goolge colab
 
Project-IOT於餐館系統的應用
Project-IOT於餐館系統的應用Project-IOT於餐館系統的應用
Project-IOT於餐館系統的應用
 
02 IoT implementation
02 IoT implementation02 IoT implementation
02 IoT implementation
 
Tiny ML for spark Fun Edge
Tiny ML for spark Fun EdgeTiny ML for spark Fun Edge
Tiny ML for spark Fun Edge
 
Openvino ncs2
Openvino ncs2Openvino ncs2
Openvino ncs2
 
Step motor
Step motorStep motor
Step motor
 
2. 機器學習簡介
2. 機器學習簡介2. 機器學習簡介
2. 機器學習簡介
 
5.MLP(Multi-Layer Perceptron)
5.MLP(Multi-Layer Perceptron) 5.MLP(Multi-Layer Perceptron)
5.MLP(Multi-Layer Perceptron)
 
3. data features
3. data features3. data features
3. data features
 
心率血氧檢測與運動促進
心率血氧檢測與運動促進心率血氧檢測與運動促進
心率血氧檢測與運動促進
 
利用音樂&情境燈幫助放鬆
利用音樂&情境燈幫助放鬆利用音樂&情境燈幫助放鬆
利用音樂&情境燈幫助放鬆
 
IoT感測器驅動程式 在樹莓派上實作
IoT感測器驅動程式在樹莓派上實作IoT感測器驅動程式在樹莓派上實作
IoT感測器驅動程式 在樹莓派上實作
 
無線聲控遙控車
無線聲控遙控車無線聲控遙控車
無線聲控遙控車
 
最佳光源的研究和實作
最佳光源的研究和實作最佳光源的研究和實作
最佳光源的研究和實作
 
無線監控網路攝影機與控制自走車
無線監控網路攝影機與控制自走車無線監控網路攝影機與控制自走車
無線監控網路攝影機與控制自走車
 
Reinforcement Learning
Reinforcement LearningReinforcement Learning
Reinforcement Learning
 
Linux Device Tree
Linux Device TreeLinux Device Tree
Linux Device Tree
 
人臉辨識考勤系統
人臉辨識考勤系統人臉辨識考勤系統
人臉辨識考勤系統
 
智慧家庭Smart Home
智慧家庭Smart Home智慧家庭Smart Home
智慧家庭Smart Home
 

Dernier

EDUC6506(001)_ClassPresentation_2_TC330277 (1).pptx
EDUC6506(001)_ClassPresentation_2_TC330277 (1).pptxEDUC6506(001)_ClassPresentation_2_TC330277 (1).pptx
EDUC6506(001)_ClassPresentation_2_TC330277 (1).pptxmekosin001123
 
哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制
哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制
哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制jakepaige317
 
1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...
1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...
1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...黑客 接单【TG/微信qoqoqdqd】
 
educ6506presentationtc3302771-240427173057-06a46de5.pptx
educ6506presentationtc3302771-240427173057-06a46de5.pptxeduc6506presentationtc3302771-240427173057-06a46de5.pptx
educ6506presentationtc3302771-240427173057-06a46de5.pptxmekosin001123
 
EDUC6506_ClassPresentation_TC330277 (1).pptx
EDUC6506_ClassPresentation_TC330277 (1).pptxEDUC6506_ClassPresentation_TC330277 (1).pptx
EDUC6506_ClassPresentation_TC330277 (1).pptxmekosin001123
 
泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书
泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书
泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书jakepaige317
 

Dernier (6)

EDUC6506(001)_ClassPresentation_2_TC330277 (1).pptx
EDUC6506(001)_ClassPresentation_2_TC330277 (1).pptxEDUC6506(001)_ClassPresentation_2_TC330277 (1).pptx
EDUC6506(001)_ClassPresentation_2_TC330277 (1).pptx
 
哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制
哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制
哪里可以购买日本筑波学院大学学位记/做个假的文凭可认证吗/仿制日本大学毕业证/意大利语CELI证书定制
 
1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...
1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...
1.🎉“入侵大学入学考试中心修改成绩”来袭!ALEVEL替考大揭秘,轻松搞定考试成绩! 💥你还在为无法进入大学招生系统而烦恼吗?想知道如何通过技术手段更改...
 
educ6506presentationtc3302771-240427173057-06a46de5.pptx
educ6506presentationtc3302771-240427173057-06a46de5.pptxeduc6506presentationtc3302771-240427173057-06a46de5.pptx
educ6506presentationtc3302771-240427173057-06a46de5.pptx
 
EDUC6506_ClassPresentation_TC330277 (1).pptx
EDUC6506_ClassPresentation_TC330277 (1).pptxEDUC6506_ClassPresentation_TC330277 (1).pptx
EDUC6506_ClassPresentation_TC330277 (1).pptx
 
泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书
泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书
泽兰应用科学大学毕业证制作/定制国外大学录取通知书/购买一个假的建国科技大学硕士学位证书
 

C程式-陣列與指標

  • 2. 陣列 Arrays 陣列 : 由一連續且相同資料型態的元素所組成 . 1. 所謂“連續”指的是元素是循序地儲存在記憶體裡 . 陣列的宣告方式 datatype name [constant-size] 1. constant-size 不可以是變數 , 只能是常數且是一個正整數 , 例如 : 2. #define MAX_SIZE 16 3. ... a[0] 5 4. int list[MAX_SIZE + 1]; a[1] -2 陣列的初始化 : a[2] 17 1. 如 int a[3] = {5, -2, 17}; 2. 陣列元素若未進行初始化 , 其每個元素的值都是 garbage value • 註 : 對於 global 和 static 陣列其元素會初始為 0 1. 陣列初始最後一個元素後 , 其它未初始化元素都會設為 0 • int b[5] = {5,-2}; 2
  • 3. 陣列 Arrays (cont.) 若未明確指定 constant-size, 則編譯器會依列示的初始 值個數來計算陣列所需的元素個數 • int q[] = {1, 2, 3}; 等同於 int q[3] = {1, 2, 3}; 陣列大小無法再更動 C 陣列索引由 0 開始 , 因此 int a[3]; 為表示有 3 個 int, 分別為 a[0], a[1] 和 a[2] 1. 小心別存取 a[3]. 字串 (String) 的宣告可以是為字元陣列加上一個空字 元 (NULL character), 如下 : 1. char str1[] = {'a', 'b', 'c', '0'}; char str2[] = "abc"; 3
  • 4. 陣列 Arrays (cont.) extern int a[]; 此非陣列宣告 , 而是明確表示陣 列 a 為外部參考 .(External Reference), 即陣列 a 是定義在其他檔案 (file scope) 或任何函數外 (global variable) const int a[3] = {5, -2, 17}; const 關鍵字可以使陣 列元素只能讀無法修改 . 4
  • 5. 範例 -1D 陣列 #include <stdio.h> #include <stdio.h> #define SIZE 33 #define SIZE #define SHOW_1D(X,Y) for ((X)=0;(X)<(Y);(X)++) #define SHOW_1D(X,Y) for ((X)=0;(X)<(Y);(X)++) printf("a[%d]=%-5d <--%pn",(X),a[(X)],&a[(X)]); printf("a[%d]=%-5d <--%pn",(X),a[(X)],&a[(X)]); int main() int main() {{ int i=0; int i=0; int a[SIZE]={5,-2,17}; int a[SIZE]={5,-2,17}; SHOW_1D(i,SIZE); SHOW_1D(i,SIZE); a[1]=100; a[1]=100; SHOW_1D(i,SIZE); SHOW_1D(i,SIZE); return 0; return 0; }} 5
  • 6. 要讓程式當掉其實很容易 void fun(void) { char a[4] ; a[4] = 0 ; // crash! } void fun(void) { char a[3] ; a[3] = 0 ; // may be still alive! Why? } 6
  • 7. 隨堂練習 Please implement this function: float D2A(int Digital_value) ; -10bit AD (0-1023) -對應電壓 0~3.3V -每次取樣 10 筆,過濾掉最大與最小值,取平均 -傳入 Digital 值 ( 八筆平均 ) ,傳回電壓值 test.c – 使用者輸入 AD 值,呼叫 AD 模組的功能,傳回正確的電壓 值。 AD.c – AD 模組的實現 AD.h – AD 模組相關的宣告 7
  • 8. D2A Converter Digital : 0~1023 Voltage: 0 ~ 3.3V 3.3V Input Digital value = X ? 1023 X = 0 X 1023 3.3 V V = 3.3 * X / 1023 8
  • 10. 指標 指標 : 目的是用來指向其他變數 . 1. 本身亦為一個變數 , 2. 指標內容為”所指向變數之記憶體位址” . 和指標有關的二個運算子 (Operator) 1. & 傳回變數的位址 2. * Redirect operator( 間接存取運算子 ) 提取 (dereferences) 被指標所指向的位置裡所儲存之值 10
  • 11. 範例 int i,i,j;j; int int **p; int p; /* pointer to `int' */ /* pointer to `int' */ i i= 6; = 6; pp= &i; = &i; /* set `p' to address of `i' */ /* set `p' to address of `i' */ j j= *p; = *p; /* set `j' to 66(value of `i') */ /* set `j' to (value of `i') */ *p = 5; *p = 5; /* set `i' to 55*/ /* set `i' to */ i 0xba04 6 5 j 0xba08 6 *p p 0xba18 0xba04 11
  • 12. 範例 #include <stdio.h> #include <stdio.h> int data[2] = {100, 200}; int data[2] = {100, 200}; int moredata[2] = {300, 400}; int moredata[2] = {300, 400}; int main(void) int main(void) {{ int **p1, **p2, **p3; int p1, p2, p3; p1 = p2 = data; p1 = p2 = data; p3 = moredata; p3 = moredata; printf(" *p1 = %d, *p2 = %d, *p3 = %dn", printf(" *p1 = %d, *p2 = %d, *p3 = %dn", *p1 , , *p2 , , *p3); *p1 *p2 *p3); printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %dn", printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %dn", *p1++ , ,*++p2 , ,(*p3)++); *p1++ *++p2 (*p3)++); printf(" *p1 = %d, *p2 = %d, *p3 = %dn", printf(" *p1 = %d, *p2 = %d, *p3 = %dn", *p1 , , *p2 , , *p3); *p1 *p2 *p3); return 0; return 0; }} 12
  • 13. data[1] = 200 data[0] = 100 data moredata[0]=400 *p1 = 100, *p2 = 100, *p3 = 300 moredata[0]=300 moredata P3 P2 P1 13
  • 14. data[1] = 200 data[0] = 100 data moredata[0]=400 *p1++ = 100 moredata moredata[0]=300 301  access (*p1)  p1++ *++p2 = 200  p2++  access (*p2) P3 P2 (*p3)++ = 300  access *p3 P1  (*p3) = (*p3) + 1 14
  • 15. data[1] = 200 data[0] = 100 data moredata[0]=400 *p1 = 200, *p2 = 200, *p3 = 301 moredata moredata[0]=300 301 P3 P2 P1 15
  • 17. 指標 (cont.) null pointer : 指標內容為 0 (NULL) 1. if (ptr) statement ; 2. if ( ptr!= 0) statement ; 指標不可以指向 1. 常數值 (constants) 如 3, 因為 3 並沒有一個固定的記 憶體位址 . 2. 暫存器 (register) 變數 , 因為暫存器變數的內容並不 是放在記憶體 , 因此沒有記憶體位址 . 3. 運算式 (expressions) 如 8 * k , 運算式的結果即如同常 數值 , 一樣沒有一個固定的記憶體位址 . 17
  • 18. 陣列與指標 (cont.) 指標與陣列的關聯 1. 陣列的存取是直接存取 (direct addressing), 而指標的存取是間接 存取 (indirect addressing) 2. 陣列名稱 arr 為一個常數值 , 代表陣列元素的起始位址 , 而指標 p 的內容為 arr 陣列起始位址 3. &arr[0]==arr 4. arr[i]==*(arr+i) 5. arr++; 是錯誤的 ( 提醒 :++ 和—運算子的對象是變數 ) 6. sizeof 運算子 • sizeof(arr) 傳回陣列所佔記憶體空間 • sizeof(p) 傳回指標變數所佔記憶體空間 18
  • 19. 陣列與指標 (cont.) 1. & 運算子 • &array == arrary == &arrary[0] • &pointer 傳回指標變數的位址 . 1. 字串常數 • 字串常數儲存在一個唯讀的記憶位置 . • char arr[] = "abc" 陣列 arrary 其第一個元素至第 4 個元素為別被設為 'a', 'b', 'c', '0' 如同 strcpy(arr,”abc”) • char *ptr = "abc" • ptr 指向字串常數所在記憶體位址 “abc” 到底儲存在哪裡? 19
  • 20. 範例 -1D 陣列 #include <stdio.h> #include <stdio.h> #define SIZE 3 #define SIZE 3 void show_1d(int *ar,int size); void show_1d(int *ar,int size); int main() int main() {{ int i=0; int i=0; int a[3]={5,-2,17}; int a[3]={5,-2,17}; show_1d(a,SIZE); show_1d(a,SIZE); a[1]=100; a[1]=100; show_1d(&(a[0]),SIZE); show_1d(&(a[0]),SIZE); return 0; return 0; }} void show_1d(int *ar,int size) void show_1d(int *ar,int size) {{ int i=0; int i=0; for (;i<size;i++) printf("ar[%d]=%-5d <--%pn",i,ar[i],&ar[i]); for (;i<size;i++) printf("ar[%d]=%-5d <--%pn",i,ar[i],&ar[i]); }} 20
  • 21. #include <stdio.h> #include <stdio.h> #define SIZE 3 #define SIZE 3 void show_1d(int *start, int *end); void show_1d(int *start, int *end); int main() int main() {{ int i=0; int i=0; int a[3]={5,-2,17}; int a[3]={5,-2,17}; show_1d(a,a+SIZE); show_1d(a,a+SIZE); a[1]=100; a[1]=100; show_1d(&a[0],a+SIZE); show_1d(&a[0],a+SIZE); return 0; return 0; }} void show_1d(int *start, int *end) void show_1d(int *start, int *end) {{ int i i= 0 ;; int = 0 for (;stasrt<end;start++,i++) for (;stasrt<end;start++,i++) printf(“start[%d]=%-5d <-- %pn",i,*start, start); printf(“start[%d]=%-5d <-- %pn",i,*start, start); }} 21
  • 22. 陣列與指標 (cont.) 千萬別存取一個未初始化的指標 1. int *pt; // an uninitialized pointer 2. *pt=4; // a terrible error 3. 使用指標前 , 必須先讓指標指向一個已存在的變數的 記憶體位址 22
  • 23. 指標的運算 ptr++ 或 ptr=ptr+1 會使指標的數值增加一個單位 . 此 單位大小由指標所指向資料型態的大小而定 例如 ptr 指向位址 0xff00: 1. 若 ptr char 的指標 , 則 ptr++ 將使 ptr 成為 0xff01 2. 若 ptr 是一個指向 int (4 bytes) 的指標 , 則 ptr++ 將使 ptr 成為 0xff04 若 ptr1 指向 a[0] 且 ptr2 指向 a[3], 則 1. ptr2 > ptr1 的結果為真 2. ptr2 - ptr1 的結果 3 ( 和 a 陣列的資料型態無關 ) 23
  • 24. 指標的運算 (cont.) 若 ptr1 指向 a[0] 且 ptr2 指向 b[3], 則 1. 無法確定 ptr2 > ptr1 或 ptr2 < ptr1 的結果 , 唯一能確 定的只有 ptr2 != ptr1 24
  • 25. 指標的指標 int **p2; // a pointer to a pointer int **p2; // a pointer to a pointer int *p1; int *p1; int arr[3]={3,6,9}; int arr[3]={3,6,9}; p1=arr+2; p1=arr+2; p2=&p1; p2=&p1; **p2= 100; **p2= 100; 25
  • 26. 多維陣列 宣告一個二維陣列如 float m[3][2]; m 陣列的 6 個元素 , 分別為 m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1] 26
  • 27. 範例 -2D 陣列 #include <stdio.h> #include <stdio.h> #define ROW 33 #define ROW #define COL 22 #define COL int main() int main() {{ int i,j; int i,j; int m[ROW][COL]={{100,200},{300,400},{500,600}}; int m[ROW][COL]={{100,200},{300,400},{500,600}}; m[1][1]=900; m[1][1]=900; for (i=0;i<ROW;j=0,i++) for (i=0;i<ROW;j=0,i++) for (j=0;j<COL;j++) for (j=0;j<COL;j++) printf("m[%d][%d]=%-5d <--%pn",i,j,m[i][j],&m[i][j]); printf("m[%d][%d]=%-5d <--%pn",i,j,m[i][j],&m[i][j]); return 0; return 0; }} 27
  • 28. 多維陣列 (cont.) 多維陣列即為多個”陣列的陣列” (of arrays of arrays...) 宣告一個二維陣列如 float m[3][2]; //array of 3 array of 2 floats 1. m 是一個 float 型態的陣列其可儲存 3 項資料而每一項 又具有 2 個元素 (2-int 資料型態單位的陣列 ) 2. float m[3][2]; // m is an array of 3 somethings 3. float m[3][2]; // an array of 2 floats (*m)[2] 4. m[3][2] 是一個以 2-int 資料型態為單位的陣列 m[0] m[0][0] m[0][0] m[1] m[0][0] m[0][0] pointer array m[2] m[0][0] m[0][0] 28
  • 29. An array of arrays zippo the address of the first 2-int element zippo+2 the address of the third 2-int element *(zippo+2) the third element, a 2-int array, hence the address of its first element, an int *(zippo+2) + 1 the address of the second element of the 2-int array, also an int *(*(zippo+2) + 1) the value of the second int in the third row (zippo[2][1]) zippo[m][n] == *(*(zippo + m) + n) 29
  • 30. Pointers to Multi-Dimensional Arrays int (* pz)[2]; // pz points to an array of 2 ints pz=zippo; pz[m][n] == *(*(pz + m) + n) 30
  • 31. Example #include <stdio.h> int main(void) { int zippo[4][2] = { {2,4} , {6,8} , {1,3} , {5, 7} }; printf(" zippo = %p, zippo + 1 = %pn", zippo, zippo + 1); printf("zippo[0] = %p, zippo[0] + 1 = %pn", zippo[0], zippo[0] + 1); printf(" *zippo = %p, *zippo + 1 = %pn", *zippo, *zippo + 1); printf("zippo[0][0] = %dn", zippo[0][0]); printf(" *zippo[0] = %dn", *zippo[0]); printf(" **zippo = %dn", **zippo); printf(" zippo[2][1] = %dn", zippo[2][1]); printf("*(*(zippo+2) + 1) = %dn", *(*(zippo+2) + 1)); return 0; } 31
  • 32. Pointer to const data int * p1; const int * p2; const int ** pp2; p1 = p2; // not valid -- assigning const to non-const p2 = p1; // valid -- assigning non-const to const pp2 = &p1; // not valid -- assigning non-const to const const int **pp2; int *p1; const int n = 13; pp2 = &p1; // not allowed, but suppose it were *pp2 = &n; // valid, both const, but sets p1 to point at n *p1 *p1= 10; // valid, but changes const n 32
  • 33. Constant pointer ch6/const_ptr.c #include <stdio.h> int main() { const int a=10; int b=20; const int * const ptr=&a; *ptr=100; ptr=&b; return 0; } 33
  • 34. Functions and Multidimensional Arrays #define ROWS 3 #define ROWS 3 #define COLS 4 #define COLS 4 void sum_rows(int ar[][COLS], int rows); void sum_rows(int ar[][COLS], int rows); int main() {{ int main() int junk[3][4] = {{ int junk[3][4] = {2,4,5,8} ,, {2,4,5,8} {3,5,6,9} ,, {3,5,6,9} {12,10,8,6} {12,10,8,6} }; }; sum_rows(junk, ROWS); sum_rows(junk, ROWS); return 0; return 0; }} 34
  • 35. void sum_rows(int ar[][COLS], int rows) void sum_rows(int ar[][COLS], int rows) {{ int r; int r; int c; int c; int tot; int tot; for (r = 0; rr < rows; r++) for (r = 0; < rows; r++) {{ tot = 0; tot = 0; for (c = 0; c < COLS; c++) for (c = 0; c < COLS; c++) tot += ar[r][c]; tot += ar[r][c]; printf("row %d: sum = %dn", r, tot); printf("row %d: sum = %dn", r, tot); }} }} 35
  • 36. Lab #6 - Homework 矩陣相乘 – 除了影像處理或加解密…等,我不認 為你 在嵌入式系統裡會碰 到更複雜的陣列運算了 ! (http://zh.wikipedia.org/zh-hk/ 矩陣乘法 ) 早晚你 要碰 到的 – 泡泡排序法。 36
  • 37. 37
  • 38. Bubble Sort #include <stdio.h> /* Bubble Sort */ void main(void) { int data[50]; int i,j,n,temp; printf("Please input integer number you want to sort:"); scanf("%d" ,&n); printf("n"); if (n > 49) { printf("number should be less than 49n"); return; } for (i = 1;i <= n;i++) { printf("input data[%d]=", i); scanf("%d", &data[i]); } 38 38
  • 39. Sorting for (i=1; i <= n; i++) { for (j = n; j > i; j--) { if (data[j-1] > data[j]) { temp = data[j-1]; data[j-1] = data[j]; data[j] = temp; } } } printf("nSorting result: n"); for(i = 1; i <= n; i++) printf("%d ", data[i]); } 39 39
  • 40. 矩陣相乘 1. 輸入矩陣 row, column 2. 輸入矩陣所有元素 3. 矩陣相乘 40
  • 41. 矩陣相乘 (1) #include <stdio.h> // Matrix A : m x n (row = m, column = n) // Matrix B : n x p // A x B = C (C should be m x p) // #define m 3 #define n 2 #define p 2 41
  • 42. 矩陣相乘 (2) void main() { int A[m+1][n+1], B[n+1][p+1], C[m+1][p+1]; int i, j, k; printf("Please input Matrix A:"); for (i =1 ; i<= m; i++) { for(j=1;j<=n;j++) scanf("%d",&A[i][j]); }/*end for*/ printf("Please input Matrix B:"); for (i =1 ; i<= n; i++) { for(j=1;j<=p;j++) scanf("%d",&B[i][j]); }/*end for*/ 42
  • 43. 矩陣相乘 (3) for (i=1; i<=m; i++) { for (j=1; j<=p; j++) { C[i][j]=0; for(k = 1; k <= n; k++) { C[i][j] = C[i][j] +A[i][k] * B[k][j]; } printf("%d ", C[i][j]); } printf("n"); } } 43
  • 44. How to access CPU registers? CPU Internal Registers Memory Mapping Registers 44
  • 46. /* 透過一般暫存器 R4 ,設定 Stack Point ( SP )暫存器的值 (通常特殊暫存器都不允許直接設值 , 必須透過一般暫存器) */ asm("xld.w %r4,0x20000"); asm("ld.w %sp,%r4"); /* 假設第 0 個 bit 代表 IE bit ( Interrupt Enable ),值為 1 時表示允許中 斷產生 以下的程式會令 CPU 允許中斷發生 */ asm("ld.w %r8, 0x000001"); // Set PSR to interrupt enable asm("ld.w %psr, %r8"); GCC-Inline-Assembly-HOWTO Reference-2 46
  • 48. “volatile” 這兩個程式等價嗎? 48
  • 49. 使用 C 語言開發驅動程式 (1) Volatile 變數 volatile unsigned int * xxx_register = 0x300024 ; // 對暫存器 0x300024 連續設值,因為變數形態設定為 volatile // 所以對 xxx_register 的操作不會被最佳化 // *xxx_register = 0x00ABCDEF ; *xxx_register = 0x12345678 ; ; // 0x300021 是 CPU 的 memory mapping Register // 以下的運算是將 bit 4 設為 1 // *((volatile unsi gned char *)0x300021) |= 0x10;  *((volatile unsigned char *)0x300021) = *((volatile unsi gned char *)0x300021) | 0x10 ; 49
  • 50. volatile unsigned char data ; data = *((volatile unsigned char *)0x300021) ; data = data | 0x10 ; // set bit 4 as 1 *((volatile unsi gned char *)0x300021 = data ; 50
  • 51. IF FPSHIFT-mask-enable set to 16bpp and color mode ELSE set LCD-panel-data-width to 4-bit mode 51
  • 52. 動態記憶體配置 void * malloc(int size) ; void free(void * ptr) ; 52
  • 53. main() { int A_array[20] ; int * B_array ; int array_no ; int i ; for(i=0;i<20;i++) A_array[i] = 0 ; printf("please input size of array B: ") ; scanf("%d",&array_no) ; B_array = (int *)malloc(array_no * sizeof(int)) ; if(B_array != NULL) { for(i=0;i<array_no;i++) B_array[i] = 0 ; } free(B_array ) ; } 53
  • 54. Lab #6-2 使用 malloc/free 修改 homework1 (多項式)程 式, 使其可以處理超過 10 項的多項式。 54
  • 55. Lab #6-3 4 個學生的四科成績 求全部平均 求第 n 位學生的平均 55 Page:97
  • 56. 記憶體測試 記憶體會出問題的機會比想像的多, e.g. 1. 電路設計或 Layout 錯誤 2. Chip Select 選錯 3. SDRAM controller 設定錯誤 4. Timing 設定 基本的硬體測試 - 把各個記憶體的每 一個 byte 都測 過,確定讀寫 ( 如果能寫的話 ) 都沒問題 56 Copyright © 2007 FITPI. All rights
  • 57. Lab #6-4 1. Allocate Memory as SRAM 2. write(address,value) 3. verify(address,value) 4. calculate_checksum(address,size) 57
  • 58. 嵌入式系統標準函式庫的效能考量 memcpy() void memcpy(void * dest, void * src, int n) { // 這個 function 也有可能是用 assembly 實現的 , 但算法基本上一樣 // int i ; char *Dest = (char *)dest ; char *Src = (char *)src ; for(i=0;i<n;i++) Dest[i] = Src[i] ; 安全的作法 安全的作法 } void my_memcpy(void * dest, void * src, int n) { // for Video-RAM copy only // 加速版 int i ; long *Dest = (long *)dest ; 加速版 long *Src = (long *)src ; for(i=0;i<(n>>2);i++) // 往右移兩個 bit  n/4 Dest[i] = Src[i] ; } 58 58
  • 59. 59
  • 60. 60
  • 61. 61

Notes de l'éditeur

  1. 傳識資訊股份有限公司 http://www.fitpi.com “ volatile ” 當然是標準 C 的關鍵字,通常只有在寫驅動程式時才會用到 在一般的狀況, C compiler 會把無效的程式剔除,除了可以減小程式的 size ,也能加快執行速度;可是如果某些狀況,連續做三次 A=1 是有意義的, C compiler 此舉就可說是幫倒忙了!“ volatile ” 這個關鍵字的作用就是用來告訴 C compiler ,凡是宣告成“ volatile ” 型態的變數,就不需對其作上述的最佳化。