본문 바로가기

2학년 2학기213

14-6장 main 함수의 인수 지금까지의 main함수는 인수가 없는 void를 갖고 잇는 함수였다. 이번에는 외부로부터 입력을 받을 수 있는 main()함수 형태를 살펴보자. //[외부로부터 입력을 받는 main()]int main(int argc, char* argv[]){} argc명령어가 가지는 인수들의 개수 argv[]명령어가 가지는 인수들을 문자열 형태로 전달main에 인수가 아래와 같이 전달되었다고 가정해보자. C:\cprogram> mycopy src dst 위에서 인수는 mycopy, src, dst를 말한다. 따라서, argc는 3이고, argv = [mycopy, src, dst]이다. 2024. 12. 3.
[Visualization] Matplotlib의 고급 기능(Subplots, annotate, Fommator, Locator) In [101]:import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltfrom matplotlib.gridspec import GridSpecfrom matplotlib.ticker import NullLocator, NullFormatter, MaxNLocator, FuncFormatterimport warningswarnings.filterwarnings(action='ignore')Subplot¶: 하나의 그림(캔버스)안에 여러 개의 plot을 넣는 것[plt.subplot]¶개별 subplot을 생성(행, 열, 위치)로 subplot 위치를 지정사용하기 간단하지만, plot간의 세부 설정.. 2024. 12. 2.
[Visualization] Colormap In [30]:import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltfrom matplotlib.colors import ListedColormapimport warningswarnings.filterwarnings(action='ignore')Qualitative (질적), Sequential (연속적), Diverging (분기적)¶Qualitative (질적): 각각의 구역이 구별 되어야함(독립적)Sequential (연속적): 데이터 값이 증가함에 따라 색상의 농도가 점진적으로 변합니다.Diverging (분기적): 강중심값을 기준으로 색상이 양쪽으로 분기됩니다.In [37]:# 데이터 .. 2024. 12. 2.
[Visualization] Regend In [7]:import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltimport warningswarnings.filterwarnings(action='ignore')Legend(범례)¶: 여러 plot이 한 축에 표현되어 있을 때, 해당 plot을 표시하는 것In [38]:x = np.linspace(0, 10, 1000)plt.plot(x, np.sin(x), '-g', label='sin(x)')plt.plot(x, np.cos(x), ':b', label='cos(x)')plt.axis('equal')plt.legend()Out[38]:In [ ]: Legend(범례) 생성관련¶label이.. 2024. 12. 2.
14-5장 헤더 파일 중복막기(분할 컴파일) 분할 컴파일이란?분할 컴파일은 하나의 프로그램에 여러 파일을 나누어 작성해서 분할로 컴파일을 진행하고 링크를 통해서 하나의 실행파일로 만드는 것을 의미한다.   이렇게 하면, 유지보수 재사용, 디버깅 하기 쉽다는 장점이 있다.   다만, 분할 컴파일. 즉, 파일을 여러 개 만들어서 메인 파일에 여러 파일을 포함(include)할 때, 중복으로 포함하면 예상치 못한 오류가 발생한다. 따라서, 이를 방지 위한 방법으로 사용자가 정의한 헤더파일에 #ifndef 조건부 컴파일 지시자를 사용하는 방법이 있다.  위의 코드를 간단하게 설명하면, main.c에서는 power.h를 #include해서 메인 파일에 포함시킨다. 중복으로 포함하는 것을 방지하기 위해서 power.h는 내부에 조건부 컴파일 지시자(#ifnd.. 2024. 12. 2.
14-4장 #if #if란?: #ifdef에서는 기호 상수의 존재를 확인했지만, #if에서는 기호 상수의 값을 기반으로 분기처하는 조건문이다. 따라서, 논리, 관계 연산자 사용이 가능하다.  관계 연산자#define DEBUG 1#if(DEBUG == 1) printf("디버그 중");#endif 논리 연산자#define VERSION 3.1#if(VERSION > 3.0) printf("버전 3.0이상입니다.");#endif 무조건 무시: 무조건 무시하는 경우는 조거문 내부의 블럭에 주석이 있고, 그 보다 더 큰 블럭 단위를 주석하고 싶을 때 사용한다. 주석 밖에 주석을 하는 경우 주석이 제대로 설정되지 않을 수 있기 때문이다.#if 0 /* 주석 */#endif 무조건 실행#if(DEBUG == 1) .. 2024. 12. 2.
14-3장 #ifdef #ifdef란?: 특정 기호 상수가  존재할 때, 특정 동작을 수행할지 안할지를 분기해주는 조건문이다.  위의 예시와 같이 DEBUG라는 기호 상수가 존재하면, 출력구문을 실행하고, 기호 상수가 존재하지 않으면(주석 처리), 출력문은 존재하지 않고 값만 반환하게 된다. 따라서, 기호 상수를 통해서 테스트 버전일 때와 릴리즈 버전일 때를 나눠서 동작을 설정할 수 있다.   [리눅스와 윈도우 버전확인 예제]#include #define LINUXint main(void){ int n;#ifdef LINUX printf("리눅스 버전입니다. \n"); printf("정수를 입력하시오:"); scanf("%d", &n);#else printf("윈.. 2024. 12. 2.
14-2장 함수 매크로 함수 매크로: 인자를 받아서 함수처럼 동작하는 매크로이다.   함수 매크로의 예시#define SUM(x, y) ((x) + (y))#define AVERAGE(x, y, z) (( (x) + (y) + (z) ) / 3 )#define MAX(x,y) ( (x) > (y) ) ? (x) : (y)#define MIN(x,y) ( (x)   [사용 방법] int v = SUM(3, 4)// v는 7‼️ 함수 매크로 사용시 주의할 점 ‼️ 1. 인자에 괄호 사용하기#define SQUARE(x) x*xint main(){ int v = SQUARE(3+4) //원하는 결과: 49 //실제 결괴 -> 3 + 4 * 3 + 4 = 3 + (4 * 3) + 4 -> 19} 인자에는 괄호를 꼭 사용해야.. 2024. 12. 2.
14-1장 전처리기와 단순 매크로 전처리기란?: # 기호로 시작하는데, 컴퓨터 처리에 있어서 중심적인 처리를 수행하는 부분을 위해 사전 준비적인 계산을 진행하는 것이다.     전처리기의 종류     단순 매크로: 변수처럼 어떠한 값을 특정 단어로 대체하는 것을 의미한다. 즉, 아래와 같이 3.141592를 PI라는 단어로 치환하는 것이다.    💡  #define과 typedef의 차이점 [define]: unsigned char를 uchar로 치환하는 것// define#define uchar unsigned char  [typedef]: unsigned char를 UCHAR로 치환하는 것// typedeftypeof unsigned char UCHAR   서로 같은 기능을 하지만 차이점도 있다. 1. 처리하는 것이 다르다.: ty.. 2024. 12. 2.
[Visualization] Contour Plot(등고선) In [4]:import numpy as npimport matplotlib.tri as triimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as plt In [5]:npts = 100x = np.random.uniform(-2, 2, npts)y = np.random.uniform(-2, 2, npts)z = x * np.exp(-x**2 - y**2)ngridx = 100ngridy = 100xi = np.linspace(-2.2, 2.2, ngridx)yi = np.linspace(-2.2, 2.2, ngridy)triang = tri.Triangulation(x, y)interpolator = tri.LinearTriInt.. 2024. 11. 26.
[Visualization] Error Bar In [1]:import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltError Bar¶평균과 표준편자를 표시하여 데이터의 전체적인 경향을 요약하여 표시할 때 사용한다.즉, 많은 라벨의 데이터 들이 있을 때 라벨마다의 데이터 분포를 표시할 때 사용한다.In [5]:x = np.linspace(0, 10, 50)dy = 0.8y = np.sin(x) + dy * np.random.randn(50)plt.errorbar(x, y, yerr=dy, fmt='.k')plt.xlabel("Label")plt.ylabel("Distribution of Label")Out[5]:Text(0, 0.5, 'Dist.. 2024. 11. 26.
[Visualization] Scatter Plot(산점도) In [1]:import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltScatter Plot¶위치에 대한 정보를 나타낼 때 사용¶기존 plot을 이용한 ScatterPlot¶In [3]:x = np.linspace(0, 10, 30)y = np.sin(x)plt.plot(x, y, 'o', color = 'black')Out[3]:[]Scatter 메소드를 사용한 ScatterPlot¶In [4]:plt.scatter(x, y, marker='o')Out[4]:In [6]:rng = np.random.RandomState(0)x = rng.randn(100)y = rng.randn(100)color.. 2024. 11. 26.
[Visualization] LinePlot In [11]:import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as plt기본적인 동작¶In [13]:x = np.linspace(0, 10, 100)In [19]:plt.plot(x, np.sin(x), '--');Matlb Style vs Object-oriented Style¶In [37]:plt.figure()plt.subplot(2, 1, 1) # 2행 1열로 나누어 1번에 그래프를 그린다.plt.plot(x, np.sin(x))plt.subplot(2, 1, 2)plt.plot(x, np.cos(x)) # 2행 1열로 나누어 2번에 그래프를 그린다.Out[37]:[]In [43]:fig, .. 2024. 11. 26.
13-12장 다차원 배열의 동적 할당 ⭐⭐⭐ 동적 할당을 통해서 다중 배열을 만들 수 있다. 첫 번째로 배열 동적 할당을 하고, 동적 할당을 배열 요소에 다음 동적 할당을 받는다. 그림으로 표현하면 다음과 같다.    [2차원]#include #include void fillArr(int **arr, int row, int col) { int i, j; for(i = 0; i   [3차원]#include #include // 3차원 배열에 값 채우는 함수void fill3DArray(int ***arr, int depth, int row, int col) { int i, j, k; for (i = 0; i  [출력]Depth 0:0 1 2 3 4 5 6 7 8 9 Depth 1:10 11 12 13 14 15 1.. 2024. 11. 26.
13-11장 Wild pointer Wild pointer란?초기화 되지 않은 포인터를 의미한다. 초기화 되지 않은 포인터를 사용하면 해당 포인터가 가리키는 주소가 어디인지 모르기 때문에, 잘못하면 이상한 메모리를 참조할 수도 있고, 메모리 할당을 못 받을 수도 있다. 따라서, 아래의 해결 방법을 통해서 해당 문제를 방지해야한다. #include #include int main(void) { int * pi; *pi = 12; // pi는 wild pointer이다. pi = malloc(sizeof(int)); // wild pointer의 해결방안 1 - malloc(동적 할당: heap 영역) // 여기서 동작 할당을 하고 NULL을 확인해야함!!! *pi = 12; int a = 12; pi = &a; // wild po.. 2024. 11. 26.
13-10장 Dangling pointer Dangling pointer: 해제(free)된 메모리 공간의 주소를 갖고있는 포인터  [경우 1]#include #include int main(void) { int * p1; int * p2; p1 = (int *)malloc(sizeof(int)); *p1 = 5; p2 = p1; // p2는 p1과 같은 메모리를 가리킨다 (aliasing) free(p1); // 이때 p2는 dangling pointer가 된다. 즉, p2 를 통해서 메모리를 접근하려고 하는 시도는 예측 불가능한 결과를 초래한다. *p1 = 5; // 이미 해제된 p1을 통해서 메모리를 접근하고자 할 때, p1 또한 dangling pointer이다. 간단한 듯 보이지만, 대부분의 경우는 찾아내기 어렵다. return 0.. 2024. 11. 26.
13-9장 메모리 누수(3)_먼저 할당된 메모리 주소를 해제를 한 경우 #include #include typedef struct _mys { char *A; int B;} mys;char* getBuf(void) { return (char *)malloc(100 * sizeof(char));}int main(void) { char * A; char * B; mys * m = (mys *)malloc(sizeof(mys)); m->A = (char *)malloc(100*sizeof(char)); getBuf(); // getBuf에서 할당한 메모리는 찾을 수 없으므로 해제 불가능하다. free(m); // m을 먼저 해제했으므로 m->A에 접근할 수 없으므로 해제 불가능하다. return 0;}   위 사진처럼 먼저 할당 된 메모리를 해제를 하면, 다음 할당된 메모.. 2024. 11. 26.
13-8장 메모리 누수(2)_이미 해제된 동적 메모리 영역을 다시 해제 하려고하는 경우 #include #include int main(void) { char * A; char * B; A = (char *)malloc(100*sizeof(char)); B = (char *)malloc(100*sizeof(char)); B = A; free(A); // A는 해제 가능하다. free(B); // 원래의 B는 해제 불가능할 뿐 아니라, 이미 해제한 A를 다시 해제하려 고 하고 있다 (double free) return 0;}   위의 사진처럼 B에 A를 할당을 하면 동적할당 받은 2000번지의 메모리 영역에는 접근할 수 없게 되고 free도 하지 못하게된다.  또한 A와 B를 free하면 같은 메모리 영역을 두번 free하는 것이기 때문에 오류가 발생한다. 따라서, 아래와 .. 2024. 11. 26.
13-7장 메모리 누수(1)_fread가 실패해서 free를 실행하지 못하는 경우 메모리 누수란?: 메모리를 할당하고, 해제하지 않은 경우  #include #include char* readBuf(File* file, const int size) { int foo = 0; char* buf = (char*) malloc(size * sizeof(char)); if(buf == NULL) { printf("메모리 할당 오류\n") ; exit(1); } if(fread(buf, sizeof(char), size, file) != size) return NULL; // fread가 실패했다면? return buf;}int main(void) { FILE * fp; char * pc; int size = 80; fp = fopen("tmp.txt", "r"); pc = readBuf(.. 2024. 11. 26.
13-6장 동적 할당에서의 대표적인 오류들 2024. 11. 25.
13-5장 realloc(), memset(), calloc() realloc: 이미 할당 받은 메모리 값의 크기를 변경하는 것 realloc(이미 할당 받아서 사용하던 메모리 주소를 담고 있는 포인터, 변경하고 싶은 전체 크기)  예제#include #include #define SIZE 5int main(void) { int i, cur = 0, curMSize = SIZE; int *p; // 초기 메모리 할당 p = (int *)malloc(sizeof(int) * curMSize); if (p == NULL) { printf("메모리 할당 오류\n"); exit(1); } while (1) { cur++; // 메모리 확장이 필요할 경우 if (.. 2024. 11. 25.
13-4장 구조체 동적 생성 이전에 우리는 구조체 여러 개를 사용하기 위해서는 배열을 사용해서 구조체를 생성했었다. 이제는 동적 할당을 배웠으니, 동적할당을 기반으로 구조체를 동적으로 생성해보자.   [구조체 동적 생성]#include#include#includestruct Movie{ char title[100]; double rate;};int main(){ struct Movie* pi; int size = 0; printf("영화의 개수: "); scanf("%d", &size); pi = malloc(size * sizeof(struct Movie)); if (pi == NULL){ printf("메모리 할당 오류\n"); exit(1); } .. 2024. 11. 25.
9.5 RISC pipeline RISC 아키텍쳐에서는 명령어를 3단계로 나누어 처리한다. 각 단계는 병렬로 실행되며, Pipelining을 통해 처리 속도를 높인다.  I : Instruction Fetch (명령어 가져오기)A : Decode, Read Registers (명령어 해독 및 레지스터 읽기)E : Execute (실행) 1. Data Manipulation Instructions: 데이터 조작 명령(예: 산술 연산, 논리 연산)를 처리한다. I : Instruction Fetch (명령어를 메모리에서 가져오기)A : Decode, ALU operations 명령어 해독 및 실행할 연산 결정필요한 레지스터 값을 읽기ALU를 통해 산술 또는 필요한 레지스터 값을 읽는다.E : Write a register (연산 결과를 레.. 2024. 11. 24.
9.4 Instruction pipeline instruction pipline   위의 Fetch, Decod, Excute를 pipeline으로 만들 수 있는데 오류가 발생할 수 있다.  위의 사진과 같이 EX에서 branch를 수행해야하는데, 아직 다음 명령어가 Fetch되지 않았기 때문에 어떤 명령어로 점프해야하는지 알 수 없다.   따라서, 아래와 같이 다음 Segment를 지연시켜서 EX 다음에 FI가 실행되도록 만들어야한다. Pipelining에서 발생할 수 있는 주요 문제점(Hazards) Structural Hazards (구조적 해저드): 하드웨어 Resource가 부족해서 동시에 실행되는 명령어들이 서로 충돌할 때 발생한다.  Fetch 시킬수 있는 코드가 하나만 있을 때 동시에 FO와 FI가 일어나면 충돌이 일어날 수 있다. .. 2024. 11. 24.
9.2 Pipelining Pipelining이란?하나의 명령어를 여러 단계로 분할하여 처리 속도를 높이는 방식이다.   이렇게 i가 1 ~ 7인 경우에 R1 * R2 + R4 를 하는 연산이 있다고 했을 때 이 경우 Pipelining을 이용하면 아래와 같이 각 세그먼트가 넘어갈 때마다 다음 값들이 순서대로 다음 연산을 대기하는 것을 볼 수 있다.   Time diagram  즉, Segment 개수 만큼 빨라진다는 것이다. 2024. 11. 24.
9.1 Parallel processing(Instruction Level Parallelism) Instruction Level Parallelism이란?한 프로그램에서 독립적인 여러 명령어를 동시에 실행하는 것을 말한다.  Processor Register가 명령어 실행에 필요한 데이터를 저장하고, 각 기능 유닛으로 데이터를 전달하게된다. 병렬적으로 데이터를 전달해서 유닛에서는 다양한 연산을 동시에 수행할 수 있다. 2024. 11. 24.
State hoisting이 뭐지? 우선, state에 대해서 알아보자. State: UI의 현재 상태를 나타내는 데이터이다. 예를 들어, 화면에 표시되는 숫자 값이 있다면 그 숫자가 State이고, 버튼 클릭에 따라 값이 변경되면 State의 값이 업데이트되어 UI도 변경된 것이다.  State 선언var count by remember { mutableStateOf(0) } state는 위의 형태와 같이 선언이 되는데 mutableStateOf는 state의 값이 변경될 때, 관련 UI가 다시 렌더링되도록 만드는 함수이다. 또한 ,remember는 UI가 렌더링 되더라도 state의 값이 변경되지 않고 유지되도록 만드는 것이다.       Stateful과 Stateless Stateful: 상태가 스스로 관리하는 방식이다. 쉽게 말해.. 2024. 11. 20.
13-3장 동적 할당 영역을 배열처럼 쓰기 이전에 malloc을 이용해서 Heap 영역에 있는 메모리를 동적 할당 받는 것을 해봤다. 이전에는 4byte(int)만 할당 받았지만, 이번에는 4byte를 5개 받아서 즉 int arr[5]와 같은 효과를 내는 메모리를 동적할당 받아보자. #include #include int main(void){ int* pi; pi = (int*)malloc(5 * sizeof(int)); if (pi == NULL) { printf("메모리 할당 오류\n"); exit(1); } *pi = 1; // pi[0] = 1; *(pi + 1) = 2; // pi[1] = 2; *(pi + 2) = 3; // pi[2] = 3; *(pi + 3.. 2024. 11. 19.
13-2장 malloc()과 free() maclloc(): 동적 메모리를 할당할 때 사용 int *pi; //stack 영역에서 할당pi = (int *)malloc(sizeof(int)) //반환은 void* 타입으로 ❓ 왜 malloc은 void*로 반환을 하는가? 사용자가 어떤 타입의 메모리를 할당하는지 모르기 때문에 메모리의 주소를 반환할 때 특정 타입에 한정해서 반환하지 않고, 범용적으로 사용할 수 있는 포인터 타입인 void*를 이용하는 것이다.  ❓ 왜 malloc 반환 값을 int*로 타입 캐스팅을 하는가? malloc이 범용적인 포인터 타입 void*를 반환하기 때문에 그 타입을 명시적으로 변경해주기 위해서 타입 캐스팅을 한다. 타입 캐스팅을 하면 가독성과 안정성을 높일 수 있다.   값 입력, 연산, printf, scanf.. 2024. 11. 19.
13-1장 동적 메모리 할당란? 메모리를 할당하는 방법에는 정적(static)과 동적(dynamic) 2가지 방법이 있다.  기본적으로 우리가 변수를 통해서 메모리를 할당하는 것 정적 메모리 할당이다. 정적 메모리 할당은 이미 프로그램이 시작되기 전에 결정되는 것이다. 즉, 더 큰 입력은 받아드리지 못하고 더 작은 입력은 메모리 공간이 낭비된다.  따라서, 우리는 동적 메모리 할당을 사용해서 우리가 원하는 메모리 공간을 확보해서 좀더 효율적으로 사용해야한다.  동적 메모리를 할당 받을 때는 Heap 영역에서 할당 받는다. 2024. 11. 19.