What is pointer

ํฌ์ธํ„ฐ๋Š” ๋จผ์ € ์ž๋ฃŒํ˜•์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ๊ฐ์˜ ์ž๋ฃŒํ˜•์— ๋Œ€ํ•ดย *ย ๋ฅผ ๋‹ฌ๊ฒŒ ๋˜๋ฉด ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ.

์ด ์˜๋ฏธ๋ฅผ ๋ง๋กœ ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ๋ฐ, int* pย ์™€ ๊ฐ™์€ ๊ฒฝ์šฐ, ํŠน์ • ์ž๋ฃŒํ˜•์ด int์ธ ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ p๋ฅผ ์ƒ์„ฑํ•ด๋ผ ๋กœ ์ƒ๊ฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

char* cย ์™€ ๊ฐ™์€ ๊ฒฝ์šฐ, ํŠน์ • ์ž๋ฃŒํ˜•์ด char์ธ ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ c๋ฅผ ์ƒ์„ฑํ•ด๋ผ ๋กœ ํŒ๋‹จํ•˜๋ฉด ๋œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค ์‹์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ํ• ๋‹น์ด ๋ ๊นŒ?

#include <iostream>
 
using namespace std;
 
int main(){
    
    int x;
    x = 4;
    int* p;
    p = &x;
    
    cout << p << endl;
    
    cout << a << ", " << *p << endl;
    
    return 0;
}
 
 

์ด๋ ‡๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ž๋ฆฌ์žก๊ฒŒ ๋œ๋‹ค. ์ด๋•Œ p์˜ ์ฃผ์†Œ์˜ ์žˆ๋Š” ๊ฐ’์œผ๋กœ๊ฐ€์„œ, ๊ทธ ๊ฐ’์„ ์ถœ๋ ฅํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ p์—ย *ย ๋ฅผ ๋‹ฌ๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•ด๋‹น ์ฃผ์†Œ๋กœย ์ ํ”„ย ๋ฅผ ํ•œ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ์ง๊ด€์ ์ด๋‹ค.

Output
0x04
4, 4

์ด๊ฒƒ์„ ๊ทธ๋ฆผ์œผ๋กœ ์ข€๋” ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•ด๋ณด์ž.

์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ํ•ต์‹ฌ์ ์œผ๋กœ ์ƒ๊ฐํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์€, ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•œ ๋’ค์— ๊ผญ ์ด ๋ณ€์ˆ˜๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

PassingByAddress

์ด์ œ๊นŒ์ง€ ํ•จ์ˆ˜ํ˜ธ์ถœ์— ๊ด€ํ•ด Callbyvalue, Callbyreference์™€ ๊ฐ™์€ ๊ฒƒ์„ ๋ฐฐ์› ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ด์ œ ํฌ์ธํ„ฐ๋ฅผ ๋ฐฐ์šฐ๊ฒŒ ๋˜๋ฉด, ํ•จ์ˆ˜์˜ ์ธ์ž๋ฅผ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•˜๊ณ , ๊ฐ’์„ ๋„˜๊ธธ ๋•Œย ์ฃผ์†Œย ๋ฅผ ๋„˜๊ฒจ์ค„ ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๋‚˜๋ฉด, ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ €์žฅ๋œ ๋‘ ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š”ย Swapย ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

#include <iostream>
 
using namespace std;
 
void swap(int* var1, int* var2){
    int temp = *var1	// var1์˜ ์ฃผ์†Œ๋กœ ์ ํ”„ํ•œ ๊ฐ’์„ temp์— ์ €์žฅํ•ด๋ผ
    *var1 = *var2;		// var1์˜ ์ฃผ์†Œ๋กœ ์ ํ”„ํ•œ ๊ฐ’์— var2์˜ ์ฃผ์†Œ๋กœ ์ ํ”„ํ•œ ๊ฐ’์„ ํ• ๋‹นํ•ด๋ผ
    *var2 = temp;		// var2์˜ ์ฃผ์†Œ๋กœ ์ ํ”„ํ•œ ๊ฐ’์— temp์˜ ๊ฐ’์„ ๋„ฃ์–ด๋ผ.
}
 
