본문 바로가기
작업/Programming

Perfect C 프로그래밍 연습 9장 7, 8, 9, 10번 해결

 

 

문제 7.

 

배열의 총합과 평균 구하기

 

//문제7
    double score[] = {98.56, 78.62, 78.69, 89.32, 95.29};
    double sum = 0; //합계 저장
    double avg = 0; //평균 저장
    
    //score의 원소값 출력
    for(int i=0; i<sizeof(score)/sizeof(score[0]); i++){
        printf("%.2f   ", score[i]);
    }

   //원소값들을 더하여 저장
    for(int i=0; i<sizeof(score)/sizeof(score[0]); i++){
        sum+=score[i];
    }

    //평균
    avg = sum/(sizeof(score)/sizeof(score[0]));

    printf("\n배열 값의 합계 = %.2f, 배열 값의 평균 = %.2f\n", sum, avg);

 

 

배열의 원소들의 합계는 for문을 통해 배열의 원소들에 접근하고

합계를 저장할 변수를 만들어 그곳에 원소들의 값을 더하여 저장하였습니다.

원소들의 평균은 합계에 원소의 개수를 나누어 구하였습니다.

 

 


문제 8.

 

배열에 입력된 수의 빈도수 구하기

 

//문제8
    int inputn[20]; //입력 값 저장할 배열
    int bins[10] = {0}; //0~9의 빈도를 저장할 배열
    int max = 0; //빈도가 가장 많은 수 저장

    printf("0~9의 정수 값 20개 입력하세요.");
    
    for(int i=0; i<20; i++){  //값 입력 받기
        scanf("%d", &inputn[i]);
    }

    //입력된 값의 개수 저장
    for(int j=0; j<20; j++){
        bins[inputn[j]] +=1;
        //입력 값이 2이면 bins[2]의 값에 1추가
    }

    //가장 큰 빈도 수 구하기
    for(int k=1; k<10; k++){
        if(bins[max]<bins[k]){
            max = k; 
            //기존의 빈도 수보다 큰 값이 등장하면 최신화시킴
        }
    }

    for(int h=0; h<10; h++){
        printf("%d의 빈도 수 = %d\n", h, bins[h]);
    }

    printf("최고 빈도 수를 가진 값 = %d, 빈도 수 = %d\n", max, bins[max]);

 

 

 

 

배열의 공간에 원소들을 직접 입력하는 과정이 필요합니다.

 

배열의 공간을 탐색하기 위해선 for문이 반드시 필요하며

scanf()를 통해서 배열의 각 공간에 값을 집어넣도록 하였습니다.

 

 

scanf() 사용 시에는 #define _CRT_SECURE_NO_WARNINGS 전처리가 필요하다는 것을 잊지 마세요.

 

 

입력을 마치면 저장된 수들의 개수를 계산하는 과정을 진행합니다.

입력된 수의 범위가 0~9이기 때문에 배열의 인덱스와 일치합니다.

 

 

2를 입력했다면 bins[2]의 값이 1 증가하게 되는 것입니다. 

bins 배열에는 0~9가 몇 번 입력되었는지 0~9의 인덱스에 순차적으로 저장되었습니다.

 

 

이제 bins 배열을 탐색하여 가장 큰 수가 저장된 인덱스가 어디인지 찾아내고 max에 인덱스를 저장합니다.

처음 max = 0으로 두어 bins[0]을 탐색할 수 있도록 합니다.

 

 

그렇기 때문에 for문의 시작은 k=1로 두어 bins[1]과 비교할 수 있도록 하였습니다.

bins[0]과 bins[1]을 비교하게 될 것이며 값의 크기가 큰 것의 인덱스가 max에 저장됩니다.

 

 

이 과정을 반복하면 최종적으로 빈도 수가 큰 인덱스가 max에 저장되며

bins[max]를 통해 해당 값에 접근할 수 있게 됩니다.

 

 


문제 9.

 

그 해 그 달의 말일 출력 (윤년 구하기)

 

//문제9
    int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int year, mon; //년과 월을 저장

    printf("년과 달을 순서대로 입력하세요. : ");

    scanf("%d %d", &year, &mon);

    //4와 100으로 나누었을 때 나머지가 0이면 평년
    //해당 조건과 반대되고 400으로 나누어지면 윤년
    if((year%4==0)&&(year%100!=0)||(year%400==0)){
        month[1] = 29; //윤년의 2월은 29일임
    }

    printf("%d년의 %d월은 %d일 입니다.", year, mon, month[mon-1]);
    //배열공간은 0부터 시작하기 때문에 mon-1

 

 

 

이전 프로그래밍 연습에서 윤년을 구하는 프로그램을 코딩한 적이 있습니다.

그것을 다시 사용해서 만드는 문제입니다.

 

 

처음 배열에는 각 월의 말일을 저장합니다. 2월의 경우 보통은 28일이기 때문에 28을 저장합니다.

(인덱스 0은 1월을 의미하게 됩니다.)

이후 조건으로 윤년인지 확인하는 식을 구성합니다.

 

 

4로 나누어지면 윤년, 4와 100으로 나누어지면 평년, 400으로 나누어지면 윤년입니다.

 

 

이것을 조건에 대입하게 된다면

4와 100으로 나누어지는 경우를 배제할 수 있도록 구성하면 됩니다.

 

 

(year%4==0) && (year%100!=0)   <-  && : AND 연산, != : NOT

이후에 or(||) 연산으로 400으로 나누어지는지도 확인합니다.

 

 


문제 10.

 

//문제10
    double value[10];

    for(int i=0; i<10; i++){ 
        //연산의 시작이 2이기 때문에 2로 시작
        value[i] = 1./((i+2)*(i+3)); 
        // . 입력으로 실수형 연산 수행
    }

    for(int j=0; j<10; j++){
        printf("%.5f  ", value[j]);
    }

 

 

배열에 저장하는 값들은

1/(2*3), 1/(3*4), 1/(4*5)...로 되어있습니다.

 

 

for문의 i를 활용하게 된다면 1 / (i+2) * (i+3) 구성으로 간단하게 만들 수 있습니다.

계산식의 전체적인 구성이 정수들로 이루어져 있기 때문에

나누기 연산의 결과도 정수형으로 나타나게 됩니다.

 

 

소수 부분은 없어진다는 의미이며, double에서 의도하는 결과를 얻을 수가 없습니다.

따라서 계산식을 "(double) 1 / (i+2) * (i+3)" 형태로 만들어 명시적 형 변환을 시켜주거나

계산식 내부에 .(점)을 추가하여 실수형 계산식이 되도록 구성합니다.

 

 

-끝-