4 분 소요

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

업데이트: