Docstoc

Pointer and Function_1_

Document Sample
Pointer and Function_1_ Powered By Docstoc
					                                                        ตัวดาเนินการบิตไวส์ จะกระทา
   ตัวดาเนินการบิตไวส์ (Bitwise Operators)              ระหว่างบิตต่ อบิตของข้ อมูลชนิด
                                                        char short int
ตัวดาเนินการ              ความหมาย                      •และlong ที่มี เครื่องหมาย
                                                        หรือไม่ มีเครื่องหมาย (Signed
    &                บิตไวส์ แอน (and)                  or unsigned)


      |                     ิ
                  บิตไวส์ อนคลูซีฟออ            a   b        a&b a^b a|b
               (inclusive or)
     ^            บิตไวส์ เอกซ์ คลูซีฟออ        0   0          0         0         0
               (exclusive or)
    <<             เลฟท์ ชีฟท์ (left shift)     1   0          0         1         1
    >>               ไรท์ ชีฟท์ (right shift)   0   1          0         1         1
     ~              คอมพลีเมนต์                 1   1          1         0         1
               (complement)
ตัวอย่ าง โปรแกรมแสดงการใช้ ตัวดาเนินการบิตไวส์
       #include <stdio.h>
       main( )
       {
              char a = „A‟, b = „B‟ ;
              printf(“bitwise         AND „a&b‟ %x\n”, a&b) ;
              printf(“inclusive OR „a|b‟ %x\n”, a|b) ;
              printf(“exclusive OR „a^b‟ %x\n”, a^b) ;
              printf(“left shift       „a<<1‟ %x\n”, a<<1) ;
              printf(“right shift       „a>>1‟ %x\n”, a>>1) ;
       }

ผลลัพธ์ จากการรัน
     bitwise AND „a&b‟ 40
     inclusive OR „a|b‟ 43
     exclusive OR „a^b‟    3
     left shift    „a<<1‟ 82
     right shift  „a>>1‟ 20
#include<stdio.h>
#include<conio.h>
void main()
{
       char c=„A‟;

      clrscr();
      printf(“ A = %d %x”,c,c);
      printf(“ A<<1 = %d %x”,c<<1,c<<1);
      printf(“ A<<2 = %d %x”,c<<2,c<<2);
      printf(“ A<<3 = %d %x”,c<<3,c<<3);
      printf(“ A<<4 = %d %x”,c<<4,c<<4);
      getch();
}
ผลลัพธ์จากการัน
     A = 65 41
     A<<1 = 130 82
     A<<2 = 260 104
     A<<3 = 520 208
     A<<4 = 1040 410
#include<stdio.h>
#include<conio.h>
void main()
{
       char c=„A‟;

       clrscr();
       printf(“ A = %d %x”,c,c);
       printf(“ A>>1 = %d %x”,c>>1,c>>1);
       printf(“ A>>2 = %d %x”,c>>2,c>>2);
       printf(“ A>>3 = %d %x”,c>>3,c>>3);
       printf(“ A>>4 = %d %x”,c>>4,c>>4);
       getch();
}
ผลลัพธ์จากการรัน
      A = 65 41
A>>1 = 32 20
A>>2 = 16 10
A>>3 = 8        8
A>>4 = 4        4
/* Program converts decimal to binary using bitwise operator */
void main ()
{

       int i;
       char c='A„ ;    /* A=0100 0001 */
       char MASK=0x80; /* MASK=1000 0000 */

       clrscr();
       for(i=0;i<4;i++) {                        ผลลัพธ์.
                                                 0100 0001
        printf("%d",(c&MASK) ? 1 : 0);
        c=c<<1;
       }
       printf(" ");
       for(i=0;i<4;i++) {
                printf("%d",(c&MASK) ? 1 : 0);
                c=c<<1;

       }
                                                                  5
}
                     Computer Programming 204112




      ตัวชี้ (Pointer)

   ภาควิชาวิทยาการคอมพิวเตอร์
