JOURNALHelloworld

C 언어 — 단차원 배열과 주소 문제

C 언어 --- 단차원 배열 + 주소 문제

범위: 단차원 배열, 인덱스, 메모리 주소, &, 배열명, 포인터 연산,
sizeof
가정: 특별한 언급이 없으면 sizeof(int) == 4,
sizeof(char) == 1이며 배열의 원소는 메모리에 연속해서 저장된다.


1. 배열의 기본 주소 계산

다음 배열이 있고 score[0]의 시작 주소가 0x1000이라고 하자.

int score[5] = {10, 20, 30, 40, 50};

다음 주소를 각각 구하시오.

  1. &score[0]
  2. &score[1]
  3. &score[2]
  4. &score[4]

2. 주소를 보고 인덱스 찾기

다음 배열의 시작 주소는 0x2000이다.

int data[8];

0x2014 주소에 저장되는 원소는 data[?]인지 구하시오.


3. char 배열의 주소

다음 배열에서 name[0]의 주소가 0x3000이라고 하자.

char name[6] = {'L', 'E', 'M', 'O', 'N', '\0'};

다음의 주소를 구하시오.

  1. &name[1]
  2. &name[3]
  3. &name[5]

그리고 int 배열과 비교했을 때 주소 증가 폭이 다른 이유를 설명하시오.


4. 배열 원소 값 추적

다음 코드를 실행한 뒤 배열의 최종 상태를 작성하시오.

int a[5] = {1, 2, 3, 4, 5};
 
a[1] = a[0] + a[2];
a[3] = a[1] * 2;
a[4] = a[3] - a[0];

최종 결과:

a = { ?, ?, ?, ?, ? }

5. 배열명과 주소

다음 코드가 있다.

int arr[4] = {10, 20, 30, 40};

아래 표현식 중 일반적인 식(expression) 문맥에서 같은 시작 주소를
나타내는 것
을 모두 고르시오.

A. arr
B. &arr[0]
C. arr + 0
D. &arr
E. &arr[1]

추가 문제: 값으로 표시되는 시작 주소가 같더라도 arr와 &arr의 타입
및 포인터 연산 결과
는 같은지 설명하시오.


6. 포인터 연산

다음 조건을 사용하시오.

int arr[6];

arr의 시작 주소가 0x4000일 때 다음 표현식이 가리키는 주소를
구하시오.

  1. arr + 1
  2. arr + 3
  3. arr + 5

7. 역으로 시작 주소 구하기

다음 배열이 있다.

int num[10];

&num[7]의 주소가 0x501C라고 한다.

num[0]의 시작 주소를 구하시오.


8. 배열의 크기

다음 코드에서 각 표현식의 결과를 구하시오.

int arr[10];
  1. sizeof(arr)
  2. sizeof(arr[0])
  3. sizeof(arr) / sizeof(arr[0])

9. 빈칸 채우기

다음 코드는 배열의 모든 원소를 출력한다.

int arr[5] = {3, 6, 9, 12, 15};
 
for (int i = 0; i < _____; i++) {
    printf("%d\n", arr[_____]);
}

두 빈칸을 채우시오.


10. 주소와 값 구분하기

다음 배열이 있다.

int arr[3] = {100, 200, 300};

arr[0]의 주소는 0x6000이다.

다음 표현식의 결과가 값(value) 인지 주소(address) 인지 구분하고,
알 수 있는 경우 실제 결과도 작성하시오.

표현식 값 / 주소 결과


arr[0] ? ?
&arr[0] ? ?
arr ? ?
arr + 1 ? ?
*(arr + 1) ? ?
&arr[2] ? ?


11. 코드 해석

다음 코드의 출력 결과를 작성하시오.

#include <stdio.h>
 
int main(void) {
    int a[4] = {5, 10, 15, 20};
 
    printf("%d\n", a[2]);
    printf("%d\n", *(a + 2));
    printf("%d\n", *(a + 3));
 
    return 0;
}

그리고 a[2]와 *(a + 2)가 같은 값을 출력하는 이유를 설명하시오.


12. 주소 차이 계산

다음 배열에서 arr[0]의 주소는 0x7000이다.

int arr[100];

&arr[73]의 주소를 구하시오.


13. 잘못된 접근 찾기

다음 코드에서 배열 범위를 벗어나는 접근을 모두 찾으시오.

int a[5] = {0};
 
a[0] = 10;
a[4] = 20;
a[5] = 30;
a[-1] = 40;

왜 문제가 되는지도 설명하시오.


14. 조금 더 어려운 주소 문제

다음 배열이 있다.

int arr[8] = {11, 22, 33, 44, 55, 66, 77, 88};

arr의 시작 주소는 0x8000이다.

다음 표현식의 주소 또는 값을 구하시오.

  1. arr + 4
  2. *(arr + 4)
  3. &arr[6]
  4. *(arr + 7)
  5. &arr[2] + 3

15. 포인터 변수와 배열

다음 코드가 있다.

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;

arr[0]의 주소가 0x9000일 때 다음 결과를 구하시오.

  1. p
  2. p + 2
  3. *p
  4. *(p + 2)
  5. p[3]

16. 함정 문제 --- 주소값은 같지만 타입은 다르다

다음 코드가 있다.

int arr[5];

다음 두 표현식을 비교하시오.

arr + 1
&arr + 1
  1. 두 표현식은 같은 주소를 가리키는가?
  2. arr의 시작 주소가 0xA000이라면 각각 어떤 주소가 되는가?
  3. 왜 이런 차이가 발생하는가?

17. 종합 문제

다음 코드를 보고 물음에 답하시오.

int x[6] = {4, 8, 12, 16, 20, 24};
int *p = x + 2;

x[0]의 주소는 0xB000이다.

  1. x + 2의 주소는?
  2. p에 저장된 주소는?
  3. *p의 값은?
  4. p + 2의 주소는?
  5. *(p + 2)의 값은?
  6. p[1]의 값은?
  7. &p[2]가 가리키는 주소는?

정답


핵심 공식

배열 arr의 시작 주소를 B, 원소 하나의 크기를 S라고 하면:

&arr[i] = B + i × S

C의 포인터 연산에서는 직접 바이트 수를 곱하지 않아도 된다.

arr + i

는 자동으로 다음 주소를 계산한다.

시작 주소 + i × sizeof(arr[0])

또한 다음 두 표현식은 같은 원소에 접근한다.

arr[i]
*(arr + i)