7 pointer day10

35
พอยน์เตอร์ พอยน์เตอร์ (Pointer) (Pointer)

Upload: xuou888

Post on 07-Jul-2015

565 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: 7  pointer day10

พอยนเตอร พอยนเตอร (Pointer)(Pointer)

Page 2: 7  pointer day10

Pointer

• Pointer หมายถงตำาแหนงหรอทอยในหนวยความจำา (memory address) Pointer (ตวช) ถอวาเปนตวแปรชนดหนง ทเกบคา address ของหนวยความจำา

• เปนจดเดนทสดในภาษาซ สามารถทำางานได รวดเรวและไมเปลองเนอทหนวยความจำา

• มความยดหยนสง เหมาะสำาหรบการทำางานของโปรแกรมทมการเปลยนแปลงไมคงท(dynamic) เชน โครงสรางขอมลแบบ linked list

Pointer แบงไดเปน 2 ลกษณะคอ พอยนเตอรทเปนคาคงท และ พอยนเตอรทเปน

คาตวแปร

Page 3: 7  pointer day10

พอยนเตอรทเปนคาคงท มสองกรณคอ1. จากการใช operator & (เรยกวา Address of)ซงถา

operator & นำาหนาตวแปรใดจะไดตำาแหนงหนวยความจำา (memory address) ซงเปนคาคงท

2. เกดจากการประกาศตวแปร array เมอใดกตามทมการประกาศตวแปรแบบอะเรย ชอตวแปรอะเรยทไมม index หรอ subscript จะเปน พอยนเตอรทเปนคาคงท

Pointer

Page 4: 7  pointer day10

หนวยความจำาในคอมพวเตอรจะมการแบงเปนสวน ๆ โดยแตละสวนจะมคาตำาแหนงไว คาตำาแหนงนจะเรยกวาทอยของหนวยความจำาหรอ address

Pointer กบ หนวยความจำา

Int a,b,c ;char ch;

a = 10;b = 20;c = 30ch = ‘x’

Value

10

20

30

x

variable

a

b

c

d

Value

FFF4

FFF2

FFF0

FFEF

Page 5: 7  pointer day10

จะใชเครองหมาย * เรยกวา Derefencing Operator ไวหนาตวแปรทตองการ

ประกาศรปแบบ

type *variable_name

หรอ type* variable_name

Type คอชนดของตวแปรvariable-name คอชอของตวแปร pointer

Ex.

int *ptr; หรอ int* prt;

เปนการประกาศตวแปร ptr ชไปยงขอมลชนด int

การประกาศ ตวแปรแบบ พอยนเตอร

Page 6: 7  pointer day10

• ตวดำาเนนการแอดเดรส (Address Operator)

ใชเครองหมาย & นำาหนาตวแปร เพอระบถง address ของตวแปรในหนวยความจำา ทจะกำาหนดคาใหแกตวแปร pointer

• ตวดำาเนนการอางอง (Dereferencing Operator)

ใชเครองหมาย * นำาหนาตวแปร pointer เพอ ระบถงคาทอยใน address ท pointer ชอย

ตวดำาเนนการสำาหรบ พอยนเตอร

Page 7: 7  pointer day10

ตวอยาง int a;

int *pa;

a = 5;

pa=&a;

• การอางถงตำาแหนงหรอ address ของตวแปร ทถกช ดวย pa (address ของ a) เขยนแทนดวย pa

• การอางถงขอมลทตำาแหนงท pa ชอย (value ของa) เขยนแทนดวย *pa

• การอางถง address ของตวแปร pa เขยนแทนดวย &pa

การใชตวแปร พอยนเตอร

5 60000

60000 55900

. .

.

.

.

.

a

pa

Page 8: 7  pointer day10

• เมอมการประกาศตวแปร คาของตวแปรจะถกเกบอยในหนวยความจำา

• แอดเดรสของตวแปร คอ ตำาแหนงในหนวยความจำาทใชเกบตวแปรตวนน เขยนแทนดวยเครองหมาย &– เชน แอดเดรสของตวแปร x เขยนแทนดวย &x

560000

1055900

y

x

..

.

..

.

int x = 10;...

int y = 5;

การใชตวแปร พอยนเตอร

Page 9: 7  pointer day10

• พอยนเตอร คอ ตวแปรชนดหนงทใชในการเกบคาแอดเดรสของตวแปรตวอน

• พอยนเตอรมหลายชนด(ตามชนดตวแปรทมอย)– พอยนเตอรของตวแปร int– พอยนเตอรของตวแปร float– พอยนเตอรของตวแปร char– ฯลฯ