คณะวิทยาศาสตร์ มหาวิทยาลัยเชียงใหม่
                                              6
    สิ่ งที่จะเรี ยนรู้
    ตัวชี้หรือพอยน์ เตอร์ (Pointer)
       ทาไมถึงมีการใช้พอยน์เตอร์ จุดเด่น
                     ั
       พอยน์เตอร์ กบหน่ วยความจาและแอดเดรส

       การประกาศตัวแปรพอยน์เตอร์

       ตัวดาเนิ นการสาหรับตัวแปรพอยน์เตอร์

       การกระทาทางคณิ ตศาสตร์ ของตัวแปรพอยน์เตอร์

                                                   ั
       การนาตัวแปรพอยน์เตอร์ ใช้งานร่ วมกับฟั งก์ชน


                                                       7
    สิ่ งที่จะเรี ยนรู้
    ตัวชี้หรือพอยน์ เตอร์ (Pointer)
       ข้อควรระวังในการใช้พอยน์เตอร์
       เทคนิ คในการใช้พอยน์เตอร์




                                        8
  ตัวชี้หรือพอยน์ เตอร์ (pointer)
                    A

  2000                        20

ptr                     Address 2000


                                       9
ทาไมถึงมีการใช้ พอยน์ เตอร์ จุดเด่ น
 เป็ นตัวแปรชนิดหนึ่งที่มีการเก็บค่าแอดเดรสของ
  หน่วยความจา
 เป็ นจุดเด่นที่สุดในภาษาซี สามารถทางานได้รวดเร็ วและ

  ไม่เปลืองเนื้อที่หน่วยความจา
                 ่
 มีความยืดหยุนสู งในการ ทางานของโปรแกรมที่มีการ

  เปลี่ยนแปลงไม่คงที่ (dynamic) เช่น โครงสร้าง ข้อมูล
  แบบ linked list

                                                         10
              ั
   พอยน์เตอร์กบหน่วยความจาและแอดเดรส
 หน่วยความจาในคอมพิวเตอร์จะมีการแบ่งเป็ นส่ วนๆ โดยแต่ละส่ วนจะมี
                                                   ่
ค่าตาแหน่งที่ระบุไว้ ค่าตาแหน่งนี้จะเรี ยกว่าที่อยูของหน่วยความจา หรื อ
แอดเดรส (address)
              “ant”       A1000             แอดเดรส ในหน่ วยความจา
              100         A2000

               „ก‟        A3000

              89.12       A4000

             A1000        A8000

        หน่ วยความจา                                                 11
                 ั
      พอยน์เตอร์กบหน่วยความจาและแอดเดรส
  เมื่อประกาศตัวแปร (Declaration) ในการทางานโปรแกรมจะมีการ
 จองเนื้อที่ในหน่วยความจาให้มีขนาดตามชนิดของตัวแปรสาหรับเก็บ
 ข้อมูลตัวแปรที่ประกาศ
 เช่ น int number;
                                                1000
                      number         10         1002
number = 10;                                    1004
                                                               12
                    ั
         พอยน์เตอร์กบหน่วยความจาและแอดเดรส
                                                             ่
     เมื่อประกาศตัวแปรพอยน์เตอร์ แอดเดรสของพอยน์เตอร์ที่อยูใน
    หน่วยความจา จะใช้เก็บตาแหน่งแอดเดรสที่พอยน์เตอร์ช้ ีอยู่
           ั
เช่น ให้ตวแปรพอยน์เตอร์ P
ชี้ที่แอดเดรส ของ number                                    1000

P
                                  number         10         1002
             number                    P        1002         1004
               10
                                                                    13
              การประกาศตัวแปรพอยน์เตอร์
       จะใช้เครื่ องหมาย (ดอกจัน) * เรี ยกว่า Dereferencing Operator
                               ้
         กาหนดไว้หน้าตัวแปรที่ตองการประกาศ

