본문 바로가기

문제풀이

[C언어] 백준 15596

long long sum(int *a, int n) {
long long ans = 0;
    
    while(--n > -1) 
        ans += (long long) a[n];
    
return ans;
}

 

  • 사용언어: C
  • 접근
    • 반복횟수 n은 이미 argument로 넘겨받고 있기 때문에, 단순히 함수 정의 안에서 루프를 돌려 sum을 구해 리턴하는 문제
    • 변수 개수를 최소화하고 코드도 단순화하기 위해 while문 선택
      • 가장 처음에는 배열의 인덱스 0까지 루프가 돌아야하기 때문에
        n--이 아닌 --n 표현문을 선택하고 해당 값이 -1보다 작을 때라고 코드를 작성

※그러나 while (n --)이 더 깔끔한 코드였다.

  • while(n--): n이 0보다 큰지 먼저 판단하고 코드블럭 안을 수행할지 말지 결정
  • 그 다음 코드블럭 안에 들어가기 직전 n에서 -1
    따라서, n = 0 일때에도 nested code는 수행된다.
  • while(--n)이라면 n을 먼저 차감하고 그 다음 조건을 체크해 블럭 안을 수행할지 말지 결정하기 때문에
    인덱스 0의 value를 더하지 않는다
long long sum(int* a, int n)
{
    long long ans = 0;

    while (n--)
        ans += *a++;

    return ans;
}

 

※두번째 코드 단순화: 요소에 직접 접근하지 않고 주소를 변경

다른 사람들 접근법을 둘러보던 와중,  a[n]처럼 요소에 직접 접근하지 않고 주소를 통해 문제를 해결하려는 방식이 돋보였다.

배열이나 데이터 구조를 좀 더 깊게 공부하기에 도움이 될 것 같아서 코드를 분석해보았다.

  • 0~4열까지 1,2,3,4,5 값을 저장 후 해당 함수를 호출 (실제 입력은 5 5 4 3 2 1)
  • ans += *a++; 디버깅 모드로 돌려보아도 한줄에서 최소 세개의 작업이 수행되는데 그 안의 우선순위를 파악하기가 어려웠음
  • 함수 sum에서 a는 배열 a의 이름으로, 값으로 a[0]의 주소를 저장하고 있다.
    • a +=1: a의 주소를 그 다음 인덱스의 주소로 업데이트
  • a값이 어떻게 변화하는지, dereference가 먼저인지, a++가 먼저인지(혹은 *a++), 값을 할당하는 게 먼저인지 생각해 봄
n a (배열의 주소) ans break point: ans += *a++; 수행 순서
4 d3ec94  0 *a = a[0] = 1 ans += 1 = 1 a++:  a = d3ec98 
3 d3ec98  1 *a = a[1] = 2
ans = 1 + 2 = 3 a++:  a = d3ec9c 
2 d3ec9c  3 *a = a[2] = 3
ans = 3 + 3 = 6 a++:  a = d3eca0 
1 d3eca0  6 *a = a[3] = 4
ans = 6 + 4 = 10 a++:  a = d3eca4 
0 d3eca4  10 *a = a[4] = 5
ans = 10 + 5 = 15 a++:  a = d3eca8 
-1 d3eca8  15 수행되지 않음

※ sum 함수 안에서 a++를 통해 a의 값을 변경시킨다 하더라도, main의 a값은 변하지 않는다.

  • 포인터를 통해 *a가 변경되는 것이 아닌 a라는 일종의 주소 copy값이 변경되고 있기 때문에

 

walkthrough를 위해 적었던 전체 코드

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

long long sum(int* a, int n);

int main(void)
{
    int n, i;
    int a[1000]; // 1 <= n <= 3,000,000

    scanf("%d", &n);
    i = n;
    while (n--)
        scanf("%d", &a[n]);
    
    sum(a, i);

    return 0;
}

long long sum(int* a, int n)
{
    long long ans = 0;

    while (n--)
        ans += *a++;

    return ans;
}

'문제풀이' 카테고리의 다른 글

[C언어] 백준 1152 단어의 개수  (0) 2021.12.22
[C언어] 백준 1157 단어공부  (0) 2021.12.22
[C언어] 백준 2675 문자열반복  (0) 2021.12.21
[C언어] 백준 10809 알파벳찾기  (0) 2021.12.21
[C언어] 백준 11720  (0) 2021.12.21