IT공부/IT서적

[윤성우 열혈 C프로그래밍] Part1. C 언어의 기본

shine94 2024. 7. 16. 22:58

** 기본적으로 제공되는 함수를 표준함수라고 하고,

   표준함수들의 모임을 가르켜 표준 라이브러리라고 함

 

** 표준함수를 호출하기 위해서는 헤더파일을 선언해야 함

 

** main 함수의 마지막에서 0을 전달(반환)하는 이유?

   : 이 값은 main 함수를 호출한 영역으로 전달

     main 함수는 프로그램이 시작되면 자동으로 호출되는 함수

     호출의 주체는 Windows나 Linux와 같은 운영체제

     ㄴ 그 값은 프로그램의 종료 상태를 알리는 용도로 사용

     ㄴ 보통 0은 정상적인 종료 상황에서 전달하는 값

     ㄴ 비정상적인 상황으로 인해서 종료될때에는 일반적으로 0이 아닌 값을 전달

 

** 서식문자(conversiuon)

   : 출력의 형태를 지정하는 용도로 사용

 

** 연산자(operator)

   : 특정연산을 요구할 때 사용되는 약속된 기호

 

** 변수를 선언만 하고 초기화하지 않으면 쓰레기 값이 저장

   ㄴ 쓰레기값? 아무런 의미가 없는 값

 

** 변수 이름 규칙

   1. 변수의 이름은 알파벳, 숫자, 언더바(_)로 구성

   2. 대소문자 구분

   3. 숫자로 시작 불가

   4. 키워드는 변수의 이름으로 사용 불가

   5. 이름 사이에 공백 불가

 

** 비트(Bit) : 컴퓨터가 표현하는 데이터의 최소 단위

   ㄴ 비트를 8개 묶으면 바이트(Byte)

 

** 정수의 표현방식

 : 정수의 가장 왼쪽에 존재하는 비트는 부호비트

   ㄴ 양수라면 0, 음수라면 1

   ㄴ 이 비트를 가르켜 MSB(Most Significant Bit)

 

: 음의 정수를 표현할 때는 2의 보수

   ㄴ 1의 보수(Not 연산) + 1

 

** 실수의 표현 방식

① 소수점을 이진수로 변환 - 곱하기 2 → 정수부를 순서대로 나열

   https://woo-dev.tistory.com/93

 

소수점 이진수로 변환하는 법 | 소수점 이진법

ex) 68.625 -> ??? 1. 정수부(68)는 그대로 이진수로 변환한다. 64 + 4 -> 100 0100 2. 소수부(0.625)만 가져온다. 0.625 3. 소수부에 2를 곱하는데 그 결과가 1로 떨어질 때까지 혹은 똑같은 소수점이 나올 때까지

woo-dev.tistory.com

② 부동소수점 구하기

   https://velog.io/@mjk3136/%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%98%EC%A0%90%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EA%B8%B0

 

부동소수점에 대해 알아보자

개념은 확실히 잡아야지🔥 / 진행 중

velog.io

 

: 4 Byte - 부호부 : 1 비트 / 지수부 : 8비트 / 가수부 23비트

 

: 컴퓨터가 실수를 표현하는 방식에는 오차가 존재 => 부동 소수점 오차

   ㄴ 컴퓨터는 실수를 100% 정확히 표현하지 못함, 근사치를 표현

 

** 비트연산자 메모

   ㄴ ^ : XOR, 두 개의 비트가 서로 다른 경우 참

   ㄴ << : 비트의 열을 왼쪽으로 1칸씩 이동할 때 마다 정수의 값은 두 배가 됨

   ㄴ >> : 비트의 열을 오른쪽으로 1칸씩 이동할 때마다 정수의 값은 2로 나누어 짐

 

** C언어의 자료형

ㄴ 주의점

    : 자료형별 크기를 정확하게 제한 X

      컴파일러마다 다를 수 있음

자료형 크기
정수형 char 1 바이트
short 2 바이트
int 4 바이트
long 4 바이트
long long 8 바이트
실수형 float 4바이트
double 8 바이트
long double 8 바이트  이상

  ▲ VS++ 컴파일러 기준

 

** sizeof는 자료형의 크기를 확인할 수 있는 연산자

 

** 정수를 표현 및 처리하기 위한 일반적인 자료형 선택

 : 일반적으로 CPU가 처리하기에 가장 적합한 크기의 정수 자료형을 int로 정의

   ㄴ 따라서, int형 연산의 속도가 다른 자료형의 연산속도에 비해서 동일하거나 더 빠름

   ㄴ 그러다보니, int보다 작은 크기의 데이터는 int형 데이터로 바꿔서 연산 진행

 

 : 그러나, 연산 속도보다 데이터의 크기를 줄이는 것이 더 중요한 데이터들에게는

   char short형 변수가 유용하게 사용

 

** 실수를 표현 및 처리하기 위한 일반적인 자료형 선택

 : 실수 자료형의 선택에 있어서 가장 중요한 점은 정밀도

   ㄴ float보다 정밀도가 높으면서, long double 보다는 덜 부담스럽기 때문

   ㄴ float는 정밀도가 너무 낮음

   ㄴ long double은 시스템에 따라 12 바이트인 경우도 있는데 너무 부담스러움

   ㄴ 따라서, 보편적으로 double 사용

 

** unsigned를 붙이면 0과 양의 정수만 표현

 

** 문자의 표현은 아스키 코드(ASCII) : 숫자를 문자에 연결(mapping)

   ㄴ int형이 빠른데 더 적합하지 않을까? No! 정수형 연산시 빠른거고, 문자끼리 연산할 일이 없음 → char

 