Syntax: ชนิดข้อมูล *ชื่อตัวแปร หรื อ ชนิดข้อมูล* ชื่อตัวแปร
   EX.
              int *p;                       FILE* ptrData;

ชนิดข้ อมูล        *ชื่อตัวแปรพอยน์ เตอร์
                                                                        14
        การประกาศตัวแปรพอยน์เตอร์
 ความหมายของการประกาศตัวแปรพอยน์เตอร์
 EX.   int *ptr;
             ความหมาย: ประกาศตัวแปร ptr ทีชี้ไปยังข้ อมูลชนิด integer
                                          ่

       FILE *ptrData;
             ความหมาย: ???

                                                                   15
      การประกาศตัวแปรพอยน์เตอร์
                            ้
 การประกาศตัวแปรพอยน์เตอร์ตองให้สอดคล้องกับชนิดของตัวแปรที่
ต้องการชี้ !!!
                                            ้
 ข้ อควรระวัง การประกาศตัวแปรพอยเตอร์หามเว้นวรรคระหว่าง
เครื่ องหมาย (ดอกจัน) * กับชื่อตัวแปร เพราะจะผิด syntax

Ex.          int * ptr;                     int *ptr; หรือ
                                            int* ptr;
                              แก้ ไขเป็ น
      ผิด syntax
                                                             16
   ตัวดาเนินการสาหรับตัวแปรพอยน์เตอร์
ประกอบด้ วย 2 ตัว คือ

    1. ตัวดาเนินการแอดเดรส (address operator)
                                              ่
         - ใช้ เครื่องหมาย & นาหน้ าตัวแปร เพือระบุถึงแอดเดรสของตัวแปร
                                 ่
                ในหน่ วยความจา ทีจะกาหนดค่ าให้ แก่ตัวแปรพอยน์ เตอร์

    2. ตัวดาเนินการอ้างอิง (dereferencing operator)
                                                         ่             ่
         - ใช้ เครื่องหมาย * นาหน้ าตัวแปรพอยน์ เตอร์ เพือระบุถึงค่ าทีอยู่ใน
                           ่
                 แอดเดรสทีพอยน์ เตอร์ ชี้อยู่

                                                                                17
          ตัวดาเนินการสาหรับตัวแปรพอยน์เตอร์
                   ตัวอย่ างการใช้ งาน ตัวดาเนินการแอดเดรส (address operator)

การอ้ างอิงตัวชี้                   ตัวแปร x
                                                                            &x
#include <stdio.h>                                 1
                                                            1000
void main()
                                                                       p = &x
{ int x=1;
     int *p;
                                                          1000
     p=&x;                                                           9000
                                        พอยน์เตอร์ p
 }
                                                                                 18
       ตัวดาเนินการสาหรับตัวแปรพอยน์เตอร์
             ตัวอย่ างการใช้ งาน ตัวดาเนินการอ้ างอิง (dereference operator)
#include <stdio.h>
                                              x
void main()
{ int x=1;
                                                   100
                                                    1
                                                               1000
    int *p;                *p=100
    p=&x;
    *p=100;                                                  1000
                                                                        9000
 printf(“%d”,x);
                                                         p
}                                                                               19
        ตัวดาเนินการสาหรับตัวแปรพอยน์เตอร์
             ตัวอย่ าง การแสดงค่ าแอดเดรสที่เก็บในพอยน์ เตอร์ และของตัวแปร
#include <stdio.h>
void main()
                                                  ใช้ %p เพื่อแสดงค่า address
{ int x=1;                                        ของตัวแปรและในตัวชี้
    int *p;
    p=&x;
    printf(“address of x is %p”,&x);
    printf(“address in p is %p”,p);
}                                                                             20
        ตัวดาเนินการสาหรับตัวแปรพอยน์เตอร์
             ผลลัพธ์ การแสดงค่ าแอดเดรสที่เก็บในพอยน์ เตอร์ และของตัวแปร
        printf(“address of x is %p”,&x);       x
