Part4 - chapter02 : 프로그래밍 언어 활용
[ 알고리즘과 코딩 ]
□ 알고리즘
○ 알고리즘이 갖추어야 할 조건
- 입력 : 외부에서 입력되는 자료가 0개 이상 존재
- 출력 : 출력이 적어도 1개 이상 결과가 있음
- 명확성(Definiteness) : 명령어들은 명확하고 모호하지 않아야 함
- 유한성(Finiteness) : 알고리즘의 명령어들은 유한 번의 수행 후 종료되어야 함 => 프로그램과 구별되는 조건
- 유효성(Effectiveness) : 모든 명령들은 명백하고 실행 가능한 연산들
○ 알고리즘을 분석하는 판단 기준
- 정확성(Correctness) : 알고리즘이 정확한지 검사하여 입력에 따른 정확한 출력이 되는지
- 간결성(Simplicity) : 표현이 간단하고 이해하기 쉽고 읽기 쉬운가
- 작업량(Amount of Work Done) : 알고리즘 수행에서 실행 횟수의 평균과 최악의 경우의 기준
- 최적성(Optimality) : 알고리즘 수행 시간의 평균과 최악이 같은 경우를 최적이라 하고 그 차이를 계산하여 분석
○ 알고리즘 설계 기법
- 동적 계획법 : 해결하고자 하는 문제의 최적 해를 부분 문제들의 최적해로 구성된 경우 이를 통해 해를 구함
- 탐욕적 알고리즘 : 최적해를 찾는 근사 알고리즘으로 최적해는 아니여도 근사적 해답을 구할 수 있음
- 재귀적 알고리즘 : 같은 알고리즘을 반복하여 수행하는 알고리즘
- 근사 알고리즘 : 최적화되는 답을 구할수 없어도 빠른 시간에 근사 해법을 수행하는 알고리즘
- 배낭 알고리즘 : 배낭에 훔친 물건을 담는 방법
- 분할 정복법 : 전체 문제를 부분으로 나누어 해결하고 부분적으로 해결된 문제를 결함하여 전체 문제 해결하는 벙법으로 Top-Down 방식 (<-> 동적 계획 : Bottom-Up 방식)
- 퇴각 검색법 : 최적해를 구하기 위한 모든 가능성을 찾는 방법으로 깊이 우선 탐색이 있음
□ 코드 품질 분석 도구
○ 코드 품질 분석 도구 개념
-코딩 스타일, 설정된 코딩 표준, 코드 복잡도 등을 발견하기 위해 사용하는 프로그램
○ 정적 분석 도구
- pmd : Java 및 타 언어 소스 코드에 대한 버그, 데드 코드를 분석, Eclipse에 내장되어 사용
- cppcheck : C/C++ 코드에 대한 메모리 누수, 오버플로우 분석 / 배령 범위, 클래스 Null 등을 체크
- SonarQube : 소스 코드의 품질을 체크하는 통합 플랫폼
- checkstyle : Java 코드가 표준을 준수하는지 검사
○ 동적 분석 도구
- Avalanche : Valgrind 프레임워크 및 STP 기반 소프트웨어 오류 및 취약점 동적 분석
- valgrind : 자동화된 메모리 및 스레드 결함을 검색하고 분석하는 도구
□ 코드 최적화 기법
○ 나쁜 코드
- 로직을 이해하기 어렵게 만든 코드
- 이름 정의를 알 수 없는 코드
- 중복되게 작성된 코드
○ 클린 코드
- 판독성이 높고 단순하고 의존성을 줄인 코드
- 가독성이 높고 유지보수 비용이 낮고 수정속도가 빠름
- 오류를 찾기 용이함
○ 클린 코드 작성 원칙
- 가독성 : 이해하기 쉬운 명령어 사용, 코드 작성시 들여쓰기 사용
- 단순성 : 한 번에 한 가지만 처리가 되도록 코딩, 클래스, 메소드, 함수 등을 최소 단위로 분리
- 의존성 : 영향도, 결함도를 최소화
- 중복성 : 중복 코드 제거, 공통된 코드 사용
- 추상화 : 클래스, 메소드, 함수에 동일한 수준의 추상화 사용, 상세 내용은 하위 클래스에서 함
○ 표준화된 코딩 형식
- 하나의 명령을 하나의 라인을 코딩함
- 줄바꿈을 적절히 사용
- 호출하는 함수는 먼저 배치하고 호출되는 함수는 나중에 배치
- 변수 선언시 지역 변수는 함수 시작 부분에서 선언
- 함수간 매개변수는 변수명만 보아도 파악할 수 있도록 부여
- 주석문으로 다른 개발자가 소스코드를 알 수 있도록 함
□ C 언어
○ C 언어 특징
- 고급 언어이자 저급 언어 : 쉽게 배울 수 있는 언어이자(고급) 하드웨어 제어 가능 프로그래밍 언어(저급)
- 구조적인 프로그램 작성 가능 : 프로그램을 기능적으로 분리하여 조립하듯 프로그래밍이 가능
- 이식성이 좋음 : 컴퓨터 기종이나 운영체제가 다르더라도 문제없이 실행
- 효율적임 : 메모리를 직접 관리하여 많은 자원을 낭비하지 않고 운영 가능
- 다양한 연산자를 가지고 있음
○ C 언어 변수명 작성 규칙
- 예약어가 아닌 프로그래머가 임의로 선언해야하는 문자열의 작성 규칙
- 영문자, 숫자, 밑줄문자를 사용
- 첫 글자는 반드시 영문자로 시작(밑줄 문자는 영문자로 취급되어 사용 가능)
- 영문자는 대소문자를 구분함
- 공백을 포함하거나 다른 특수문자를 사용하면 안되며 예약어를 사용할 수 없음
○ C 언어 변수 선언 예약어(대형 기종/소형 기종)
- 문자형 : char - 1byte / 1byte => java(2)
- 정수형 : short(2/2), int(4/2), long(4/4) => java(2,4,8)
- 실수형 : float(4/4), double(8/8) => java(4,8)
○ 이스케이프 시퀀스
- \n : 줄 바꿈, 개행문자
- \t : 일정 크기의 열을 띄우는 것, tab
- \b : 한 칸 앞으로 이동하는 것, <-
- \f : 출력
- \r : 현재 행의 처음으로 이동, home
- \0 : Null 문자, 1바이트에 모두 0이 채워짐
○ 변환 문자
- float b=45.678 %7.2f => _ _45.68
- float b=45.678 %-7.2f => 45.68_ _
- char c[]="HOLE" %7s => _ _ _HOLE
- char c[]="HOLE" %-7s => HOLE_ _ _
- char c[]="HOLE" %7.2s => _ _ _ _ _HO
[ C언어의 연산자 ]
□ C 언어 연산자 우선순위
○ 개념
- 연산자 우선순위는 묵시적으로 정해져 있음
- 동일 우선순위를 갖는 연산자는 연산자에 따라 좌측에서 우측 혹은 우측에서 좌측으로 결합됨
○ C 언어, Java
연산자 | 종류 | 결합 |
단항 | ++, --, -, !, ~, sizeof, &, * | <- |
산술 | *, /, % | -> |
+, - | ||
시프트 | <<, >> | |
관계 | <, >, <=, >= | |
==, != | ||
비트논리 | &, ^, | | |
논리 | &&, || | |
조건 | ?, : | |
할당 | =, +=, -=, *=, /=, %=, <<=, >>= | <- |
콤마 | , | -> |
○ Python
연산자 | 종류 | 결합 |
단항 | +, -, ~ | <- |
산술 | ** | -> |
*, /, //, % | ||
+, - | ||
시프트 | <<, >> | |
비트논리 | &, ^, | | |
관계 | <, >, <=, >= | |
==, != | ||
논리 | not, is not, and, or | |
할당 | =, +=, -=, *=, /=, %=, <<=, >>=, //== | <- |
멤버 | in, not in | -> |
□ C 언어 연산자 우선순위
○ ~ 연산자
- 변수와 상수를 이진수로 풀어 비트 하나하나 대상으로 연산
- 비트가 0이면 1로, 1이면 0으로 변환한다
- 7 : 00000111, ~7 : 11111000 = -8
○ &, * 연산자
- & 연산자 : 변수의 절대 번지를 표현하는 번지 지정 연산자
- * 연산자 : 포인터 변수를 선언하거나 포인터 내용을 표현하는 간접 연산자
○ <<, >> 연산자
- 시프트 연산자 : 변수와 상수를 이진수로 풀어 비트 하나하나 대상으로 좌/우측으로 위치 이동 연산자
- a << n : a x 2^n , a >> n : a / 2^n
○ 비트논리 연산자
- 비트논리 연산자 : 변수와 상수를 이진수로 풀어 비트 하나하나를 대상으로 연산
- 우선순위 : & -> ^ -> |
- a & b : 비트 AND, 대응되는 비트가 한쪽이라도 0이면 0
- a | b : 비트 OR, 대응되는 비트가 한쪽이라도 1이면 1
- a ^ b : 비트 XOR, 대응되는 비트가 같으면 0, 다르면 1
○ 논리 연산자
- 변수와 상수를 대상으로 연산하여 참, 거짓을 판단
- a && b : AND, 한쪽이라도 거짓이면 거짓으로 0
- a || b : 한쪽이라도 참이면 참으로 1
- 수식 처리가 중단될 수 있다 => 참, 거짓을 수식 전체를 처리하지 않고 판단할 수 있으면 중단됨
○ 삼항연산자
- 항이 3개 있는 연산자로 참, 거짓에 따라 수행할 명령문이 선택됨
- 조건식 ? A : B => 조건식이 참이면 A, 거짓이면 B 명령문 수행
[ C언어의 제어문 ]
□ 선택문
○ switch ~ case ~ default 문
- 다중 if 문의 복잡하고 어려운 문제를 보와한 다중 선택문
- break문을 생략할 수 있지만 생략하게 되면 하나의 case문만을 수행하는 것이 아니라 case문을 순차적으로 모두 수행하게 된다.
switch(jum/10) {
case 10 : ch ='A'; break;
case 9 : ch ='B'; break;
...
default : ch ='F'; }
[ C언어의 고급 기법 ]
□ 배열
○ 배열은 여러 개의 변수명을 하나로 통일하여 사용
- 연속적 기억 공간에 변수명이 동일하여 실행속도가 빠르고 프로그래밍이 쉬움 => 동질형의 데이터
○ 배열에서 배열명은 배열의 시작 번지이며 문자 상수로 취급
- 상수인 a에 번지 지정 연산자 &를 사요해서는 안된다
- a[0]은 변수이므로 &를 사용하면 a[0]의 절대 번지이며 a와 같은 번지가 됨
○ 배열에 첨자가 1개면 1차원, 2개면 2차원 배열임
- a[0][0] : 2차원 배열
- 실제 기억 장소 할당은 1차원 배열 형태로 할당된다 => 선형적 공간 할당
- &a[1][0] == a[1]
○ 첨자는 변수, 상수, 수식 모두 가능
- a[k], a[6], a[k+6], a[i++] 모두 가능
□ 증감 연산자
○ 정수형 배열과 포인터에 증감 연산자 사용
# include <stdio.h>
main() {
static int a[5]={1,3,5,7,9};
int *p =a; # 정수형 포인터 변수 p 선언, 1차원 배열의 시작번지 기억
int *q =a+4; # 정수형 포인터 변수 q 선언, 1차원 배열의 a[4]의 번지 기억
p++;
q--;
*p =35; # a[1]에 35 기억
*p++ =77; # a[1]에 77 기억하고 p를 1 증가
*--q =88; # q를 1 감소하고 a[2]에 88 기억
}
# a : 1 77 88 7 9
□ 기억 클래스
선언 예 | 설명 | 생성(할당) | 소멸 | 사용 범위 |
auto int a; | 동적인 스택 영역에 기억장소 할당 | 실행 시 | 블록이나 함수 종료 시 | 블록이나 함수 내에서 |
static int a; | 정적인 힙 영역에 기억장소 할당 | 번역 시 | 프로그램 종료 시 | 하나의 프로그램 파일에서 |
extern int a; | 정적인 힙 영역에 기억장소 할당 | 번역 시 | 프로그램 종료 시 | 모든 프로그램 파일에서 |
register int a; | CPU내 고속 메모리인 레지스터에 기억장소 할당 | 실행 시 | 블록이나 함수 종료 시 | 블록이나 함수 내에서 |
선언 예 | 기억장소 내용과 초기화 여부 | 특징 |
auto int a; | 기존에 기억된 내용이 있으므로 초기화 필요 | auto 예약어 생략 가능 |
static int a; | 기존에 기억된 내용이 없어 초기화 필요 없음 | 함수 내부의 선언과 외부 선언의 위치 차이 |
extern int a; | 기존에 기억된 내용이 없어 초기화 필요 없음 | 프로그램에 속한 모든 파일에 영향 |
register int a; | 기존에 기억된 내용이 있으므로 초기화 필요 | 개수의 제한이 있고 &를 사용할 수 없음 |
□ 함수
○ 함수의 부품화된 기능
- 전체 프로그램을 한 번에 프로그래밍하는 것이 아니라 기능별로 구분하여 프로그래밍
- 독립적으로 개발하여 결합하여 전체 프로그램 완성
- 유용한 함수들 잘 저장하는 것이 중요하고 이 파일들을 라이브러리, 헤더 파일이라고 함
○ 함수의 매개변수 전달 기법
- Call by Value : 함수 호출 시에 인수의 값을 전달 => 리턴 값이 있는 경우
- Call by Address : 함수 호출 시에 인수의 절대 주소를 전달 => 포인터 변수 사용
[ 파이썬 ]
□ Python의 변수와 상수
○ Python 변수 작성 규칙
- 첫 글자에 숫자를 사용할 수 없음
- 영문, 대문자, 소문자, 숫자, 밑줄 문자를 사용
- 대소문자는 구분함
- 공백을 사용할 수 없고 예약어를 사용할 수 없음
- 변수명 길이에 제한이 없음
- 한글을 사용해도 되지만 사용하지 않는 것이 좋음
□ Python의 연산자
○ 단항 : +, -, ~
- ~(-30) = 29
- ---30 = -30
○ 산술 : **, *, /, //, %, +, -
○ 시프트 : >>, <<
○ 관계 : <, >, <=, >=, ==, !=
○ 비트 논리 : &, |, ^
○ 논리 : and, not, or
○ 멤버 : in, not in
○ C언어에는 //, in, ** 연산자가 없음 <-> Python에는 ++, --연산자가 없음