** 리터럴 상수 : 자료형을 기반으로 상수를 표현, 해당 자료형을 의미하는 접미사를 붙여주기

 

** const 상수 : 이름을 지니는 심볼릭(Symbolic) 상수

 

** 정수의 승격(Integral Promotion)에 의한 자동 형변환

: int형 연산의 속도가 다른 자료형의 연산속도에 비해서 동일하거나 빠르기 때문에,

   일반적으로 CPU가 처리하기에 가장 적합한 크기의 정수 자료형을 int로 정의

   [정말?] 오늘날의 컴퓨팅 환경에서는 정수형 데이터의 연산속도는 정수의 크기에 상관없이 거의 동일

                CPU의 성능 및 구조가 이전과는 달리 많이 개선되어,

                정수형 데이터의 연산속도는 사실상 차이가 나지 않음

                하지만, 세상에는 많은 종류의 CPU가 있고,

                또 새로운 CPU의 등장도 고려해야 하기 때문에 정수의 승격은 여전히 의미를 갖는다

 

** 도전 프로그래밍1

1.

#include <stdio.h>

int main(void)
{
    int input = 0;
    scanf("%d", &input);
    printf("Decimal: %d, Hexadecimal: %x\n", input, input);
    return 0;
}

 

 

2.

#include <stdio.h>

int main(void)
{
    int inputNum[2];
    scanf("%d %d", &inputNum, inputNum + 1);

    int startNum, endNum;
    if (inputNum[0] < inputNum[1])
    {
        startNum = inputNum[0];
        endNum = inputNum[1];
    }
    else
    {
        startNum = inputNum[1];
        endNum = inputNum[0];
    }

    for (int i = startNum; i <= endNum; i++)
    {
        printf("%d times Tables\n", i);
        for (int j  = 1; j <= 9; j++)
        {
            printf("%d * %d = %d\n", i, j, i * j);
        }
        printf("\n");
    }
    return 0;
}

 

 

3.

#include <stdio.h>

int main(void)
{
    int inputNum[2];
    scanf("%d %d", &inputNum, inputNum + 1);

    int min;
    int gcm = -1;
    if (inputNum[0] < inputNum[1])
        min = inputNum[0];
    else
        min = inputNum[1];

    for (int i = 2; i <= min; i++)
    {
        if (inputNum[0] % i == 0 && inputNum[1] % i == 0)
        {
            gcm = i;
            break;
        }
    }
    printf("GCM : %d\n", gcm);
    return 0;
}

 

→ 유클리드 호제법

   https://velog.io/@yerin4847/W1-%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C-%ED%98%B8%EC%A0%9C%EB%B2%95

 

유클리드 호제법(Euclidean-algorithm)

유클리드 호제법에 대해 알아보자.

velog.io

 

#include <stdio.h>

int main(void)
{
    int inputNum[2];
    scanf("%d %d", &inputNum, inputNum + 1);

    int max;
    int gcm = -1;
    if (inputNum[0] > inputNum[1])
    {
        max = inputNum[0];
        gcm = inputNum[1];
    }
    else
    {
        max = inputNum[1];
        gcm = inputNum[0];
    }

    while(1) {
        int remainNum = max % gcm;

        if (remainNum == 0)
            break;

        max = gcm;
        gcm = remainNum;
    }

    printf("GCM : %d\n", gcm);
    return 0;
}

 

 

4.

#include <stdio.h>

int main(void)
{
    int momey = 3500, snack = 700, bread = 500, coke = 400;

    for (int i = 1; i <= (momey / snack); i++)
    {
        for (int j = 1; j <= (momey / bread); j++)
        {
            for (int z = 1; z <= (momey / coke); z++)
            {
                int payMoney = (snack * i) + (bread  * j) + (coke * z);
                if (payMoney == 3500)
                {
                    printf("snack : %d, bread : %d, coke : %d\n", i, j, z);
                    break;
                }
                else if (payMoney > momey)
                    break;
            }
        }
    }
    return 0;
}

 

 

5.

#include <stdio.h>

int main(void)
{
    int startNum = 2;
    int targetNum = 2;
    int i = 0;
    while (i < 10)
    {
        int count = 0;
        for (int j = 2; j <= targetNum; j++)
        {
            if (targetNum % j == 0)
                count += 1;
            else if (count > 1)
                break;
        }

        if (count == 1)
        {
            printf("%d\n", targetNum);
            i += 1;
        }
        
        targetNum += 1;
    }
    return 0;
}

 

 

6.

#include <stdio.h>

int main(void) 
{
    int inputSec;
    scanf("%d", &inputSec);

    int hourSec = 60 * 60;
    int minuteSec = 60;

    int hour = inputSec / hourSec;
    inputSec = inputSec % hourSec;

    int minute = inputSec / minuteSec;
    inputSec = inputSec % minuteSec;

    printf("%d hours %d minutes %d seconds\n", hour, minute, inputSec);

    return 0;
}

 

 

** 해당 글은 윤성우의 열혈 C프로그래밍 도서를 읽고 정리한 글입니다.

  https://product.kyobobook.co.kr/detail/S000001589148

 

윤성우의 열혈 C 프로그래밍 | 윤성우 - 교보문고

윤성우의 열혈 C 프로그래밍 | 윤성우 열형강의『C 프로그래밍』은 C언어에 대한 기본을 배울 수 있는 개론서이다. 이 책은 총 4개의 파트로 구성이 되어 있다. C언어의 기본이 되는 내용들을 다

product.kyobobook.co.kr