Skip to content
Snippets Groups Projects
Select Git revision
  • main default protected
1 result

pcc004

  • Clone with SSH
  • Clone with HTTPS
  • Nayoung Kim's avatar
    Nayoung Kim authored
    30f0680a
    History

    실전코딩 2 실습

    sshid : pcc004

    name : 김나영

    id : 202126850

    Lecture 01 [2022.01.04]

    Linux command

    1. ls (ls -l, ls -al 등의 형태)
    • 현재 directory에 있는 파일 리스트 확인 가능
    • ls -l : ls 명령어보다 상세한 파일 정보를 제공
    • ls -al (ls -la) : directory에 있는 모든 파일 정보를 보여줌
      • .으로 시작하는 hidden file(숨겨진 파일)까지 확인할 수 있음
    1. date
    • 현재 시간(시, 분, 초)와 날짜 및 요일에 대한 정보를 제공
    1. who
    • 현재 컴퓨터에 접속 중인 id 목록을 보여줌
    1. ~~ | sort
    • ~~ 내용을 정렬된 상태로 보여줌
    1. ~~ | wc
    • word count
    • line수 단어수 글자수(공백과 줄바꿈 포함) 정보 제공
    1. pwd
    • 현재 작업 중인 directory의 절대 경로를 제공
    1. cd
    • change directory
    • directory의 위치를 변경
    1. mkdir
    • 새로운 directory 생성
    1. vi ~~
    • 기존에 ~~ 파일이 없는 경우 파일을 생성하고 vi editor 모드로 변환됨
    • 기존에 ~~ 파일이 있는 경우 ~~ 파일을 vi editor 모드로 보여줌
    1. cc ~~
    • ~~ 파일을 컴파일
    1. passwd
    • 비밀번호 변경 명령어
    1. rm ~~
    • ~~ 파일을 제거
    1. rmdir ~~
    • ~~ directory를 제거
    1. cat
    • 파일 내용을 출력
    • 파일이 존재하지 않는 경우
      • standard input을 받은 후 standard output으로 내보냄
    • 파일이 존재하는 경우
      • 파일을 합침
      • cat data.txt hello.c output.txt > total.txt
        • data.txt, hello.c, output.txt 파일의 내용을 total.txt 파일에 저장.
    1. chmod
    • dr--r----- 2 pcc039 pcc 4096 1월 4 15:35 forAll
      • d로 시작함 -> directory
      • directory의 소유자는 pcc라는 그룹에 속해있는 pcc039
      • 소유자는 directory를 read 할 수 있는 권한을 가짐
      • 그룹원들은 directory를 read 할 수 있는 권한을 가짐
      • 다른 사람들은 directory를 read, write, execute 할 수 있는 권한을 가지지 않음
    • d/rwx/rwx/rwx
      • 종류/소유자에게 부여된 권한/그룹원에게 부여된 권한/다른 사람들에게 부여된 권한
      • rwx는 8진수 체계
      • chmod 777을 사용하면 모든 사용자에게 모든 권한이 부여됨
      • chmod 770의 경우에는 소유자와 그룹원들에게 모든 권한이 부여됨
      • chmod 700의 경우에는 소유자에게만 권한이 부여됨
      • w 권한을 막고 싶은 경우 5를 할당하는 방식

    hello.c 파일 컴파일 (vi editor 사용법)

    1. vi hello.c
    • vi 명령어를 이용해 hello.c 파일을 만듦
    • vi editor로 변환됨
    1. Insert 키
    • vi editor를 인서트 모드로 전환
    #include <stdio.h>
    int main()
    {
        printf("Hello World! \n");
    }
    • 삽입하고자 하는 문구를 입력 (c언어 문법에 맞게)
    1. esc
    • esc키를 통해 인서트 모드에서 빠져나옴
    1. :wq
    • :wq(저장 후 종료)를 입력하여 vi editor모드에서 빠져나옴
    1. cc hello.c
    • hello.c 파일을 컴파일
    • 같은 디렉토리에 a.out이라는 출력파일이 생성됨
    1. ./a.out
    • 현재 디렉토리 아래의 a.out 파일을 실행시킴
    • Hello World! 출력

    Lecture 02 [2022.01.05]

    Linux command

    1. echo
    • 출력하고자 하는 문구를 출력
    1. wall
    • 접속해있는 모든 사용자에게 원하는 문구를 출력
    1. write ~~(특정 사용자 id)
    • ~~(특정 사용자)에게 원하는 문구를 출력
    1. mesg y/n
    • 다른 사용자의 write 명령을 통해 나에게 보내지는 메세지를 차단하거나 허용할 수 있음
    1. man
    • manual
    • 명령어에 대한 정보를 제공함
    1. mv ~~ --
    • --이 이미 존재하는 경우 ~~를 --로 이동시킴
    • --이 존재하지 않는 경우 ~~의 이름을 --로 수정함
    1. cp ~~ --
    • ~~를 --로 복사함
    1. more
    • 한 페이지 이상의 출력 내용을 페이지 단위로 보여줌
    1. history
    • 지금까지 사용한 명령어 리스트를 보여줌
    1. sleep ~~(초 단위의 시간)
    • ~~초까지 모든 실행을 중단
    • sleep ~~; 다른 명령어
      • ~~초 이후에 다른 명령어를 실행함
    • (sleep ~~; 다른 명령어) &
      • ~~c초 이후에 다른 명령어를 실행하고 그 동안 다른 작업 가능
      • 괄호 안의 작업을 background에서 실행
    1. diff ~~ --
    • ~~ 파일과 -- 파일을 비교
    • 일치하는 경우 메세지가 뜨지 않음
    • 일치하지 않는 경우 다른 부분을 보여줌
    1. ctrl + c
    • kill
    • 현재 진행 중인 작업을 지움
    1. ctrl + d
    • 현재 진행 중인 작업을 중단함
    1. ps
    • 현재 진행 중인 process 확인
    • ps -al의 경우 hidden file까지 확인 가능
    1. fg %(~~)
    • background(백그라운드)에서 실행 중인 ~~를 foreground(포그라운드) 작업으로 전환
    1. strings
    • 읽을 수 있는 데이터만 보여줌
    1. standard stream(표준 스트림)
    • standard input(stdin, 표준 입력 스트림)
      • 입력을 위한 스트림
      • fd(File Descriptor, 파일 디스크립터) : 0 할당
    • standard output(stdout, 표준 출력 스트림)
      • 출력을 위한 스트림
      • fd(File Descriptor, 파일 디스크립터) : 1 할당
    • standard error(stderr, 표준 에러 스트림)
      • 에러메세지 출력을 위한 스트림
      • fd(File Descriptor, 파일 디스크립터) : 2 할당
    • stream(스트림)
      • 유닉스 계열 운영체제에서 프로그램과 주변 기기 사이에 미리 연결된 입출력 통로
    1. redirection(리다이렉션)
    • '>' (표준 출력-덮어쓰기)
      • 사용법 : 명령어 > 파일
      • 명령어의 표준 출력 스트림 도착 지점을 파일로 설정
    • '<' (표준 입력)
      • 사용법 : 명령어 < 파일
      • 파일로부터 입력 받음
    • '>>' (표준 출력-추가)
      • 사용법 : 명령어 >> 파일
      • 명령어의 표준 출력 스트림 도착 지점 파일에 내용 추가
    1. | (pipe)
    • 사용법 : A | B
    • A command의 표준 출력을 B command의 표준 입력으로 사용
    • ls -al | grep root
      • ls -al command의 출력 결과 중 "root"라는 문자를 포함하는 결과만 출력

    Linux System

    • stdio(표준입출력장치)
      • shell에서 기본이 되는 input, output 장치

    computer hardware system

    comhardware

    • CPU
    • Memory
    • Storage Devices
    • Input Devices
    • Output Devices
    • buffer
      • 데이터를 전송하는 동안 일시적으로 데이터를 보관하는 메모리의 일종
      • Input Devices에 관여하는 buffer는 inbuffer
      • Output Devices에 관여하는 buffer는 outbuffer
      • inbuffer와 outbuffer를 합쳐 iobuffer라고 함

    Software

    • System Software (SS : 시스템 소프트웨어)
      • Operating System (OS : 운영체제)
      • Compiler (컴파일러)
      • Devices (디바이스)
    • Application (APP : 애플리케이션)

    Linux Software

    linuxsoftware

    1. Hardware
    2. Linux : Kernel
    3. System Call : Interface
    4. System Utilities : cat, ls, date, ps, kill, who
    5. Linux Shell : bash

    Linux Kernel SCI (System Call Interface)

    linuxkernel

    • I/O sub system
      • Terminals

      • Character device driver

      • Sockets

      • Network protocols

      • Network device drivers

      • File systems

      • Block device drivers

    • Memory management sub system
    • Process management sub system

    컴퓨터 구성 요소

    • Users (사용자)
    • Hardware (하드웨어)
    • Software (소프트웨어)
    • Data (데이터)

    파일 종류

    • d~ : directory
    • c~ : character device
    • b~ : block device
    • l~ : link

    Lecture 03 [2022.01.06]

    프롬프트 색상 변환

    cp ~hwan/.profile ~hwan/.bashrc ~hwan/.bash_logout ~
    source .profile

    교수님 코드를 카피하여 프롬프트의 색상을 바꿈

    linux command

    1. grep
    • 찾고자 하는 텍스트를 입력하면 텍스트가 들어간 line을 출력함
    • grep 텍스트 파일명
      • 파일 내부에서 텍스트 찾기
    • grep 텍스트
      • standard input을 받고 입력된 텍스트 중에서 원하는 텍스트가 있을 경우 standard output을 출력
    1. which
    • 찾고자하는 파일의 위치에 대한 정보 제공
    1. tee
    • standard input(표준 입력)에서 읽어서 standard output(표준 출력)과 파일에 쓰는 명령어
    • echo "hello" | tee a.txt
      • 명령을 실행하면 a.txt 파일과 터미널에 hello가 출력됨

    git command

    • git clone
      • 저장소 복제
      • window에서는 git Bash, macOS나 Linux에서는 터미널을 사용
    • git pull
      • 원격 저장소에서 로컬 저장소로 소스를 가져오는 명령어
      • 실습에서는 git.ajou.ac.kr의 소스를 git Bash로 가져올 때 사용
    • git commit
      • 의미있는 변화에 대해 기록
      • vi editor 모드로 바뀜
      • vi editor 모드로의 변환을 원하지 않으면 git commit -m
      • vi editor 모드에서 Insert 키를 누른 뒤 입력하고자 하는 commit 내용을 작성
    • git push
      • 현재 프로젝트에서 커밋(commit)된 내용을 원격 저장소로 내보냄
      • 실습에서는 git Bash에서 수정된 내용을 git.ajou.ac.kr로 내보낼 때 사용
    • git add
      • 다음 변경을 기록(commit)하기 전 변경하고자 하는 것들을 모아두기 위해 사용
    • git config
      • commit을 누가 작성했는지 표시하기 위해 username과 email을 설정해야 함
      • 설정하는 방법
      git config --global user.name "KimNayoung"
      git config --global user.email "skdud1201@ajou.ac.kr"
      • 삭제하는 방법
      git config --unset --global user.name
      git config --unset --global user.email
      • config 리스트 확인
      git config --list
    • git mv
      • git에 있는 파일의 이름을 변경
    • git rm
      • git 저장소와 로컬 디렉토리에서 파일을 삭제

    markdown

    • #을 통해 제목을 설정
      • #/##/###/####/#####/###### 6단까지 가능
    • *를 통해 리스트를 설정
      • Tab키를 통해 구분
    • <> 괄호 안에 br을 넣으면 줄 구분 가능
    • 1.을 통해 텍스트에 번호를 매길 수 있음
      • Tab키를 누르면 다른 리스트로 분류되어 숫자가 리카운트됨
      • 번호를 매기지 않고 "1."이라고 입력하기를 원한다면 1.로 입력함
    • BOLD
      • ** ** 사이에 텍스트를 입력하면 텍스트를 볼드처리할 수 있음
    • ITALIC
      • 이탤릭체로의 변환을 위해서는 * * 사이에 텍스트를 입력
    • BOLD ITALIC
      • *** *** 사이에 텍스트를 입력하면 텍스트를 볼드 이탤릭체로 바꿀 수 있음
    • 글자 끝에 #를 삽입하면 줄 구분이 가능
    • `을 소스코드의 시작과 끝에 세번씩 쓰면 소스코드를 입력할 수 있음

    Lecture 04 [2022.01.10]

    Linux command

    1. sh

      • 새로운 shell을 여는 명령어
      • ps -l을 통해 PPID를 비교해보면 새로 생성된 sh이 bash에서 실행된 shell이라는 것을 확인할 수 있음
      • exit, ctrl + d, logout 명령어를 통해 shell에서 나갈 수 있음
    2. ;

      • 한 줄에서 여러 개의 명령 실행 가능
      • a.out <<< 0 ; a.out <<< 999 ; a.out <<< -100
        • a.out 출력 파일에 0, 999, -100을 넣은 출력 값을 전부 보여줌
    3. << (명령 종료할 때 입력할 문자)

      • cat << QQQ
        • QQQ를 입력하면 cat 명령이 종료됨
    4. $(명령)

      • 명령을 실행한 값
      • cat <<< $(echo "hello")
        • echo "hello" 명령을 실행한 결과값 hello를 cat명령의 stdin으로 연결하여 실행함
    5. cc -o (실행파일 이름) (컴파일할 파일 이름)

      • 컴파일 명령(cc)를 실행할 때 실행 파일 이름을 지정하고 싶은 경우 cc -o 명령을 이용함

    Command

    1. flush
      • 현재 buffer에 있는 모든 값들을 지우는 명령어
      • stdout 실행과 stderr 실행 사이의 우선 순위를 정해주고 싶은 경우 flush 명령을 통해 buffer를 비워줌으로써 해결함

    Python Command

    • Git Bash에서 python이라고 치면 파이썬 실행 가능
    • python에서 나가고자 할 때는 ctrl + d 또는 exit() 입력
    1. bin(10진수)
      • 10진수 수를 2진수로 바꿔주는 명령어

    Standard IO stream

    standardIO

    • stdin buffer, stdout buffer, stderr buffer는 memory에 저장되어 있음

    Understanding redirection

    • < 0< << 0<< > 1> >> 1>> 2> 2>>
    • redirection의 위치는 신경쓰지 않아도 됨
    • echo hello > ./out.txt
      • echo > ./out.txt hello와 결과가 동일함
      • hello를 현재 디렉토리 아래에 있는 out.txt파일에 저장
    • echo hello >&2
      • echo >&2 hello와 결과 동일
      • stdout과 stderr을 모두 내보냄
    • read -r line < file
      • < file read -r line
      • file의 한 줄을 읽음
    • https://mug896.github.io/bash-shell/redirections.html
    • 추가
    a.out <<< 300 > out.txt // Hello stderr 300 출력
    cat out.txt             // Hello stdout 300 출력

    a.out 출력파일에 300을 stdin으로 넣고 stdout을 out.txt파일로 보냄 남은 출력값인 stderr이 위 명령에 대한 출력으로 실행되고 cat 명령을 통해 out.txt 파일을 실행하면 이전에 보내진 stdout 값이 출력

    Here document, Here strings

    • 0<< or <<
      • 임시 파일을 만들어 stdin으로 연결
    • <<< (bash에서만 존재)
      • string을 stdin 입력으로 연결
      • globbing이 발생하지 않음
      • a.out <<< 99
        • a.out 출력파일을 실행할 때 입력하는 값을 <<< 뒤에 넣어서 한 줄로 실행 가능

    Pipe

    • cmd1 | cmd2
      • cmd1과 cmd2는 동시에 병렬로 실행
      • cmd1이 cmd2보다 빠르면 write은 파이프에 블록되고 더이상 진행되지 않음
      • cmd2가 cmd1 보다 빠르면 파이프로부터의 read는 블록
      • cmd1이 먼저 종료하면 파이프는 close 되고 cmd2는 End-Of-File 로 인식해 종료
      • cmd2가 먼저 종료하면 파이프는 close 되고 cmd1은 다음번 write에 SIGPIPE 신호를 받고 종료

    Glob (글로브)

    glob

    • glob 패턴은 와일드카드 문자로 여러 파일 이름의 집합을 지정
    • mv *.txt textfiles/
      • .txt로 끝나는 모든 파일을 textfiles 디렉토리로 이동
      • *은 모든 문자열을 가리키는 와일드 카드
      • *.txt는 글로브 패턴
    • 일반적인 와일드카드로는 *,?,[…]등이 있음

    Explain code function

    int ifuncAdd(int a, int b)
    {
        return a+b;
    }
    • 함수명 : ifuncAdd
    • 매개변수(parameter) : a, b (int 형)
    • 정수 형태의 a와 b를 받아서 더한 값을 return하는 함수
    • 수학적 의미의 정수는 아님
      • 수학적 의미의 정수 범위는 -무한대 ~ 무한대. 그러나 코드에서의 a와 b는 무한대 범위의 수를 표현할 수 없음
      • 따라서 '정수형'이라고 표현 -> 진짜 정수는 아님!

    Type Basic

    • Standard signed integer type
      • signed char, short int, int, long int, long long int
    • Unsigned
      • unsigned ...
    • floating type
      • float, double, (long double)
    • Definition in standard
      • char - large enough to store any execution character set
      • floating - The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double.
      • _Complex
      • _Bool - can store 0,1

    Negative integer

    • the corresponding value with sign bit 0 is negated (sign and magnitude)
    • the sign bit has the value - (2M) (two's complement)
      • 1의 보수를 구한 후 가장 낮은 비트에 +1
    • the sign bit has the value - (2M-1) (one's complement)

    Memory Model

    • Automatic
    • Static
    • Manual
    • Const

    binary code

    #include <stdio.h>
    int main() {
    	int i;
    	int in_a;
    	fscanf(stdin, "%d", &in_a);
    	for (i = 31; i >= 0; i--) {
    		fprintf(stdout, "%d", ((in_a >> i) & 1));
    		if (i % 4 == 0) {
    			fprintf(stdout, " ");
    		}
    	}
    	fprintf(stdout, "\n");
    }
    • int 형으로 in_a를 입력받고 shift 연산을 한 후 1과 & operation을 하여 2진수로 변환하는 코드
    • '>>' (right shift) = /2
    • '<<' (left shift) = *2

    & operation

    • 100 & 255
      • 100 출력
      • 255를 2진수로 변환하면 1111 1111이 되기 때문에 어떤 수 A와 & operation을 하면 항상 A가 출력됨
    • 100 & -1
      • 100 출력
      • -1을 2의 보수를 통해 2진수로 변환하면 모든 비트가 1로 채워져있기 때문에 100이 출력됨

    shift

    • signed int
    int in_a, in_b;
    fscanf(stdint, "%d", &in_a);
    in_b = in_a >> 2;

    shift 연산 이후 비어있는 비트에 0이 채워짐

    • unsigned int
    unsigned int in_a, in_b;
    fscanf(stdint, "%d", &in_a);
    in_b = in_a >> 2;

    shift 연산 이후 비어있는 비트에 1이 채워짐

    Lecture 05 [1.11]

    Linux Command

    1. ln 옵션 원본파일 대상파일(대상 디렉토리)

      • ln은 link의 약어로서 리눅스 파일시스템에서 링크 파일을 만드는 명령어
      • 리눅스에서는 심볼릭링크(소프트링크)와 하드링크의 두가지 링크 파일이 존재하는
      • Symbolic link
        • ln -s 원본파일 대상파일
        • 단순히 원본파일을 가리키도록 링크만 시켜둔 것
        • 원본파일을 가리키고만 있으므로 원본 파일의 크기와는 무관
        • 경로의 글씨 수가 파일의 크기가 됨
        • 원본 파일이 삭제되어 존재하지 않는 경우, 링크파일이 깜박이며 원본 파일이 없다는 것을 알려줌
      • Hard Link
        • ln 원본파일 대상파일
        • 원본 파일과 다른 이름으로 존재하는 동일한 파일
        • 원본 파일과 동일한 내용의 다른 파일
        • 둘 중 하나가 삭제되더라도 나머지 하나는 그대로 존재
        • 원본 파일의 내용이 변경될 경우 링크파일의 내용 또한 자동으로 변경
      • 옵션
        • --backup(=CONTROL) : 대상파일이 이미 존재할 경우에 백업파일을 만든 후에 링크파일 생성
        • -b : 링크파일 생성시에 대상파일이 이미 존재하면 백업파일을 만든 후에 링크파일을 생성
        • -d : 디렉토리에 대한 하드링크파일생성을 가능하게 함. 단 root 권한으로 수행하더라도 시스템의 권한제한으로 인하여 실패할 가능성이 높음. (-F 와 --directory 는 -d 와 동일함)
        • -f : 대상파일이 존재할 경우에 대상파일을 지우고 링크파일을 생성
        • -i : 대상파일이 존재할 경우에 대상파일을 지울것인가를 확인요청 (--interactive 와 동일)
        • -s : 심볼릭 링크파일을 생성
        • -S : 백업파일 생성시에 원하는 접미사(suffix)를 지정할 수 있음
        • -t, --target-directory=DIRECTORY : 링크파일을 생성할 디렉토리를 지정
    2. cc -Wall 파일이름

      • 파일을 컴파일할 때 모든 부분에 대해서 경고가 필요한 부분에 warning 메세지를 띄움

    vi Command

    1. dd

      • 한 줄 잘라내기
    2. yy

      • 한 줄 복사
    3. p

      • 붙여넣기
    4. yw

      • 한 단어 복사

    c preprocessor (cpp, C 전처리기)

    • 컴파일 전에 C 프로그램을 수정하는 매크로 프로세서
    • 원본 파일을 처리하는 동안 전처리기는 헤더 파일과 매크로를 정의된 파일과 값으로 바꿈
      • 즉, #으로 시작하는 line은 실제 컴파일이 시작되기 전에 처리
      • 전처리가 끝난 코드는 추가 작업을 위해 컴파일러로 전송
    • 작업 종류
      1. 헤더 파일 추가
      • #include <stdio.h> 소스 코드에서 #include 문을 제거하고 stdio.h 파일 내용을 소스 프로그램에 포함
      1. 매크로 확장
      • #define PI 3.14 컴파일이 시작되기 전에 전처리기가 프로그램 전체에서 PI 변수를 3.14로 변환
      1. 조건부 컴파일
      • #if..., #ifdef..., #ifndef..., #error 특별한 전처리 지시어를 사용하여 다양한 조건에 따라 프로그램의 일부 포함 혹은 제외 가능
      1. 라인 컨트롤
      • #line 프로그램을 사용하여 소스 파일을 중간 파일로 결합하거나 재배열한 다음 컴파일 하는 경우, 각 소스 라인이 어디서 왔는지 컴파일러에 알릴 수 있음

    x86_64 의미

    • x86 : CPU 종류 -> intel CPU
    • 64 : 64비트

    signed & unsigned

    • signed
      • %d를 이용해서 출력
      • 정수형 변수 중 부호를 갖는 변수를 선언
      • signed int 범위 : –2,147,483,648 ~ 2,147,483,647
      • signed char 범위 : -128 ~ 127
    • unsigned
      • %u를 이용해서 출력
      • 부호 비트를 제거해 저장 가능한 양수 범위를 두배로 늘림
      • 음수를 사용하지 않겠다는 의미로 부호 비트가 필요없음
      • unsigned int 범위 : 0 ~ 4,294,967,295
      • unsigned char 범위 : 0 ~ 255

    Count number of 1 (binary)

    #include <stdio.h>
    
    int count_one(int in_a)
    {
            int i, count = 0;
            for(i = 31; i>=0; i--)
            {
                    if((in_a>>i) & 1)
                            count++;
                    // count += (in_a>>i)&1; 위의 if문 대체 가능
            }
            return count;
    }
    
    int main()
    {
            int i;
            unsigned int in_a;
            fscanf(stdin, "%u", &in_a);
            fprintf(stdout, "%u \t: ", in_a);
            for(i=31; i>=0; i--)
            {
                    fprintf(stdout, "%d", ((in_a>>i) & 1));
                    if(i % 4==0)
                    {
                            fprintf(stdout, " ");
                    }
            }
            fprintf(stdout,": %d \n", count_one(in_a));
    }

    이전 Lecture 05에 있는 binary code 참고 count_one 함수에 입력받은 in_a를 전달하여 2진수 형태로 바꾸고 count += (in_a>>i)&1 연산을 통해 1의 개수를 구한 후 return

    int count_one(int in_a)
    {
            int i=32, count = 0;
            while (i>0)
            {    
                count += (in_a>>i) & 1;
                i--;
            } 
            return count;
    }

    코드 실행을 빠르게 하기 위해 위와 같이 코드 수정 가능 if문은 실행이 오래 걸림

    C Operator Precedence

    c_operator

    The basic memory model in C

    • Automatic(동적변수)
      • 처음 사용할 때 변수 선언
      • 범위를 벗어날 때 제거됨
    • Static(정적변수)
      • 프로그램이 실행되는 동안 같은 장소에 존재
      • 배열 크기는 고정되지만, 값은 변경 가능
      • 주 작업이 시작되기 전 데이터가 초기화되므로 상수를 사용하여 초기화해야 함
      • 정적 키워드를 사용하여 함수 외부에 선언된 변수 및 내부 함수는 정적임
      • 정적 변수를 초기화하지 않으면 0(또는 Null)으로 초기화
    • Manual
      • 타입의 종류는 malloc과 free
      • 선언 후 배열 크기를 조정할 수 있는 유일한 메모리 유형

    Question

    • double (*f[10])(int const *a, double (*g[10])(double h));
    • 함수 명이 f인 함수 선언
    • 함수는 double을 return
    • 함수 f는 크기가 10인 포인터의 array
    • 첫번째 매개변수는 int const 형태의 포인터 a
    • 두번째 매개변수
      • 함수 명이 g이며 크기가 10인 포인터의 array
      • double을 return
      • double을 리턴하는 상수 h를 매개변수로 가짐

    Static

    int static_check(int a)
    {
        int static numCalls = 0;
        fprintf(stderr, "Call : %d\n", numCalls);
        numCalls++;
    }
    
    int main()
    {
        int num;
        fscanf(stdin, "%d", &num);
        static_check(num);
        static_check(num);
        static_check(num);
        static_check(num);
        static_check(num);
    }
    • static으로 선언된 변수는 main 함수의 시스템이 끝까지 돌아갈 때까지 초기화되지 않음
    • 따라서 위 코드의 출력 값은
    Call : 0
    Call : 1
    Call : 2
    Call : 3
    Call : 4

    그러나 static이 아닌 int형으로 선언하면 static_check함수가 선언될 때마다 numCalls 변수가 0으로 초기화 됨

    int static_check(int a)
    {
        int numCalls = 0;
        fprintf(stderr, "Call : %d\n", numCalls);
        numCalls++;
    }
    
    int main()
    {
        int num;
        fscanf(stdin, "%d", &num);
        static_check(num);
        static_check(num);
        static_check(num);
        static_check(num);
        static_check(num);
    }
    • 위 코드의 출력 값은
    Call : 0
    Call : 0
    Call : 0
    Call : 0
    Call : 0
    • int static numCalls; 위 코드와 같이 초기화하고자 하는 값을 입력하지 않으면 static의 경우 자동으로 0으로 초기화됨 0으로 초기화되는 것을 원하지 않는 경우 int static numCalls = 100과 같이 초기화함

    • automatic variable의 경우 초기화 없이 값을 출력하는 명령을 실행할 경우 랜덤 값이 출력됨

    const & define

    • const
      • 메모리가 할당됨
      • 주소를 직접 건드리면 const의 값 또한 변경 가능
      • 상수화가 되어 read only로 변환 -> 주로 라이브러리에서 사용
      • 타입을 함께 선언하여 #define에 비해 표현 범위와 구조에 대해 명확함
    • define
      • 컴파일 전처리단계에서 글자를 치환해주는 방식

    Lecture 06 [2022.01.12]

    Linux Command

    1. clear

      • 터미널 내용 지우기
    2. alias

      • 자주 사용하는 긴 명령어 조합을 간단하게 등록해놓을 수 있는 명령어
      • alias 별칭='명령어'
      • 별칭을 삭제하기 위해서는 unalias 명령을 이용
      • alias -p를 통해 등록된 단축어 확인 가능
      • unalias -a는 모든 alias 설정을 삭제
      • 설정된 alias를 사용하고 싶지 않은 경우 명령어 앞에 \를 붙여서 사용
      • logout된 상태에서도 alias 단축어를 사용하고 싶은 경우
    3. h

      • alias로 지정된 history의 단축어
    4. !$

      • 가장 최근 명령의 마지막 파라미터를 쓰고 싶은 경우 사용
    5. kill

      • 다른 터미널에 떠있는 프로세스를 kill하는 명령어
      • 터미널의 프로세스를 확인하는 명령어는 ps
    6. cc && a.out

      • 컴파일 후 문제가 없을 경우 a.out을 실행
    7. cc ; a.out

      • 컴파일 후 a.out을 실행
      • 이때 컴파일 에러가 발생하면 가장 최근에 컴파일 성공한 a.out의 결과를 출력
    8. cc || echo "Error"

      • 컴파일 에러가 날 경우 echo의 결과를 출력

    vi Command

    1. o

      • 현재 위치 다음 줄에 insert 모드로 문구를 삽입하고 싶은 경우
    2. O

      • 현재 위치 윗 줄에 insert 모드로 문구를 삽입하고 싶은 경우

    Pointer Basic

    • operation
      • &val - Address of val (val의 주소)
        • a & b - bitwise and (& 연산) // 헷갈리지않기
        • %lld로 받음
      • *ptr - Value in address val (val의 주소의 값)
    • increment
      • int *a; // 64 bits 컴퓨터에서 일반적으로 4 bites
      • long long *b // 64 bits 컴퓨터에서 일반적으로 8 bites
      • void *c // 64 bits 컴퓨터에서 일반적으로 1 bites
        • 기본적으로 char *c와 똑같음

    operation code

    #include <stdio.h>
    
    int main()
    {
        int a = 100;
        int b = 200;
    
        fprintf(stdout, "%d : %d\n", a, &a);
        fprintf(stdout, "%d : %d\n", b, &b);
    }

    코드를 실행하면 &a와 &b의 값 차이가 4인 것을 확인할 수 있음 -> 랜덤으로 출력되는 값이 아니라는 의미 음수로 출력되는 경우 = 값을 출력하는 과정에서 오버플로우가 생김 -> %lld를 통해 출력함

    64비트 컴퓨터~~에서 64비트의 의미

    • 한번에 처리 가능한 데이터의 크기
    • Address line의 크기

    code

    #include <stdio.h>
    
    void add(int *a, int *b, int *c)
    {
            *c = *a + *b;
    }
    
    int main()
    {
            const int a = 100;
            int b = 200;
            const int c = 999;
    
            fprintf(stdout, "%d : %lld\n", a, &a);
            fprintf(stdout, "%d : %lld\n", b, &b);
            add(&a,&b,&c); //1
            c = a+b; //2
    
            fprintf(stdout, "%d : %lld\n", c, &c);
            int d=999;
            fprintf(stdout, "%d :%lld  %lld\n", d, ((void *)(&d))+1, &d+1);
    }
    • c가 const int로 선언되어 있기 때문에 1의 방법으로 c의 값을 수정할 수 있음
    • 방법 1 : 새로운 함수 add를 선언하여 매개변수로 a, b, c의 주소를 넣고 그 값을 계산하여 c를 수정
    • 방법 2 : main 함수 내부에서 a와 b를 더해 c를 수정 -> 오류가 생김
    • 기존 int 자료형이었던 d의 주소값을 void로 선언함으로써 메모리 크기를 4에서 1로 바꿈
    • &d+1의 경우 기존 int형으로 선언된 경우에는 4가 증가하지만 void형에서는 1이 증가
    • 컴파일 후 실행할 때마다 주소 값 바뀜

    int an_array[ ] vs int *a_pointer

    • int an_array[32];
      • 4 bytes 메모리 32개 존재
      • Program will do;
      • set aside a space on the stack big enough for 32 integers, and
      • declare that an_array is a pointer, and
      • bind that pointer to point to the newly allocated space.
    • int *a_pointer
      • Just pointer;
      • a_pointer = malloc(32*4);

    array pointer code

    #include <stdio.h>
    
    int sumArray3(int a[3], int sum)
    {
            sum = *a;
            a++;
            sum += *a;
            a++;
            sum += *a;
            fprintf(stdout, "%d : %lld %llx\n", sum, &sum, &sum);
            return a[3];
    }
    
    int main()
    {
            int a = 100;
            int b = 200;
            int c = 999;
            int arr[4] = {100,200,300,400};
            int *parr;
            parr = arr;
            parr++;
            fprintf(stdout, "%d : %lld %lld\n", *parr, parr, arr);
            c = sumArray3(arr, b);
            fprintf(stdout, "%d : %lld %llx\n", b, &b, &b);
    
            fprintf(stdout, "%d : %lld %llx\n", *arr, *arr, *arr);
            fprintf(stdout, "%d : %lld %llx\n", &arr, &arr, &arr);
            fprintf(stdout, "%d : %lld %llx\n", arr[2], &arr[2], &arr[2]);
            fprintf(stdout, "%d : %lld %llx\n", arr[3], &arr[3], &arr[3]);
            fprintf(stdout, "%d : %lld %llx\n", arr[4], &arr[4], &arr[4]);
            fprintf(stdout, "%d : %lld %llx\n", arr[4000], &arr[4000], &arr[4000]);
    
    }
    • arr 배열을 선언하여 출력
    • arr과 &arr을 %lld로 출력하면 같은 값을 가지며 arr, arr[2], arr[4]가 각각 8씩 차이나는 것을 보아 arr은 arr[0]을 의미
    • 배열 역시 int로 선언되는 경우 메모리 값이 4씩 차이남
    • 배열의 크기가 4(0~3)임에도 arr[4]의 메모리 값이 출력됨
    • 배열 arr을 const로 선언하여 arr++; 과 같이 직접적으로 arr의 값을 바꾸려고 하면 에러 발생
    • 따라서 int *parr;과 같이 포인터를 따로 선언하여 사용해야 함
    • arr[4000]에 대한 값을 출력하려고 하면 에러가 발생함
      • 배정된 메모리 용량을 넘어서는 범위이기 때문

    Pointer / Address

    • int const A constant integer
    • int const * A (variable) pointer to a constant integer
    • int * const A constant pointer to a (variable) integer
    • int * const * A pointer to a constant pointer to an integer
    • int const * * A pointer to a pointer to a constant integer
    • int const * const * A pointer to a constant pointer to a constant integer

    Call by Address(Reference) vs Call by Value

    #include <stdio.h>
    
    void addPointer(int *a, int *b, int *c) // Call by Address
    {
            *c =  *a + *b;
            fprintf(stdout, "In addPointer A %d : %lld %llx\n", *a, a, a);
            fprintf(stdout, "In addPointer B %d : %lld %llx\n", *b, b, b);
            fprintf(stdout, "In addPointer C %d : %lld %llx\n", *c, c, c);
            *a = -100;
            *b = -200;
    }
    
    int addValue(int a, int b, int c) // Call by Value
    {
            c =  a + b;
            fprintf(stdout, "In addValue A %d : %lld %llx\n", a, &a, &a);
            fprintf(stdout, "In addValue B %d : %lld %llx\n", b, &b, &b);
            fprintf(stdout, "In addValue C %d : %lld %llx\n", c, &c, &c);
            a = 999; b=888;
            return c;
    }
    
    int main()
    {
            int a = 100;
            int b = 200;
            int c = 999;
    
            fprintf(stdout, "%d : %lld %llx\n", a, &a, &a);
            fprintf(stdout, "%d : %lld %llx\n", b, &b, &b);
            addPointer(&a,&b,&c);
            fprintf(stdout, "%d : %lld %llx\n", c, &c, &c);
            // a = 200; b = 300;
            c = addValue(a,b,c);
            fprintf(stdout, "%d : %lld %llx\n", a, &a, &a);
            fprintf(stdout, "%d : %lld %llx\n", b, &b, &b);
            fprintf(stdout, "%d : %lld %llx\n", c, &c, &c);
    }

    실행 결과

    100 : 140732089039420 7ffebe2cfa3c
    200 : 140732089039424 7ffebe2cfa40
    In addPointer A 100 : 140732089039420 7ffebe2cfa3c
    In addPointer B 200 : 140732089039424 7ffebe2cfa40
    In addPointer C 300 : 140732089039428 7ffebe2cfa44
    300 : 140732089039428 7ffebe2cfa44
    In addValue A -100 : 140732089039388 7ffebe2cfa1c
    In addValue B -200 : 140732089039384 7ffebe2cfa18
    In addValue C -300 : 140732089039380 7ffebe2cfa14
    -100 : 140732089039420 7ffebe2cfa3c
    -200 : 140732089039424 7ffebe2cfa40
    -300 : 140732089039428 7ffebe2cfa44
    • main 함수에서 변수 a, b, c에 대한 메모리가 할당됨
    • 메모리 주소는
      • a : 140732089039420
      • b : 140732089039424
      • c : 140732089039428
    • addPointer(&a,&b,&c);
      • addPointer 함수에 a, b, c의 메모리 주소값을 매개변수로 넣고 실행
      • Call by Address 형태의 함수에서는 main 함수의 메모리에 대해 수정 가능 -> a, b값이 -100, -200으로 바뀜
      • 여전히 c는 300
    • c = addValue(a,b,c);
      • addValue 함수에 위에서 바뀐 값 a = -100, b = -200을 넣고 실행
      • Call by Value 형태의 함수에서 수정된 값은 main 함수의 메모리에 저장되지 않음
      • 함수 내부에서 a, b, c의 메모리 주소를 출력하면
        • a : 140732089039388
        • b : 140732089039384
        • c : 140732089039380
      • 연산 후 c = -300
      • 함수를 int형으로 선언하고 return c; 를 통해 c 값(-300)을 메인 함수로 리턴하여 c = addValue(a,b,c); 에서 메인함수의 변수 c에 값을 저장

    Lecture 07 [2022.01.13]

    Linux Command

    1. cp (복사하고자 하는 파일의 경로) (바꿀 파일의 이름)

      • 파일을 복사할 때 파일의 이름을 바꿔서 복사할 수 있음
    2. od

      • 바이너리 파일을 8진수로 dump하는 명령어
      • 바이너리 파일의 내용을 읽을 수 있음
      • od -x : 16진수로 dump
      • 가장 왼쪽에 출력되는 7자리 수는 주소를 나타냄
    3. gcc(GNU Compiler Collection)

      • -o : 실행 파일 이름 바꾸기
      • -c : .o 파일 생성 (assembly)
      • -E : .c 파일 생성
      • -O : 최적화
      • -S : 전처리된 파일을 어셈블리 파일로 컴파일하고 멈춤 (.s 파일 생성)
      • --32, --64 : 32비트 컴파일(64비트 컴퓨터에서도 컴파일 가능), 64비트 컴파일
      • -Dmacro : #define 가능

    Noun-Adjective Form

    • 코드는 위의 Pointer / Address 참고
    • 수식하고자 하는 문자-수식어 순으로 작성함
    const int a = 100;
    int *p = &a;
    fprintf(stdout, "a : %d\n", a); // 100
    *p = 200;
    fprintf(stdout, "a : %d\n", a); // 200

    코드를 실행하면 a를 const로 선언했음에도 불구하고 a의 값이 변경가능하다는 것을 확인할 수 있음 그럼에도 불구하고 const로 선언하는 이유는

    • 에러가 생기게 함으로써 경고

    함수의 포인터

    • void fp();
      • void : 리턴하는 값을 알려줌

    fnpointer 코드

    #include <stdio.h>
    #define FN_ADD 0
    #define FN_SUB 1
    #define FN_MUL 2
    #define FN_DIV 3
    #define FN_ERR 4
    
    void add(int *a, int *b, int *c)
    { *c = *a + *b; }
    
    void sub(int *a, int *b, int *c)
    { *c = *a - *b; }
    
    void mul(int *a, int *b, int *c)
    { *c = (*a) * (*b); }
    
    void div(int *a, int *b, int *c)
    { *c = (*a) / (*b); }
    
    int main()
    {
            int a, b, c;
            char ch;
            int op = FN_ERR; // default is err
    
            scanf("%d %c %d", &a, &ch, &b);
    
            void (*fp[4])(int *, int *, int *) = {add, sub, mul, div};
            switch (ch)
            {
                    case '+':
                            op = FN_ADD;
                            break;
                    case '-':
                            op = FN_SUB;
                            break;
                    case '*':
                            op = FN_MUL;
                            break;
                    case '/':
                            op = FN_DIV;
                            break;
                    default :
                            op = FN_ERR;
                            break;
            }
    
            fp[op](&a,&b,&c);
            if(op == 4){
                    fprintf(stdout, "wrong input\n");
                    return 0;
            }
            fprintf(stdout, "%d \n", c);
    }

    수정 코드 설명

    • '#define'을 지정하여 실수를 줄임
    • 잘못된 부호를 입력한 경우 -> wrong input 출력

    C Compile and Executive

    compile

    • preprocessor 명령이 가장 먼저 실행

      • c언어에서는 주로 #으로 시작
    • user의 소스코드 컴파일

      • preprocessor 명령이 실행된 상태
      • assembly를 생성
      • 프로그래밍 언어를 기계어로 바꾸는 과정
        • Interpreter : 한 줄씩 컴파일 (대표적으로 파이썬)
        • Compiler : 소스코드를 한 번에 컴파일 (대표적으로 C언어)
    • Link

      • scanf와 printf를 연결하는 등의 과정
      • linking 이후에 generate executable code를 만듦
      • dynamic link와 static link로 구분
    • Loader

      • a.out 실행파일을 실행할때 loading이 일어남
    • 이러한 단계를 확인하는 명령어 : gcc

    #define vs const

    • #define
      • preprocessor
    • const
      • 표현 범위와 구조에 대해 명확하게 표현
      • 메모리 할당 -> 주소로 접근하면 const 값 변경 가능

    조건부 컴파일

    • 정해진 조건에 따라 소스 코드의 컴파일 여부를 제어하는 전처리기

    • #define으로 매크로의 이름을 정의

    • 'DATE',' TIME', 'FILE', 'LINE'는 컴파일러에서 제공하는 매크로

      • 'DATE': 컴파일한 날짜(실행 시점의 현재 날짜가 아님)
      • 'TIME': 컴파일한 시간(실행 시점의 현재 시간이 아님)
      • 'FILE': 'FILE' 매크로가 사용된 헤더, 소스 파일
      • 'LINE': 'LINE' 매크로가 사용된 줄 번호
    • #ifdef와 #endif 지시자를 사용하여 정의

    #ifdef 매크로 // 매크로가 정의되어 있다면 #ifdef, #endif 사이의 코드를 컴파일
    코드
    #endif
    • #ifndef와 #endif 지시자를 사용하여 정의
    #ifndef 매크로 // 매크로가 정의되어 있지 않다면 #ifndef, #endif 사이의 코드를 컴파일
    코드
    #endif
    #include <stdio.h>
    #define DEBUG
    
    int main() {
    #ifdef DEBUG // #ifdef는 위에서 매크로가 선언된 경우 내부 코드가 실행됨
            printf("Debug : %s \t %s \t %s \t %d \n", __DATE__, __TIME__, __FILE__, __LINE__);
    #endif
    
            char name[] = "Nayoung";
            int age = 21;
    
    #ifndef INTRO // #ifndef는 위에서 매크로가 선언되지 않은 경우 내부 코드를 실행함
            printf("Name : %s \t Age : %d \n", name, age);
    #endif
            return 0;
    }

    코드에 #define INTRO를 추가하면 #ifndef 내부 코드는 실행되지 않음

    • 값 또는 식 판별 후 조건부 컴파일
    #if 값 또는 식
    코드
    #endif
    #include <stdio.h>
    #define DEBUG_LEVEL 2
    
    int main()
    {
    #if DEBUG_LEVEL >= 2 // DEBUG_LEVEL이 2보다 크거나 같으면 #if, #endif 사이의 코드를 컴파일
            printf("Debug Level 2 \n");
    #endif
    
    #if 1 // 조건이 항상 참이므로 내부 코드 컴파일
        printf("It is 1 \n");
    #endif
    
    #if 0 // 조건이 항상 거짓이므로 내부 코드 컴파일하지 않음
        printf("It is 0 \n");
    #endif
    
            return 0;
    }
    • defined
    #if (defined DEBUG || defined TEST) && !defined (VERSION_10)
    // DEBUG 또는 TEST가 정의되어 있으면서 VERSION_10이 정의되어 있지 않을 때

    #include

    • 전처리기
    • 헤더 파일(.h)과 소스 파일(.c)를 포함
    #include <파일>
    #include "파일"
    • <>
      • C언어 표준 라이브러리의 헤더 파일을 포함할 때 사용
    • " "
      • 현재 소스 파일을 기준으로 헤더 파일을 포함
      • 헤더 파일을 찾지 못할 경우 컴파일 옵션에서 지정한 헤더 파일 경로를 따름

    extern

    • 다른 소스 파일의 전역 변수를 사용할 수 있음

    CPP - include file

    • #include file as text
      • #include <stdio.h> or "file.h"
    • gcc Option - I
      • Include location - ./usr/include/
      • Default include location
    • Prevent multiple include
      • #pragma once (로딩 한번만)
        #ifndef _MATH_ 
        #include <math.h>
        #endif

    Lecture 08 [2022.01.17]

    Linux Command

    1. ^(위 명령에서 잘못 입력한 문자)^ (바꿀 문자)
      • 위 명령에서 특정 문자를 잘못 입력한 경우 사용함

    .o file

    file

    GCC Optimization

    • -O0(기본값)
      • 최적화 수행 안 함
    • -O, -O1
      • 만들어지는 .o, .out 파일을 가능한 작게 하면서 컴파일 시간이 오래걸리지 않는 범위에서 최적화 수행
    • -O2
      • 만들어지는 코드가 가능한 빠르게 수행되지만 코드의 크기가 너무 커지지않는 범위에서 최적화 수행
    • -O3
      • 코드의 크기 신경 쓰지 않고 빠른 코드를 만들어내기 위한 최적화 수행
      • -O2 최적화에 인라인 함수와 레지스터에 대한 최적화 추가로 수행
      • -O2 코드보다 빠르다는 보장은 없음
      • 인라인 함수 (inline) inline
        • 호출 없이 함수의 코드를 그 자리에서 실행
        • 컴파일러는 함수를 사용하는 부분에 함수의 코드를 복제해서 넣어줌
        • 함수 호출 과정이 없어 속도가 비교적 빠름
            inline 반환값자료형 함수이름(매개변수자료형 매개변수이름)
            {
            }
            #include <stdio.h>
            inline int add(int a, int b)
            {
                return a+b;
            }
            int main()
            {
                int num1;
               /*
                num1 = inline int add(10, 20)
                {
                    return 10 + 20;
                }
                */
                // 주석 부분을 컴파일러가 함수를 복제해서 넣어줌!
                printf("%d", num1);
            }
    • -Os
      • -O2 최적화 기능 사용
      • 코드 크기를 증가시키는 최적화는 생략 gcco

    #error

    • #error 토큰 문자열
    • 컴파일 시간에 사용자 지정 오류 메시지를 내보낸 다음 컴파일을 종료
    • 프로그램 불일치나 제한된 내용에 접근하는 경우 개발자에게 고치도록 알림
    • 명확한 에러 설명 혹은 프로그램의 안전성을 위해 사용

    Token stringification (토큰 문자열화)

    #define str(s) #s
    str(p = "foo\n";) // outputs "p = \"foo\n\";"
    str(\n) // outputs "\n"
    
    #define xstr(s) str(s)
    #define str(s) #s
    #define foo 4
    str (foo) // outputs "foo"
    xstr (foo) // outputs "4" 
    • #define #s을 통해 문자열로 바꿔줌
      • 항상 #s일 필요는 없음 str(문자) 내부의 문자와 동일
    • 출력 형태를 다양하게 하는 매크로를 만들 때 유용 (%c, %d, %s 등)
    • 토큰
      • 프로그램을 구성하고 있는 문법적으로 의미 있는 최소 단위

    Token Concatenation (토큰 붙여넣기)

    #define DECLARE_STURCT_TYPE(name) typedef struct name##_s name##_t
    
    DECLARE_STRUCT_TYPE(g_object);
    // Outputs: typedef struct 
    g_object_s g_object_t;
    
    //다른 예제
    #include <stdio.h>
    #define paster( n ) printf( "token" #n " = %d", token##n )
    int token9 = 9;
    
    int main()
    {
       paster(9); // output : token9 = 9
    }

    Macro Definition (2)

    • Multiple lines
      • 여러 줄 define 하고 싶을 때
            #define NUMBERS 1, \
                            2, \ 
                            3
    
            int x[] = { NUMBERS }; 
            //int x[] = {1,2,3};
    • Define Where?
            foo = X;
            #define X 4
            bar = X; // foo = X and bar = 4
    
            #define TABLESIZE BUFSIZE
            #define BUFSIZE 1024
            // TABLESIZE == BUFSIZE ==1024
    
            #define BUFSIZE 1020
            #define TABLESIZE BUFSIZE
            #undef BUFSIZE
            #define BUFSIZE 37 // TABLESIZE = 37

    Macro Definition (3) - Function like Macro

    • if문 보다 성능이 좋음
        #define min (X, Y) ((X) < (Y) ? (X) : (Y))
        x = min(a,b); -> ((a) < (b) ? (a) : (b));
        y = min(1,2); -> ((1) < (2) ? (1) : (2));
        z = min(a + 28, *p) -> z = ((a+28) < (*p) ? (a+28) : (*p));

    Macro Definition (4) - Stringization and concat

    • Stringization
      • Parameter leading with #
            #define str(s) #s
            #define foo 4
            str(foo) // "foo"
    • Concatenation
            #define COMMAND(name) { #name, name##_command }
            COMMAND(quit) // { "quit", quit_command }

    Macro Definition (5) - Variadic

    • #define eprintf(...) fprintf (stedrr, VA_ARGS)
        eprintf ("%s:%d: ", input_file, lineno)
            -> fprintf (stderr, "%s:%d: ", input_file, lineno)
    
        #define eprintf(format, ...) fprintf (stderr, format __VA_OPT__(,) __VA_ARGS__)

    Lecture 09 [2022.01.18]

    Linux Command

    1. cc -g

      • gdb에게 제공하는 정보를 바이너리에 삽입
      • -g 옵션을 사용하지 않고 gdb로 디버깅하면 역어셈블리 코드에서 어셈블리 코드로만 디버깅 가능
    2. cc -pg

      • 프로파일을 위한 코드 삽입
      • -pg 옵션으로 컴파일 → gmon.out(프로파일 정보) → gprof로 gmon.out 파일 분석

    gdb Command

    • 실행파일과 소스파일이 같은 디렉토리에 있어야 제대로 동작
    1. gdb (실행파일)

      • 시작 명령
    2. run

      • 프로그램 실행
    3. break (line or *address)

      • 정지 명령
      • break n : n번째 라인에서 정지 (정지점 생성)
      • break Add : Add가 포함된 라인에서 정지 (정지점 생성)
    4. clear

      • 정지점 삭제
      • clear n : n번째 라인 정지점 삭제
    5. delete breakpoints

      • 정지점 모두 지움
    6. step

      • 현재 라인 수행 후 정지
      • 함수 호출 시 함수 안으로 들어감
      • step n : step 명령 n번 수행
    7. next

      • 현재 라인 수행 후 정지
      • 함수 호출 시 함수 다음 라인으로 넘어감
      • next n : next 명령 n번 실행
    8. print

      • 주소나 변수 등을 출력
    9. list

      • 소스 파일 내용 출력
      • list a, b : a ~ b번째 라인의 소스 출력
    10. continue

      • 다음 정지점까지 코드 실행
    11. watch

      • 해당 변수에 watchpoint를 설정하여 변수가 바뀔 때마다 현재 값을 출력함
    12. info reg

      • 특정 레지스터의 정보 출력
    13. set

      • 특정 메모리 혹은 레지스터에 값을 지정
    14. finish

      • 현재 함수를 수행하고 빠져나감
    15. Quit (q)

      • 종료 명령

    CPU

    • ALU (Arithmetic / Logic Unit)
    • CU (Control Unit)

    고정소수점 관련 코드

    • 부동소수점 대신 고정소수점을 사용하는 이유

      • 부동소수점은 컴퓨터에 따라 연산에 많은 에너지를 필요로 함
    • S32_31 => signed long long

    • S16_15 => signed int

    • S8_7 => signed short

    • S4_3 => signed character

    #include <stdio.h>
    // #### #### #### #### . #### #### #### ####
    // S 15 . 16
    #define FX_Q_NUM 16
    #define FX_2_MINUS_16 1.52587890625e-05F
    #define FX_2_PLUS_16 (1<<16)
    #define FX_S_15_16 11516
    #define FX_SYSTEM FX_S_15_16
    
    typedef int fixed32;
    
    fixed32 fromFloat(float fa)
    {
            return (fixed32) (fa * FX_2_PLUS_16);
    }
    
    float toFloat(fixed32 xa)
    {
            return ((float) (xa)) * FX_2_MINUS_16;
    }
    
    fixed32 fxAdd(fixed32 a, fixed32 b)
    {
            return fromFloat(toFloat(a)+toFloat(b));
    }
    
    
    fixed32 fxAdd2(fixed32 a, fixed32 b)
    {
            return a+b;
    }
    
    int main()
    {
            int i = 0;
            int ia, ib, ic, ic2;
            float fa;
            fscanf(stdin, "%d %d", &ia, &ib);
            for (i = 0; i < 64*256*256*256; i+=(256*256)){
                    ic = fxAdd(i, i);
                    ic2 = fxAdd2(i, i);
                    fprintf(stdout, "%f + %f : %f, %f diff = %d \n", toFloat(i), toFloat(i), toFloat(ic), toFloat(ic2), ic-ic2);
            }
    
            fprintf(stdout, "%d + %d : %d \n", ia, ib, ic);
    }

    Lecture 10 [2022.01.19]

    Linux Command

    1. ulimit
      • 프로세스의 자원 한도를 설정하는 명령
      • Soft : 새로운 프로그램을 생성하면 기본으로 적용되는 한도
      • hard : 소프트한도에서 최대로 늘릴 수 있는 한도
      • 옵션
        • -a : 모든 제한 사항을 보여줌
        • -c : 최대 코어 파일 사이즈 설정
        • -d : 프로세스 데이터 세그먼트의 최대 크기
        • -f : shell에 의해 만들어질 수 있는 파일의 최대 크기
        • -s : 최대 스택 크기
        • -p : 파이프 크기
        • -n : 오픈 파일의 최대수
        • -u : 오픈파일의 최대수
        • -v : 최대 가상메모리의 양
        • -S : soft 한도
        • -H : hard 한도

    숫자의 표현

    float1

    숫자의 표현 - 2's complement

    float2

    숫자의 표현 float (IEEE 754)

    • float

      • sign 1 bit, exp 8 bits (bias = 127), mantissa or fraction 23 bits float
      • 의미하는 값은 (sign, exponent, fraction을 정수라고 하면)
        • (sign * -2 + 1) * (1.0 + fraction * 2^(-23)) * 2^(exp-127)
    • Others

      • half - sign 1, exp 5, fraction 11
      • double - sign 1, exp 11, fraction 53
      • quadruple - sign 1, exp 15, fraction 113

    숫자의 표현 - fixed FX_S03_04 (Q = 4)

    float3

    • floating point에 비해서 정밀도가 떨어짐

    사칙연산

    • 덧셈 / 뺄셈

      • v = v_a + v_b = iv_a2^(-q) + iv_b2^(-q) = (iv_a + iv_b)*2^(-q)
      • iv = iv_a + iv_b
    • 곱셈

      • v = v_a * v_b = iv_a2^(-q) * iv_b2^(-q) = (iv_a * iv_b)*2^(-2q)
      • iv = iv_a * iv_b * 2^(-q) = v * 2^(q)
    • 나눗셈

      • v = v_a / v_b = iv_a2^(-q) / iv_b2^(-q) = (iv_a / iv_b)
      • iv = iv_a / iv_b * 2^(-q)
      • iv = iv_a * 2^(-q) / iv_b

    Project S17.14

    • s : 부호 비트 -> signed

    • 17 : 소수점 위 비트 수

    • 14 : 소수점 아래 비트수

    • 실제 구현은 int 혹은 long long을 사용하여 구현

    • 실제 값은 val / 2^14

    • 예 :

    typedef int fx_s17_14;
    typedef fx_s17_14 fixed;
    • #define FX_S17_14 ((1<<16)|(17<<8)|(14)) //69902

    How to compile for 32bits in 64bits

    • 64 bits compile
      • gcc -pg test.c -m64
    • 32 bits compile
      • gcc -pg test.c -m32

    What makes different performance

    • Golden Rule

      • Speed - CPU > Memory > Storage > IO > Human
      • Register > Cache(1st, 2nd) > Memory > ...
      • Locality
      • Pipeline
        • 구성요소
        1. 빌드(Build) - 애플리케이션을 컴파일하는 단계
        2. 테스트(Test) - 코드를 테스트하는 단계
        3. 릴리스(Release) - 애플리케이션을 리포지토리에 제공하는 단계
        4. 배포(Deploy) - 코드를 프로덕션에 배포하는 단계
        5. 검증 및 컴플라이언스(Validation & compliance)
          • 빌드 검증 단계는 해당 조직의 필요에 따라 결정
          • Clair와 같은 이미지 보안 스캔 툴을 사용하여 알려진 취약점(CVE)과 비교하는 방법으로 이미지의 품질을 보장
        • pipelining
          • 한 functional unit을 사용하는 동안 다른 unit은 일하지 않음
          • unit이 명령어를 처리하는 동안 다음 명령어를 받아와서 처리하는 방식
          • 명령어 하나를 처리하는데 걸리는 시간은 그대로지만 throughput(유닛이 일정한 시간에 처리하는 일의 양)을 늘려 더 빨라보이게 만듦 + 실제로 빨라짐
      • Error
    • FLOP(Floating Point Operation)

      • 컴퓨터의 성능을 수치로 나타낼 때 주로 사용되는 단위
      • 초당 부동소수점 연산이라는 의미로 컴퓨터가 1초동안 수행할 수 있는 부동소수점 연산의 횟수가 기준
      • 연산식은 FLOPS = cores x clock x (FLOPS/cycle)

    ARM 9 - CPI

    arm9

    ARM Compile (optimization)

    lec10-8

    • 숫자가 높아질수록 세부적인 최적화
    • 최적화 후 코드가 변경되기 때문에 디버깅 불가

    gprof - GNU Profiling

    • gprof - display call graph profile data
    • Compile with -pg option
      • cc -pg -Wall test.c
    • Execute program and generate gmon.out file
      • a.out
    • Execute gprof
      • gprof a.out gmon.out
    • gprof1
      • 첫번째 열을 보면 총 걸린 시간의 % 확인 가능
      • self를 통해 함수 안에서 발생한 연산 시간 확인 가능
      • gprof할 때 충분한 call이 필요하고 함수 호출은 굉장히 비쌈
      • 10~20%의 오차가 항상 발생

    Lecture 11 [2022.01.20]

    rgba.c 코드

    #include <stdio.h>
    
    typedef unsigned int t_rgba;
    
    // input value must be 0~255
    
    /*
    방법 1. 함수 만들기
    unsigned int fromRGBA(int r, int g, int b, int a)
    {
    
            if (r > 255 || r < 0)
                    r = 0;
            if (g > 255 || g < 0)
                    g = 0;
            if (b > 255 || b < 0)
                    b = 0;
            if (a > 255 || a < 0)
                    a = 0;
            if문 성능 나빠짐
    
    
            // return r*256*256*256 + g*256*256 + b*256 + a*1;
            // return ((r<<24)+(g<<16)+(b<<8)+a);
            // return ((r<<(24+g))<<(16+b))<<(8+1);
            // return (r<<24|g<<16|b<<8|a);
            return ((r&0xff)<<24)|((g&0xff)<<16)|((b&0xff)<<8)|(a&0xff);
    }
    */
    
    // 방법 2. macro
    #define fromRGBA(r,g,b,a) ((((r)&0xff)<<24)|(((g)&0xff)<<16)|(((b)&0xff)<<8)|((a)&0xff))
    #define F_NUM_1_255       (1.0f/255.0f)
    
    t_rgba mul_float(t_rgba c1, t_rgba c2){
            float r1, g1, b1, a1;
            float r2, g2, b2, a2;
            int   ir, ig, ib, ia;
    
            r1 = (float) ((c1 >> 24) & 0xff) * F_NUM_1_255;
            g1 = (float) ((c1 >> 16) & 0xff) * F_NUM_1_255;
            b1 = (float) ((c1 >>  8) & 0xff) * F_NUM_1_255;
            a1 = (float) ((c1 >>  0) & 0xff) * F_NUM_1_255;
    
            r2 = (float) ((c2 >> 24) & 0xff) * F_NUM_1_255;
            g2 = (float) ((c2 >> 16) & 0xff) * F_NUM_1_255;
            b2 = (float) ((c2 >>  8) & 0xff) * F_NUM_1_255;
            a2 = (float) ((c2 >>  0) & 0xff) * F_NUM_1_255;
    
            ir = (int) ((r1 * r2) * 255.0f);
            ig = (int) ((g1 * g2) * 255.0f);
            ib = (int) ((b1 * b2) * 255.0f);
            ia = (int) ((a1 * a2) * 255.0f);
    
            return fromRGBA(ir, ig, ib, ia);
    }
    
    t_rgba mul_int(t_rgba c1, t_rgba c2)
    {
            unsigned int r1, g1, b1, a1;
            unsigned int r2, g2, b2, a2;
            unsigned int  r,  g,  b,  a;
    
            r1 =  c1 >> 24         ; r2 =  c2 >> 24        ;
            g1 = (c1 >> 16) & 0xff ; g2 = (c2 >> 16) & 0xff;
            b1 = (c1 >> 16) & 0xff ; b2 = (c2 >>  8) & 0xff;
            a1 =  c1        & 0xff ; a2 =  c2        & 0xff;
    
            r= (r1 * r2) / 255;
            g= (g1 * g2) / 255;
            b= (b1 * b2) / 255;
            a= (a1 * a2) / 255;
    
            return fromRGBA(r,g,b,a);
    
    }
    
    int main()
    {
            int red, green, blue, alpha;
            t_rgba rgba_1, rgba_2, rgba_3;
            // input value must be 0~255 : 0.0~1.0
            // rgba_1 [rrrrrrrr][gggggggg][bbbbbbbb][aaaaaaaa]
            printf("input 4 values with 0~255 : ");
            scanf("%d %d %d %d", &red, &green, &blue, &alpha);
            rgba_1 = fromRGBA(red, green, blue, alpha);
            printf("%d %d %d %d : %u 0x%08x\n", red, green, blue, alpha, rgba_1, rgba_1);
            rgba_2 = mul_float(rgba_1, rgba_1);
            printf("%d %d %d %d : %u 0x%08x\n", red, green, blue, alpha, rgba_2, rgba_2);
            rgba_3 = mul_int(rgba_1, rgba_1);
            printf("%d %d %d %d : %u 0x%08x\n", red, green, blue, alpha, rgba_3, rgba_3);
    }

    출력 결과

    input 4 values with 0~255 : 127 127 127 127
    127 127 127 127 : 2139062143 0x7f7f7f7f
    127 127 127 127 : 1061109567 0x3f3f3f3f
    127 127 127 127 : 1061109567 0x3f3f3f3f

    Lecture 12 [2022.01.24]

    Final Project (fx_s17.14)

    • fx_head.h
    #pragma once
    
    #define FX_S17_14       ((1<<16) | (17<<8) | (14))
    
    // Operation Preference
    #define FX_OP_FLOAT             1
    #define FX_OP_PRECISION         2
    #define FX_OP_FAIR              3
    #define FX_OP_PERFORMANCE       4
    • fx_s17_14.h
    #include "fx_head.h"
    #include <math.h>
    
    #define FX_POINT                FX_S17_14
    
    #define FX_Q_NUM                (FX_POINT & 0xFF)               // 14
    
    // If you want calculate with high precision set 64
    #define FX_SYSTEM_INTEGER       64                              // 32 or 64
    #define FX_SYSTEM_FLOAT         64                              // 32 or 64
    
    #define FX_DATA_TYPE            signed int
    
    
    typedef int fx_s17_14;
    typedef fx_s17_14 fixed;
    
    #define  fromDouble(d)          ((fixed)((d)*DOUBLE_Q_VALUE))
    #define  toDouble(d)            ((double)(d)*DOUBLE_1_Q_VALUE)
    #define  fromFloat(d)           ((fixed)((d)*FLOAT_Q_VALUE))
    #define  toFloat(d)             ((float)(d)*FLOAT_1_Q_VALUE)
    
    // CONSTANTS
    #define  FLOAT_Q_VALUE          (float)(1<<FX_Q_NUM)
    #define  DOUBLE_Q_VALUE         (double)(1<<FX_Q_NUM)
    #define  FLOAT_1_Q_VALUE        (float)(1.0f/FLOAT_Q_VALUE)
    #define  DOUBLE_1_Q_VALUE       (double)(1.0f/DOUBLE_Q_VALUE)
    #define  FX_PI                  fromDOUBLE(M_PI)
    
    // One of FX_OP_FLOAT, FX_OP_PRECISION, FX_OP_FAIR, FX_OP_PERFORMANCE
    #define FX_OP_PREFERENCE        FX_OP_FLOAT
    
    extern fixed fxAdd_float(), fxAdd_precision(), fxAdd_fair(), fxAdd_performance();
    extern fixed fxSub_float(), fxSub_precision(), fxSub_fair(), fxSub_performance();
    extern fixed fxMul_float(), fxMul_precision(), fxMul_fair(), fxMul_performance();
    extern fixed fxDiv_float(), fxDiv_precision(), fxDiv_fair(), fxDiv_performance();
    • project_main.c
    #include "fx_s17_14.h"
    #include <stdio.h>
    
    
    int main()
    {
    
            printf("%f : %d\n",1.0, fromDouble(1.0));
            printf("%f : %f\n",1.3*0.3, toFloat(fxMul_float(fromDouble(1.3),fromDouble(0.3)))) ;
    
    }
    • cc project_main.c fx_s17_14.c 실행 결과 1.000000 : 16384 0.390000 : 0.389954

    Make (GNU make)

    • Lots of source files: foo1.h, foo2.h, foobar1.cpp ...
    • How to manage them allocated
    • Compiling is not easy
      • different target system
      • different purpose of compiling - debug, release, preprocessor ...
      • compile what we need to
      • dependency
    • Solution is
      • make

    Understanding MAKE

    • 파일 간의 종속관계를 파악하여 Makefile에 적힌 대로 컴파일러에 명령하고 SHELL 명령이 순차적으로 실행될 수 있게 함

    • MAKE를 쓰는 이유

      • 각 파일에 대한 반복적 명령의 자동화로 인한 시간 절약
      • 프로그램의 종속 구조를 빠르게 파악할 수 있으며 관리가 용이
      • 단순 반복 작업 및 재작성을 최소화
    • Makefile의 구성

      • 목적파일(Target) : 명령어가 수행되어 나온 결과를 저장할 파일
      • 의존성(Dependency) : 목적파일을 만들기 위해 필요한 재료
      • 명령어(Command) : 실행되어야 할 명령어들
      • 매크로(Macro) : 코드를 단순화 시키기 위한 방법
    • Makefile 작성규칙

    목표파일 : 목표파일을 만드는데 필요한 구성요소들
        목표를 달성하기 위한 명령 1
        목표를 달성하기 위한 명령 2
    • 더미타겟
      • 파일을 생성하지 않는 개념적인 타겟
    clean :
        rm *.o projectfile

    의 형태

    실행할 때는 make clean 으로 명령하여 현재 디렉토리의 모든 object 파일과 생성된 실행파일인 projectfile을 제거할 수 있음

    • 매크로 사용 작성 규칙

      • 매크로를 참조할 때는 소괄호나 중괄호로 둘러싸고 앞에 $
      • 탭으로 시작할 수 없으며 :, =, #, "" 등의 기호는 이름에 사용할 수 없음
      • 매크로는 반드시 치환될 위치보다 먼저 정의
    • 내부 매크로 사용

      • $@ : 현재 타겟의 이름
      • $^ : 현재 타겟의 종속 항목 리스트
      • $< : 현재 타겟의 첫번째 요소 macro
    • Make에서 컴파일 할 파일이 변경되는 경우 이미 실행 파일이 만들어져 있더라도 다시 만듦

    • touch 명령을 통해 timestamps가 바뀌더라도 다시 make 명령 실행 가능

    CMake

    • 요구 CMake 최소 버전
    CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
    • 프로젝트 이름 및 버전
    PROJECT ("andromeda")
    SET (PROJECT_VERSION_MAJOR 0)
    SET (PROJECT_VERSION_MINOR 1)
    • 빌드 형상(Configuration) 및 Makefile 생성 여부
    SET (CMAKE_BUILD_TYPE Debug)
    SET (CMAKE_VERBOSE_MAKEFILE true)

    Lecture 13 [2022.01.25]

    Linux Command

    1. ps

      • 현재 실행중인 프로세스 목록과 상태를 보여줌
    2. ps -l

      • 더 구체적으로 보여줌

    vi Command

    1. :r

      • 파일을 읽음
    2. :!

      • 명령어를 실행

    CPU Code

    • Intel i7-980x cpu

    Context Switching

    • 현재 진행하고 있는 task(process, thread)의 상태를 저장하고 다음 진행할 task의 상태 값을 읽어 적용하는 과정
    • 진행과정
      • Task의 대부분 정보는 Register에 저장되고 PCB(Process Control Block)로 관리됨
      • 현재 실행하고 있는 Task의 PCB정보를 저장
      • 다음 실행할 Task의 PCB 정보를 읽어 Register에 적재하고 CPU가 이전에 진행했던 과정을 연속적으로 수행
    • Context Switching이 발생하면 많은 비용이 소요됨

    Process 상태

    • RUN
      • fg
      • bg
    • STOP
    • KILL

    Fork function

    • 프로세스가 자기 자신을 복제하는 동작
    • 시스템 호출의 일종으로 커널 안에서 구현
    • 복제 대상을 부모 프로세스, 결과물을 자식 프로세스라고 함
    • unistd.h를 include하여 사용함
    • 프로세스가 가지는 고유한 번호를 프로세스 ID라고 함
    • fork함수 성공시 부모 프로세스는 자식 프로세스의 프로세스 ID를 리턴

    Thread

    • 프로세스 내에서 실제로 작업을 수행하는 주체
    • 모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행함
    • 두개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스라고 함
    • 장점
      • 프로세스에 비해 생성 및 종료시간, 스레드간 전환시간이 짧음
      • 프로세스의 메모리, 자원등을 공유하므로 커널의 도움없이 상호간 통신이 가능

    Process vs Thread

    • Process
      • 운영체제로부터 자원을 할당받는 작업의 단위
      • 실행 중인 프로그램
      • 디스크로부터 메모리에 적재되어 CPU의 할당을 받을 수 있는 것
      • 많은 자원과 시간을 소비
    • Thread
      • 프로세스가 할당받은 자원을 이용하는 실행의 단위
      • 프로세스의 실행 단위
      • 한 프로세스 내에서 동작되는 여러 실행 흐름으로 프로세스 내의 주소 공간이나 자원을 공유
      • 각각의 쓰레드는 독립적인 작업을 수행하기 때문에 각자의 스택과 PC 레지스터 값을 가짐

    system - system call

    #include <stdlib.h>
    int system(const char *command);
        execl("/bin/sh", "sh", "-c", command, (char *) 0);
    int execl(const char *path, const char *arg, ... 
        /* (char *) NULL */);

    popen

    #include <stdio.h>
    
    FILE *popen(const char *command, const char *type);

    실행시킨 명령어와 표준 입력/ 표준 출력을 주고 받기 위한 용도로 사용함. (Input/Output pipe를 open하기 위한 용도로 사용함)

    Core vs Thread

    corethread corethread2

    thread.h (C11)

    #include <streads.h>
    #include <stdio.h>
    
    int run(void *arg)
    {
        printf("Hello world of C11 threads.");
        return 0;
    }
    
    int main(int argc, const char *argv[])
    {
        thrd_t thread;
        int result;
        thrd_create(&thread, run, NULL);
        thrd_join(&thread, &result);
        printf("Thread return %d at the end \n", result);
    }

    pthread.h (POSIX)

    #include <pthread.h>
    #include <stdio.h>
    
    void *run (void *arg)
    {
        printf("Hello world of POSIX threads.");
        return 0;
    
    }
    
    int main()
    {
    	pthread_t thread;
    	int result; 
    	pthread_create(&thread, NULL, run, NULL );
    	pthread_join(thread, &result);
    	printf("Thread return %d at the end\n", result);
    }
    • POSIX Thread의 약자로 유닉스 계열 POSIX 시스템에서 병렬적으로 작동하는 소프트웨어를 작성하기 위하여 제공하는 API
    • 즉, 스레드를 편하게 만들 수 있게 도와주는 API
      • API (Application Programming Interface)
        • 애플리케이션 소프트웨어를 빌드하고 통합하기 위한 정의 및 프로토콜 세트
        • 구현 방식을 알지 못하는 제품 또는 서비스와도 통신할 수 있음
        • 애플리케이션 개발을 간소화하여 시간과 비용을 절약할 수 있음
        • 새로운 툴과 제품을 설계하거나 기존 툴과 제품을 관리할 때 유연성을 높이고 설계, 관리, 사용 방법을 간소화 가능
        • 리소스에 대한 액세스 범위를 넓히는 동시에 보안과 제어 유지

    Lecture 14 [2022.01.26]

    vi editor

    • ~/.vimrc
      • vi editor모드로 전환할 때 실행될 명령어들을 저장하는 파일
    • set num
      • vi editor를 실행하면 자동으로 라인 수가 표시됨
    • set tabstop=(숫자)
      • tab을 누르면 이동하는 칸 수를 지정

    POSIX

    • 다른 운영체제들 사이의 호환성을 위해 IEEE에서 만든 표준
    • 한 운영체제에서 개발한 프로그램을 다른 운영체제에서도 쉽게 돌아가도록 하는 것
    • UNIX 기반

    UNIX

    • 주로 서버용 컴퓨터에서 사용되는 운영체제

    • 특징

      • 시분할 시스템을 위해 설계된 대화식 운영체제
      • 소스가 공개된 개방형 시스템
      • 대부분 C언어로 작성되어 있어 이식성이 높음
      • 장치, 프로세스 간 호환성이 놓음
      • 크기가 작고 이해하기가 쉬움
      • 다중 사용자, 다중 작업을 지원
      • 많은 네트워킹 기능을 제공하여 통신망 관리용 운영체제로 적합
      • 트리구조의 파일 시스템을 가지고 있음
      • 전문적인 프로그램 개발에 용이
      • 다양한 유틸리티 프로그램들이 존재
    • 구성

      • 커널(Kernel)
        • 유닉스의 가장 핵심적인 부분
        • 컴퓨터가 부팅될 때 주기억장치에 적재된 후 상주되면서 실행
        • 하드웨어를 보호하고 프로그램과 하드웨어 간의 인터페이스 역할을 담당
        • 프로세스 관리, 기억 장치 관리, 파일 관리, 입출력 관리, 프로세스 간 통신, 데이터 전송 및 변환 기능 수행
      • 쉘(Shell)
        • 사용자의 명령어를 인식하여 프로그램을 호출하고 명령을 수행하는 명령어해석기
        • 시스템과 사용자 간 인터페이스를 담당
        • 명령어가 포함된 파일 형태로 존재하며 보조기억장치에서 교체 가능
        • 파이프 라인 기능을 지원하고 입출력 재지정을 통해 입력, 출력 방향 변경
      • 유틸리티 프로그램(Utility Program)
        • 일반 사용자가 작성한 응용프로그램을 처리하는데 사용
        • Dos에서의 외부 명령어에 해당
        • 에디터, 컴파일러, 인터프리터, 디버거 등이 포함됨

    buffer

    • 입출력을 수행하는데에 있어 속도 차이를 극복하기 위해 사용하는 임시 저장 공간
    • 프로그래밍이나 운영체제에서 사용하는 버퍼는 CPU보조기억장치 사이에서 사용되는 임시 저장 공간을 의미
    • CPU 내부의 캐시메모리 보다는 느리지만 보조기억장치보다 빠른 주기억 장치를 이용
    • 과정
      • 보조기억장치가 주기억장치의 버퍼로 데이터를 보냄
      • CPU가 다른 일들을 처리한 후 시간이 남으면 버퍼를 확인하여 쌓여있는 데이터를 한번에 처리함

    Lecture 15 [2022.01.27]

    Software Testing

    • 실제 결과가 예상 결과와 일치하는지 확인하고 소프트웨어 시스템에 결함이 없는지 확인하는 활동

    • 하나 이상의 관심 속성을 평가하기 위한 소프트웨어 구성 요소 또는 시스템 구성 요소의 실행을 포함

    • 실제 요구 사항과 달리 오류, 결함 또는 누락된 요구 사항을 식별하는데 도움이 됨

    • 수동으로 또는 자동화 된 도구를 사용하여 수행 가능

    • 중요성

      • 소프트웨어 버그가 비싸거나 위험할 수 있기 때문
      • 소프트웨어 버그는 잠재적으로 금전적 손실과 인적 손실을 초래할 수 있음
    • 테스트 방식

    • SW 내부 구조 파악 여부

      • 화이트박스 테스트 (White Box Test)
        • 응용 프로그램의 내부 구조, 동작을 디테일하게 거사하는 테스트 방식
        • 유형
          • 경로 테스트
          • 루프 테스트
          • 상태 테스트
      • 블랙박스 테스트 (Black Box Test)
        • 소프트웨어의 내부 구조나 작동 원리를 모르는 상태에서 동작을 검사하는 방식
        • 유형
          • 기능 테스트
          • 비 기능 테스트
          • 회귀 테스트
    • 소프트웨어 실행 여부

      • Static
        • 프로그램을 실행하지 않고 소스 코드 전체 또는 일부를 분석하는 기법
      • Dynamic
        • SW를 실행하여 다양한 입력 값에 대해 기대하는 결과 값이 나타나는지 확인하는 테스팅 기법
    • V-model

      • v-bind와 v-on의 기능을 합쳐놓은 문법
      • 소프트웨어 개발 프로세스로 폭포수 모델의 확장된 형태 중 하나
      • 요구 사항 분석에서의 오류, 설계 등 개발 단계의 작업들에 대한 테스트를 포함

    vmodel

    소프트웨어 기능안전

    • 시스템이나 장비의 총체적 안전의 일환으로 하드웨어 고장, 소프트웨어 오류, 운영자 오류, 환경적 영향등에 대한 안전 관리
    • IEC61508 안전표준을 기반

    정적 테스트

    • 소프트웨어를 실행시키지 않고 결함을 검출하는 방법
    • 특징 : 코딩 규칙, 가이드 준수 여부 검사
    • 장점 : 코드 실행 전 사용
    • 단점 : 정확도 상대적 낮음
    • 인스펙션
      • 공식적 검사
      • 프로그램을 실행하지 않고 산출물을 대상으로 공식적 검토, 결함 발견 과정
      • 구성 : 이해 관계자, 중재자, 검토자, 기록자
    • 피어 리뷰
      • 동료 검토
      • 프로젝트 수행과정에서 각 단계 별 산출물, 제품에 대해 동료들이 상호 교차하여 검토 수행하는 활동
      • 구성 : 프로젝트 팀원, 체크리스트
    • 워크쓰루
      • 비공식 검토
      • 프로젝트 개발 초기에 팀 내에서 수행하는 검토 과정
      • 구성 : 프로젝트 팀원

    informal

    구분 인스펙션 피어 리뷰 워크쓰루
    공식성 Formal Mid Formal Informal
    개념 산출물 대상 공식 검토 개발단계별 산출물 대상 동료 검토 소팀 내 결함 해결방안 상호 검토
    목적 요구사항 확인 계획의 적합성 평가 결함 발견
    기법 이해관계자 산출물 검사 검토 회의 집중 검토 기법
    규모 3 ~ 6명 3명 이상 2 ~ 7명
    참석자 이해관계자 경영자, 개발 관리자 개발자
    리더십 훈련된 중재자 선임 관리자 개발자 본인
    결함 기록 공식 기록 공식 기록 개인별 기록

    동적 테스트

    • 소프트웨어 실행을 통해 소프트웨어에 존재하는 결함을 검출하는 방법
    • 특징 : 단독분석보다 정적 기법 병행 수행 적용
    • 장점 : 오류 탐색 정확도 높음
    • 단점 : 코드 전체 수행 어려움