int main(){
    
    int a = 4, b = 5;
    cout << a << "," << b << endl;
    swap(&a,&b);
    cout << a << ", " << b << endl;
    
    return 0;
}
Output
4, 5
5, 4

Function Pointer

ํ•จ์ˆ˜ ํฌ์ธํ„ฐ? ํ•จ์ˆ˜ ์—ญ์‹œ ํฌ์ธํ„ฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ชจ๋ฅธ๋‹ค๋ฉด ๋‹นํ™ฉ์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๋Š” ๊ฒƒ์€, ์ปดํŒŒ์ผ ์ดํ›„ ํŠน์ • ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ •์˜๋˜์–ด ์žˆ๋Š” ํ–‰์œ„์˜ ์œ„์น˜๋กœ ๊ฐ€์„œ ์ฝ์–ด์˜ค๋ผ๋Š” ๋œป์ด๋‹ค.

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•จ์ˆ˜ํ˜ธ์ถœ์„ ํ–ˆ์„ ๋•Œ, ๊ทธ ์œ„์น˜๋กœ ๊ฐ€์•ผํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๊ณ , ๊ฒฐ๊ตญ์€ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฃผ์†Œ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค๋Š” ๊ฒฐ๋ก ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•˜๊ณ  ๋‚˜๋ฉด, ์ด ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ํฌ์ธํ„ฐ์ด๋‹ค.

์ฆ‰, ์ปดํŒŒ์ผ ์ดํ›„ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ์ƒ์„ฑ๋œ ์ผ๋ จ์˜ ์ž‘์—… ํ–‰์œ„๊ฐ€ ์ ํžŒ ๊ณณ์˜ ์‹œ์ž‘ ์œ„์น˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

์ด ๊ตฌ์กฐ๋ฅผ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ์šฐ๋ฆฌ๋Š” ํŠน์ • ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ์งค๋•Œ, ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ด ํ•จ์ˆ˜์˜ ์‹œ์ž‘ ์ฃผ์†Œ๋ฅผ ๋„ฃ์–ด ๋” ๊ณ ์ฐจ์›์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ์‚ฌ์šฉ๋ฒ•

ํ•จ์ˆ˜๊ฐ€_๋ฐ˜ํ™˜ํ•˜๋Š”_์ž๋ฃŒํ˜• (*ํ•จ์ˆ˜ํฌ์ธํ„ฐ๋กœ_์‚ฌ์šฉํ• _๋ณ€์ˆ˜_์ด๋ฆ„)(์ธํ’‹ํŒŒ๋ผ๋ฏธํ„ฐ์˜_์ž๋ฃŒํ˜•, ์ธํ’‹ํŒŒ๋ผ๋ฏธํ„ฐ์˜_์ž๋ฃŒํ˜•, ...)

์˜ˆ์ œ

#include <iostream>
 
using namespace std;
 
int add(int a, int b){
    return x + y;
}
 
int multiply(int a, int b){
    return x*y;
}
 
int evaluate(int (*f)(int, int), int x, int y){
    return f(x, y);		// main ์œผ๋กœ๋ถ€ํ„ฐ ํ•จ์ˆ˜์˜ ์‹œ์ž‘์ฃผ์†Œ๋ฅผ ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ f๋กœ ๋ฐ›๊ณ ,
    					// ๊ทธ ํ•จ์ˆ˜์˜ ์ธํ’‹์œผ๋กœ x, y๋ฅผ ์ค€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด๋ผ.
}
 
int main(){
    cout << add(2, 3) << endl;
    cout << multiply(2, 3) <<  endl;
    cout << evaluate(&add, 2, 3) << endl;
    cout << evaluate(&multiply, 2, 3) << endl;
}
Output
5
6
5
6