포인터 (2)

라이라·2023년 6월 23일
0

배열은 시작 주소를 알면 포인터로 모든 요소에 접근할 수 있다.

1. 배열명은 첫번째 요소의 주소

int ary[3];
ary == &ary[0];

2. 배열명(주소) + 정수

가리키는 자료형의 크기를 곱해서 더한다.
	int arr[3];
    arr + 1; 
	>> arr + (1*sizeof(*arr))

3. 배열명 = 포인터

포인터가 배열명을 저장하면 배열명처럼 쓸 수 있다.
	int arr[3];
    int *pa = arr;
    pa[1] = 10;
    >> arr[1] = 10;

4. 배열명 =/= 포인터

배열명은 상수이므로 값 변경이 불가하지만 포인터는 가능하다.
	arr++; (x)
    pa++; (0)

1-1. 배열명은 컴파일 과정에서 첫 번째 배열 주소로 바뀐다.

1-2

void main(void){

	int arr[3];
    int i;
    
    *(arr + 0) = 10;
    *(arr + 1) = 20;
    
    printf("키보드 입력 => arr[3] : ");
    scanf("%d", arr+2);
    for(i=0; i<3; i++){
        printf("%5d\n", *(arr + i));
    }
    
    return 0;
}
첫번째 배열요소 :: arr[0] == arr == (arr + 0)

배열 요소에 사용하는 대괄호는 연산자이다.

  • 배열의 대괄호는 포인터 연산의 '간접참조, 괄호, 더하기 연산기능을 가진다.

배열요소 표현식(arr[1]) == 포인터 연산식(*(arr+1))

  • 특별한 경우가 아니면 대괄호가 추천되고 &arr[2]와 같은 경우 arr+2로 쓰면 연산과정이 줄여진다.

그렇다면 배열의 할당 영역을 벗어나는 포인터 연산식은 사용할 수 있나?

  • 문법적으로 문제가 없기 때문에 컴파일은 가능하나 실행할 때 결과를 예상할 수 없다.
  • 배열에 할당된 영역이 아니므로 그곳이 다른 변수나 배열에 할당되어 있는 영역이라면 그 값이 변경될 수 있고 만약 운영체제가 관리하는 부분이라면 프로그램이 강제종료될 수도 있다.
  • 즉, 사용할 수는 있으나 사용하면 안된다.

배열명은 주소이므로 포인터에 저장할 수 있다.

포인터가 배열명을 저장하면 배열명처럼 사용할 수 있다.

	
    int arr[3];
    int i;
    int *pa = arr;
    
    *pa = 10;
    *(pa+1) = 20;
    pa[2] = pa[0] + pa[1];
    
    for(i=0; i<3; i++){
        printf("%5d\n", pa[i]);
    }
    
    >>> 10 20 30

배열명과 포인터의 차이

1. sizeof 연산 결과가 다르다.

	int arr[3];
    int *pa = arr;
    
    sizeof(arr); // 12바이트 (배열 전체 크기)
    sizeof(pa); // 4바이트 (포인터 하나의 크기)
  • 배열명에 사용하면 배열 전체의 크기를 구하고 포인터에 사용하면 포인터 하나의 크기를 구한다.
  • 따라서 배열명을 포인터에 저장하면 포인터로 배열 전체의 크기를 확인하는 것은 불가능하다.

2. 배열명은 상수이므로 값의 변경이 불가하지만 포인터는 가능하다.

포인터를 증가 연산식으로 증가시킬 수 있고 다음 배열요소를 간단히 출력할 수 있다.

pa = pa + 1; 또는 pa++;

포인터로 배열의 데이터를 처리하면 특정 배열 요소의 위치를 기억할 수 있는 이점이 있다.
하지만 포인터의 값이 변할 수 있으므로 유효한 값인지 확인하는 습관이 필요하다.
  • 만약 배열을 할당한 포인터로 다시 처음 배열의 값부터 데이터를 처리해야한다면 배열명으로 다시 초기화해야한다.

  • 배열명은 주소값이 상수로 그 값이 변하지 않으므로 언제든지 배열의 시작 위치를 찾아가 사용할 수 있다.

괄호를 간접참조 연산자에 먼저 사용하면?

  • 이 경우 pa 값 자체는 변화하지 않으며 첫번째 배열 요소를 가리키는 상태로 고정된다.
    그리고 pa가 가리키는 배열 요소의 값이 증가하며 차례로 출력된다.

++(*pa) // 전위형, 결과는 11, 12, 13 출력

(*pa)++ // 후위형, 결과는 10, 11, 12 출력

profile
혼자 보려고 올리는 용도

0개의 댓글