[C] 활용 기초
1) 프로그래밍 언어 분류
컴파일러 언어
- 기계어로 컴파일되는 언어
- 소스코드가 일괄적으로 번역된 후 실행되는 방식
- 작고 빠른 코드로 변환된 후 시스템에서 실행 가능한 파일로 생성하고 실행
- C, C++, JAVA, FORTRAN, PASCAL
- 장점
- 재컴파일을 통해 이식성 향상
- 빠른 실행
- 단점
- 시스템마다 코딩과 컴파일 별도로 수행
- 번역으로 인한 많은 코드 생성으로 메모리 사용 증가
인터프리터 언어 (스크립트 언어)
- 기계어로 미리 변환되는 것이 아니고 실행 중에 ‘Interpreted’
- 속도가 느림
- 스크립트 언어
- ASP, PHP, Java Script, VB Script
- 장점
- 한 줄씩 바로 실행되므로 추가적 메모리가 많이 필요하지 않음
- 플렛폼에 덜 의존적임
- 자료형과 범위가 유연함
- 단점
- 처리 속도가 느림
- 처리 가능 작업의 한계
2) 컴퓨터 언어별 특징
C언어
- 어셈블리어와 고급 언어의 장점을 가지고 있음
- 작고 빠른 프로그램
- 뛰어난 이식성
- 컴파일러 언어
- 특징
- 하드웨어 제어
- 범용 프로그래밍
- 효율적 자료 관리 및 메모리 관리
- 주사용 분야
- 시스템 프로그램(운영체제, 디버깅 S/W, 미들웨어) : 비트 조작, 메모리 접근, 형변환
- 컴파일러, 유틸리티
- 응용 프로그래밍(게임, 워드프로세서, 오라클)
- 임베디드 프로그래밍
C++
- 객체지향 언어로 C언어의 확장판
- 다중 상속, 오버로드
- 컴파일러 언어
- 특징
- 하드웨어 제어 + 객체지향 프로그래밍
- C언어 라이브러리를 상당수 사용 가능
- 효율적 자료 관리 및 메모리 관리
- 주사용 분야
- 게임 프로그램
- 빠른 처리가 필요한 응용프로그램
- 하드웨어 제어 프로그램
C#
- 객체지향 언어(C언어의 기본문법 + C++의 객체 지향개념 + UI 컴포넌트)
- .NET프레임워크에서 개발
- 이 기종 간에 인터넷을 통한 자료 교환을 위해 개발
- 특징
- .NET프레임워크에서 동작하므로 운영체제에 독립적
- CRL(Common Runtime Library)을 지원
- 뛰어난 생산성
- 주사용 분야
- 웹 응용 프로그램
- 네트워크 프로그램
JAVA
- C++와 유사하나 모호하거나 복잡한 기능(공용체, 구조체, 포인터, 다중상속)을 제거한 객체지향 프로그램
- 모든 테이터는 객체를 통하여 처리
- 바이트 코드로 컴파일되기 때문에 자바를 지원하는 어떠한 플랫폼에서도 실행
- OS에서 실행되는 것이 아니라 JVM에서 실행해주기 때문에 다른 어떤 프로그램에도 JVM만 맞춘다면 실행 가능하다.
- 특징
- 가상머신에서 동작하므로 운영체제에 독립적
- 다중 쓰레드 프로그램이 가능
- 뛰어난 호환성
- 주사용 분야
- 웹 응용프로그램
- 분산환경에 적합한 언어
- 휴대기기용 프로그램
Python
- 인간 친화적 언어로 익히기 쉬운 언어
- 다른 언어와 혼합하여 개발 가능
- 인터프리터식 언어
- 특징
- 개발 속도가 빠르고 간결
- 무료 소프트웨어
- 주사용 분야
- C/C++과의 결합
- 웹 프로그래밍
- GUI 프로그래밍
3) 애플리케이션 최적화
- 병목지점 찾기(소요시간)
- 구조체 복사 시 대입연산자 대신 라이브러리 함수 사용
- 구조체 전달은 포인터를 이용
- 함수의 매개변수를 축소
- 4바이트 이상 전달 시 포인터를 이용
- 4개 이상인 경우 인자를 구조체로 선언하고 구조체 포인터를 매개변수로 전달
- const를 적절히 활용 (안정성 확보)
- 2의 n제곱을 곱하는 연산은 쉬프트 연산 수행
- 실수연산을 축소
- 소수점 이하 2자리까지만 필요한 연산 (실수의 연산에서 100을 곱한 후 연산을 해 100으로 나눈다.)
- 지역변수를 최대한 활용
- 전역변수 사용을 최소화
4) 라이브러리의 이해
- 자주 사용되는 특정한 기능을 main 함수에서 분리해 놓음
- 사용 이유
- 프로그램 유지
- 쉬운 디버깅
- 컴파일 시간 단축
정적 라이브러리
- 프로그램을 컴파일하여 생성되는 바이너리에 적재
공유 라이브러리
- 프로그램이 시작될 때 적재
- 하나의 프로그램에서 적재 후 사용하면 동일 라이브러리를 사용하는 다른 프로그램이 이용
동적 라이브러리
- 바이너리가 실행 후 적재
- 플러그인 모듈 구현에 적합
- 라이브러리 개선 등에 효과적인 형태 (정적은 재컴파일)
표준 라이브러리
- 작업에 필요한 라이브러리 함수 검색
- 헤더파일과 함수 원형 파악
- include와 매개변수 기술
5) 함수 포인터의 이해
- 필요성
- 프로그램 코드 간결화
- 배열로 처리함으로써 중복 코드 제거 가능
- 상황에 따른 함수 호출
- 함수를 데이터 형태로 처리 -> 함수의 보관과 전달이 용이
- 형식
- 리턴타입 (*함수 포인터명)(매개변수리스트);
#include <stdio.h>
int add(int a, int b) // 덧셈함수
{
return a + b;
}
int sub(int a, int b) // 뺄셈함수
{
return a - b;
}
int main()
{
int (*fp)(int, int); //함수 포인터 선언
fp = add; //add 함수의 메모리 주소를 함수 포인터 fp에 저장
printf("결과 값 : %d\n", fp(10, 20)); //add 함수를 호출
fp = sub; //sub 함수의 메모리 주소를 함수 포인터 fp에 저장
printf("결과 값 : %d\n", fp(10, 20)); //sub 함수 호출
return 0;
}
함수 포인터 배열
- 리턴타입 (*함수 포인터명[배열 사이즈])(매개변수 리스트);
- int (*fp[4])(int, int) = {add, sub, mul, div};
#include <stdio.h>
int add(int a, int b){return a + b;} //덧셈함수
int sub(int a, int b){return a - b;} //뺄셈함수
int mul(int a, int b){return a * b;} //곱셈함수
int div(int a, int b){return a / b;} //나눗셈함수
int main()
{
int (*fp[4])(int, int); //함수 포인터 배열 선언
fp[0] = add; // 배열[1]에 덧셈 함수의 메모리 주소 저장
fp[1] = sub; // 배열[2]에 뺄셈 함수의 메모리 주소 저장
fp[2] = mul; // 배열[3]에 곱셈 함수의 메모리 주소 저장
fp[3] = div; // 배열[4]에 나눗셈 함수의 메모리 주소 저장
for (int i = 0; i < 4; i++) {
printf("배열[%d] 함수의 실행 값 : %d\n",i, fp[i](20, 10));
}
return 0;
}
함수 포인터 매개변수
- 함수의 매개변수로 함수 포인터가 가능하다.
void function(int (*fp)(int, int)){}
qsort()
- 헤더 : stdlib.h
- 기능 : 테이블의 자료를 퀵 정렬로 내림이나 오름차순으로 정렬
- 매개변수 :
- void *base : 테이블의 포인터 주소
- size_t num : 테이블에 들어 있는 실제 데이터 개수
- size_t size : 한 개 요소의 크기
- int (* compar)(const void *, const void *) : 두 요소를 비교하기 위한 함수 포인터
- 반환값 : void
- 구현 : 비교함수는 직접 구현해야 함 (배열의 자료형과 비교방식이 다르기 때문)
#include <stdio.h>
#include <stdlib.h>
// 오름차순으로 정렬할 때 사용하는 비교함수
int static compare (const void* first, const void* second)
{
if (*(int*)first > *(int*)second)
return 1;
else if (*(int*)first < *(int*)second)
return -1;
else
return 0;
}
int main()
{
int arr[] = {32, 11, 97, 42, 21, 70, 56, 67, 88, 100};
int array_size = sizeof(arr) / sizeof(int);
int i;
// 정렬 전
for (i = 0; i < array_size; i++) printf("%d ", arr[i]);
printf("\n");
qsort(arr, array_size, sizeof(int), compare);
// 정렬 후
for (i = 0; i < array_size; i++) printf("%d ", arr[i]);
printf("\n");
return 0;
}
6) 파일 입출력 기초
- 파일 입출력 : 입력과 출력의 대상이 파일인 경우
- 입출력 대상 : 텍스트 파일, 이진 파일
라이브러리 함수
- 텍스트 파일
- 입력 : fgetc, fgets, fscanf
- 출력 : fputs, fputs, fprintf
- 닫기 : fclose
- 이진 파일
- 입력 : fread
- 출력 : fwrite
입출력 과정
- 스트림 생성 : fopen
- 입출력 : fgets, fputs, fread, fwrite
- 스트림 닫기 : fclose