จอภาพ                                                 1
                                                               a2000
address of x is a2000
address in p is a2000


                                                              a2000
                                                                        9000
             printf(“address in p is %p”,p);              p
                                                                               21
    การกระทาทางคณิ ตศาสตร์ของตัวแปรพอยน์เตอร์
                                                          ่
     พอยน์ เตอร์ สามารถนามาใช้ ในการคานวณได้ เสมือนตัวแปรทัวไป
EX. int *myData=&x;          /* x = 100 และ &x เท่ ากับ 2000 */
          *myData++;         /* มีค่าเท่ ากับเท่ าใด ??? */
          *myData - = 10;    /* มีค่าเท่ ากับเท่ าใด ??? */

     myData++;           /* มีค่าเท่ากับเท่าใด ??? */
           2000     2001     2002      2003



          myData        ++                                        22
                                            ั
   การนาตัวแปรพอยน์เตอร์ใช้งานร่ วมกับฟังก์ชน

                                           ั
 ใช้งานลักษณะเป็ นการส่ งค่าเข้าไปในฟังก์ชน แล้วยินยอมให้มีการ
                                  ั
เปลี่ยนแปลงค่าของตัวแปรในฟังก์ชนได้
                              ั        ั
 การส่ งผ่านค่าเข้าไปในฟังก์ชน โดยใช้ตวแปรพอยน์เตอร์ จะเรี ยกว่า
call by reference
 ทาให้เกิดการเปลี่ยนแปลงของค่าตัวแปรอย่างถาวร
                              ั
 ทาให้การส่ งกลับค่าของฟังก์ชน (return) ทาได้มากกว่า 1 ค่า

                                                                    23
    ข้อควรระวังในการใช้พอยน์เตอร์
 เมื่อมีการเปลี่ยนแปลงค่า ที่พอยน์เตอร์ช้ ีอยู่ จะทาให้ขอมูลของตัวแปร
                                                         ้
ต้นฉบับ ถูกเปลี่ยนแปลงค่าไปด้วย
 การ Assign ค่าให้แก่พอยน์เตอร์โดยไม่ใช้ operator Dereference
(เครื่ องหมายดอกจัน) จะทาให้เกิด Error ขึ้น
                                   ั
 การ Assign ค่าพอยน์เตอร์ให้แก่ตวแปรที่ไม่ใช่พอยน์เตอร์ และไม่ใช้
operator Dereference (เครื่ องหมายดอกจัน) จะทาให้เกิด Error ขึ้น
เช่นกัน
                                                                         24
    เทคนิคในการใช้พอยน์เตอร์
 เมื่อมีการประกาศตัวแปรพอยน์เตอร์ ค่าเริ่ มต้นของพอยน์เตอร์ควร
             ่                                          ้
กาหนดให้มีคา NULL หรื อ 0 ป้ องกันการชี้แอดเดรสที่ไม่ตองการ
    เช่น        int *ptrData=NULL;
 เครื่ องหมาย * และ & ต่างเป็ นเครื่ องหมายที่มีคุณสมบัติการทางานที่
ตรงกันข้ามกัน (inverse) ถ้านามาใช้ติดกันไม่ทาให้เกิดการเปลี่ยนแปลง
ค่าใดๆ
    เช่น    *&ptrData; จะมีค่าเท่ากับ &*ptrData;
                                                                        25
           พอยน์ เตอร์ และอาร์ กิวเมนท์ ของฟั งก์ ชัน
            (Pointers and Function Arguments)
   เรื่ องฟั งก์ ชัน มีการส่ งตัวแปรที่บรรจุข้อมูลไปยังฟั งก์ ชัน เพื่อทา
