2010-1 학기프로그래밍입문 (1) chapter 06-2 참고자료 포인터 박종혁 Tel: 970-6702 Email: jhpark1@snut.ac.kr 한빛미디어 출처 : 뇌를자극하는 C프로그래밍, 한빛미디어 -1-
포인터의정의와사용 변수를선언하는것은메모리에기억공간을할당하는것이며할당된이후에는변수명으로그기억공간을사용한다. 할당된기억공간을사용하는방법에는변수명외에메모리의실제주소값을사용하는것이다. 이주소값을포인터라고한다. 한빛미디어 -2-
포인터란무엇인가? 메모리에는바이트 (byte) 단위로그위치를식별할수있는물리적인주소값이있다. - 메모리의용량이 64kb 라면주소값은 0 번지부터 65535 번지까지존재한다. 한빛미디어 -3-
포인터란무엇인가? 변수를선언하면그자료형의크기만큼메모리에연속된바이트의기억공간이할당되는데그첫번째바이트의주소값이포인터이다. 이포인터를사용하여 4바이트의기억공간에값을저장하거나저장된값을꺼내어쓸수있다. 한빛미디어 -4-
포인터를구하자 ( 주소연산자 ) 특정변수의포인터를구하기위해서는주소연산자 (&) 를사용한다. 포인터를구하여출력해보자. char ch; int in; double db; printf( ch 의포인터 : %u n, &ch); printf( in 의포인터 : %u n, &in); printf( db 의포인터 : %u n, &db); ch의포인터 : 1245052 in의포인터 : 1245048 db의포인터 : 1245040 // char형변수의주소값 // int형변수의시작주소값 // double형변수의시작주소값 한빛미디어 -5-
포인터는특정자료형을가리킨다. 포인터에는자신이어떤자료형으로부터만들어졌는지에대한정보를가지고있다. 포인터 &ch &in &db 값 1245052 1245048 1245040 혈통에대한정보 나는 char형기억공간의주소값이다! 나는 int형기억공간의시작주소값이다! 나는 double형기억공간의시작주소값이다! 포인터가특정자료형에대한정보를가지고있다는것을간단히표현할때 가리킨다 고하고화살표를사용하여그림을그린다. 한빛미디어 -6-
포인터를사용하자 ( 참조연산자 ) 포인터를통해서기억공간을사용하기위해서는참조연산자 (*) 를사용한다. char ch; int in; double db; *&ch = P ; *&in = 100; *&db = 3.14; printf( 변수 ch에저장된문자 : %c n, ch); printf( 변수 in에저장된값 : %d n, in); printf( 변수 db에저장된값 : %lf n, db); // 포인터 &ch가가리키는기억공간에 P 를저장한다. // 포인터 &in이가리키는기억공간에 100을저장한다. // 포인터 &db가가리키는기억공간에 3.14를저장한다. 변수 ch에저장된문자 : P 변수 in에저장된값 : 100 변수 db에저장된값 : 3.140000 한빛미디어 -7-
포인터를사용하자 ( 참조연산자 ) 참조 는기억공간뿐만아니라기억공간에저장된값도사용한다. int a=100, b=0; b = *&a; // 포인터 &a가가리키는기억공간의값을 b에대입한다. printf( b의값 : %d n, b); 기억공간을사용하는것과값을사용하는것은대입연산자의어디에위치하느냐에따라결정된다. int a=10, b=20; *&a = *&b; // 변수 b에저장된값을변수 a의기억공간에저장한다. printf( a의값 : %d n, a); // a의값은 20이출력된다. 한빛미디어 -8-
포인터를저장하자 ( 포인터변수 ) 포인터의값자체는정수값이지만가리키는자료형에대한정보를가지고있으므로정수형변수에저장할수없다. int a; int ap; ap = &a; // 포인터를구할변수 // 포인터를저장할변수 // a 의포인터를구해서 ap 에저장한다. 직관적으로는충분히가능할듯하지만컴파일에러가발생한다. error C2440: = : cannot convert from int * to int 한빛미디어 -9-
포인터를저장하자 ( 포인터변수 ) 포인터는포인터가가진정보를그대로보존할수있도록포인터변수에저장해야한다. 포인터변수는변수명앞에 * 을붙이고가리키는자료형을앞에적어준다. - int 형변수의포인터를저장하는포인터변수의선언 포인터변수가포인터를저장하면포인터와마찬가지로기억공간을가리킨다. int a; int *ap; ap = &a; 한빛미디어 -10-
포인터변수를사용한참조 포인터를저장한포인터변수도참조연산자로그것이가리키는기억공간또는그기억공간의값을사용할수있다. int a; int ap = &a; *ap = 10; // int형변수의선언 // 포인터변수의선언과동시에초기화, ap는변수 a를가리킨다. // 포인터변수가가리키는기억공간에 10 을저장한다. 포인터변수도하나의변수이므로주소연산자로메모리에서의위치를구할수있다. int a; // int형변수의선언 int ap = &a; printf( ap에저장된값 :%u n, ap); printf( ap자체의주소값 : %u n, &ap); // 포인터변수의선언과동시에초기화, ap 는변수 a 를가리킨다. // 변수 a 의시작주소값출력 // 포인터변수 ap 의시작주소값출력 한빛미디어 -11-
포인터정리 int a = 10; int *ap = &a; // int 형변수선언, 정수값 10 으로초기화 // int 포인터변수선언, a 의시작주소값으로초기화 printf( %d, a); printf( %d, *ap); printf( %u, &a); printf( %u, ap); printf( %u, &ap); // 1번출력, a에저장된정수값 10 // 1번출력, ap가가리키는곳에저장된값 10 // 2번출력, a의시작주소값 52번지 // 3번출력, ap에저장된주소값 52번지 // 4번출력, 포인터변수 ap의시작주소값 48번지 한빛미디어 -12-
포인터의필요성 함수들은독립된기억공간을가지므로다른함수에선언된변수를사용할수없다. - assign 함수를호출하여메인함수에있는 cheoli 변수에값을할당하는예 #include <stdio.h> void assign(); int main() { int cheoli=0; } assign(); printf(" 함수가호출된후에 cheoli 에저장된값 : %d n", cheoli); return 0; void assign() { cheoli=100; } 함수가호출된후에 cheoli 에저장된값 : 0 한빛미디어 -13-
포인터로다른함수의기억공간을사용한다. assign함수가 main함수의 cheoli변수를사용하기위해서는메모리에서의위치 ( 포인터 ) 를알아야한다. #include <stdio.h> void assign(int *ip); int main() { int cheoli=0; assign(&cheoli); printf(" 함수가호출된후에 cheoli 에저장된값 : %d n", cheoli); // 100 출력 } return 0; void assign(int *ip) { *ip=100; } 한빛미디어 -14-
함수의한계를극복한다. 함수는전달인자가많아도리턴되는값은오직하나이다. 따라서메인함수에있는두변수의값을바꾸는함수는포인터를사용해야한다. #include <stdio.h> void exchange(int *, int *); int main() { int cheoli=10, metel=20; } exchange(&cheoli, &metel); // [1] return 0; void exchange(int *cp, int *mp) { int temp; } temp=*cp; // [2] *cp=*mp; // [3] *mp=temp; // [4] 한빛미디어 -15-
함수의한계를극복한다. [1] [2] [3] [4] 한빛미디어 -16-
포인터에관한중요한질문 포인터와포인터변수의크기는몇바이트인가? - 컴파일러마다다를수있으므로 sizeof 연산자로계산한다. int in; int *ip = ∈ printf( int형변수의포인터의크기 : %d n, sizeof(&in)); printf( int형변수를가리키는포인터변수의크기 : %d n, sizeof(ip)); - 포인터와포인터변수의크기는가리키는자료형과는관계없이항상같다. char ch; int in; double db; char *cp = &ch; int *ip = ∈ double *dp = &db; printf( %d, %d, %d n, sizeof(cp), sizeof(ip), sizeof(dp)); printf( %d, %d, %d n, sizeof((*cp), sizeof(*ip), sizeof(*dp)); // 결과는 4, 4, 4 // 결과는 1, 4, 8 한빛미디어 -17-
포인터에관한중요한질문 포인터와포인터변수는자동형변환이가능한가? - 기본자료형은자동형변환이가능하나포인터 ( 변수 ) 는불가능하다. ( 형변환연산자를사용한명시적형변환은가능하다.) int *ip; double db=6.5; ip=&db; // int 형변수를가리키는포인터변수 // double 형변수 // double 형변수의포인터를 int 형포인터변수에대입 컴파일에러 error C2440: = : cannot convert from double * to int * - 자동형변환이가능하다면정수값이저장된기억공간에서실수값을참조하는오류를범하게될것이다. - 포인터의형변환규칙은함수의전달인자와매개변수사이에도적용된다. 한빛미디어 -18-