C 언어 --- 단차원 배열 + 주소 문제
범위: 단차원 배열, 인덱스, 메모리 주소,
&, 배열명, 포인터 연산,
sizeof
가정: 특별한 언급이 없으면sizeof(int) == 4,
sizeof(char) == 1이며 배열의 원소는 메모리에 연속해서 저장된다.
1. 배열의 기본 주소 계산
다음 배열이 있고 score[0]의 시작 주소가 0x1000이라고 하자.
int score[5] = {10, 20, 30, 40, 50};다음 주소를 각각 구하시오.
&score[0]&score[1]&score[2]&score[4]
2. 주소를 보고 인덱스 찾기
다음 배열의 시작 주소는 0x2000이다.
int data[8];0x2014 주소에 저장되는 원소는 data[?]인지 구하시오.
3. char 배열의 주소
다음 배열에서 name[0]의 주소가 0x3000이라고 하자.
char name[6] = {'L', 'E', 'M', 'O', 'N', '\0'};다음의 주소를 구하시오.
&name[1]&name[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일 때 다음 표현식이 가리키는 주소를
구하시오.
arr + 1arr + 3arr + 5
7. 역으로 시작 주소 구하기
다음 배열이 있다.
int num[10];&num[7]의 주소가 0x501C라고 한다.
num[0]의 시작 주소를 구하시오.
8. 배열의 크기
다음 코드에서 각 표현식의 결과를 구하시오.
int arr[10];sizeof(arr)sizeof(arr[0])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이다.
다음 표현식의 주소 또는 값을 구하시오.
arr + 4*(arr + 4)&arr[6]*(arr + 7)&arr[2] + 3
15. 포인터 변수와 배열
다음 코드가 있다.
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;arr[0]의 주소가 0x9000일 때 다음 결과를 구하시오.
pp + 2*p*(p + 2)p[3]
16. 함정 문제 --- 주소값은 같지만 타입은 다르다
다음 코드가 있다.
int arr[5];다음 두 표현식을 비교하시오.
arr + 1
&arr + 1- 두 표현식은 같은 주소를 가리키는가?
arr의 시작 주소가0xA000이라면 각각 어떤 주소가 되는가?- 왜 이런 차이가 발생하는가?
17. 종합 문제
다음 코드를 보고 물음에 답하시오.
int x[6] = {4, 8, 12, 16, 20, 24};
int *p = x + 2;x[0]의 주소는 0xB000이다.
x + 2의 주소는?p에 저장된 주소는?*p의 값은?p + 2의 주소는?*(p + 2)의 값은?p[1]의 값은?&p[2]가 가리키는 주소는?
정답
정답 보기
1.
0x10000x10040x10080x1010
int하나가 4바이트이므로 인덱스가 1 증가할 때 주소가 4씩 증가한다.2.
0x2014 - 0x2000 = 0x14 = 20바이트이다.
20 / 4 = 5따라서
data[5].3.
0x30010x30030x3005
char는 1바이트이므로 다음 원소의 주소가 1바이트씩 증가한다.4.
a = {1, 4, 3, 8, 7}5.
A,B,C,D는 시작 지점의 수치상 주소가 같다.단,
arr는 대부분의 식에서int *로 변환되고,&arr는int (*)[4],
즉 int 4개짜리 배열을 가리키는 포인터이다.따라서:
arr + 1은
sizeof(int)만큼 이동하지만,&arr + 1은
sizeof(arr)만큼 이동한다.6.
0x40040x400C0x40147.
7 * 4 = 28 = 0x1C따라서:
0x501C - 0x1C = 0x5000정답:
0x50008.
404109.
for (int i = 0; i < 5; i++) { printf("%d\n", arr[i]); }10.
표현식 값 / 주소 결과
arr[0]값100
&arr[0]주소0x6000
arr주소0x6000
arr + 1주소0x6004
*(arr + 1)값200
&arr[2]주소0x600811.
15 15 20C에서 배열 인덱싱은 다음 관계를 가진다.
a[i] == *(a + i)따라서
a[2]는*(a + 2)와 같은 원소에 접근한다.12.
73 * 4 = 292 = 0x124따라서:
0x7000 + 0x124 = 0x7124정답:
0x712413.
범위를 벗어나는 접근:
a[5] a[-1]
a[5]에서 유효한 인덱스는0부터4까지이다. 범위를 벗어난 배열
접근은 C에서 정의되지 않은 동작(undefined behavior) 을 일으킨다.14.
arr + 4→0x8010*(arr + 4)→55&arr[6]→0x8018*(arr + 7)→88&arr[2] + 3→&arr[5]→0x801415.
p→0x9000p + 2→0x9008*p→10*(p + 2)→30p[3]→4016.
같지 않다.
arr는 식에서 보통 첫 번째 원소를 가리키는int *로 변환된다.따라서:
arr + 1 = 0xA004반면
&arr의 타입은int (*)[5]이다. 포인터가 가리키는 대상 하나의
크기가 배열 전체 크기인 20바이트이다.따라서:
&arr + 1 = 0xA01417.
x + 2→0xB008p→0xB008*p→12p + 2→0xB010*(p + 2)→20p[1]→16&p[2]→0xB010
핵심 공식
배열 arr의 시작 주소를 B, 원소 하나의 크기를 S라고 하면:
&arr[i] = B + i × SC의 포인터 연산에서는 직접 바이트 수를 곱하지 않아도 된다.
arr + i는 자동으로 다음 주소를 계산한다.
시작 주소 + i × sizeof(arr[0])또한 다음 두 표현식은 같은 원소에 접근한다.
arr[i]
*(arr + i)