01. 알고리즘과 코딩
01. 알고리즘(Algorithm)
1) 알고리즘의 정의
- 주어진 문제를 해결하기 위하여 잘 정의된 동작의 유한 집합
- 프로그램은 알고리즘과 데이터 구조가 결합된 것
- 알고리즘은 수학, 컴퓨터 과학, 언어학 등의 관련 분야에서 어떠한 문제를 해결하기 위해 정해진 일련의 절차나 방법을 공식화한 형태로 표현한 것
- 알고리즘은 넓은 의미에서 자료 구조와 함께 프로그램을 구성하는 요소를 의미함
- 좁은 의미에서 어떤 문제에 대한 답을 찾는 해법을 의미함
- 프로그래밍 언어가 아니더라도 알고리즘의 표현은 가능함
2) 알고리즘이 갖추어야 할 조건(알고리즘의 5가지 특성)
- 입력(Input) : 외부에서 입력되는 자료가 0개 이상 존재함
- 출력(Output) : 출력이 적어도 1개 이상의 결과가 있어야 함
- 명확성(Definiteness) : 명령어들은 명확하고 모호하지 않아야 함
- 유한성(Finiteness) : 알고리즘의 명령어들은 유한 번의 수행 후 종료되어야 함
- 유효성(Effectiveness, 효과성, 실제성) : 모든 명령들은 명백하고 실행 가능한 연산들이어야 함
3) 알고리즘을 분석하는 판단 기준
- 정확성(Correctness) : 알고리즘이 정확한지를 검사하여, 입력에 대해서 정확한 출력이 되는지를 나타내는 기준
- 간결성(Simplicity) : 표현이 간단하고, 일기 쉽고, 이해가 용이한가를 나타내는 기준
- 작업량(Amount of Work Done) : 알고리즘을 수행할 때 명령어의 실행 횟수로 평균과 최악의 경우는 나타내는 기준
- 최적성(Optimality) : 알고리즘 수행 시간의 평균과 최악이 같을 때 최적이라고 하며 두 가지 경우의 시간 차이를 계산하여 분석함
4) 순서도
- 알고리즘을 누구나 알아볼 수 있는 형식으로 표현해야 하는데 영문이나 한글로는 표현이 어렵고, 많기 때문에 약속된 기호인 순서도 기로를 사용하는 것
- 순서도로 그려진 알고리즘은 프로그래머는 쉽게 알아볼 수 있기 때문에 문법이 다른 프로그래밍 언어를 사용하더라도 프로그램으로 변환이 쉬움
5) 코딩(Coding)
- 알고리즘을 선정한 프로그래밍 언어로 변환하여 작성하는 것
- 정확하고 간결한 좋은 프로그램을 작성하는 것은 프로그래밍 언어의 선택과 관계가 없음
6) 알고리즘 설계 기법
- 동적 계획법(Dynamic Programming)
- 해결하고자 하는 문제의 최적해(Optimal Solution)가 부분 문제들의 최적해들로 구성되어 있을 경우 이를 이용하여 문제의 최적해를 구하는 기법
- 부분적으로 해결된 문제들을 이용하여 최적해를 구함
- Bottom-up 방식
- 탐욕적 알고리즘(Greedy Algorithm)
- 최적해를 구하는 데에 사용되는 근사적인 알고리즘으로, 문제의 해법을 욕심 형태로 선택하면서 최적의 해법에 도달하기를 바라는 방법
- 가장 좋아 보이는 해법을 선택하는 알고리즘으로 결국 최적 해법을 구할 수는 없을지라도 근사적인 해답을 얻을 수 있음
- 대표적으로 배낭 채우기 알고리즘
- 재귀적 알고리즘(Recursion Algorithm)
- 같은 알고리즘을 반복하여 수행하는 알고리즘
- 근사 알고리즘(Approximation Algorithm)
- 회적화되는 답을 구할 수는 없어도 비교적 빠른 시간에 계산이 가능하도록 근사 해법을 수행하는 알고리즘
- 배낭 알고리즘(Knapsack Algorithm)
- 어떤 도둑의 배낭에 훔친 물건을 채우는 방법을 찾는 알고리즘
- 분할 정복법(Divide and Conquer)
- 전체 문제를 부분적으로 나누어 해결하고, 부분적으로 해결된 문제들을 결합하면 전체 문제를 해결할 수 있음
- 대표적으로 병합 정렬 알고리즘
- Top-Down 방식
- 퇴각 검색법(Backtracking)
- 최적해를 구하기 위한 모든 가능성을 찾아가는 방법
- 대표적으로 깊이 우선 탐색 알고리즘
02. 코드의 품질 향상
1) 리팩토링(Refactoring)
- 코드의 외부 행위는 바꾸지 않고, 내부 구조를 개선하여 소프트웨어를 변경하는 프로세스로 버그 발생을 최소화하는 코드 정화(Clean Up) 방법
- 리팩토링은 이미 존재하는 코드의 설계를 안전하게 향상하는 기술이라고 할 수 있음
- 단순히 코딩 스타일만을 개선하는 것이 아니라 성능과 코드의 구조, 즉 좋은 설계가 되도록 개선하는 과정을 의미함
- 리팩토링은 소프트웨어의 디자인을 개선함
- 리팩토링은 소프트웨어를 이해하기 쉽게 만들어 줌
- 버그를 빨리 찾을 수 있도록 도움을 줌
- 리팩토링은 프로그램을 빨리 작성할 수 있도록 도와줌
2) 코드 품질 향상 기법
- 테스트(Test) : 코드의 품질을 높이는 방법 중 가장 일반적인 기법
- 코드 인스펙션(Code Inspection) : 코드에 존재하는 결함을 발견하기 위해 눈으로 확인하는 검사
- 정적 분석(Static Analysis) : 프로그램을 실행시키지 않고 분석하는 도구로, 사전에 결함을 발견하는 예방 기법으로 데드 코드(Dead Code)가 없는지, 선언이 되지 않고 사용한 변수가 없는지 등을 검사함
- 동적 분석(Dynamic Analysis) : 프로그램을 실행시키고 분석하는 도구로, 실행 과정에서 비효율적인 코드를 분석하는 도구
- 증명(Proof) : 가장 이상적인 방법으로 소프트웨어 품질이 아주 중요한 경우에 주로 활용됨
3) 코드 품질 분석 도구
1. 코드 품질 분석 도구의 개념
- 코딩 스타일, 설정된 코딩 표준, 코드의 복잡도, 코드 내에 존재하는 메모리 누수 현상, 스레드의 결함 등을 발견하기 위해 사용하는 프로그램
- 코드 품질 분석 도구는 정적 분석과 동적 분석 도구가 있음
2) 정적 분석 도구
- pmd
- Java 및 타 언어 소스 코드에 대한 버그, 데드 코드를 분석함
- Eclipse에 내장되어 사용함
- cppcheck
- C/C++ 코드에 대한 메모리 누수, 오버플로우를 분석함
- 배열 범위, 클래스, 메모리 누수, NULL 포인트 등을 체크함
- SonarQube
- 소스 코드의 품질을 체크하는 통합 플랫폼
- checkstyle
- Java 코드가 표준을 준수하였는지를 검사함
2. 동적 분석 도구
- Avalanche
- valgrind 프레임워크 및 STP 기반 소프트웨어로 오류 및 취약점을 동적으로 분석함
- valgrind
- 자동화된 메모리 및 스레드 결함을 검색하고 분석하는 도구
- 메모리 오류를 검출함
- Cache, Heap, 다중 스레드의 프로파일링을 지원함
4) 코드 최적화 기법
1. 코드 최적화 기법의 개념
- 코드 최적화 기법, 아키텍처 조정 및 호출 순서 조정 등을 적용하여 성능을 개선할 수 있음
- 프로그래밍 언어의 특성에 대한 이해를 기반으로 소스 코드 품질 분석 도구를 활용하여 성능을 개선할 수 있음
- 코드 최적화 기법은 나쁜 코드를 찾아 읽기 쉽고 변경 및 추가가 쉬운 클린 코드를 작성하는 것
- 소스 코드는 지속적으로 변경이 되기 때문에 실행 시간이나 자원 사용량 측면에서 비효율적일 수 있기 때문에, 소스 코드는 지속적으로 최적화 해야 함
2. 나쁜 코드(Bad Code)
- 로직(Logic)을 이해하기 어렵게 작성된 코드
- 로직의 제어가 정제되지 않고 서로 얽혀 있는 스파게티 코드
- 변수나 메소드에 대한 이름 정의를 알 수 없는 코드
- 동일한 처리 로직이 종복되게 작성된 코드
- 소스 코드가 이해가 안 되면 유지보수 비용이 높아질 수밖에 없음
- 스파게티 코드의 경우 잦은 오류가 발생할 가능성이 있음
- 코드의 이해가 어려워 덧붙이기가 계속되고 코드 복잡도가 증가함
3. 클린 코드(Clean Code)
- 판독성이 높고, 단순하며, 의존성을 줄이고, 중복을 최소화하여 깔끔하게 잘 정리된 코드
- 클린 코드가 높을수록 가독성이 좋아져서 유지보수 비용이 낮아지고, 수정 속도가 빨라짐
- 판독성이 높으므로 기능을 쉽게 이해할 수 있음
- 오류를 찾기 용이함
- 프로그래밍 속도가 빨라짐
5) 클린 코드의 작성 원칙
- 가독성
- 이해하기 쉬운 명령어를 사용함
- 코드 작성 시 들여쓰기 기능을 사용함
- 단순성
- 한 번에 한 가지만 처리가 되도록 코딩함
- 클래스, 메소드, 함수 등을 최소 단위로 분리함
- 의존성
- 영향도, 결합도를 최소화함
- 코드의 변경이 다른 부분에 영향이 없게 작성함
- 중복성
- 중복된 코드를 제거함
- 공통된 코드를 사용함
- 추상화
- 클래스, 메소드, 함수에 동일한 수준의 추상화를 함
- 상세 내용은 하위 클래스에서 함
6) 표준화된 코딩 형식
- 하나의 명령을 하나의 라인을 코딩함
- 명령어를 구분할 수 있는 줄 바꿈을 적절히 사용함
- 호출하는 함수는 먼저 배치하고, 호출되는 함수는 나중에 배치함
- 변수 선언 시 지역 변수는 함수 시작 부분에서 선언함
- 함수 간의 매개 변수는 변수명만 보아도 쉽게 파악할 수 있도록 부여함
- 변수명은 기억하기 쉬운 명칭, 발음하기 쉬운 용어, 접두어 등을 사용함
- 주석문을 사용하여 다른 개발자가 소스 코드를 쉽게 이해하도록 함
- 공백을 이용하여 실행문 그룹과 주석을 명확히 구분함
- 복잡한 논리식과 산술식은 괄호와 들여쓰기를 통해 명확히 표현함
- 빈 줄을 사용하여 선언부와 구현부를 구별함
03. C언어의 기초
1) C언어의 특징
- 고급 언어이면서 저급 언어
- 쉽게 배울 수 있는 언어(고급 언어)이면서 하드웨어는 제어할 수 있는 시스템 프로그래밍 언어(저급 언어)
- 구고적을 프로그램을 작성할 수 있음
- 프로그램을 기능별로 분리하여 부품처럼 만들어 조립하듯이 프로그래밍할 수 있음
- 이식성이 뛰어남
- C언어로 작성된 프로그램은 컴퓨터의 기종이나 운영체제가 다르더라도 전혀 문제 없이 실행됨
- 효율적
- C언어는 메모리를 직접 관리하면서 실행에 필요한 많은 자원을 낭비 없이 운영할 수 있음
- 다양한 연산자를 가지고 있음
- 기본 연산자 외에도 비트 관련 연산자는 물론 다양한 연산 기능을 가지고 있어 프로그램 개발에 제한이 없음
- 다양한 연산자로 인해 개발자는 물론 소스 분석자도 이해하기 어려울 수 있음
2) C언어의 작성 규칙
- 반드시 main() 함수로 시작함
- 영문자는 대소문자를 구분함
- 모든 함수는 블록 구조로 만들어야 함
- 모든 명령문은 세미콜론으로 종료를 알려야 함
- 프로그램 내에 설명이 필요하면 주석을 사용함
- 1열에 #include를 사용하여 <stdio.h> 파일을 포함해야 표준 입출력 함수를 사용할 수 있음
3) C언어 변수명 작성 규칙
1. C언어 변수명의 개념
- C언어에서 제공하는 예약어가 아닌 프로그래머가 임의로 선언해야 하는 문자열의 작성 규칙
- 변수명이나 함수명이 프로그래머가 임의로 작성해야 하는 문자열
2. 변수명이나 함수명의 작성 규칙
- 영문자, 숫자, 밑줄 문자를 사용함
- 첫 글자는 반드시 영문자로 시작해야 하며, 밑줄 문자는 영문자로 취급되기 때문에 첫 글자로 사용할 수 있음
- 영문자는 대소문자를 다른 문자로 취급함
- 공백을 포함하거나 다른 특수 문자를 포함해서는 안 됨
- 예약어를 변수명으로 사용할 수 없음
4) C언어 변수 선언의 예약어
- 문자형
- char(대형 기종 : 1byte / 소형 기종 : 1byte)
- 정수형
- short(대형 기종 : 2byte / 소형 기종 : 2byte)
- int(대형 기종 : 4byte / 소형 기종 : 2byte)
- long(대형 기종 : 4byte / 소형 기종 : 4byte)
- unsigned(대형 기종 : 4byte / 소형 기종 : 4byte)
- 실수형
- float(대형 기종 : 4byte / 소형 기종 : 4byte)
- double(대형 기종 : 8byte / 소형 기종 : 8byte)
5) C언어 상수
- 정수형 상수
- 10진 상수
- 일반적으로 사용하는 방식으로 사용
- 예시 : 10, 235, 56, -456
- 8진 상수
- 0으로 시작
- 예시 : 043, 023
- 16진 상수
- 0x로 시작
- 예시 : 0x43, 0x5E0, 0xFFFF
- 10진 상수
- 실수형 상수
- 소수점형
- 일반적으로 사용하는 방식으로 사용
- 예시 : 1.4, -4.56, -0.001
- 지수형
- 문자 e나 E를 중간에 포함하여 사용
- 예시 : 1e4, 2E-3, 1.2e4
- 소수점형
6) 이스케이스 시퀀스(Escape Sequence)
종류 | 설명 |
---|---|
\n | 줄 바꿈, 개방 문자로 Enter 키와 같은 역할 |
\t | 일정한 크기의 열을 띄우는 것으로 Tab 키와 같은 역할 |
\b | 한 칸 앞으로 이동하는 것 |
\f | 프린터에서 다음 페이지를 출력할 수 있도록 이동함 |
\r | 현재 행의 처음으로 이동함, home 키와 같은 역할 |
\0 | NULL 문자, 1바이트 안에 모두 0이 채워짐 |
\\ | \ 자체, printf("\\"); 은 \가 출력됨 |
\' | ' 자체, 단일 인용 부호(') 자체를 의미함 |
\" | " 자체, 이중 인용 부호(") 자체를 의미함 |
7) 변환 문자
종류 | 설명 |
---|---|
%d | 10진 정수로 변환하여 출력함 |
%o | 8진 정수로 변환하여 출력함 |
%x | 16진 정수로 변환하여 출력함 |
%u | 부호 없는 정수로 변환하여 출력함 |
%f | 소수점이 있는 실수로 변환하여 출력함 |
%e | 지수 형태의 실수로 변환하여 출력함 |
%g | %f, %e 중에 출력 길이가 짧은 쪽을 선택하여 출력함 |
%c | 한 문자로 변환해서 출력함 |
%s | 문자열을 출력하며, 시작 번지로부터 "\0" 이전까지 출력함 |
- 변환 문자의 옵션
- : 좌측에 맞춰 출력함
- : 숫자 앞에 부호를 붙임
- 0 : 숫자 앞 공백은 모두 0으로 채움
05. C언어의 표준 입출력 함수
1) 한 문자를 입력하거나 출력하는 함수
- getchar() : 한 문자를 키보드에서 입력 받는 함수로 () 안에 인수를 사용하지 않음
- putchar(char) : 한 문자를 모니터로 출력하는 함수
2) 문자열을 입력하거나 출력하는 함수
- gets(string) : 문자열을 키보드로부터 입력 받는 함수
- puts(string) : 문자열을 모니터로 출력하는 함수
3) 포맷을 갖춘 문자열을 입력하거나 출력하는 함수
- scanf(format) : 포맷 문자열을 키보드로부터 입력 받는 함수
- printf(format) : 포맷 문자열을 모니터로 출력하는 함수
06. C언어의 문자열 함수
- strcpy() : 문자열을 복사함
- strncpy() : 문자열에서 지정한 부분만큼 복사함
- strcat() : 두 개의 문자열을 합침
- strncat() : 두 개의 문자열을 지정한 부분만큼 합침
- strlen() : 문자열의 길이를 구함
'정보처리기사 > 프로그래밍 언어 활용' 카테고리의 다른 글
프로그래밍 언어 활용 3 (0) | 2023.05.29 |
---|---|
프로그래밍 언어 활용 2 (0) | 2023.05.29 |
프로그래밍 언어 기초 3 (0) | 2023.05.29 |
프로그래밍 언어 기초 2 (0) | 2023.05.29 |
프로그래밍 언어 기초 1 (0) | 2023.05.29 |