목차
C언어 포인터 / 박은종 쌤의 포인터 강의 3~5
- 포인터와 배열 - 1
- 포인터와 배열 실습 - 1
- 포인터와 배열 실습 - 2
C언어 포인터 / 박은종 쌤의 포인터 강의
포인터와 배열 - 1
https://www.youtube.com/watch?v=ce37lzsbUgQ&t=333s
포인터를 왜 쓰는가?
- 메모리의 주소를 가지면 항상 접근 가능
- 매개 변수로 전달하기 편함
- 배열이나 구조체와 함께 쓰면 아주 편리함
int arr[5]
0 ~ n-1 인덱스 생성
배열의 가장 큰 장점은 인덱스 연산이 가능하다는 점, element를 찾는 속도가 정말 빠르다. 산술 연산으로 계산하기 때문에, 빅-오 표기법으로 O(1)에 해당한다.
그에 반해, 링크드 리스트는 논리적으로는 다음 것으로 예상 가능하지만, 물리적으로 걸리는 시간은 모든 개수를 다 찾아야 하기 때문에 오래 걸리며, 빅-오 O(n)에 해당한다.
배열의 이름은 주소이다. 포인터에 배열의 이름을 assign 하면 포인터로 접근 가능하다.
포인터와 배열 실습 - 1
https://www.youtube.com/watch?v=2FyplQq4EPI
배열
- 동일한 자료형을 일렬로 관리하는 선형 자료구조
- 물리적 위치와 논리적 위치가 동일함
- 배열의 이름은 주소다
- 배열은 인덱스 연산을 할 수 있다
배열의 각각의 요소 값들의 주소 값을 아래 실습을 통해 알아보자.
gcc로 컴파일 후 a.out로 확인해보면 아래처럼 4바이트씩 할당되어있는 것을 알 수 있다.
int형 arr이기 때문에 각각의 요소 값 하나씩 모두 4바이트로 할당된다.
포인터와 배열
- 배열의 이름은 배열의 시작 주소
- 배열의 이름은 값을 바꿀 수 없는 '상수 형태의 포인터'
int a[5];
int *pa;
pa = &a[0];
pa = a;
위처럼 선언을 했을 때, 아래 사진과 같이 할당되는 상태인 것이다.
포인터 연산
- 포인터는 연산하거나 비교할 수 있음
- 연산은 정수와의 덧셈, 뺄셈만 가능
- 포인터 변수 간의 연산은 뺄셈만 가능
- 배열과 함께 사용할 때 증/감 연산을 많이 사용
포인터 변수 + 정수 : pa +1; pa++; ++pa;
포인터 변수 - 정수 : pa -2; pa--; --pa;
포인터 변수 포인터 변수
pa1과 pa2 두 개의 변수가 동일한 배열을 가리킬 때
i = p2 - pa1 // 두 변수가 가리키는 요소의 간격
포인터 연산은 더하기는 되지 않고 오로지 뺄셈만 가능하다.
포인터와 배열
int array[5] = {1, 2, 3, 4, 5};
int *pa = array;
아래의 사진을 보면 포인터가 배열에 어떻게 접근하는지 직관적으로 이해할 수 있다. *(pa + i), i++ 형태로 접근하면 pa가 가리키고 있는 주소를 늘려 접근하지만, pa가 가리키고 있는 주소는 봐뀌지 않는다.
그 이유는 대입 연산자를 사용하지 않아, 기존에 가리키고 있던 주소 값은 변하지 않기 때문이다.
반면 대입 연산자(증감 연산자) *(pa++)을 사용을 하면 해당 주소 값이 계속 변화하게 된다.
포인터와 배열 실습 - 2
https://www.youtube.com/watch?v=wHgh_HftTFI
*pa++과 *(pa + 1)은 다름
연산 후 pa++ 은 연산 후 포인터의 위치가 이동함
int a[5] = {1, 2, 3, 4, 5};
int *pa1 = a;
int *pa2 = a;
*(++pa1) = 10;
*(pa2 + 2) = 20;
포인터와 배열 실습
int main(void)
{
int array[5] = {10, 20, 30, 40, 50};
int *ptr = array;
printf("++*ptr = %d\n", ++*ptr);
printf("*++ptr = %d\n", *++ptr);
printf("--*ptr = %d\n", --*ptr);
printf("*--ptr = %d\n", *--ptr);
printf("*(ptr++) = %d\n", *(ptr++));
printf("*(ptr--) = %d\n", *(ptr--));
return 0;
}
결과 값
int array[5] = {10, 20, 30, 40, 50}
int *ptr = array
++*ptr 의 의미는 포인터가 현재 가리키고 있는 값을 1 증가시키는 것이다, 전위 연산자이기 때문에 statement가 끝나기 전에 연산이 되어 버린다. 현재 *ptr이 가리키고 있는 것은 배열의 시작점인 10이다. 그렇기 때문에 연산이 되어 11이 출력된다.
*++ptr의 의미는 ptr 포인터의 위치를 한 칸 대입 연산하여 옮긴 값을 출력하는 것이다. 현재 0번 인덱스에서 1 증가시킨 1번 인덱스 값을 출력하게 된다.
--*ptr의 의미는 포인터가 현재 가리키는 값을 -1 하여 값을 변경시킨다. 그렇기에 현재 가리키고 있는 값이 20 - 1 되어 19가 된다.
*--ptr의 의미는 포인터의 위치를 대입 연산하여 한 칸 이전으로 간다. 즉 현재 0번 인덱스 값을 출력하게 되는 것. (현재 11이다)
*(ptr++)의 의미는 현재 가리키고 있는 값을 출력하고 나서 후위 연산되어 포인터의 위치가 증가하게 하는 것이다.
*(ptr--)의 의미는 현재 가리키고 있는 값을 출력하고 나서 후위 연산되어 포인터의 위치가 한 칸 감소하게 되는 것이다.
문자열
문자열을 표현하는 방법
char pstr1[] = "hello"; // 배열
char *pstr2 = "hello"; // 문자열 상수
배열의 값은 변경 가능하다.
문자열은 상수다. 문자열은 불변(immutable)이다.
'Programming > C language' 카테고리의 다른 글
[C] 구조체와 포인터 [박은종 쌤의 포인터 강의] (0) | 2021.11.22 |
---|