[정보처리기사 실기] C언어 총 정리(1) 프로그래밍 기초
[1강] 프로그래밍이란?
* 프로그램 동작 과정
선언 > 입력 > 처리 > 출력
* C언어 입출력
- 입력함수 : scanf("형식", 매개변수)
*int x; scanf("%i", &x); → 입력받은 값을 x의 주소에 저장 |
- 출력함수 : printf("형식", 매개변수 )
[2강] 컴파일러, 인터프리터
* 컴파일 : 고급어(인간의 언어) → 저급어(기계어) 변환
- 컴파일러(번역), 인터프리터(통역), 어셈블리어(어셈블리 언어를 번역)
* 컴파일 과정
.c → 전처리기 → .i → 컴파일러 → .s → 어셈블러 → .o → 링커 → .exe(실행파일)
* 용어
구분 | 기능 | 확장자 |
전처리기 | 전처리 구문을 처리하는 과정 #include<stdio.h> 내가 만든거랑 누가 만들어 놓은 #include 같은거 합쳐주는거 |
.c (내가작성) |
*컴파일러 | 고급 프로그래밍 언어(ex. C)를 저수준 언어(기계어)로 번역. 기계어와 가장 가까운 형태의 언어 전체를 번역하므로, 번역시간이 오래 걸리지만 한 번 번역한 후에는 다시 번역하지 않으므로 실행 속도가 빠름. ex. C,C++,JAVA등 |
.i (합쳐진거) |
*어셈블러 | 어셈블리어를 오브젝트 코드(기계어, 2진언어)로 바꿔줌 완전히 기계어로 바꾸어 주는 역할 |
.o |
링커 | 여러 개의 오브젝트 파일(.o)을 합치거나 라이브러리를 합치는 역할 | .exe |
*인터프리터 | 고급언어로 작성된 프로그램을 한 줄씩 읽어 들여서 실행하는 프로그램 번역과 실행이 동시에 이루어지므로(통역), 별도의 실행파일이 존재하지 않음 종류 : Ruby, php, javascript, Basic |
[3강] 변수
* 변수 : 데이터를 저장할 수 있는 메모리의 기억공간
* 변수 생성 규칙 및 특징
- 예약어(키워드)는 사용할 수 없다. ex. break
- 공백을 포함할 수 없다.
- 첫 글자는 영문과 언더바(_)만 사용이 가능하다. ex. 하이픈(-) (X) , 3id (X)
- 언더바(_) 이외의 특수문자는 사용할 수 없다.
- 대소문자를 구분한다.
*데이터 타입(자료형)
자료형 | 메모리크기 | 데이터범위 | |
불리언 | bool | 1 Byte | 0,1 |
문자 | char | 1 Byte | -128 ~ +128 |
정수 | short | 2 Byte | -32768 ~ +32768 |
int | 4 Byte | -2147483648 ~ +2147483647 | |
long 더 큰 정수 | 8 Byte | ||
실수 | float | 4 Byte | |
double 더 큰 실수 | 8 Byte | ||
* 개념만 (문자열) |
char * (string) |
? Byte | str → 첫번째 값'H'의 주소를 가리킴 마지막에 /0(nul값을 포함) ex. char *str = 'HI', str[2]=0 |
* 변수선언
- int 변수명;
- int 변수명 = 초기값;
[4강] 변수의 종류와 유효범위
지역변수 | 함수/블록{} 안에서 선언하는 변수 함수/블록의 종료와 함께 메모리상에서 소멸 초기값이 없으면 쓰레기 값이 들어감 스택 영역에 저장됨 |
[문제] void main() { add(10); add(5); add(3); } int add(int i){ static int sum = 0; sum = sum + i; printf("sum:%d\n",sum); } [답] add(10) → i = 10, sum = 0 +10 = 10 출력 ** sum이 다시 초기화 되지 않고 값유지 add(5) → i = 5, sum = 10 + 5 =15 출력 add(3) → i = 3, sum = 15 + 3 =18 출력 ** int sum이 static으로 선언X, 지역변수 add(10) → i = 10, sum = 0 +10 = 10 출력 add(5) → i = 5, sum = 0 + 5 =5 출력 add(3) → i = 3, sum = 0 + 3 =3 출력 |
전역변수 | 함수 블록 밖에서 선언하며 전체 함수에 영향을 미친다. 프로그램이 종료될 때 메모리상에서 소멸 초기 값이 없으면 0 값이 들어감 데이터 영역에 저장됨 |
|
*정적변수 | static으로 선언하며 선언된 블록 내에서만 가용가능 함수가 종료되어도 소멸되지 않고, 값이 그대로 유지됨 프로그램이 종료될 때 메모리상에서 소멸 초기값이 없으면 0이 입력되고, 단 한번만 초기화 데이터 영역에 저장됨 |
|
동적변수 | 메모리 동적할당으로 생성되는 변수(그때 그때 만들고 삭제) malloc(sizeof(int)) int 크기의 메모리를 할당하고 첫주소를 반환 Run time (실행하고 있는 동안)시간에 메모리를 할당 동적 기억저장소에 할당하여 메모리 낭비를 피함 무조건 포인터를 사용해야 함 힙 영역에 저장됨 |
[5,7,8,9,11,12,13강] 연산자
구분 | 종류 | 예 | |
산술연산자 | 이항 연산자 | +, -, *, /, %(나머지) | **정수/정수 = 정수 (* 정수/실수 = 실수) 3/4 = 0 몫만, 나머지는 버림 float i ; i = 100/300 = 0.0 (정수/정수 = 정수이므로 i 가 실수값으로 선언되어 있어도 0만 들어감 대신 0.0) |
단항 연산자 | ++, -- | a=10, b=a++, c=++a; a++; a를 먼저 처리하고 +1이므로 b=10, a=11 ++a; +1을 하고 대입하므로 a=12, c=12 |
|
대입 연산자 | =, +=, -= ,*= ,/= ,%= | a+=10; a=a+10 이므로 a=10+10=20 |
|
관계연산자 | ==, !=, >, >=, <, <= | 3 !=(같지 않다) 3 → 거짓이므로 0 | |
논리연산자 | &&(and), ||(or), !(not) | 거짓&&참/거짓 경우 좌항 거짓이므로 우항 연산X | |
비트연산자 | &(and), |(or),^(xor), ~(not), >>, << * ^(xor) :다르면1,같으면0 *~: 양수면+1하고음수 음수면 양수로바꾸고-1 |
2진수로 바꾼 뒤에 연산 후 다시 10진수로 변경(~제외) 5&3 → 101 &(and) 011 → 001 → 1 5|3 → 101 |(or) 011 → 111 → 7 5^3 → 101 ^(xor) 011 → 110 → 6 ~5 → 양수면+1 =6 → 음수로바꿔줌 -6 ~(-5) →양수로바꾸고+5 → -1해줌4 10>>2 → 10을 2진수로 바꾸면 1010 → 오른쪽으로 2번 밈 오른쪽 끝에 10이 삭제됨 10(10) → 10만남음 → 10진수 로 표현하면 2 |
|
삼항연산자 | 조건?참:거짓 조건에 따라서 다른 명령을 수행하는 연산자 |
a=20; b=(a>10) ? a+a : a*a; 20>10 참이니까 a+a수행 20+20=40 = b |
[6강] 연산자 우선순위
구분 | 종류 | 예 | 연습문제 | |
높음 ↑ | ( ) | 괄호 | 문제1 | int a=3; int b=4; int c=5; int d=6; 일때 |
++, --, ~, ! | 단항 | d % b + ++a * c-- = | ||
*, /, % | 산술 | 풀이 | (6 % 4 = 2 (나머지) ) + ((++a=3+1=4)*5=20, c=4가됨) | |
+, - | 산술 | 2 + 20 = 22 | ||
<<. >> | 비트 | *a=4, b=4, b=4, d=6 로 바뀜 | ||
<. <=, >, >= | 비교 | 문제2 | int a=3; int b=4; int c=5; int d=6; 일때 | |
==, != | 관계 | d % b + a++ * c-- = | ||
&, ^, | | 비트 | 풀이 | (6%4=2) + (3*5=15, a=4, c=4가 됨) | |
&&, || | 논리 | 2+15 = 17 | ||
낮음 ↓ | =, +=, -=, /=, %= | 대입 | *a=4,b=4, c=4, d=6 |
[10강] 출력형식
*출력 변환기호
기호 | 의미 | 데이터타입 | 예 |
%d | 부호 있는 10진수 | 정수, 문자 (ex. 아스키코드 A=65) |
printf("값: %d, 13) → 값:13 printf("값: %5d, 13) → 값: 13 printf("값: %05d, 13) → 값:00013 |
%f | 고정 소수점 | 정수, 실수 | printf("값: %f",3.26); →값 3.260000 (소숫점 뒤 6자리 고정) printf("값: %6.1f",3.3) →값 3.3(점포함 6자리, 소수점1자리) printf("값:%-6.1f",3.26) →값3.3(점포항 6자리, 소수점 1자리 + 앞에서부터 출력,소수점1자리니까 반올림) **int는 버림 printf("값:%-6.3f",3.26) →값3.260 (소수점 3자리까지니까 0) |
%c | 문자 | 문자 (ex. "A" 글자 딱 하나) |
printf("값: %c", 65); → 값:A printf("값: %c", 'A'); → 값:A |
%s | 문자열 | 문자열 포인터 char들이 모여있는 배열 주소값을 저장 (nul(/0)을 만날때까지 출력) |
int 변수명 = 변수의 값, int * 포인터 이듯이 string s ="EMMA"는 char *s = "EMMA";와 같다 (문자열, 배열은 주소값을 저장하므로) printf("%s\n,s); EMMA출력 print("%p\n,s);0x42a9f2, printf("%p\n, &s[0]); 0x42a9f2 출력 printf("%c\n,*s);E출력, printf("%c\n,*(s+1));M출력 ** char *s = "EMMA", char *t="EMMA"일 경우 s와 t는포인터이고, 각자 다른 저장공간을 가리키므로 s != t이다 |
%x | 16진수 | 정수 | printf("값 : %x", 34); → 값:22 |
%o | 8진수 | 정수 | printf("값 : %x", 34); → 값:42 |
%p | 주소값 | 16진수(0xF)로 출력해줌 | int n=50; int *p = &n; (p는 *붙어 있으므로 포인터라는 것을 알 수있다) printf("%p\n",p) → n의 주소를 출력(0x7fff3977662c) printf("%p\n",*p) → n의 주소의 값을 출력(50) |
[11강] 진법변환, 비트연산
* 진법변환 (10진수 → 2진수 → 8진수 or 16진수)
10진수 | 2진수 | 8진수(8=2^3, 3개씩 쪼갬) | 16진수(16=2^4, 4개씩 쪼갬) |
19 |
16 8 4 2 1 1 0 0 1 1 |
4 2 1 | 4 2 1 0 1 0 | 0 1 1 |
8 4 2 1 | 8 4 2 1 0 0 0 1 | 0 0 1 1 |
19 = 16 + 2 +1 | 2 | 2+1 =3 | 1 | 2+1=3 | |
10011 | 23 | 0x13 |
* 진법변환 (16진수 → 2진수 → 10진수)
문제 | 16진수 | 2진수 | 답 |
0x11 & 0x0f | 0x11 → 1 | 1 | 10001 | 10001 & 01111 --------------- 00001 10진수(%d) : 1 |
8 4 2 1 | 8 4 2 1 0 0 0 1 | 0 0 0 1 |
|||
0x0f → 0 | f | 01111 | ||
16진수에서 a=10, b=11, c=12, d=13, e=14, f=15 15 = 8 + 4 + 2 + 1 8 4 2 1 | 8 4 2 1 0 0 0 0 | 1 1 1 1 |
[12강] 매크로, 비트연산
* 매크로(#define) : 반복적인 일들을 쉽게 하기 위해 만들어 놓은 것.
#define N 10 : 앞으로 나오는 모든 N은 10이다
#define SQR(X) X*X
SQR(N); 10*10=100
SQR(N+2); N+2*N+2 → 연산자 우선순위에 의해 2*N이 먼저 수행됨 N+(2*N)+2 = 10+(2*10)+2=32
***** 함수랑 다르게 매크로로 선언 했을 때는 ()안의 값이 그대로 올라감 (먼저 계산x)
※ 출처 : 흥달쌤 깨알 C언어 1~13강 https://youtu.be/Lj0EszeZo2A?si=NxYWYQE9yQvYo4w8
※ 컴파일 사이트 : http://ideone.com