การประมวลผล การส่ งตัวแปรไปยังฟั งก์ ชันมี 2 รู ปแบบคือ
        1) การส่ งตัวแปรเฉพาะค่ าหรื อการเรี ยกด้ วยมูลค่ า (call by
value) ซึ่งกล่ าวถึงในบทที่ 4 และฟั งก์ ชันสามารถคืนค่ า (return)
ได้ เพียงหนึ่งค่ า        หากต้ องการให้ ฟังก์ ชันมีการคืนค่ ากลับมายัง
ฟั งก์ ชันที่เรี ยกใช้ (เช่ น ฟั งก์ ชัน main) มากกว่ าหนึ่งค่ า ต้ อง
พิจารณาใช้
        2) การส่ งตัวแปรแบบอ้ างอิงหรือการเรียกด้ วยการอ้ างอิง
                                                  ้
(call by reference) จะต้ องอาศัยตัวแปรตัวชีในการดาเนินการ
      รูปแบบ การส่ งตัวแปรแบบอ้ างอิงไปยังฟั งก์ ชัน
             หรือแบบ argument and pointer
             หรือแบบ pass by reference
             หรือ Call by Reference
วิธีการส่ งตัวแปรแบบอ้ างอิงไปยังฟั งก์ ชัน หรือการเรียกใช้ ฟังก์ ชัน Call by
Reference ใช้ รูปแบบ ดังนี ้
                                           ส่ ง Address
       ชื่อฟั งก์ ชัน (&ตัวแปร) ;
                                                                    รับด้ วย Pointer
การเขียนส่ วนหัวของตัวฟั งก์ ชัน ใช้ รูปแบบ ดังนี ้
    ชนิดข้ อมูล ชื่อฟั งก์ ชัน (ชนิดข้ อมูล *ตัวแปรชนิดตัวชี)้
                                                                               ่
                                        ชนิดข้ อมูลประกาศให้ ตรงกันกับตัวแปรทีส่งมา
 *** หลักการใช้ งานฟังก์ชันแบบ by reference คือ ส่ ง Address จะรับด้วย pointer
ตัวอย่ าง โปรแกรมสลับค่ าตัวแปร 2 ตัวโดยผ่ านฟั งก์ ชัน การรั บ
พารามิเตอร์ เป็ นตัวแปรชนิดพอยน์ เตอร์
#include <stdio.h> void swap (int *px, int *py)
                           { int temp;
void swap(int*, int*); temp = *px; /*Put x value to temp*/
void main ( )                *px = *py; /*Put y value to x*/
 {                           *py = temp; /*Put old x to y */
    int x=5, y=10;         }
    printf(“Before swap:x=%d y=%d\n”, x ,y);
    swap (&x,&y); /* Pass address of x and y to swap( ) */
    printf(“After swap : x = %d y = %d\n”, x, y);
 }
ตัวอย่ าง เขียนโปรแกรมเพื่อรับข้ อมูลจานวนจริง
                                                       ้
 3 จานวนจากผู้ใช้ และหาค่ าเฉลี่ยของค่ าที่รับเข้ ามาทังหมด
โดยเขียนในลักษณะการส่ งอาร์ กิวเมนท์ แบบพอยน์ เตอร์


วิเคราะห์ input-process-output
มี 3 งานย่ อย  - รั บข้ อมูล 3 จานวน
               - หาค่ าเฉลี่ย
               - แสดงผลลัพธ์
#include <stdio.h>
void readData(int, double*);
void calAverage(double, double, double, double*);
  void printData(double, double, double, double);
void main( )
{
    double x1, x2, x3, average;
    readData(1, &x1);
    readData(2, &x2);
    readData(3, &x3);
     calAverage(x1, x2, x3, &average);
     printData(x1, x2, x3, average);
}
void readData(int seq, double *px)
{
    printf("Enter value %d : ", seq);
    scanf("%lf", px);    /*ไม่ ใช้ &px เพราะป็ น address แล้ ว */
}
void calAverage(double a1,double a2,double a3,double *pAvg)
{
    *pAvg = (a1 + a2 + a3)/3.0;         /*เหตุผลเหมือน slide 20 */
}
void printData(double b1, double b2, double b3, double avg)
{
  printf("Average of %.2lf, %.2lf, %.2lf is %.2lf",b1, b2, b3, avg);
}                                      /*ใช้ ตัวแปรแบบปกติ */
ตัวอย่ าง โจทย์ เดิม คือ เขียนโปรแกรมเพื่อรั บข้ อมูลจานวน
จริง 3 จานวนจากผู้ใช้ และหาค่ าเฉลี่ยของค่ าที่รับเข้ ามา
  ้