• ประโยชนของพอยนเตอร– ใชในการพฒนาโครงสรางขอมล (Data Structure)– ใชในโปรแกรมทตองมการตดตอกบหนวยความจำา

โดยตรง

การใชตวแปร พอยนเตอร

Page 10: 7  pointer day10

สญลกษณทใชกบพอยนเตอร• การประกาศตวแปร ใชเครองหมาย * เชน

– int* countPtr;

countPtr เปนพอยนเตอรของ int (ซงสามารถใชในการเกบคาแอดเดรสของตวแปร int ได)

– char* str;

str เปนพอยนเตอรของ char– float *nums;

nums เปนพอยนเตอรของ float

Page 11: 7  pointer day10

สญลกษณทใชกบพอยนเตอร (ตอ)• การกำาหนดคาใหกบพอยนเตอร• ใชเครองหมาย =• คาทกำาหนดใหกบพอยนเตอรตองเปนคาแอดเดรสของ

ตวแปร

int num = 6;

int *numPtr;

numPtr = #

50000numPtr

6num

6numnumPtr

กำาหนดให numPtr ชไปท num

5000040000

Page 12: 7  pointer day10

สญลกษณทใชกบพอยนเตอร (ตอ)

• การอางองถงคาในตำาแหนงทพอยนเตอรชอย– เรยกอกอยางวา “Dereferencing”– ใชเครองหมาย * นำาหนาตวแปร– ตวอยางเชน int num = 6;int *numPtr;

numPtr = #

cout << *numPtr;

*numPtr = 20;

6numnumPtr20

Page 13: 7  pointer day10

MemoryAddress Memory Variable

0x0012FF48 100 X

0x0012FF4c

0x0012FF50 11.25 y

0x0012FF54

0x0012FF58

0x0012FF5C 0x0012FF48 px

0x0012FF60

0x0012FF64

0x0012FF68 0x0012FF50 py

0x0012FF6C

…….

การใชตวแปร พอยนเตอร

Int x = 100; Int *px = &x;float y = 11.25;float *py;py = &y

*ตวแปรพอยนเตอรจะเกบคาของหนวยความจำา

Page 14: 7  pointer day10

2.5a

p

5.6b

q

#include <iostream.h>int main(){ float a = 2.5,b = 5.6; float *p,*q; p = &a; q = &b; cout << "*p = " << *p << endl; cout << "*q = " << *q << endl; *p = *p + 1; *q = *q + 3; cout << "a = " << a << endl; cout << "b = " << b << endl; return 0;}

3.5 8.6

*p = 2.5*q = 5.6a = 3.5b = 8.6

ผลลพธ

Page 15: 7  pointer day10

การเรยกใชแบบ Call-by-Reference• การเรยกใชฟงกชนม 2 แบบ คอ Call-by-Value

และ Call-by-Reference• Call-by-Value– ใชวธการสงคาของตวแปรใหกบฟงกชน– ไมสามารถแกไขคาของอารกวเมนตภายในฟงกชนได– ใชกบฟงกชนทรบคาเขาเปนตวแปรธรรมดา (int,

float, char, ...)• Call-by-Reference– ใชวธการสงแอดเดรสของตวแปรไปใหฟงกชน– ใชกบฟงกชนทรบคาเขาเปนพอยนเตอรหรออารเรย

Page 16: 7  pointer day10

#include <iostream.h>

int squareByValue(int n);

int main()

{

int number = 5;

cout << "The original value of number is " << number <<endl;

number = squareByValue(number);

cout << "The new value of number is " << number << endl;

return 0;

}

int squareByValue(int n)

{

n = n*n;

return n;

}

5number

main

squareByValue

n525

25

Page 17: 7  pointer day10

#include <iostream.h>

void squareByReference(int *nPtr);

int main()

{

int number = 5;

cout << "The original value of number is " << number <<endl;

squareByReference(&number);

cout << "The new value of number is " << number << endl;

return 0;

}

void squareByReference(int *nPtr)

{

*nPtr = *nPtr * *nPtr;

} nPtr

5number

main

squareByReference

25

Page 18: 7  pointer day10

การใชตวดำาเนนทางคณตศาสตรกบพอยนเตอร

• ตวดำาเนนการทางคณตศาสตรทมกจะใชกบพอยนเตอร– +, -, ++, --, +=, -=– ใชในการเลอนพอยนเตอรไปขางหนาหรอถอยหลง

