Upload
others
View
1
Download
0
Embed Size (px)
Citation preview
PointersadoptedfromKNKCProgramming:AModernApproach
요약
2
순서• BinarytoByte• 주소
• 변수의주소확인
• Scanf에서 &연산자의활용
• 포인터의 2개의연산자
• 포인터변수와사용예
• 활동:인간포인터연습
• void타입과변수크기와의관계
• 포인터에서의캐스팅
• 포인터와배열
3
Binary toByte• 1203의 2진수표현
4
1203 = 1024 + 128 + 32+16+2+1=210 +27 +25 +24 +21 +20
2진수 =>01001011001116진수 =>4B 3
Binary(2진수)는각자리또는 bit에 0과 1만표현가능1203을 2진수로표현하기위해 11bit가필요함
10 9 8 7 6 5 4 3 2 1 01 0 0 1 0 1 1 0 0 1 1
위치
값
8 bit = 1 byte
주소• 32bit주소체계를따르는컴퓨터의경우정보의표현• 64bit인경우한줄에 64개 2진수표현가능
5
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 1 1
1byte 1byte 1byte 1byte
1word
0byte
offset
주소
4byte
8byte
12byte
16byte
주소• 모든객체 (변수,함수등)은고유의주소를갖음
6
…031…
100
104
108
112
116
120
124
128
132
136
int a = 100;int b = 200;int c = 300;
예시
주소• 모든객체 (변수,함수등)은고유의주소를갖음
7
…031…
100
104
108
112
116
120
124
128
132
136
int a = 100;int b = 200;int c = 300;
예시
a1 변수할당
주소• 모든객체 (변수,함수등)은고유의주소를갖음
8
…031…
100
104
108
112
116
120
124
128
132
136
int a = 100;int b = 200;int c = 300;
예시
a1 변수할당
1002 값초기화
주소• 모든객체 (변수,함수등)은고유의주소를갖음
9
…031…
100
104
108
112
116
120
124
128
132
136
int a = 100;int b = 200;int c = 300;
예시
a1 변수할당
1002 값초기화
b200
c300
34
56
할당위치는운영체제가정함
문제• 다음의메모리상태를참고로,변수초기화문장을작성
10
392
…031…
100
104
235108
112
116
ABC\0120
124
128
8.0132
136
int a = 235;float c = 8.0;int b = 392;char d[] = “ABC”;
a
b
c
d
문제• 다음의메모리초기화문장을토대로메모리배치도작성
11
1
…031…
100
104
39.2108
112
116
400201120
124
128
132
136
int a = 1;float b = 39.2;double c = 400201;char d[5] = { 1, 2, 3, 4, 5};
b
b
a
c1
2
3
4
5
132
133
134
135
136
변수의주소확인
12
#include <stdio.h>int main(){
int c[5] = { 3, 2, [3] = 8, [4] = 9};for (int k = 0; k < 5; k++)
printf("value of c[%d] = %d; address is %p\n", \k, c[k], &c[k]);
return 0;}
16진수주소형식
주소연산자:변수의저장된주소
1. 변수 c할당2. 변수 c초기화3. 변수 k할당4. 변수 k초기화5. c[k]의값과주소출력6. 변수 k의값증가
변수의주소확인
13
value of c[0] = 3; address is 0x7fff5602a3e0value of c[1] = 2; address is 0x7fff5602a3e4value of c[2] = 0; address is 0x7fff5602a3e8value of c[3] = 8; address is 0x7fff5602a3ecvalue of c[4] = 9; address is 0x7fff5602a3f0
실행결과
0
…031…
30x7fff5602a3e0
20x7fff5602a3e4
00x7fff5602a3e8
80x7fff5602a3ec
90x7fff5602a3f0
0x7fff541c13d8…
Scanf에서 &연산자의활용
14
1 float a; // 4byte2 scanf(“%f”, &a);
…031…
300
304
308
312
316
320
324
328
332
336
a1 변수할당
3.14 ⏎
2 사용자입력
3.14
3 a의주소확인주소: 308
3.14저장
포인터의 2개의연산자
15
& *참조연산자(referenceoperator) 역참조연산자(dereferenceoperator)
“~의주소”로이해 “~가가리키는값”으로이해
포인터변수저장하는것은주소
*Dereference는역참조또는간접참조라부름
포인터변수• 선언 – 역참조연산자를사용하여주소를저장하는변수임을표시
• 할당 – 참조연산자를사용하여주소를포인터변수에저장
• 읽기 – 역참조 연산자를사용하여저장된주소가가리키는곳의값을가져옴
16
double *pointer_variable;
pointer_variable = &variable;
*pointer_variable;
타입역참조연산자 포인터변수명
포인터변수참조연산자 변수명
역참조연산자 포인터변수명
포인터변수의사용예• 다른변수의주소를포인터변수에저장하는방법
• TypeI–포인터변수선언시주소할당
• TypeII–일반적인주소할당방법
17
1 int a = 100; // a 의 주소는 256이라 가정2 int *pa; // 포인터 변수 선언3 … // 다른 문장들 실행4 pa = &a; // 포인터 변수에 a의 주소 저장
1 int a = 100; // a 의 주소는 256이라 가정2 int *pa = &a; // 포인터 변수 선언 및 주소 할당
포인터변수의사용예
18
1 int a = 100; // a 의 주소는 256이라 가정2 int *pa; // 포인터 변수 선언3 … // 다른 문장들 실행4 pa = &a; // 포인터 변수에 a의 주소 저장
…031…
300
100304
308
312
316
320
324
328
a
…031…
300
100304
308
312
316
320
324
328
a
pa
…031…
300
100304
308
312
&a=304316
320
324
328
a
pa
1 2 3
예시
19
…031…
100
104
108
112
116
120
124
128
132
a
b
c
100
200
300
1 int a = 100, b = 200, c = 300;2 int *pv;3 printf(“%p\n”, pv = &a);4 printf(“%p\n”, pv = &b);5 printf(“%p\n”, pv = &c);
pv1 pv 값은 a의주소 104
2 pv 값은 b의주소 120
3 pv 값은 c의주소 112
예시
20
…031…
100
104
108
112
116
120
124
128
132
a100
1 int a;2 int *pv = &a, *pu = &a);3 printf(“%d\n”, *pu = 400);4 printf(“%d, %d\n”, a, *pv);
pv
pu
1 pu가가리키는 a에 400저장
2 pv가가리키는 a의값 400읽음
3 pv 값은 c의주소 112
// pv와 pv는 a의주소 104를저장
활동:인간포인터연습• 전체인원을반으로나누어 2팀으로나눔
• 제비뽑기를통해모든사람은두개의숫자를갖음• 그중한숫자는주소다른한숫자는값임• 주소는 1에서부터 40까지,값도 1에서부터 40까지임• 주소와값이동일한수이면왼쪽사람의값과교환
• 1번주소부터 40번주소까지모두순회하는데걸리는시간을비교함
• 1번주소의사람은자신의값을활용하여역참조(*연산)를하여값을찾아부름
• 역참조된값을갖고있는주소로반복• 예시:
21
3 1 21 2 3
int a; // a의 주소는 1
int *p = &a; // p의 주소는 20
*p = 12;
문제:
포인터연습문제
12 3 4 11 14
20 17 15 10 19
18 9
1 2 3 4 5
6 7 8 9 10
11 12
8 16 13
7 2 6 5 1
13 14 15
16 17 18 19 20
값주소
void타입과변수크기와의관계
• 캐스팅방법
23
float a = 3.9, b = 7.2int sum;sum = (int)b % (int)a;
void는 타입 미지정필요에 따라 void 타입 변수를다른 타입으로 캐스팅(casting)하여 사용
(새로운 타입) 변수명
float형 변수 a와 b를 int형으로 캐스팅int형 변수 sum에 결과를 저장
포인터에서의캐스팅
24
int a = 100;double b = 300;int c[2] = {1, 2};
…031…
500
504
508
512
516
520
524
528
532
536540
544
548
100 a
300 b
c[0]
500 pa
504 pb
1
2
512 pc
c[1]
500 k
int *pa = &a;
void *k;
k = &a;
double *pb = &b;
int *pc = &c[0];
1 k값은 a의주소 500
포인터에서의캐스팅
25
int a = 100;double b = 300;int c[2] = {1, 2};
…031…
500
504
508
512
516
520
524
528
532
536540
544
548
100 a
300 b
c[0]
500 pa
504 pb
1
2
512 pc
c[1]
500 k
int *pa = &a;double *pb = &b;
int *pc = &c[0];
void *k;
k = &a;printf(“%d\n”, *(int*)k);
1 k값은 a의주소 500
2 읽을바이트의길이는int타입의길이 4바이트
포인터에서의캐스팅
26
int a = 100;double b = 300;int c[2] = {1, 2};
…031…
500
504
508
512
516
520
524
528
532
536540
544
548
100 a
300 b
c[0]
500 pa
504 pb
1
2
512 pc
c[1]
504 k
int *pa = &a;
void *k;
k = &a;printf(“%d\n”, *(int*)k);
k = &b;printf(“%d\n”, *(double*)k);
double *pb = &b;
int *pc = &c[0];
포인터에서의캐스팅
27
int a = 100;double b = 300;int c[2] = {1, 2};
…031…
500
504
508
512
516
520
524
528
532
536540
544
548
100 a
300 b
c[0]
500 pa
504 pb
1
2
512 pc
c[1]
512 k
int *pa = &a;
void *k;
k = &a;printf(“%d\n”, *(int*)k);
k = &b;printf(“%d\n”, *(double*)k);
k = &c[0];printf(“%d\n”, *(int*)k);
double *pb = &b;
int *pc = &c[0];
포인터와배열
28
…031…
500
504
508
512
516
520
524
528
532
536540
544
548
c[0]1
2 c[1]
512 pc
int c[4] = {1, 2, 3, 4};int *pc;
3 c[2]
4 c[3]
포인터를 이용한 배열 접근pc = &c[0]; // c[0]의 주소pc = &c[1]; // c[1]의 주소pc = &c[2]; // c[2]의 주소pc = &c[3]; // c[3]의 주소
포인터 연산을 이용한 배열 접근pc; // c[0]의 주소pc+1; // c[1]의 주소pc+2; // c[2]의 주소pc+3; // c[3]의 주소
시작주소+(변수의타입)*배열인덱스c[2]의주소 = 512+4*2=520
Pointer자료
Copyright©2008W.W.Norton&Company.Allrightsreserved. 29
PointerVariables• Thefirststepinunderstandingpointersisvisualizingwhattheyrepresentatthemachinelevel.포인터를이해하는첫단계는기계레벨에서어떻게표현되는지가시화하는것
• Inmostmoderncomputers,mainmemoryisdividedintobytes,witheachbytecapableofstoringeightbitsofinformation:메인메모리는바이트로구분되어있고각바이틑 8bit정보를저장할수있음
• Eachbytehasauniqueaddress.각바이트는유일한주소를갖고있음
Copyright©2008W.W.Norton&Company.Allrightsreserved. 30
PointerVariables• Iftherearen bytesinmemory,wecanthinkofaddressesasnumbersthatrangefrom0ton – 1:n바이트의메모리가있다면주소는 0부터 n-1까지라고가정
Copyright©2008W.W.Norton&Company.Allrightsreserved. 31
주소 내용
PointerVariables• Eachvariableinaprogramoccupiesoneormorebytesofmemory.각변수는 1또는 2바이트의메모리를차지함
• Theaddressofthefirstbyteissaidtobetheaddressofthevariable.변수의주소는첫번째바이트의주소임
• Inthefollowingfigure,theaddressofthevariablei is2000:변수 i의주소는 2000
Copyright©2008W.W.Norton&Company.Allrightsreserved. 32
PointerVariables• Addressescanbestoredinspecialpointervariables.주소는포인터변수라는특별한변수에저장됨
• Whenwestoretheaddressofavariablei inthepointervariablep,wesaythatp “pointsto”i.변수 i의주소를포인터변수 p에저장한다면, p는 i를가리킨다(포인트한다)라고표현함
• Agraphicalrepresentation:도식화해보자
Copyright©2008W.W.Norton&Company.Allrightsreserved. 33
DeclaringPointerVariables• Whenapointervariableisdeclared,itsnamemustbeprecededbyanasterisk:포인터변수를선언할때,변수명앞에별표를해야함
int *p;
• p isapointervariablecapableofpointingtoobjects oftypeint.해석하면포인터변수 p는 int타입객체를포인트할수있다는의미임
• Weusethetermobject insteadofvariable sincepmightpointtoanareaofmemorythatdoesn’tbelongtoavariable.변수대신객체라부르는이유는 p가변수가아닌다른메모리영역을가리킬수도있기때문
Copyright©2008W.W.Norton&Company.Allrightsreserved. 34
DeclaringPointerVariables• Pointervariablescanappearindeclarationsalongwithothervariables:포인터변수는다른변수들과같이선언될수있음
int i, j, a[10], b[20], *p, *q;
• Crequiresthateverypointervariablepointonlytoobjectsofaparticulartype(thereferencedtype):모든포인터변수는특정타입(참조타입)의객체만포인트할수있음
int *p; /* points only to integers */double *q; /* points only to doubles */char *r; /* points only to characters */
• Therearenorestrictionsonwhatthereferencedtypemaybe. 참조타입에대한제한조건은없음
Copyright©2008W.W.Norton&Company.Allrightsreserved. 35
TheAddressandIndirectionOperators• Cprovidesapairofoperatorsdesignedspecificallyforusewithpointers.포인터에활용할수있는연산자를 c에서제공함
• Tofindtheaddressofavariable,weusethe& (address)operator.변수의주소는 &(주소)연산자를통해얻음
• Togainaccesstotheobjectthatapointerpointsto,weusethe* (indirection)operator.포인터가포인트하는객체를접근하기위해서는 *(간접참조,간접)연산자를씀
Copyright©2008W.W.Norton&Company.Allrightsreserved. 36
TheAddressOperator• Declaringapointervariablesetsasidespaceforapointerbutdoesn’tmakeitpointtoanobject:포인터변수를선언하는것은변수자체를위한공간만할당;객체참조안함
int *p; /* points nowhere in particular */
• It’scrucialtoinitializep beforeweuseit.포인터변수 p를사용전에초기화하는것이중요!!
Copyright©2008W.W.Norton&Company.Allrightsreserved. 37
TheAddressOperator• Onewaytoinitializeapointervariableistoassignittheaddressofavariable:포인터변수를초기화하는방법중하나는다른변수의주소를할당하는것
int i, *p;…p = &i;
• Assigningtheaddressofi tothevariablepmakesp pointtoi:변수 i의주소를 (포인터)변수 p에저장하면 (포인터)변수 p가 i를포인팅함
Copyright©2008W.W.Norton&Company.Allrightsreserved. 38
TheAddressOperator• It’salsopossibletoinitializeapointervariableatthetimeit’sdeclared:또다른방법:선언하면서포인터변수초기화
int i;int *p = &i;
• Thedeclarationofi canevenbecombinedwiththedeclarationofp:변수 i를선언하면서포인터변수 p를 i의주소를포인팅하도록초기화할수있음
int i, *p = &i;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 39
TheIndirectionOperator• Onceapointervariablepointstoanobject,wecanusethe*(indirection)operatortoaccesswhat’sstoredintheobject.포인터변수가어떤객체를포인팅하면 *(간접참조)연산자를사용해서객체에저장된것에접근할수있음
• Ifp pointstoi,wecanprintthevalueofi asfollows:p가 i를가리킬때 i의값을다음처럼출력할수있음
printf("%d\n", *p);
• Applying& toavariableproducesapointertothevariable.Applying* tothepointertakesusbacktotheoriginalvariable:어떤변수에 &를쓰면그변수를가리킬수있는주소를알려줌다시 *를쓰면주소에저장된값을알려줌
j = *&i; /* same as j = i; 서로 동치 */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 40
TheIndirectionOperator• Aslongasp pointstoi,*p isanalias fori.p가 i를가리키는동안에는 *p는 i에대한또다른이름임
• *p hasthesamevalueasi. *p는 i와동일한값을갖음
• Changingthevalueof*p changesthevalueofi.*p의값을변경하면 i의값도변경됨
• Theexampleonthenextslideillustratestheequivalenceof*pandi.다음슬라이드의예제를살펴보자.
Copyright©2008W.W.Norton&Company.Allrightsreserved. 41
TheIndirectionOperatorp = &i;
i = 1;
printf("%d\n", i); /* prints 1 */printf("%d\n", *p); /* prints 1 */
*p = 2;
printf("%d\n", i); /* prints 2 */printf("%d\n", *p); /* prints 2 */
Copyright©2008W.W.Norton&Company.Allrightsreserved. 42
TheIndirectionOperator• Applyingtheindirectionoperatortoanuninitializedpointervariablecausesundefinedbehavior:간접참조연산자를초기화하지않고사용하면오동작을일으킴
int *p;printf("%d", *p); /*** WRONG ***/
• Assigningavalueto*p isparticularlydangerous:포인터변수 *p에상수를저장하는것은특히위험!!왜일까?
int *p;*p = 1; /*** WRONG ***/
Copyright©2008W.W.Norton&Company.Allrightsreserved. 43
PointerAssignment• Callowstheuseoftheassignmentoperatortocopypointersofthesametype.할당연산자를통해동일한타입에대한포인터를복사가능
• Assumethatthefollowingdeclarationisineffect:다음과같이선언했다고가정
int i, j, *p, *q;
• Exampleofpointerassignment:포인터할당예제
p = &i;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 44
PointerAssignment• Anotherexampleofpointerassignment:또다른포인터할당예제
q = p;
q nowpointstothesameplaceasp:q가이제 p가가리키는곳을똑같이가리킴
Copyright©2008W.W.Norton&Company.Allrightsreserved. 45
PointerAssignment• Ifp andq bothpointtoi,wecanchangei byassigninganewvaluetoeither*p or*q:p와 q가 i를가리킨다면, *p또는 *q의값변경으로 i의값을변경가능
*p = 1;
*q = 2;
• Anynumberofpointervariablesmaypointtothesameobject. 포인터변수가몇개든상관없이동일한객체를가리킬수있음
Copyright©2008W.W.Norton&Company.Allrightsreserved. 46
PointerAssignment• Becarefulnottoconfuseq = p;
with*q = *p;
위의 두 문장이 서로 갖다고 생각하지 말것
• Thefirststatementisapointerassignment,butthesecondisnot.첫번째문장은포인터할당이지만,두번째문장은아님
• Theexampleonthenextslideshowstheeffectofthesecondstatement.다음슬라이드에서두번째문장의의미를살펴보자
Copyright©2008W.W.Norton&Company.Allrightsreserved. 47
PointerAssignmentp = &i;q = &j;i = 1;
*q = *p;
Copyright©2008W.W.Norton&Company.Allrightsreserved. 48
PointersasArguments• InChapter9,wetried—andfailed—towriteadecomposefunctionthatcouldmodifyitsarguments.9장에서 decompse함수가실수부분과소수부분을분리하는것을실패하였음
• Bypassingapointer toavariableinsteadofthevalue ofthevariable,decompose canbefixed.변수의값대신변수에대한포인터를전달하는것으로문제를해결할수있음
Copyright©2008W.W.Norton&Company.Allrightsreserved. 49
PointersasArguments• Newdefinitionofdecompose:새로운 decompose함수의정의
void decompose(double x, long *int_part,double *frac_part)
{*int_part = (long) x;*frac_part = x - *int_part;
}
• Possibleprototypesfordecompose:이함수의프로토타입
void decompose(double x, long *int_part,double *frac_part);
void decompose(double, long *, double *);
Copyright©2008W.W.Norton&Company.Allrightsreserved. 50
PointersasArguments• Acallofdecompose:함수호출방법
decompose(3.14159, &i, &d);
• Asaresultofthecall,int_part pointstoi andfrac_partpointstod:호출의결과로 int_part는 i를가리키고 frac_part는 d를가리킴
Copyright©2008W.W.Norton&Company.Allrightsreserved. 51
PointersasArguments• Thefirstassignmentinthebodyofdecompose convertsthevalueofx totypelong andstoresitintheobjectpointedtobyint_part:decompse함수의첫할당문은 x의값을 long타입으로변경한후 int_part가가리키는객체에저장함
Copyright©2008W.W.Norton&Company.Allrightsreserved. 52
PointersasArguments• Thesecondassignmentstoresx - *int_part intotheobjectthatfrac_part pointsto:두번째할당문은 x- *int_part의계산결과를 frac_part가가리키는객체에저장함
Copyright©2008W.W.Norton&Company.Allrightsreserved. 53
PointersasArguments• Argumentsincallsofscanf arepointers:scanf호출의인자에도포인터가포함되어있음
int i;…scanf("%d", &i);
Withoutthe&,scanf wouldbesuppliedwiththevalue ofi.&없이는 scanf는 i의값을전달받게됨
Copyright©2008W.W.Norton&Company.Allrightsreserved. 54
PointersasArguments• Althoughscanf’s argumentsmustbepointers,it’snotalwaystruethateveryargumentneedsthe& operator:scanf의인자가포인터야하지만,모든인자값이 &연산자가있어야하는것은아님
int i, *p;…p = &i;scanf("%d", p);
• Usingthe& operatorinthecallwouldbewrong:이경우 &연산자를호출하는것은잘못된것임
scanf("%d", &p); /*** WRONG ***/
Copyright©2008W.W.Norton&Company.Allrightsreserved. 55
PointersasArguments• Failingtopassapointertoafunctionwhenoneisexpectedcanhavedisastrousresults.함수에포인터전달이실패된다면결과가이상할수있다.
• Acallofdecompose inwhichthe& operatorismissing:decompe의호출에 &연산자를안쓴다면
decompose(3.14159, i, d);
• Whendecompose storesvaluesin*int_part and*frac_part,itwillattempttochangeunknownmemorylocationsinsteadofmodifyingi andd.decompose는 i와 d의값을변경하는대신 *int_part와 *frac_part이가리는임의의주소의값을변경함
• Ifwe’veprovidedaprototypefordecompose,thecompilerwilldetecttheerror.decompse의프로토타입을선언했었다면오류를검출했을것임
• Inthecaseofscanf,however,failingtopasspointersmaygoundetected.단, scanf의경우포인터를사용안더라도검출안될수있음
Copyright©2008W.W.Norton&Company.Allrightsreserved. 56
Program:FindingtheLargestandSmallestElementsinanArray
• Themax_min.c programusesafunctionnamedmax_min tofindthelargestandsmallestelementsinanarray.max_min.c이라는프로그램은max_min함수를사용하여배열에서가장큰수와작은수를찾음
• Prototypeformax_min:프로토타입은다음과같음
void max_min(int a[], int n, int *max, int *min);
• Examplecallofmax_min:호출예제
max_min(b, N, &big, &small);
• Whenmax_min findsthelargestelementinb,itstoresthevalueinbig byassigningitto*max.이함수가배열 b에서가장큰요소를찾으면 *max를통해서 big에할당
• max_min storesthesmallestelementofb insmall byassigningitto*min.이함수가배열 b에서가장작은요소를찾으면 *min을통해서 small에할당
Copyright©2008W.W.Norton&Company.Allrightsreserved. 57
Program:FindingtheLargestandSmallestElementsinanArray
• max_min.c willread10numbersintoanarray,passittothemax_min function,andprinttheresults:사용자로부터 10개의수를받아들이고max_min함수에전달함.이후결과를출력
Enter 10 numbers: 34 82 49 102 7 94 23 11 50 31Largest: 102Smallest: 7
Copyright©2008W.W.Norton&Company.Allrightsreserved. 58
maxmin.c/* Finds the largest and smallest elements in an array */
#include <stdio.h>
#define N 10
void max_min(int a[], int n, int *max, int *min);
int main(void){int b[N], i, big, small;
printf("Enter %d numbers: ", N);for (i = 0; i < N; i++) scanf("%d", &b[i]);
Copyright©2008W.W.Norton&Company.Allrightsreserved. 59
max_min(b, N, &big, &small);
printf("Largest: %d\n", big);printf("Smallest: %d\n", small);
return 0;}
void max_min(int a[], int n, int *max, int *min){int i;
*max = *min = a[0];for (i = 1; i < n; i++) {if (a[i] > *max)*max = a[i];
else if (a[i] < *min)*min = a[i];
}}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 60
Usingconst toProtectArguments• Whenanargumentisapointertoavariablex,wenormallyassumethatx willbemodified:어떤인자가변수 x에대한포인터라할때 x가변경될것을가정함
f(&x);
• It’spossible,though,thatfmerelyneedstoexaminethevalueofx,notchangeit.때로는 x의값을변경하는것이아니라확인만하고자할수있음
• Thereasonforthepointermightbeefficiency:passingthevalueofavariablecanwastetimeandspaceifthevariablerequiresalargeamountofstorage.이때포인터를쓰는것은효율성때문임:값으로전달하면변수를복사하는과정에서공간과시간이낭비될수있음,특히변수가많은저장공간을필요로한다면문제는더심각함
Copyright©2008W.W.Norton&Company.Allrightsreserved. 61
Usingconst toProtectArguments• Wecanuseconst todocumentthatafunctionwon’tchangeanobjectwhoseaddressispassedtothefunction.이경우 const라는키워드를사용하여함수가전달받은변수의주소가가리키는객체가변경되지않을것을명시할수있음
• const goesintheparameter’sdeclaration,justbeforethespecificationofitstype:const는매개변수를선언할때기록하고타입앞에붙여야함
void f(const int *p){*p = 0; /*** WRONG ***/
}
Attemptingtomodify*p isanerrorthatthecompilerwilldetect.*p를변경하려고시도하면컴파일러가해당오류를검출함
Copyright©2008W.W.Norton&Company.Allrightsreserved. 62
PointersasReturnValues• Functionsareallowedtoreturnpointers:함수는포인터를리턴할수있음
int *max(int *a, int *b){if (*a > *b)return a;
elsereturn b;
}
• Acallofthemax function: max를호출하는방법
int *p, i, j;…p = max(&i, &j);
Afterthecall,p pointstoeitheri orj. 호출결과, p는 I또는 j를가리킴
Copyright©2008W.W.Norton&Company.Allrightsreserved. 63
PointersasReturnValues• Althoughmax returnsoneofthepointerspassedtoitasanargument,that’snottheonlypossibility.max가인자로전달받은포인터중하나를리턴하지만다른것도가능함
• Afunctioncouldalsoreturnapointertoanexternalvariableortoastaticlocalvariable.함수가 external변수나정적지역변수에대한포인터도리턴할수있음
• Neverreturnapointertoanautomatic localvariable:절대로자동지역변수에대한포인터를리턴하지말것int *f(void){int i;…return &i;
}
Thevariablei won’texistafterf returns.변수 i는 f가리턴하면소멸됨
Copyright©2008W.W.Norton&Company.Allrightsreserved. 64
PointersasReturnValues• Pointerscanpointtoarrayelements.포인터는배열의원소를포인트할수있음
• Ifa isanarray,then&a[i] isapointertoelementi ofa.만약 a가배열이면 &a[i]는 a의 i번째요소에대한포인터임
• It’ssometimesusefulforafunctiontoreturnapointertooneoftheelementsinanarray.때로는배열의요소중하나에대한포인터를리턴하는데유용함
• Afunctionthatreturnsapointertothemiddleelementofa,assumingthata hasn elements:다음함수는배열 a의가운데요소에대한포인터를리턴함, a는 n개요소가있음
int *find_middle(int a[], int n) {return &a[n/2];
}
Copyright©2008W.W.Norton&Company.Allrightsreserved. 65