** 기본적으로 제공되는 함수를 표준함수라고 하고,
표준함수들의 모임을 가르켜 표준 라이브러리라고 함
** 표준함수를 호출하기 위해서는 헤더파일을 선언해야 함
** 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
② 부동소수점 구하기
: 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
#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프로그래밍 도서를 읽고 정리한 글입니다.
'IT공부 > IT서적' 카테고리의 다른 글
[윤성우 열혈 C++프로그래밍] Part2. 객체지향의 도입 (0) | 2024.08.15 |
---|---|
[윤성우 열혈 C++프로그래밍] Part1. c++로의 전환 (0) | 2024.08.08 |
[윤성우 열혈 C프로그래밍] Part4. C언어의 깊은 이해 (0) | 2024.07.28 |
[윤성우 열혈 C프로그래밍] Part3. 포인터와 배열의 완성 (0) | 2024.07.24 |
[윤성우 열혈 C프로그래밍] Part2. 포인터 배열의 시작 (0) | 2024.07.19 |