• การเลอนพอยนเตอรจะเลอนทละ 1 บลอก เชน– ถาเปนพอยนเตอรของ int 1 บลอกคอ 4 ไบต– ถาเปนพอยนเตอรของ char 1 บลอกคอ 1 ไบต– ถาเปนพอยนเตอรของ float 1 บลอกคอ 4 ไบต– ฯลฯ

Page 19: 7  pointer day10

ตวอยางการเลอนพอยนเตอร

v[0]

vPtr

v[1] v[2] v[3] v[4]

3000 3004 3008 3012 3016int v[5];int *vPtr;vptr = v;//or vPtr = &v[0];

v[0]

vPtr

v[1] v[2] v[3] v[4]

3000 3004 3008 3012 3016

vPtr = vPtr + 2;

Page 20: 7  pointer day10

#include <iostream.h>

#include <string.h>

int main()

{

char msg[10];

char *ptr;

cout << "Enter text to reverse: ";

cin >> msg;

int len = strlen(msg);

ptr = &msg[len-1];

while(ptr >= &msg[0])

{

cout << *ptr;

ptr--;

}

return 0;

}

Enter text to reverse: CoeeoC

'\0''e''o''C'

msg[3]msg[2]msg[1]msg[0]...

msg[9]

ptr

Page 21: 7  pointer day10

การใชคำาสง cout กบ char * และ อารเรยของ char

• ถาใชคำาสง cout กบตวแปรอารเรยของ char สงทพมพออกมาคอ ตวอกษรตงแตอลเมนตแรกไปจนกวาจะเจอ ‘\0’

• ถาใชคำาสง cout กบพอยนเตอรชนด char * สงทพมพออกมาคอ ตวอกษรตงแตตำาแหนงทพอยนเตอรชอยไปจนกวาจะเจอ ‘\0’

• ตวอยางเชนchar name[8] = "Somchai";

cout << name;

char *namePtr = name;

cout << namePtr;

namePtr = &name[3];

cout << namePtr;

Somchai

Somchai

chai

Page 22: 7  pointer day10

ความสมพนธระหวางอารเรยกบพอยนเตอร

• ตวแปรอารเรยและพอยนเตอรสามารถใชงานแทนกนไดในหลายโอกาส

• ตวแปรอารเรยถอเปนพอยนเตอรเนองจากคาในตวแปรอารเรยคอแอดเดรสของอลเมนตแรก

Page 23: 7  pointer day10

ความสมพนธระหวางอารเรยกบพอยนเตอร (ตอ)

• สามารถกำาหนดใหพอยนเตอรชไปทอารเรยไดint b[5];

int *bPtr;

bPtr = b; // มความหมายเหมอนกบ bPtr = &b[0];

• สามารถใชสญลกษณ [] กบพอยนเตอรได เชน– bPtr[2] หมายถง คาในตำาแหนงทถดจาก bPtr ชอย

ไปอก 2 บลอก – bPtr[0] หมายถง คาในตำาแหนงเดยวกบท bPtr ชอย

Page 24: 7  pointer day10

#include <iostream.h>

int main()

{

int b[5] = {2,7,5,4,6};

int *bPtr;

bPtr = b;

cout << "bPtr[0] = " << bPtr[0] << endl;

cout << "bPtr[1] = " << bPtr[1] << endl;

bPtr = &b[2];

bPtr[1] = 10;

cout << "b[1] = " << b[1] << endl;

cout << "b[3] = " << b[3] << endl;

return 0;

}

bPtr[0] = 2bPtr[1] = 7b[1] = 7b[3] = 10

4

b[3]

5

b[2]

7

b[1]

2

b[0]

6

b[4]

bPtr

10

Page 25: 7  pointer day10

การจองหนวยความจำา (Memory Allocation)• ในการประกาศตวแปรแตละครง คอมไพเลอรจะจอง

หนวยความจำาชวคราว เพอใชเกบคาของตวแปรตวนน เชน– int a; จองหนวยความจำาขนาด 4 ไบต– char ch; จองหนวยความจำาขนาด 1 ไบต

– int nums[10]; จองหนวยความจำาขนาด 40 ไบต

– char name[20]; จองหนวยความจำาขนาด 20 ไบต

• แตหนวยความจำาเหลานจะมขอบเขตการใชงานอยภายในเครองหมาย {} ทไดมประกาศตวแปรไวเทานน– เชน ตวแปรทประกาศไวในฟงกชน เมอออกจาก

ฟงกชนแลว หนวยความจำาสำาหรบตวแปรเหลานนกจะถกคนใหแกระบบ

