[c언어] 기초프로그래밍 중간고사 준비 (1~5번)

학교수업...c언어 기초 배우는 동국대학교 컴퓨터공학과 기초프로그래밍 수업 21년 기출문제 풀이 게시글이다.
제한시간은 2시간..!

1번


10진수를 2진수, 1의 보수, 2의 보수로 나타내는 방법이다.

교수님 코드

#include <stdio.h>

// 2진수 : 0,1로만 표현
// 1의 보수 : 각 자리가 모두 1인 수에서 주어진 2진수를 빼면 된다.
// 2의 보수 : 1의 보수에 1 더한다
#define INTSIZE 32


int main(void)
{
    
    unsigned int num,bp,ubit=0,msb;
    // ubit
    // msb
    // bp

    
    
    printf("10진수를 입력하시오 : ");
    scanf("%d",&num);
    
    bp = 0x80000000; // unsigend int 형식 0x80000000 는 2147483648 이다. 즉, 최댓값이다.
    
    for(int i=0;i<INTSIZE;i++){
        
        //num bp and연산 둘이 1로 겹칠때 1을 출력한다.
        if((num&bp)==bp){
            break;
        }
        ubit++; //비트 수 계산
//        printf("%d\n",ubit);
        bp >>= 1; // bp의 비트열을 1칸씩 오른쪽으로 이동시킨것을 넣는다.
    }
    
    msb = bp;
    
    //2진수 출력
    for(int i=0;i<(INTSIZE-ubit);i++){
        printf("%d",(num&msb)==msb);
        msb>>=1;
    }
    printf("(2)\n");
    
    //1보수 출력
    num = ~num;
    msb = bp;
    for(int i=0;i<(INTSIZE-ubit);i++){
        printf("%d",(num&msb)==msb);
        msb>>=1;
    }
    printf("(one's complement)\n");
    
    //2의 보수 출력
    num += 1;
    msb = bp;
    for(int i=0;i<(INTSIZE-ubit);i++){
        printf("%d",(num&msb)==msb);
        msb>>=1;
    }
    printf("(two's complement)\n");

    return 0;
}

진짜 1번부터 자비가 없네....미친..보통은 1번은 쉽게 내지않나...
1~5번 중 제일 어려운거같다...
비트연산 복습하고 다시보자 .. 흑 흑 ..

2번

시간 헤더파일을 가져와서 쓰고, 키를 입력받으면 end-start를 하면 될 것같다.. 근데 뭐지 이게

교수님 코드

#include <stdio.h>
#include <time.h> // 시간 헤더
#include <conio.h> // 콘솔 입출력 함수 제공 헤더

// iny kbhit()
// keyboard hit 약자, 버퍼에 값 있으면 1, 없으면 0 리턴

// time_t : 리턴 타입

int main(void)
{
    
    time_t start, end;
    
    printf("key를 입력하면 시간(초) 출력됩니다.");
    
    start = time(NULL); // 1970년 1월 1일 0시 0분 0초부터, 현재까지 몇 초가 지났는지를 리턴
    
    while(1){
        if(_khbit()){ //키보드 입력이 있을때
            end = time(NULL);
            break;
        }
    }
    printf("%d 초\n",(int)(end-start)); // 지난 시간 출력
    return 0;
}

아니 교수님...장난하는것도 아니고.. vsc에만 되는 conio헤더 파일을 사용하시면 리눅스나 맥사용자는 어떡하라고요....
돌리는거 확인을 못해서 교수님 정답 코드를 가져왔다.

우선,.. 코드 설명을 하자면 아래와같다.
time_t로 시간 start,end 변수를 만들어 준 후 start에는 100000초가 들어가고 5초뒤에 키를 입력했다면 end에는 100005초가 들어가서 5초가 출력된다.

하... conio...미치겠네~
이번에는 이렇게 안내시겠지..제발..

3번

