포인터
포인터는 변수의 주소를 저장하는 변수이다.
포인터를 선언하려면 * 를 붙여줌으로써 보통의 변수와 구별해준다.
1
2
3
4
5
6
7
8
9
|
int main() {
int a = 20;
int* ptr_a;//포인터 선언
ptr_a = &a; //&는 주소값 즉 a의 주소값을 의미
printf("%d\n", ptr_a);
}
|
cs |
int * ptr_a; 는 포인터를 선언해준 것이고
ptr_a=&a;를 해줌으로써 ptr_a라는 변수에 a의 주소값이 들어가게 된다.
*의 두가지의 의미
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#include <stdio.h>
#include<string.h>
int main() {
int a = 20;
int* ptr_a;//포인터 선언
ptr_a = &a; //&는 주소값 즉 a의 주소값을 의미
printf("a의 값:%d\n", a);
printf("a의 주소값:%d\n",&a);
printf("ptr_a에 저장된 값:%d\n", ptr_a);
printf("ptr_a가 가리키는 변수의 값:%d\n", *ptr_a);
}
|
cs |
int *ptr_a 와 printf안에 있는 *ptr_a는 형태만 같지 의미는 다르다.
전자는 컴퓨터에게 포인터를 선언했다고 알려주시 위해 *를 붙인 것이고,
후자는 ptr_a가 가리키는 변수 자체를 가져오라고 한 것이다. ptr_a는 &a이기에 &a가 가리키는 변수가 a 이기에 *ptr_a==a이다.
*ptr
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <stdio.h>
#include<string.h>
int main() {
int a = 10;
int* ptr;
ptr = &a;
printf("a의 값:%d\n", a);
*ptr = 20;
printf("a의 값:%d\n", a);
}
|
cs |
첫번째와 두번째 출력값은 어떻게 될까?
첫번째는 10이 나올것이다.
*ptr은 ptr이 가리키는 변수, 즉 a를 의미하는데 *ptr=20;을 함으로써 a에 값이 20으로 바뀐다.
그렇기에 두번째는 20이 나올 것이다.
포인터를 가리키는 포인터
int **ptr_ptr; 의 형태로 *가 2번 들어간다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
#include<string.h>
int main() {
int a = 10;
int* ptr;
ptr = &a;
int** ptr_ptr;
ptr_ptr = &ptr;
printf("ptr_ptr=%d\n", ptr_ptr);
printf("*ptr_ptr=%d\n", *ptr_ptr);
printf("**ptr_ptr=%d\n", **ptr_ptr);
}
|
cs |
첫번째 출력값은 ptr의 주소값이
두번째 출력값은 ptr_ptr이 가리키는 변수이므로 ptr이
세번째 출력값은 *(*ptr_ptr)인데 ptr_ptr이 가리키는 변수인 ptr 그리고 그 ptr이 가리키는 변수이므로 a가 나온다.
++ 더 알아보기
1번과 2번의 차이점은 무엇일까? 앞에서부터 계속 말했지만
1번은 그냥 포인터 선언이다.
int *ptr_a;
ptr_a=&a; 를 한줄로 적어준 것이다.
2번은 ptr_a가 가리키는 변수가 20이라는 것 즉 a가 20 이라는 것이다.
포인터와 배열
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <stdio.h>
#include<string.h>
int main() {
int a = 10;
int* ptr_a = &a;
printf("ptr_a의 값:%d\n", ptr_a);
printf("ptr_a+1의 값:%d\n", ptr_a + 1);
}
|
cs |
ptr_a +1을 하면 14219933이 되어야하는데 왜 14219936일까? 즉, 왜 4만큼 더해진걸까??
a 는 int 이기에 4바이트이다. 램에서는 1바이트(8비트)가 가장 작은 공간이다.
ptr_a가 a를 가리키고 있는데 거기에 1을 더하면 포인터가 가리키는 자료형의 크기만큼 즉 int의 경우는 4만큼이 더해진다.
1
2
3
4
5
6
7
8
9
10
|
#include <stdio.h>
#include<string.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("arr의 값:%d\n", arr);
printf("arr+1의 값:%d\n", arr + 1);
}
|
cs |
arr은 arr[0]의 주소값을 의미하고 arr+1은 arr[0]의 주소값에 4만큼 더한, 즉 arr[1]의 주소값이 나온다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <stdio.h>
#include<string.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++) {
printf("&arr[%d]=%d\n", i,&arr[i]);
printf("arr+%d=%d\n", i, arr + i);
}
}
|
cs |
이 출력값을 통해 arr+i=&arr[i] 라는 것을 일반화 할 수 있다.
1
2
3
4
|
for (int i = 0; i < 10; i++) {
printf("%d\n", arr[i]);
printf("%d\n", *(arr + i));
}
|
cs |
두개의 같은 값이 출력되는데
이유는 arr+i=&arr[i]이므로 arr[i]의 주소값이 가리키는 변수는 arr[i]이기에 *(arr+i)는 사실상 arr[i]를 의미한다.
마지막 예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <stdio.h>
#include<string.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int* ptr = arr; ptr < arr + 10; ptr++) {
printf("%d\n", *ptr);
}
}
|
cs |
어떻게 1부터 10까지 출력될 수 있을까?
for (int* ptr = arr; ptr < arr + 10; ptr++)
for문 부분을 자세히보자.
int *ptr=arr 이라는 것은 arr이 arr[0]의 주소값이기에 ptr이라는 포인터를 선언하고 그 값을 &arr[0]으로 초기화 한 것이다.
ptr<arr+10 이라는 것은 ptr이 &arr[10]이 될 때까지 for문을 돌린다는 것이고
ptr++은 ptr+1이기에 사실상 4바이트가 더해지는 것이므로 &arr[i+1]이 ptr이라는 변수에 들어가는 것을 의미한다.
그렇기에 *ptr이면 arr[i]를 의미하는 것이고, arr에 들어있는 원소인 1부터 10이 나오는 것이다.
포인터 연습문제
1) 길이가 5인 int형 배열 arr이 있고 1,2,3,4,5로 초기화 한다. 첫번째 요소를 가리키는 포인터 변수 ptr을 선언한다. 그 다음 포인터 변수 ptr에 저장된 값을 증가시키는 형태의 연산을 기반으로 배열요소에 접근하면서 모든 배열 요소의 값을 2씩 증가시킨다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include <stdio.h>
#include<string.h>
int main() {
int arr[5] = { 1,2,3,4,5 };
int* ptr = arr; //&arr[0]
for (int i = 0; i < 5; i++) {
*ptr += 2;//배열 요소의 값 2씩 증가
ptr++;//ptr+1=&arr[i+1] 즉 ptr이 arr[i+1]의 주소값으로 변함
}
}
|
cs |
2) 1번문제에서는 ptr에 저장된 값을 변화시켰는데, 이번에는 ptr에 저장된 값을 변화시키지 않고 모든 배열의 요소를 2씩 증가시키려면 어떻게 해야할까?
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <stdio.h>
#include<string.h>
int main() {
int arr[5] = { 1,2,3,4,5 };
int* ptr = arr; //&arr[0]
for (int i = 0; i < 5; i++) {
*(ptr+i) += 2; //*(ptr+i)는 ptr+i=&arr[i] *(ptr+i)는 arr[i]를 가리킴
}
}
|
cs |
int arr[5]
int *ptr=arr 일때,
ptr=&arr[0]
ptr+1=&arr[1]
*(ptr+1)=arr[1]
'C > 기초(두들낙서)' 카테고리의 다른 글
[C기초] 포인터와 배열 연습문제 (0) | 2022.01.08 |
---|---|
[C기초] 포인터 배열 (0) | 2022.01.04 |
[C 백준] 브론즈 3/ 세 수 (0) | 2022.01.02 |
[C기초] 배열 포인터 (0) | 2022.01.02 |
[C기초] 배열과 문자열 (0) | 2022.01.02 |
댓글