Page 26: 7  pointer day10

การจองหนวยความจำา (ตอ)• ถาตองการหนวยความจำาเพอใชในการเกบ

ขอมล โดยสามารถทจะคนหนวยความจำาสวนนเมอไรกได จะตองจองหนวยความจำาโดยใชคำาสง new

• การจองหนวยความจำาโดยใชคำาสง new ม 2 แบบ คอ– การจองหนวยความจำาแบบหนงบลอก– การจองหนวยความจำาเพอใชงานเปนอารเรย

Page 27: 7  pointer day10

การจองหนวยความจำาแบบหนงบลอก• ใชแทนการประกาศตวแปร 1 ตว• รปแบบ:

ตวแปรพอยนเตอร = new ชนดตวแปร;• เชน

int *ptr;

ptr = new int;

• การคนหนวยความจำาdelete ptr;

ptr

Page 28: 7  pointer day10

การจองหนวยความจำาเพอใชงานเปนอารเรย• รปแบบ:

ตวแปรพอยนเตอร = new ชนดตวแปร[ขนาดอารเรย];

• ตวอยางเชนint *nums;

nums = new int[5];

• การใชงานจะใชแบบอารเรยหรอพอยนเตอรกได เชนnums[1] = 10; // same as *(num+1) = 10;

• การคนหนวยความ ตองมเครองหมาย [] หนาตวแปรพอยนเตอรดวยdelete []nums;

10nums

Page 29: 7  pointer day10

#include <iostream.h>

int main()

{

int num_std;

cout << "Enter number of students: ";

cin >> num_std;

float *scores = new float[num_std];

int i;

for(i=0;i<num_std;i++)

{

cout << "Enter score of student " << i+1 << ": ";

cin >> scores[i];

}

Page 30: 7  pointer day10

cout << "\nThe scores are ";

float total = 0;

for(i=0;i<num_std;i++)

{

cout << scores[i] << " ";

total = total + scores[i];

}

cout << "\nTotal scores of all students is "<< total;

delete []scores;

return 0;

}• จากโปรแกรม จะเหนวาสามารถจองหนวยความจำาไดตามทผใช

กำาหนด• แตถาใชตวแปรอารเรยธรรมดา จะไมสามารถทำาอยางนได

เนองจากขนาดอารเรยตองเปนคาคงท จะกำาหนดเปนตวแปรไมได

Page 31: 7  pointer day10

สตรง (String)• สตรงม 3 ชนด คอ– คาคงทประเภทขอความ เชน "Sanook"– อารเรยของ char – พอยนเตอรชนด char *

Page 32: 7  pointer day10

สตรงแบบทใชอารเรยของ char• ตวอยางเชน

char name[8] = "Sawat";

• การเปลยนแปลงขอความในอารเรยของ char– หามใชเครองหมาย = (เชน name = "Sombat"; ไม

ได)– ใชฟงกชน strcpy เชนstrcpy(name,"Sombat");

name[0]

'S'

name[1]

'a'

name[2]

'w'

name[3]

'a'

name[4]

't'

name[5]

'\0'

name[6] name[7]

Page 33: 7  pointer day10

สตรงแบบทใชพอยนเตอรชนด char *

• สามารถกำาหนดคาโดยใชเครองหมาย = ได– char *str;– str = "Hello";

‘H’

str

‘e’ ‘l’ ‘l’ ‘o’ ‘\0’

หนวยความจำาชวคราว

Page 34: 7  pointer day10

สตรงแบบทใชพอยนเตอรชนด char * (ตอ)

• สามารถเปลยนแปลงขอความโดยใชฟงกชน strcpy กได แตตองมการจองหนวยความจำาเพอใชในการเกบขอความทจะนำามาวางเสยกอน

• ตวอยางเชนchar *str = new char[6];

strcpy(str,"Hello");

Page 35: 7  pointer day10

อารเรยของพอยนเตอร• ใชในกรณทตองการใชงานพอยนเตอรหลายๆ ตว• ตวอยางเชน

char *name_arr[3];

name_arr[0] = "Somchai";

name_arr[1] = "Sombat";

name_arr[2] = "Sawat";

‘S’name_arr[0] ‘o’ ‘m’ ‘c’ ‘h’ ‘\0’‘a’ ‘i’

‘S’ ‘o’ ‘m’ ‘b’ ‘a’ ‘t’ ‘\0’name_arr[1]

‘S’ ‘a’ ‘w’ ‘a’ ‘t’ ‘\0’name_arr[2]