음... 그냥 두 양수 unsigned int로 받고 double에 넣고
범위 넘으면 넘었다 말해주고 안넘으면 그냥 출력하면 되는 문제이다.

#include <stdio.h>

#define LIMIT 4294967295

int main(void)
{
    unsigned int num1,num2;
    double num3=0;
    printf("두 개의 양수를 입력하시오 : ");
    scanf("%u %u",&num1,&num2);
    
    num3 = (double)num1 + (double)num2; //double에 넣기 위해 형 변환 해주기
    
    // 범위 넘음
    if(num3>LIMIT){
        printf("unsigned int의 최대값 : 4294967295\n");
        printf("%.f 만큼 오버플로우가 발생했습니다.\n",num3-LIMIT ); // 소수점 날리기
        printf("더한 값 : %.1f\n",num3);
    }
    // 범위안
    else{
        printf("더한 값 : %.f\n",num3);
    }
    return 0;
}

주의 해야할 점

  • double에 넣을려면 double로 형변환 해줘야한다.
  • 소수점 출력 %.f하면 소수점 다 날린다.
  • unsigned int 최대값 : 4294967295

교수님 코드도 비슷하니 생략하겠다.

4번

교수님 코드

#include <stdio.h>

#define a 0.25
// E(0) = 1


int main(void)
{ 
    int cnt = 0;
    double X,E = 1;
    
    printf("문자열을 입력하시오. ");
    // 문자열을 반복해서 입력받는다.
    while(1){
        scanf("%lf",&X); //문자열 입력받는 테크닉
        
        // X가 -1일때
        if(X==-1)
            break;
        
        E = a*E + (1-a)*X; // E값을 매번 초기화
        printf("E(%d) = %f\n",++cnt,E);
    }
    

    return 0;
}

교수님의 압도적으로 깔끔한 코드이다..
문자열을 입력받아야해서 문자열을 배우지 않은 지금 어떻게 접근해야지 생각을 했는데 반복문으로 입력을 반복받는 방법이 있었다.
C언어에서는 입력을 하나 받고 돌리고 이런느낌이기에 저게 가능한것같다..

그렇기 때문에 매번 E값을 초기화 해주고, E(N)을 출력해주고 마지막인 -1이 왔을때 반복문을 끝내면 된다..

이 코드는 정말 멋지다..! 굿굿!

5번

소수판별 알고리즘을 사용하는 문제이다.

내가 짠 코드

#include<stdio.h>

int main(void)
{
    int cnt ,num;
    printf("n을 입력하세요 : ");
    scanf("%d", &num);
    
    for (int i = 2; i <= num; i++) // num이하
    {
        cnt = 0;
        for (int j = 2; j <= i; j++) // i이하
        {
            if (i % j == 0) // 나눠질때
                cnt++; //cnt 올린다
        }
        if (cnt == 1) // 나눠지는 수 1개만 있을때
            printf("%d ", i);
    }
}

이중 for문으로 구현 했으며 수가 나눠질때마다 cnt를 올려서 cnt가 1일때 소수임을 판단하고 출력하는 방식의 코드이다.

교수님 코드

#include<stdio.h>

int main(void)
{
    int flag=0 ,num;
    printf("n을 입력하세요 : ");
    scanf("%d", &num);
    
    for (int i = 2; i <= num; i++) // num이하
    {
        flag=0;
        for (int j = 2; j <= i/2; j++) // i이하
        {
            if (i % j == 0) // 나눠질때
            {
                flag = 1;
                break;
            }
        }
        if (flag == 0) // 나눠지는 수 1개만 있을때
            printf("%d ", i);
        
    }
}

시간적,메모리적으로 훨 효율적이다.
cnt대신 flag로 true/false구분한 점, flag=1이되면 반복문 탈출한 점, i/2로 절반만 탐색하게 작성한 점이 체크하고 넘어가야할 점이다.

좋은 웹페이지 즐겨찾기