React 컴포넌트 분리와 연동된 state 업데이트
TIL
원-달러 환율 변환기를 구현했다.사용자가 한 화폐 단위의 금액을 입력하면, 사전에 정의된 환율을 사용해 다른 화폐 단위로 변환된 금액을 동시에 보여준다.구현 과정컴포넌트 분리입력 필드를 재사용 가능한 CurrencyInput 컴포넌트로 분리한다.const CurrencyInput = ({ value, onChange, currencyUnit }) => { return ( {currencyUnit} onChange(currencyUnit, e.target.value)} /> );};currencyUnit: 화폐 단위(krw 또는 usd)를 받아 라벨과 id로 사용한다.value: 현재 입력값을 props로 받아 표시한다.onChange: 입력값이 변경될 때 화..
React 객체 state 관리와 useRef 활용하기
TIL
이전 글에서 다뤘던 배달 음식 주문 폼을 개선해봤다.여러 개로 분리된 state를 하나로 통합하고, useRef를 활용해 입력 유효성 검사 기능을 추가했다.구현 과정State 통합하기기존에 분리되어 있던 3개의 state를 객체 형태의 하나의 state로 합친다.기존 코드const [menu, setMenu] = useState("");const [address, setAddress] = useState("");const [request, setRequest] = useState(""); 변경 후const [state, setState] = useState({ menu: "", address: "", request: "",}); 이에 맞춰 JSX의 value 속성도 수정한다.return ( ..
React로 사용자 입력 관리하기
TIL
React로 간단한 배달 음식 주문 페이지를 구현했다.메뉴, 배달 주소, 요청사항을 입력받고 주문 완료 시 입력값을 확인할 수 있도록 만들었다.구현 과정마크업 구조먼저 주문에 필요한 입력 폼들을 구성한다. 메뉴 선택을 위한 select,주소 입력을 위한 input, 요청사항 입력을 위한 textarea, 그리고 주문 완료 button을 배치한다.export default function OrderEditor() { return ( 배달의민족 주문 아이스크림 젤리 초콜릿 배달 주소 배달 요청사항 주문 완료 );} state 관리각 입력 필드의 값을 관리하기 위한 state를..
[CS50] 메모리 - 파일 입출력
TIL
사용자에게 입력을 받는 함수는 어떻게 구현할 수 있을까? 파일을 읽고 쓰는 방법을 알아보자. 메모리 구조를 다시 한 번 살펴보면,메모리 영역머신 코드: 프로그램이 컴파일된 바이너리글로벌: 프로그램 안에서 저장된 전역 변수힙: malloc으로 할당된 메모리의 데이터스택: 프로그램 내의 함수와 관련된 것들힙 영역에서는 malloc에 의해 메모리가 더 할당될수록 아래로 늘어나고, 스택 영역에서는 함수가 더 많이 호출될수록 위로 늘어난다. 제한된 메모리 용량 하에서 점점 늘어나다 보면 기존의 값을 침범하는 상황이 발생하는데, 이를 힙 오버플로우 또는 스택 오버플로우라고 한다. 사용자에게 입력 받기get_int 구현#include int main(void){ int x; printf("x: "); ..
[CS50] 메모리 - 메모리 교환, 스택, 힙
TIL
각각 사이다와 콜라가 들어있는 컵 두 개가 있을 때, 사이다와 콜라를 바꿔 담고 싶으면 어떻게 해야 할까?아마 교환을 도와줄 새로운 컵이 잠시 필요할 것이다. 메모리에 저장된 값들을 교환할 때도 이와 비슷하게 할 수 있을까?잘못된 값 교환다음 코드를 보자.#include void swap(int a, int b);int main(void){ int x = 1; int y = 2; printf("x is %i, y is %i\n", x, y); swap(x, y); printf("x is %i, y is %i\n", x, y);}void swap(int a, int b){ int tmp = a; a = b; b = tmp;}// 출력// x is 1, y is 2..
[CS50] 메모리 - 메모리 할당과 해제
TIL
메모리를 할당한 후에 저장한 값이 필요 없어지고 나면 어떻게 해야 할까?유한한 메모리를 효과적으로 관리하기 위해 할당한 메모리를 어떻게 관리해야 하는지 알아보자.메모리 해제의 필요성malloc 함수를 이용하여 메모리를 할당한 후에는 free 함수를 이용하여 메모리를 해제해야 한다.그렇지 않으면 메모리에 저장한 값은 쓰레기 값으로 남게 되어 메모리 용량의 낭비가 발생하는데, 이러한 현상을 메모리 누수(Memory Leak)라고 한다. 문제가 있는 코드다음 코드를 살펴보자.#include void f(void){ int *x = malloc(10 * sizeof(int)); x[10] = 0;}int main(void){ f(); return 0;}함수 f는 포인터 x에 int형의 크기..
[CS50] 메모리 - 문자열 복사
TIL
이미 저장되어 있는 문자열을 다른 곳에 복사하려면 어떻게 해야 할까? 문자열을 복사하는 방법과 주의사항을 알아보자.잘못된 문자열 복사문자열을 복사하기 위해 아래 코드를 실행해보자.#include #include #include int main(void){ string s = get_string("s: "); string t = s; t[0] = toupper(t[0]); printf("s: %s\n", s); printf("t: %s\n", t);} 입력: emma출력:s: Emmat: Emmas 변수에는 'emma'라는 문자열이 아닌 그 문자열이 있는 메모리 주소가 저장된다. string s는 char *s와 동일한 의미이므로, t도 s와 동일한 주소를 가리킨다. 그렇기 때문..
[CS50] 메모리 - 문자열 비교
TIL
두 문자열이 같은 내용을 담고 있는지는 어떻게 비교할 수 있을까?문자열이 저장되어 있는 방식을 들여다보며, 문자열을 직접 비교하는 것이 가능한지 알아보자.문자열의 메모리 주소#include int main(void){ char *s = "EMMA"; printf("%p\n", s); // "E"의 메모리 주소}이 코드는 포인터 s의 값을 출력한다. 즉, "EMMA"라는 문자열의 가장 첫 번째 값인 "E"에 해당하는 메모리 주소를 출력한다. 각 문자의 주소printf("%p\n", &s[0]); // "E"의 메모리 주소printf("%p\n", &s[1]); // "M"의 메모리 주소printf("%p\n", &s[2]); // "M"의 메모리 주소printf("%p\n", ..
[CS50] 메모리 - 문자열과 메모리
TIL
우리는 이전에 string이라는 자료형을 사용했지만, 이는 실제로 C에서 존재하지 않는 자료형이다.문자열이 실제로 메모리상에 어떻게 저장되어 있는지, 문자열을 손쉽게 저장하고 접근하기 위한 방법을 배워보자.문자열의 정체지금까지 문자열을 저장하기 위해 CS50 라이브러리에 포함된 string 자료형을 사용했다.string s = "EMMA"; 문자열은 결국 문자의 배열이다. s[0], s[1], s[2], ...와 같이 하나의 문자가 배열의 한 부분을 나타낸다. 가장 마지막의 \0은 0으로 이루어진 바이트로, 문자열의 끝을 표시하는 약속이다.변수 s는 결국 이러한 문자열을 가리키는 포인터가 된다.더 정확히는 문자열의 가장 첫 번째 문자, 즉 주소 0x123에 있는 s[0]을 가리킨다. string의 정의실..
[CS50] 메모리 - 포인터
TIL
메모리 주소를 직접 관리하는 것은 쉽지 않기 때문에, C에서는 포인터라는 개념을 통해 변수의 주소를 쉽게 저장하고 접근할 수 있다. 포인터에 대해 알아보자.포인터 변수* 연산자는 어떤 메모리 주소에 있는 값을 받아오게 해준다. 이 연산자를 이용해 포인터 역할을 하는 변수를 선언할 수 있다.#include int main(void){ int n = 50; int *p = &n; printf("%p\n", p); printf("%i\n", *p);}// 출력 예시// 0x7ffe00b3adbc// 50int n = 50; - 정수형 변수 n에 50 저장int *p = &n; - 포인터 변수 p에 변수 n의 주소 저장printf("%p\n", p); - 포인터 p의 값(변수 n의 주소) ..