This chapter introduces pointers, a data type that can hold addresses. We study how to use them to provide call-by-reference parameter passing and to traverse arrays efficiently. We also see how to use them to access dynamically allocated arrays, arrays for which space is allocated at run time rather than compile time. The chapter concludes with a new implementation of sets, this time with dynamically allocated sets of varying sizes.
Jump to: [Previous Chapter | Next Chapter]
Pointer: Memory address¸¦ ÀúÀåÇÏ´Â data structure (¸Þ¸ð¸® ÁÖ¼Ò¸¦ ÀúÀåÇÏ´Â º¯¼ö)
Pointer variable Á¤ÀÇ: base_type *pointer_variable;
¿¹)
int *p1, p2;
Integer¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â memory pointer
º¯¼ö p1 (pointer to integer)°ú integer¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â º¯¼ö p2¸¦
Á¤ÀÇ
Pointer¿¡ ´ëÇÑ pointer (pointer to pointer), pointer¿¡ ´ëÇÑ pointer¿¡
´ëÇÑ pointerµµ Á¤ÀÇÇÒ ¼ö ÀÖ´Ù. ±×·¯³ª ¼¼ ´Ü°è ÀÌ»óÀÇ pointer Á¤ÀÇ´Â
ÇÁ·Î±×·¥À» ÀÌÇØÇϱ⠾î·Æ°Ô ¸¸µé¹Ç·Î °¡±ÞÀû »ç¿ëÀ» Á¦ÇÑÇÑ´Ù.
int **p; // pointer to pointer to integer
&: Address-of (º¯¼öÀÇ ÁÖ¼Ò)
*: Value-pointed-to (pointer°¡ pointÇÑ ¸Þ¸ð¸®¿¡ ÀúÀåµÈ
°ª)
int val = 10; // int °ª 10À» ÀúÀåÇÏ°í ÀÖ´Â ¸Þ¸ð¸® : val int *p = &val; // º¯¼ö p´Â °ª 10À» ÀúÀåÇÏ°í ÀÖ´Â º¯¼ö val¿¡ ÇÒ´çµÈ ¸Þ¸ð¸®ÀÇ ÁÖ¼Ò °ªÀ» ÀúÀå: pointer variable // ³ªÁß¿¡ Ãʱ⠰ªÀ» ºÎ¿©ÇÏ·Á¸é p = &val;À» »ç¿ëÇÏ¿©¾ß ÇÑ´Ù. printf("&val=%X, p=%d, *p= %d, val=%d\n", &val, p, *p, val);
NULL pointer: Ư¼ö ¸ñÀûÀ¸·Î »ç¿ë (address 0)
void swap(int *a, int *b) // integer a, b °ªµéÀ» ¼·Î ±³È¯
{ int temp; temp = *a; *a = *b; *b = temp; }
FunctionÀº ÇϳªÀÇ °ªÀ» returnÇϳª pointer¸¦ ÀÌ¿ëÇÏ¿© ¿©·¯ °ªµéÀ» È£Ãâ functionÀ¸·Î º¸³¾ ¼ö ÀÖ´Ù. ÀÌ·¯ÇÑ functionÀº ÀÌÇØÇϱ⠾î·Á¿î ºÎ¼ö È¿°ú (side-effect)¸¦ °¡Á®¿Í ÀÚÁÖ »ç¿ëÀº º°·Î ¹Ù¶÷Á÷ÇÏÁö ¾Ê´Ù. ƯÈ÷ functionÀ» ´Ù¸¥ functionÀÇ argument·Î »ç¿ëÇϱ⠾î·Æ°Ô ÇÑ´Ù.
¿¹) hours.c
Pointer¿Í °ü·ÃµÈ ÀǹÌÀÖ´Â ¿¬»êµéÀº ´ÙÀ½°ú °°´Ù.
Pointer ¿¬»ê ½Ã pointer°¡ pointÇÏ´Â ÀÚ·áÇü¿¡ µû¶ó ÀÚµ¿ÀûÀ¸·Î ÁÖ¼Ò
°è»êÀÌ ÇàÇØÁø´Ù. Áï, pointer to integer¿Í pointer to float °ªÀ»
1 Áõ°¡ ½ÃÅ°´Â °ÍÀº °¢°¢ integer¿Í float¿¡ »ç¿ëµÇ´Â ¸Þ¸ð¸® byte
¼ö ¸¸Å Áõ°¡½ÃÅ°´Â °á°ú¸¦ °®´Â´Ù.
* ÁÖÀÇ: Pointer¿Í pointerÀÇ ´õÇϱâ, pointer¿¡ ´ëÇÑ °öÇϱâ, ³ª´©±â´Â
¾Æ¹« Àǹ̰¡ ¾ø´Ù.
¿¹) 32bit compile ½Ã
char *p1; int *p2; float *p3; double *p4; p1 = 100; p2 = 200; p3 = 300; p4 = 400; // p1 + 1 ==> 101 // p2 + 1 ==> 204 // p3 + 1 ==> 304 // p4 + 1 ==> 408
¹è¿¸íÀº ÁÖ¼Ò (pointer °ª)·Î 󸮵ȴÙ. (ÇÁ·Î±×·¥ ³»¿¡¼ °ªÀ» º¯°æ½Ãų
¼ö ¾ø´Ù. Áï, »ó¼ö·Î 󸮵Ê.)
int ary[5] = { 10, 20, 30, 40, 50 }; int *p1, *p2; // integer¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â ¸Þ¸ð¸® ÁÖ¼Ò¸¦ ÀúÀåÇÏ´Â Æ÷ÀÎÅÍ º¯¼ö p1, p2 Á¤ÀÇ p1 = ary; // p1 = &ary[0]; ¿Í µ¿ÀÏ p2 = &ary[4]; // p2 = p1 + 4;¿Í µ¿ÀÏ 1: *p1 == ary[0], *(p1 + 1) == ary[1], *(p + i) == ary[i] == p[i] 2: (p1 < p2)´Â TRUE 3: *p1 ==> 10 4: *(p1 + 3) ==> 40 5: *p1 + 3 ==> 13 6: *p1++ ==> *(p1++) ==> evaluate °á°ú´Â 10ÀÌ°í ±× ÈÄ p1À» 1 Áõ°¡ ½ÃÅ´ (p1 == &ary[1]) 7: (*p1)++ ==> 11 8: *++p1 ==> 20 9: ++*p1 ==> 11 10: *p1 = 100; ==> ary[0] = 100;
int *ptr[10]; // pointer to integer 10°³¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â ¹è¿ ptr Á¤ÀÇ int (*ptr)[10]; // integer 10°³¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â ¹è¿¿¡ ´ëÇÑ Æ÷ÀÎÅÍ ptr Á¤ÀÇ
int (*fp)(); // fp´Â int¸¦ returnÇÏ´Â function¿¡ ´ëÇÑ pointer
int *f(); // f´Â pointer to integer¸¦ returnÇÏ´Â function
¿¹)
void f1() { printf("Function 1 is called.\n"); } void f2() { printf("Function 2 is called.\n"); } void main() { void (*fp)(); fp = f1; (*fp)(); // f1();°ú µ¿ÀÏ fp = f2; (*fp)(); // f2();¿Í µ¿ÀÏ } °á°ú: Function 1 is called. Function 2 is called.
º¹ÀâÇÑ pointer p Á¤ÀÇ ¿¹)
char *p; // pointer to char char **p; // pointer to pointer to char char (*p)[10]; // pointer to array [10] of char char *p[10]; // array [10] of pointer to char char *p(); // function returning pointer to char char (*p)(); // pointer to function returning char char (*p[10])(); // array [10] of pointer to function returning char
Static allocation: global variableó·³ compile ½Ã ƯÁ¤ ¿µ¿ªÀÇ ¸Þ¸ð¸®°¡ ÇÒ´çµÇ¾î ÇÁ·Î±×·¥ ½ÇÇà Áß °è¼Ó »ç¿ë °¡´ÉÇÑ ¸Þ¸ð¸® »ç¿ë
Automatic allocation: function ¶Ç´Â block ½ÇÇà ½Ã ÇÒ´çµÇ¾î ±× function ¶Ç´Â block ½ÇÇàÀÌ ³¡³ª¸é Àç»ç¿ëÀÌ °¡´ÉÇÑ ¸Þ¸ð¸® »ç¿ë
Dynamic allocation: ÇÁ·Î±×·¥ ½ÇÇà µµÁß ÇÊ¿ä ½Ã »ç¿ë °¡´É
¸Þ¸ð¸® ¿µ¿ª (heap; pool of unallocated memory)¿¡¼ ÇÒ´ç¹Þ¾Æ »ç¿ëÇÏ°í
»ç¿ëÀÌ ³¡³ª¸é ´Ù½Ã heapÀ¸·Î µÇµ¹¸± ¼ö ÀÖ´Â ¸Þ¸ð¸® »ç¿ë
ÀÓÀÇÀÇ ÀÚ·áÇüÀ» pointÇÒ ¼ö ÀÖÀ¸³ª Å©±â¸¦ ¸ð¸£±â ¶§¹®¿¡ pointer
°ü·Ã ¿¬»êÀº ÇÒ ¼ö ¾ø´Ù. »ç¿ë ½Ã ƯÁ¤ ÀÚ·áÇü pointer·Î castingÇÏ¿© »ç¿ëÇÒ ¼ö ÀÖ´Ù.
Heap¿¡¼ memory¸¦ ÇÒ´ç¹ÞÀ» °æ¿ì malloc functionÀ» »ç¿ëÇÏ°í ÇÒ´ç¹ÞÀº
memory¸¦ heapÀ¸·Î µ¹·ÁÁÙ °æ¿ì free functionÀ» »ç¿ëÇÑ´Ù.
(memory »ç¿ë)
Prototypes:
void *malloc(int);
free(void *);
¿¹) char 10°³¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â ¸Þ¸ð¸® ÇÒ´ç
char *cp; cp = (char *)malloc(10); // int 100°³¸¦ ÀúÀåÇÒ ¼ö ÀÖ´Â ¸Þ¸ð¸® ÇÒ´ç int *ip; ip = (int *)malloc(100 * sizeof(int)); // ÀÌÈÄ pointer ¿¬»ê ±â´ÉÀ» »ç¿ëÇÏ¿© memory¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖ´Ù. // malloc functionÀÌ memory¸¦ returnÇÒ ¼ö ¾ø´Â °æ¿ì (heap¿¡ ÃæºÐÇÑ memory°¡ ³²¾Æ ÀÖÁö ¾ÊÀ» °æ¿ì) NULL pointer (ȤÀº NULL °ª)¸¦ returnÇÑ´Ù. // »ç¿ëÀÚ´Â malloc functionÀÌ Á¦´ë·Î memory¸¦ ÇÒ´çÇÏ¿´´ÂÁö ´ÙÀ½°ú °°ÀÌ °Ë»çÇÏ¿©¾ß ÇÑ´Ù. if (ip == NULL) Error("No memory available"); // »ç¿ëÀÌ ³¡³ memory´Â ´ÙÀ½°ú °°ÀÌ heapÀ¸·Î µ¹·ÁÁØ´Ù. free(ip); // ¶Ç´Â free((void *) ip);
Integer¸¦ ÀúÀåÇÑ array¿Í ±× Å©±â¸¦ ÆĶó¹ÌÅÍ·Î ¹Þ¾Æ array¿¡ ÀúÀåµÈ °¢ ¼ýÀÚÀÇ ºóµµ¼ö¸¦ Ãâ·ÂÇÏ°í array¿¡ ÀúÀåµÈ ¼ö Áß ÃÖ¼Ò°ª°ú ÃÖ´ë°ªÀ» ¸ðµÎ returnÇÏ´Â ÇÁ·Î±×·¥À» ÀÛ¼ºÇ϶ó.
¿¹)
array ³»¿ë: 91 93 98 92 92 95 93 92 91 95 99 92 98
Ãâ·Â:
91: 2
92: 4
93: 2
95: 2
98: 2
99: 1
ÃÖ¼Ò°ª: 91
ÃÖ´ë°ª: 99