1 / 28

pointer (ตัวชี้)

pointer (ตัวชี้). เนื้อหาที่สอนในวันนี้. ขั้นตอนการประกาศตัวแปรในภาษาซี ตัวแปรชนิด pointer การกำหนดค่าให้กับตัวแปร pointer การใช้งานตัวแปร pointer pointer กับนิพจน์ทางคณิตศาสตร์ สิ่งที่ต้องระวังในการใช้งาน pointer pointer กับตัวแปร array. ขั้นตอนการประกาศตัวแปรในภาษาซี.

Download Presentation

pointer (ตัวชี้)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. pointer (ตัวชี้)

  2. เนื้อหาที่สอนในวันนี้เนื้อหาที่สอนในวันนี้ • ขั้นตอนการประกาศตัวแปรในภาษาซี • ตัวแปรชนิด pointer • การกำหนดค่าให้กับตัวแปร pointer • การใช้งานตัวแปร pointer • pointer กับนิพจน์ทางคณิตศาสตร์ • สิ่งที่ต้องระวังในการใช้งาน pointer • pointer กับตัวแปร array #07 pointer

  3. ขั้นตอนการประกาศตัวแปรในภาษาซีขั้นตอนการประกาศตัวแปรในภาษาซี • การประกาศตัวแปรในโปรแกรม -> การกำหนดพื้นที่ในหน่วยความจำเพื่อใช้ในการเก็บค่าของตัวแปรนั้นๆ • int x = 25; -> การกำหนดพื้นที่ในหน่วยความจำสำหรับตัวแปรชื่อ x ที่มีค่าข้อมูลชนิดจำนวนเต็ม โดยกำหนดค่าเริ่มต้นไว้ในพื้นที่หน่วยความจำ ณ ตำแหน่งดังกล่าวเป็น 25 • ดังนั้น ค่า 25 จะถูกจัดเก็บในหน่วยความจำ ณ ตำแหน่งหนึ่งในหน่วยความจำ โดยมีตัวแปร x เพื่อใช้ในการอ้างถึงตำแหน่งนั้น #07 pointer

  4. 0xFFF0 0xFFF0 int x x = 25 x 0xFFF2 0xFFF2 x 25 0xFFF4 0xFFF4 • สมมุติตำแหน่งในหน่วยความจำดังกล่าวคือ ตำแหน่ง FFF216 ( address ที่ FFF216 ) • เมื่อเราอ้างถึงตัวแปร xก็คือการอ้างถึงข้อมูลที่เก็บอยู่ในหน่วยความจำตำแหน่ง FFF216นั่งเอง เช่น x = x + 10; #07 pointer

  5. 0xFFF2 px 0xFFEE 0xFFF0 25 0xFFF2 x 0xFFF4 ตัวแปรชนิด pointer • นอกจากตัวแปรธรรมดา (int, long, float, double, short, char) แล้วภาษาซียังมีตัวแปรชนิดพิเศษซึ่งใช้เก็บตำแหน่ง (address) ในหน่วยความจำของตัวแปรชนิดอื่นๆ ได้ ซึ่งจะเรียกว่า ตัวแปรชนิด pointer (ตัวชี้) xเป็นตัวแปรชนิด int pxเป็นตัวแปรชนิด pointer ที่ชี้ไปยัง int #07 pointer

  6. การประกาศตัวแปรชนิด Pointer Type * Variable_Name; • Type : ชนิดของตัวแปร • * : เป็นเครื่องหมายที่แสดงว่าตัวแปรที่ตามหลังเครื่องหมายนี้เป็นตัวแปรชนิด pointer • Variable_Name: เป็นชื่อตัวแปรที่ต้องการประกาศว่าเป็นตัวแปรชนิด pointer โดยมีกฎการตั้งชื่อเหมือนตัวแปรทั่วไป #07 pointer

  7. ข้อควรจำ เมื่อเราต้องการประกาศตัวแปร pointer เพื่อชี้ (เก็บค่า address) ไปยังตัวแปรชนิดใด เราจำเป็นต้องประกาศตัวแปร pointer ให้มีชนิดข้อมูลเป็นชนิดเดียวกับตัวแปรนั้นด้วย • ตัวอย่าง int *pt_i ; หมายความว่า pt_i เป็นตัวแปร pointer ที่ชี้ ไปยังข้อมูลชนิด integer float *pt_f ; หมายความว่า pt_f เป็นตัวแปร pointer ที่ชี้ ไปยังข้อมูลชนิด float #07 pointer

  8. การกำหนดค่าให้ตัวแปร pointer float a = 3.5; float *pa ; • จากตัวอย่างเป็นการกำหนดให้aเป็นตัวแปรชนิด float เก็บค่า 3.5 และpaเป็นตัวแปรpoiterที่จะชี้ไปยัง a • เมื่อกำหนดตัวแปรชนิด pointer แล้วในตอนต้นตัวแปร pointer ที่ได้จะเก็บค่า address ขยะ (เราไม่สามารถทราบได้ว่าเป็น address ตำแหน่งใด) • ดังนั้นเราต้องกำหนดให้ตัวแปร pointer เก็บค่า address ของตัวแปรที่เราต้องการ #07 pointer

  9. การกำหนดให้ตัวแปร pointer เก็บค่า address ของตัวแปรอื่นกำหนดได้โดยอาศัยเครื่องหมาย& (address operator) pa = &a ; • หมายถึงให้นำค่า address ของตัวแปรaไปจัดเก็บไว้ในตัวแปร pointer pa ( หรืออาจกล่าวได้อีกอย่างว่าเป็นการกำหนดให้ pointer pa ชี้ไปยังตัวแปร a ) • เมื่อมีเครื่องหมาย & อยู่หน้าตัวแปรใดจะหมายถึง address ของตัวแปรนั้น (ยกเว้นตัวแปร pointer) #07 pointer

  10. pa1 0xFFF6 0xFFEE 0xFFF6 pa2 0xFFF2 3.5 0xFFF6 a 0xFFFA • ตัวแปรชนิด pointer เป็นตัวแปรที่เก็บค่า address • สามารถมีตัวแปร pointer สองตัวที่ชี้ไปยังตัวแปรตัวเดียวกัน (เก็บค่า address ตำแหน่งเดียวกัน) float a = 3.5 , *pa1 , *pa2 ; pa1 = pa2 = &a ; #07 pointer

  11. การใช้งานตัวแปร pointer • เราสามารถเข้าถึงค่าที่จัดเก็บอยู่ใน address ตำแหน่งที่ตัวแปร pointer ชี้อยู่ได้ โดยอาศัย * (star operator) เพื่อเข้าถึงค่านั้นๆ float a = 3.5 , b; float *pa ; pa = &a ; b = *pa ; • ตัวแปรbจะมีค่าเท่ากับ 3.5 เนื่องจากเป็นการนำค่าที่เก็บอยู่ใน address ที่ตัวแปร paเก็บไว้ไปใส่ (ตำแหน่งเดียวกับตัวแปรa ) #07 pointer

  12. ถ้าเราต้องการอ้างถึง address ของตัวแปร pointer ใดๆอีกต่อหนึ่ง เราสามารถอ้างถึงโดยใช้ตัวแปรนั้นโดยตรง float a = 3.5 , b; float *pa , *ptr; pa = &a ; b = *pa ; ptr = pa ; pa 0xFFF4 0xFFF0 a 3.5 0xFFF4 ptr 0xFFF4 0xFFF8 b 3.5 0xFFFC #07 pointer

  13. ตัวอย่าง int a = 1 , b = 3 , *p1 , *p2 ; p1 = &a ; p2 = &b ; b = *p1 ;  1 a = *p2 + 5 ;  2 *p1 = 5 ;  3 *p2 = *p1 ;  4 หลังจากผ่านคำสั่งหมายเลข 1, 2, 3, 4 ? 1 2 3 4 3 line b=*p1 a=*p2+5 *p1=5 *p2=*p1 a 0xFFF0 1 1 6 5 5 b 0xFFF2 3 1 1 1 5 p1 0xFFF4 0xFFF0 0xFFF0 0xFFF0 0xFFF0 0xFFF0 p2 0xFFF6 0xFFF2 0xFFF2 0xFFF2 0xFFF2 0xFFF2 #07 pointer

  14. pointer กับนิพจน์คณิตศาสตร์ • เราสามารถใช้นิพจน์คณิตศาสตร์ร่วมกับตัวแปร pointer ได้เช่น int a = 1 , b = 3 , *p1 , *p2 ; p1 = &a ; p2 = &b ; a = *p2 + 1 ; • เป็นการนำค่าที่จัดเก็บอยู่ในตัวแปรที่ pointer p2ชี้อยู่ (ตัวแปรb) มาบวกกับตัวเลข 1 จากนั้นจึงจัดเก็บผลลัพธ์ไว้ในตัวแปรa #07 pointer

  15. สิ่งที่ต้องระวังในการใช้งาน pointer • ตัวแปร pointer สามารถนำมาดำเนินการทางคณิตศาสตร์ได้ แต่ความหมายที่ได้อาจผิดพลาด เช่น a =* ( p1 + 1 ) ; • สามารถทำได้ แต่จะหมายถึงการเพิ่มค่า address ที่ตัวแปร pointer ชี้ไปอีก 1 ตำแหน่ง แล้วจึงหาค่าที่จัดเก็บอยู่ใน address ตำแหน่งนั้น (ซึ่งเราไม่ทราบว่าเป็นตำแหน่งอะไร) #07 pointer

  16. สิ่งที่ต้องระวังในการใช้งาน pointer • ในทำนองเดียวกัน เมื่อเราทำงานกับตัวแปรปกติทั่วไป และมีการใช้ & operator เพื่อหาค่า address ของตัวแปรนั้น เช่นp1 = &a + 1 ; • สามารถทำได้ แต่จะหมายถึงการเพิ่มค่า address ของตัวแปร a อีก 1 ตำแหน่ง แล้วจัดเก็บ address นั้นไว้ในตัวแปร pointer p1 ซึ่งผิดความหมายไป #07 pointer

  17. สิ่งที่ต้องระวังในการใช้งาน pointer • ในการทำงานกับตัวแปร pointer ต้องกำหนดค่าเริ่มต้นให้กับตัวแปร pointer ก่อนเสมอว่าต้องการให้ชี้ไปยัง address ของตัวแปรใด (ใช้สัญลักษณ์ & ในการกำหนด) จากนั้นจึงจะสามารถกระทำการใดๆกับค่าข้อมูลที่ pointer นั้นชี้อยู่ได้ (ใช้สัญลักษณ์ * ในการจัดการข้อมูล) int a = 2 , *p ; *p = 3 ; • ผิดเพราะเราไม่ทราบว่า pointer pจะชี้ไปที่ใด #07 pointer

  18. pointer กับตัวแปร array • เราสามารถใช้ pointer ชี้ไปยังข้อมูลในแต่ละช่องของอาร์เรย์ได้ โดยอาศัยความจริงที่ว่า ถ้าทำการบวกตัวแปร pointer ตรงๆ จะหมายถึงการเพิ่มค่า address ที่ pointer นั้นชี้ไป (เลื่อนตำแหน่ง address ไปเป็นจำนวนช่องเท่ากับค่าที่นำมาบวก) • และโดยปกติแล้ว ในการจัดเก็บอาร์เรย์ลงในหน่วยความจำ จะจัดเก็บในลักษณะเป็นช่องเรียงต่อกันไปตามลำดับ #07 pointer

  19. Memory address อาร์เรย์ pointer ข้อมูลที่เก็บ score[0] &FF00 78 s_ptr score[1] &FF02 56 s_ptr + 1 s_ptr + 2 score[2] &FF04 42 score[3] &FF06 83 s_ptr + 3 score[4] &FF08 25 s_ptr + 4 score[5] &FF0A 36 s_ptr + 5 s_ptr + 6 score[6] &FF0C 68 score[7] &FF0E 54 s_ptr + 7 #07 pointer

  20. ตัวอย่าง #include <stdio.h> void main() { int sc[5] = {1,2,3,4,5} , *sc_ptr , a , b , c , d , e ; sc_ptr = &sc[0] ; a = *sc_ptr ; b = *(sc_ptr + 1) ; c = *(sc_ptr + 2) ; d = *(sc_ptr + 3) ; e = *(sc_ptr + 4) ; }  a = 1  b = 2  c = 3  d = 4  e = 5 #07 pointer

  21. ตัวอย่าง 1. #include<stdio.h> 2. void main() • { • int i; • float sum = 0.0 , data[5] , *f_ptr ; • f_ptr = data ;// f_ptr = &data[0]; • for( i = 0 ; i < 5 ; i++ )// read float data 5 times • { • printf( “ Give float data %d : " , i+1) ; • scanf( “ %f “ , (f_ptr+i) ) ; • } • do • { • sum += * ( f_ptr++ ) ;/* add them up */ • } while (f_ptr < &data[5] ) ; • printf( "Sum of all number is %f\n " , sum) ; • } #07 pointer

  22. ข้อควรระวัง • ในการใช้ pointer ชี้ไปยังอาร์เรย์ สามารถทำได้ 2 วิธี คือ • sc_ptr = &sc[0] ;กำหนดให้ pointer เก็บค่า address ของอาร์เรย์ช่องแรก (ระบุ index = 0) • fptr = data ; กำหนดชื่อของอาร์เรย์ data ให้กับ pointer fptr โดยตรง (ไม่ต้องทำการระบุ index และไม่ต้องใส่เครื่องหมาย &) • ไม่สามารถใช้คำสั่ง sc_ptr = &sc; หรือ fptr = &data; ได้ • จริงๆ แล้วตัวแปรอาร์เรย์ก็เป็น pointer ชนิดหนึ่งนั่นเอง (pointer แบบคงที่, ไม่สามารถชี้ address อื่นได้) #07 pointer

  23. ตัวอย่าง 1. #include<stdio.h> 2. void main() • { • int i; • float sum = 0.0 , data[5] ; • for( i = 0 ; i < 5 ; i++ )// read float data 5 times • { • printf( “ Give float data %d : " , i+1) ; • scanf( “ %f “ , &data[i] ) ; • } • i = 0 ; • do • { • sum += * ( data + i++ ) ;/* add them up */ • } while ( i <= 4 ) ; • printf( "Sum of all number is %f\n " , sum) ; • } #07 pointer

  24. สรุปลักษณะการประกาศตัวแปรสรุปลักษณะการประกาศตัวแปร int a ; aคือตัวแปรที่ใช้เก็บข้อมูลชนิด int ธรรมดา int a[] = {1,2,3};หรือ int a[3] ; aคือตัวแปรชนิด pointer แบบคงที่ ที่เก็บ address ของอาร์เรย์ช่องแรก ( aเท่ากับ &a[0], *aเท่ากับ a[0] ) int *a ; aคือตัวแปรชนิด pointer ที่เก็บ address ของข้อมูลชนิด int (ชี้ไปยังข้อมูลชนิด int) #07 pointer

  25. a[0] 1 0xFFEA a[1] 2 0xFFEC a[2] 3 0xFFEE 4 a[3] 0xFFF0 init 5 a[4] 0xFFF2 pa 0xFFF4 การบ้าน ถ้ากำหนดให้ส่วนของโปรแกรมใน main function เป็นดังนี้ init int a[5]={1,2,3,4,5} , *pa ; 1. pa = a; 2. pa = &a[1]; 3. pa++; 4. a[0] = *a+*pa; 5. *pa = *(a+3); 6. a[4] =*a+3; 7. *(pa-1) = 3x3; 8. a[1] =*(pa++); จงแสดงให้เห็นว่ามีการเปลี่ยนแปลงค่าในหน่วยความจำตำแหน่งต่างๆ อย่างไรบ้างหลังจากจบคำสั่งแต่ละคำสั่ง #07 pointer

  26. a[0] 1 0xFFEA 2 a[1] 0xFFEC 3 a[2] 0xFFEE 4 a[3] 0xFFF0 init 5 a[4] 0xFFF2 0xFFF4 pa • init int a[5]={1,2,3,4,5} , *pa ; • 1. pa = a; • 2. pa = &a[1]; pa เก็บค่า add ของ a[1] • 3. pa++; เพิ่มค่าของ pa ไป 1 ตำแหน่ง • 4. a[0] = *a+*pa; a = ชี้อยู่ที่ a[0] บวก กับ ค่าที่ pa ชี้อยู่ • *pa = *(a+3); address ของ a เพิ่มขึ้น 3 จะไปชี้ที่ a[3] • ดังนั้น ตำแหน่งที่ pa ชี้อยู่จะเป็นค่า 4 1 1 1 4 4 2 2 2 4 2 1 2 3 4 5 3 3 3 4 3 4 4 4 4 4 5 5 5 5 5 0xFFEC 0xFFEE 0xFFEE 0xFFEE 0xFFEA a 0xFFE0

  27. a[0] 1 0xFFEA 2 a[1] 0xFFEC 3 a[2] 0xFFEE 4 a[3] 0xFFF0 init 5 a[4] 0xFFF2 pa 0xFFF4 6. a[4] =*a+3; ค่าของ pointer a ซึ่งขณะนี้ ชี้ที่ a[3] ดังนั้น a[4] = 4+3 7. *(pa-1) = 3x3; pa -1 คือไปชี้ที่ a[2] 8. a[1] =*(pa++); ค่าของ a[1] จะมีค่าเท่ากับ address ของ pa เพิ่มขึ้น 1 ซึ่งก็คือ a[3] มีค่าเป็น 4 4 4 4 6 7 8 4 4 9 4 4 4 4 4 4 7 7 7 a 0xFFE0 0xFFEE 0xFFEC 0xFFEE

  28. ส่ง Address รับด้วย Pointer รูปแบบ การส่งตัวแปรแบบอ้างอิงไปยังฟังก์ชัน หรือแบบ argument and pointer หรือแบบ pass byreference หรือ Call by Reference วิธีการส่งตัวแปรแบบอ้างอิงไปยังฟังก์ชัน หรือการเรียกใช้ฟังก์ชัน Call by Referenceใช้รูปแบบ ดังนี้ ชื่อฟังก์ชัน (&ตัวแปร) ; การเขียนส่วนหัวของตัวฟังก์ชัน ใช้รูปแบบ ดังนี้ ชนิดข้อมูล ชื่อฟังก์ชัน (ชนิดข้อมูล *ตัวแปรชนิดตัวชี้) ชนิดข้อมูลประกาศให้ตรงกันกับตัวแปรที่ส่งมา ***หลักการใช้งานฟังก์ชันแบบ by reference คือ ส่ง Address จะรับด้วย pointer

More Related