ทังหมด โดยเขียนในลักษณะพอยน์ เตอร์ อีกลักษณะหนึ่ง
   #include <stdio.h>
   void readData(double*,double*,double*);
   void calAverage(double*,double*,double*,double*);
   void printData(double*,double*,double*,double*);
void main( )
{
   double x1, x2, x3, average;
   readData(&x1, &x2, &x3);
   calAverage(&x1, &x2, &x3, &average);
   printData(&x1, &x2, &x3, &average);
}          /*ส่ ง argument เป็ น address เพราะ argument รับ
ค่ าที่ function เป็ นตัวแปร pointer การรับส่ งค่ าระหว่ างฟั งก์ ชัน
main กับ function ต้ องใช้ argument ที่สอดคล้ องกัน */
void readData(double *px1,double *px2,double *px3)
{
     printf("Enter value 1 : ");
     scanf("%lf", px1);
     printf("Enter value 2 : ");
     scanf("%lf", px2);
     printf("Enter value 3 : ");
     scanf("%lf", px3);
}       /* ไม่ ต้องใช้ &px1 เพราะ px1 เป็ น address แล้ ว */
void calAverage(double *pa1, double *pa2, double
                               *pa3, double *pAvg)
{
     *pAvg = (*pa1 + *pa2 + *pa3)/3.0;
}
void printData(double *pb1,double *pb2,double *pb3,
                                       double *pAvg)
{
    printf("Average of %.2lf, %.2lf, %.2lf is %.2lf",
                        *pb1, *pb2, *pb3, *pAvg);
}
                                       ้
ตัวอย่ าง เขียนโปรแกรมเพื่อคานวณพืนที่ส่ ีเหลี่ยมรูปหนึ่ง
โดยรั บข้ อมูลความกว้ างและความยาวของรู ปสี่เหลี่ยมจาก
                                         ้
ผู้ใช้ กาหนดให้ ใช้ ฟังก์ ชันเพื่อคานวณพืนที่ของรูปสี่เหลี่ยม
ดัง function prototype
         void calRecArea(float, float, float*);

โดยที่ พารามิเตอร์ ตัวแรกคือความกว้ าง
       พารามิเตอร์ ตัวที่ 2 คือความยาว
                                    ้
       และพารามิเตอร์ ตัวที่ 3 คือพืนที่ของรู ปสี่เหลี่ยม
    #include <stdio.h>
    void main( )
{                                void calRecArea (float w, float l,
      float width,length,area;                     float *pArea)
      printf("Enter width : "); {
      scanf("%f", &width);         *pArea = w*l;
      printf("Enter length : "); }
      scanf("%f", &length);
      calRecArea(width, length, &area);
      printf("Rectangle area is %.2f", area);
}
        ตัวอย่ าง รั บ r, h ของวงกลมที่ ฟั งก์ ชัน main แล้ วหา
        area และ volumn โดยใช้ function กับ pointer

#include <stdio.h>
void calRecArea (float r, float h, float *pArea, float *pVol)
{
    *pArea = 2 * pi * r * r;
     *pVol = pi * r * r * h;
}
void main( )
  {
     float r, h, area, vol;
     printf("Enter :radius ");
     scanf("%f", &r);
     printf("Enter height : ");
     scanf("%f", &h);
     calRecArea(r, h, &area, &vol);
     printf(" area is %.2f", area);
     printf(" area is %.2f", vol);
}

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:4
posted:10/17/2011
language:Thai
pages:40