C언어 입문 시 듣기 좋은 흥달선생님의 '깨알 C언어 특강' 내용을 정리해보았습니다.
제 1강 | 프로그래밍이란?
C언어 - 문법 위주 공부
자바 - 객체지향 위주 공부
자바랑 C언어는 되게 친한 언어 (문법 비슷)
전산직/군무원/계리직 문제까지 가져 옴
모든 프로그램은 선언 -> 입력 -> 처리 -> 출력의 과정을 거침
(Ex. 회원가입 ID를 입력해라 프로그램 선언 -> ID입력 -> ID맞는지 처리 -> 회원가입 완료되었습니다!)
선언: int age1, age2, result
입력: scanf("%d", &age1);
처리: result = age1 + age2;
출력: printf("나이의 합은 %d살.", result);
알고리즘: 문제를 해결 하는 방법 (ex. 라면 끓이는 방법)
프로그래밍은 수학이 아니라 논리임
제 2강 | 컴파일러, 인터프리터
사람의 언어와 컴퓨터의 언어는 달라서 번역해줘야 함
컴파일
인간이 만든 고급언어를 컴퓨터가 해석할 수 있는 저급언어로 번역
C언어 -> 컴파일 -> 000 010 같은 컴퓨터 언어로 변환
컴파일러는 전체를 번역하므로 번역 시간이 오래 걸리지만, 한 번 번역한 후에는 다시 번역하지 않으므로 실행속도가 빠름
컴파일 언어 종류: C, C++, JAVA 등
C언어 컴파일 과정
프로젝트.c -> 전처리기 -> 프로젝트.i -> 컴파일러 -> 프로젝트.s -> 어셈블러 -> 프로젝트.o
-> 링커 -> 프로젝트.exe
전처리기: 전처리 구문을 처리하는 과정 #include<stdio.h>
컴파일러: 고수준 언어를 저수준 언어로 변환. 기계어와 가까운 형태의 언어
어셈블러: 완전히 기계어로 변환 (cf. 여기서 말하는 어셈블러 말고 어셈블리어 번역해주는 어셈블러도 있음)
링커: 여러 개의 오브젝트 파일을 합치거나 라이브러리를 합침
인터프리터
고급언어로 작성된 프로그램을 한 줄씩 읽어 들여서 실행하는 프로그램 (계속 통역)
번역과 실행이 동시에 이루어지므로, 별도의 실행파일이 존재하지 않음
종류: Ruby, php, javascript, Basic
어셈블러
어셈블리어를 번역 (C언어 컴파일 속의 어셈블러와는 다름)
제 3강 | 변수
변수 이름
변수: 데이터를 저장할 수 있는 메모리의 기억공간
- 예약어(키워드)는 사용할 수 없음: 이미 정해진 명령어들 (ex. break)
- 공백 불가
- 첫 글자는 영문과 언더바(_)만 사용 가능 (ex.40age 변수 불가, _age 변수 가능)
- 언더바(_)이외의 특수문자는 사용할 수 없음 (ex. age-age 변수 불가)
- 대소문자를 구분(Java, C)
데이터 타입(자료형)(= 데이터 형태)
예를 들어 200이라는 숫자는 효율적으로 관리하기 위해 int보단 short를 쓰는 게 좋음
cf. 실수는 float 쓰면 오류가 많아서 현업에선 double을 주로 씀
변수 선언
int 변수명; ----> 기억공간에 변수명의 자리를 만듦
int 변수명 = 초기값; ----> 변수명의 자리에 해당 값을 넣음
제 4강 | 변수의 종류와 유효범위
지역: 지역 안에서만
전역: 전체
정적: 전체
동적: 그 때 그 때 만들어서 씀
지역변수
함수/블록 안에서 선언하는 변수
함수/블록의 종료와 함께 메모리 상에서 소멸
초기값이 없으면 쓰레기 값(모름)이 들어감
스택 영역에 저장됨
1(참)일 때 num1은 10이라고 지정. 그러나 블록의 종료 이후 그 값은 사라짐. printf 불가
전역변수
함수 블록 밖에서 선언하며 전체 함수에 영향
프로그램이 종료될 때 메모리상에서 소멸
초기값이 없으면 0이 들어감
데이터 영역에 저장
num1값 전역변수 값 지정 안했으니 0이 들어감. 마지막 출력값 10 20
정적변수 (전역변수와 유사)
static으로 선언, 선언된 블록 내에서만 사용 가능
함수가 종료되어도 소멸되지 않고, 값이 그대로 유지
프로그램이 종료될 때 메모리상에서 소멸
초기값이 없으면 0이 입력되고, 단 한번만 초기화
데이터 영역에 저장
add(10)으로 인해 i=10, sum = 0 + 10 까지 하면 원래 사라져야 되는데, 정적변수(static)이라서 10이 안 사라지고 위로 올라가서 다시 i=5를 호출하는 거. sum = 10 + 5가 됨 // 따라서 결과 sum:10 sum:15 sum:18 (만약 static이 아니었다면 10 5 3이 됨)
동적변수
메모리 동적할당으로 생성되는 변수
Run time 시간에 메모리를 할당 (실행되고 있는 공간)
동적 기억장소에 할당하여 메모리 낭비를 피함
무조건 포인터를 사용해야 함
힙 영역에 저장
제 5강 | 산술연산자
이항 연산자
+, -, *, /, %(나머지)
예: 3*4;
참고로 c언어에서는 정수와 정수의 나머지는 정수부분만 출력함
단항 연산자 (우선 순위 거의 제일 높음, 위치가 굉장히 중요함)
++, --
예: 4++;
참고로 a++는 앞의 연산을 수행하고 나서 1 증가
++a는 1 증가 하고 나서 연산을 수행
대입 연산자 (우선 순위 제일 낮음)
=, +=, -=, *=, /=, %=
예: a += 3; → a = a + 3
예시 문제
3/4 = 0
4*(1/2) = 0
a=10;
b=a++;
c=++a;
연산하고 나면 b=10 c=12
a= 10;
a += 10;
연산하고 나면 a = 20
제 6강 | 연산자 우선순위
++와 -- 가 제일 빠르다는 거 기억하기
곱하기 나누기 먼저 해 줌
!= 는 같지 않으면 참(1)
가장 마지막이 && 따라서 && 좌우로 나눠서 볼 것
++a랑 c--가 연산 우선순위 제일 높음
a는 1 더해주고 c는 아무 변화 없음
2 + 4*5 = 22
제 7강 | 관계/논리연산자, 조건문
연산자 문제는 산수 수준이라고 생각해야 함. ++와 --가 좀 귀찮은 수준
모든 프로그램에는 조건문이 있음 (if 조건 선택, switch 자판기 선택하듯 선택)
관계연산자
좌변과 우변 두개가 같냐? 두 개의 관계가 어떠냐를 묻는 것
→ 0(거짓), 1(참) 둘 중에 하나로 출력
종류: ==, !=, >, >=, <, <=
10 == 9 → 결과값: 0
3 != 3 → 결과값: 0
5 >= 5 → 결과값: 1
논리연산자
값을 비교
→ 0(거짓), 1(참) 둘 중에 하나로 출력
종류: !(참은 거짓으로 출력), &&(두 개의 값이 참이어야 참 출력), ||(둘 중 하나가 참이면 참 출력)
!9 → 0
5>5 || 5>=0 → 1
조건문
- 단순 If문 (조건 아니면 아무 것도 안 수행하고 끝남)
if(조건){
조건을 만족할 때의 처리;
}
- If ~ else 문
if(조건){
조건을 만족할 때의 처리;
}
else{
조건이 아닐 때의 처리;
}
- 다중 if 문
if(조건1){
조건1을 만족할 때의 처리;
}
if(조건2){
조건2를 만족할 때의 처리;
}
else{
모든 조건이 아닐 때의 처리;
}
4 > 4 (이 후에 j는 3으로 떨어짐) && .... 인데 왼쪽 항이 0이 되어버리니 바로 수행하지 않고 else 항으로 가 버림!
(&&는 둘 다 1이어야만 수행을 하는 것이기 때문, OR(||) 의 경우엔 뒤에도 연산 해야 함)
지금 그런데 else항으로 가기 전에 i에는 4가 들어가 있고 j에는 3이 들어가 있음. ★이걸 그대로 가져감★
다중 조건문의 경우 앞선 if문에서 변경된 값으로 다음 if문을 처리한다는 것을 기억하기
따라서 else항 수행 j = 4-- - 2
마지막 결과값 j=2, i=3
제 8강 | 논리연산자, 증감연산
연산자 문제는 대부분 ++와 --가 나오니까 해당 부분 연습 많이 하면 잘 맞힐 수 있음
(선언된 변수의 공간을 그려서 그 때 그 때 변경해서 그려주거나 표기하면 풀기 더 쉬움)
c에는 그냥 이상한 값 암거나 들어가 있다고 생각 하면 됨
ap = 8++ (a에 9값 들어감)
bp = 2 (b에 2값 들어가 있음)
b = 3 * 1;
c = 0
따라서 차례로 9, 3, 0, 8, 2
※ 참고사이트
컴파일러 사이트 http://ideone.com
++와 -- 바꿔보고 수행해보고 값 비교해보기
제 9강 | 산술연산자
개발은 무조건 익숙해져야 해. 한 번에 듣고 지금 이해하봤자 나중에 못 쓰면 쓸모 없음
정수 나누기 정수 = 정수라는 점 기억하기
Q. 모든 변수가 int라고 가정했을 때,
y = 3 + 2 * ( x = 7 / 2); 을 실행한 결과 각 변수들의 값은?
⇒ int(정수), 정수 나누기 정수는 정수
⇒ x = 3, y = 9
Q. num = 6 + 14 % 5 / 2 - 2 * 2;
⇒14 % 5 / 2 ⇒ 4 / 2 ⇒ 2
⇒num = 4
Q. int a = 10, b = 20;
num = (a++ == 11) && (b++ == 20);
⇒ num = 0
⇒ 참고로 마지막에 a는 11, b는 20이 들어가 있음 (&&는 왼쪽항이 0이면 오른쪽 수행 아예X)
제 10강 | 출력형식
원하는 목표를 가지고 있다면, 그 목표를 원하는 다른 사람들보다 내가 더 열심히 해야 승리함
※ 출력 변환 기호
%d 추가 설명: A는 아스키코드 65를 가지고 있음. 따라서 %d가 정수, 문자 데이터 타입을 가지는 것
%c는 딱 문자 한 글자 출력함! (길게 쓰고 싶으면 %s)
%s는 문자열도 출력하고, 나중에 포인터도 출력함
34를 %x 16진수로 출력하는 법
⇒ 일단 손쉽게 2진수로 바꿈. ... 64 32 16 8 4 2 1 적어두고 34 만들기 (32+2)
⇒ 0100010
⇒ 2진수를 16진수(2^4)로 만들려면 4개씩 잘라서( 8 4 2 1 ) 그걸 한자리로 만들면 됨
⇒ 010 / 0010
⇒ 22
34를 %o 8진수로 출력하는법
⇒ 위 식에서 2진수 만든걸 8진수(2^3)로 만들려면 3개씩 잘라서 (4 2 1) 그걸 한자리로 만들면 됨
⇒ 0/100/010
⇒ 42
※ 정수형 자리수 지정
%d는 그냥 출력값에 맞게 자리지정
%5d는 5개의 공간을 만들고 오른쪽부터 채움
%05d는 5개의 공간을 일단 0으로 채우고 오른쪽부터 채움
※ 실수형 자리수 지정
%f는 소수점 6자리까지 공간 만들어서 표기
%6.1f는 6개의 공간을 만들고, 소수점 1자리까지 표기
%-6.1f는 6개의 공간을 만들고, 소수점 1자리까지 표기하며, 오른쪽이 아닌 왼쪽부터 채움
⇒ 해당 결과가 3.3이 된 이유는 소수점 1자리만 표기해야 되는데 값은 3.26이라반올림하게 된 것
%-6.3f는 6개의 공간을 만들고, 소수점 3자리까지 표기하며, 오른쪽이 아닌 왼쪽부터 채움
⇒ 소수점 3자리까지 표기해야 하기에 소수점 뒷자리 0으로 채움
double이나 floatt이나 소수점을 받기 때문에 d_value에 5.65 바로 들어감
그 다음 0.5 더해서 6.15 값이 d_value로 들어감
n은 정수형 공간인데 d_value는 소수점이라 넣을 수가 없음
⇒ 따라서 (int)로 형태를 변환함. 반올림이 아니라 아예 버려버리는 것, 따라서 n=6
마지막 d_value 출력 때 %3.1f로 뒷자리 반올림,뒷자리 5는 반올림 됨! 따라서 6.2 출력
답: 6.2, 6