{ }codelper

배우기 › C

데이터 · 10

리스트와 배열

여러 값을 한 줄로: 개수, 처음과 끝, 합, 모두 바꾸기.

리스트(배열)는 값 여러 개를 순서대로 담아요.
아래 예제는 수들을 읽어 개수, 처음과 끝, 합을 찍고 모두 두 배로 바꿔요.

#include <stdio.h> int main(void) {    int n, nums[1000], sum = 0;    scanf("%d", &n);    for (int i = 0; i < n; i++) scanf("%d", &nums[i]);    printf("%d\n", n);    printf("%d %d\n", nums[0], nums[n - 1]);    for (int i = 0; i < n; i++) sum += nums[i];    printf("%d\n", sum);    for (int i = 0; i < n; i++) printf(i > 0 ? " %d" : "%d", nums[i] * 2);    printf("\n");    return 0;}
stdin
5
3 1 4 1 5
stdout
5
3 5
14
6 2 8 2 10

핵심

  • 번호는 0부터예요.
    그래서 마지막 값은 개수 - 1번이에요.
  • 크기가 정해진 배열과, 값을 더 넣을 수 있는 목록 두 종류가 있어요.
    이름과 쓰는 법은 언어마다 달라요.
  • 합·최댓값은 처음부터 끝까지 한 번 훑으며 구해요.
    "모두 두 배" 같은 변환을 한 줄로 쓰는 언어도 있어요.
  • b = a는 복사가 아니에요.
    같은 목록에 이름을 하나 더 붙이는 거라서, b에 넣으면 a도 바뀌어요(C++ vector만 대입하면 복사돼요).
  • 범위를 벗어나 읽으면 대부분 오류로 멈춰요.
    멈추지 않고 엉뚱한 값을 주는 언어가 더 위험해요.

언어별로 쓰는 법

Pythonlist — append, len(nums), 마지막은 nums[-1].
sum·max가 있고, 두 배는 [x * 2 for x in nums].
범위 밖은 IndexError
JavaScript배열 — push, length, 마지막은 nums.at(-1).
합은 reduce, 최댓값은 Math.max(...nums), 변환은 map.
범위 밖은 오류 없이 undefined
TypeScriptJavaScript와 같아요.
number[]처럼 담을 타입을 적어요
Java고정 배열 int[] a = new int[n](a.length), 늘어나는 ArrayList<Integer>(add, size(), get(i)).
합은 Arrays.stream(a).sum()이나 반복문.
범위 밖은 ArrayIndexOutOfBoundsException
C#고정 int[](Length), 늘어나는 List<int>(Add, Count).
마지막은 nums[^1].
LINQ Sum()·Max()·Average()·Select.
범위 밖은 IndexOutOfRangeException
C++std::vector<int> — push_back, size(), 마지막은 back().
합은 std::accumulate, 최댓값은 std::max_element.
[]는 범위를 확인하지 않고, at(i)는 예외를 던져요
Cint a[1000]처럼 크기를 미리 정하고, 개수는 따로 들고 다녀요.
합·최댓값·변환은 모두 반복문.
범위 밖을 읽어도 아무 말이 없어요
Craykon[ ] — 넣기, 개수(1만 개까지), 마지막은 nums[nums.개수 - 1].
합·최댓값은 반복문.
범위 밖은 "목록에는 0~4번만 있어요" 오류

자주 하는 실수

최댓값을 0에서 시작했어요

nums = [-3, -1]
best = 0
for x in nums:
    if x > best: best = x
print(best)

→ 0 — 값이 모두 음수라 한 번도 바뀌지 않아요(답은 -1)

첫 값 nums[0]에서 시작해요.

평균이 정수로 잘렸어요Java · C# · C · C++

int sum = 14, n = 5;
double avg = sum / n;

→ 2 — 14 / 5가 먼저 정수 나눗셈이 돼요(2.8이 아니에요)

나누기 전에 바꿔요: (double)sum / n → 2.8.

범위 밖을 읽었는데 멈추지 않아요JavaScript · TypeScript · C · C++

const nums = [3, 1, 4];
console.log(nums[3]);
console.log(nums[-1]);

→ undefined가 두 번 — 오류 없이 지나가요. C·C++ []는 옆 메모리의 아무 값이나 읽어요

읽기 전에 번호가 0부터 개수 - 1 안인지 확인해요.

언어마다 다른 점
목록을 통째로 찍으면 언어마다 모양이 달라요: Python [3, 1, 4], JavaScript [ 3, 1, 4 ], Java 배열은 [I@1b6d3586 같은 이름표, C# 배열은 System.Int32[].
빈칸으로 이어 찍으려면 Python print(*nums), JavaScript nums.join(" "), C# string.Join(" ", nums), Java는 반복문을 쓰고, 크레이콘 콘솔.쓰기(nums)는 바로 3 1 4로 찍어요.

연습 문제