C언어 | 배열(Array)

설탕·2024년 4월 13일
0
post-thumbnail

배열

  • 배열명은 첫 번째 요소의 주소이다.
int ary[3];
ary == &ary[0];
  • 포인터에 배열명을 저장하면 포인터를 배열명처럼 사용할 수 있다.
int ary[3];
int *pa = ary;
pa[1] = 10; // 두 번째 배열 요소에 10 대입
  • 배열명의 정수 덧셈은 가리키는 자료형의 크기를 곱해서 더한다. ary + (1 * sizeof(*ary))
  • 배열명의 뺄셈 결과는 배열 요소 간의 간격 차이를 의미한다.
int ary[3];
ary + 1; // ary 첫 번째 요소의 주소 + 4 (int형 변수의 크기는 4byte)
  • 배열명은 상수이므로 그 값을 바꿀 수 없지만, 포인터는 변수이므로 가능하다.
ary++; // 불가
pa++; // 가능

포인터로 배열의 값 출력하기

#include <stdio.h>

int main(void)
{
  int ary[3] = { 10, 20, 30 };
  int *pa = ary;

  for (int i = 0; i < 3; i++)
  {
    printf("%d\n", pa[0]); // 10 20 30
    printf("%d\n", *(pa + 0)); // 10 20 30
    printf("%d\n", *pa); // 10 20 30

    pa++;
  }
  
  return 0;
}

다음은 모두 배열 첫 번째 요소를 출력한다.

  • pa[0]: 포인터를 배열명처럼 사용해 첫 번째 배열 요소를 출력
  • *(pa + 0): 포인터 연산식으로 출력
  • *pa: pa가 가리키는 배열 요소 출력

증가 연산자로 pa에 1을 더하면 pa가 두 번째 배열 요소를 가리키게 되어 20을 출력하고, 반복문을 돌면서 pa에 한 번 더 1을 더하면 세 번째 배열 요소를 가리키게 되어 30을 출력한다.

백준 문제 5597번. 과제 안 내신 분..?

입력 예시

3
1
4
5
7
9
6
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

출력 예시

2
8

풀이

#include <stdio.h>

int main(void)
{
  int students[30] = { 0, }; // 배열 모든 요소를 0으로 초기화
  int *p = students; // 포인터에 배열명 저장

  for (int i = 0; i < 28; i++)
  {
    int num;
    scanf("%d", &num); // 제출한 사람 출석번호
    p[num - 1] = 1; // 0으로 초기화한 배열에서 제출한 사람 출석번호 인덱스의 값을 1로 바꿈
  }
  
  for (int i = 0; i < 30; i++)
  {
    if (p[i] == 0) printf("%d\n", i + 1); // 배열 요소의 값이 0인 인덱스를 출력
  }
  
  return 0;
}

처음에 풀 때 값을 출력하려고 하면 계속 abort가 찍히면서 프로그램이 다 실행되지 못하고 종료되었다. 이리저리 헤매다 원인을 찾았는데, 포인터가 배열에 할당된 영역을 벗어났기 때문이었다. 출석번호는 1부터 시작하고 배열 인덱스는 0부터 시작하므로 제출한 사람 출석번호로 배열 인덱스를 찾을 때 1을 빼야 하는데, 1을 빼지 않아서 배열의 31번째 요소에 값을 할당하려고 하니 에러가 발생해서 프로그램이 강제 종료된 것이었다. 이렇게 포인터가 배열에 할당된 영역을 벗어나게 사용하려고 하면 운영체제에 의해 프로그램이 강제 종료될 수도 있고, 그렇지 않더라도 예상치 못하게 값이 바뀔 수 있으니 주의하자!!

profile
공부 기록

0개의 댓글