49. 간접 연산자

피연산자로 포인터를 사용하는 더하기, 빼기 연산은 프로그램 메모리 주소를 계산하거나 상대적 거리를 계산하죠.
하지만 실제 개발자는 프로그램 메모리 주소를 아는 것은 큰 의미가 없어요.

개발자는 특정 프로그램 메모리 주소에 있는 값을 얻어오거나 설정하는 것을 원해요.
C언어에서 포인터(배열 이름 포함)가 갖는 메모리 주소에 원하는 값을 설정하거나 얻어오는 방법은 크게 간접 연산자와 인덱스 연산자를 사용하는 방법이 있어요.

간접 연산자는 선언문이 아닌 코드 구문에서 포인터 형식을 피연산자로 오는 단항 연산자예요.
연산 기호는 포인터 변수를 선언할 때 사용한 지시 연산자 *와 같아요.
모양은 같지만 선언문에 있는 것은 선언한 변수가 포인터 형식임을 나타내는 지시 연산자예요.

간접 연산의 결과는 포인터 변수가 가리키는 메모리를 나타내며 형식은 포인터의 원소형식이예요.

예를 들어 int 형식의 변수 a의 주소를 int 형식의 포인터 변수 p에 대입하였다고 가정할게요.
그리고 간접 연산으로 p가 가리키는 곳에 값을 8로 설정하면 어떻게 될까요?
포인터 변수 p에는 변수 a의 주소를 값으로 갖고 있으면 간접 연산을 하면 a변수에 의해 관리하는 메모리를 의미하죠.
따라서 간접 연산으로 p가 가리키는 곳에 8을 설정하면 a  변수의 값은 8로 변해요.

◈ 기본 형식 변수의 주소를 포인터 변수의 초기값으로 설정한 후에 간접 연산 사용 예

#include <stdio.h>
int main()
{
    int a = 0;
    int *p = &a; //a 변수의 메모리 주소를 p의 초기값으로 설정
 
    *p = 8;
    printf("&a:%d p:%d *p;%d a:%d\n", &a, p, *p, a);
    return 0;
}

◈ 실행 결과

&a: 1043440 p:1243440 *p:8 a:8

배열 이름은 관리하는 메모리의 시작 주소를 의미하여 배열 원소 형식의 포인터로 상수로 취급해요.
따라서 배열 이름은 원소 형식이 같은 포인터 변수에 대입할 수 있어요.
또한 포인터와 정수로 원하는 원소의 주소를 계산한 후 간접 연산을 통해 각 원소에 원하는 값을 설정할 수도 있답니다.

◈ 배열 이름을 포인터 변수에 대입한 후 간접 연산 사용 예

#include <stdio.h>
int main()
{
    int arr[3] = {1,2,3};
    int *p = arr;
    int index = 0;
    for(index = 0; index<3; index++)
    {
        printf("%d %d\n",*(p+index), *(arr+index));
    }
    return 0;
}

◈ 실행 결과

1 1
2 2
3 3

◈ 기본 연습 (정답 바로가기)
1. 다음 3단계를 수행하는 코드를 작성하세요.
a. char 형식 변수 c를 선언하고 char 형식 을 원소로 하는 포인터 변수 p를 선언한 후에 변수 c의 주소를  p의 초기값으로 설정하세요.

b. 포인터 변수  p에 간접 연산을 이용하여 ‘A’를 대입하세요.

c. 그리고 변수 c의 문자를 출력하세요.

2. 다음 3단계를 수행하는 코드를 작성하세요.

a. int 형식을 원소로 하고 원소 개수가 5인 배열 arr을 선언하시오.
그리고 int 형식의 포인터 변수 p를 선언하고 arr로 초기화하시오.
int 형식의 변수 index를 선언하시오.

b. index 변수를 0에서 5보다 작을 동안 순차적으로 증가하면서 다음을 수행하시오.
포인터 변수 p와 index 의 더하기 연산한 결과에 간접 연산을 이용하여 배열의 각 원소에 1, 2, 3, 4, 5의 값을 설정

c. index 변수를 0에서 5보다 작을 동안 순차적으로 증가하면서 다음을 수행하시오.
배열 이름 arr과 index의 더하기 연산한 결과에 간접 연산을 이용하여 배열의 각 원소 값을 출력

3. 아래와 같이 10명의 성적을 기억하는 배열 scores를 선언하였다.
int scores[10]={90,38,45,67,98,87,88,20,98,85};
그리고 다음과 같이 포인터 변수 p를 scores로 초기화하였다.
int *p = scores;
반복문과 조건문과 포인터 변수와 더하기 연산, 간접 연산을 이용하여 최대값이 있는 원소가 몇 번째 원소인지 판단하는 코드를 작성하시오.