- 학습목표
- 16진법을 읽고 쓸 수 있다.
- 메모리 주소에 접근하고 값을 받아오는 코드를 C로 작성할 수 있다.- 핵심단어: 16진법, 메모리주소
- 16진법 (hexadecimal)
-- : 9보다 큰 숫자를 A B C D E F 라고 쓴다. 알파벳을 사용하는 이유는 한 자리로 0~9 뿐만 아니라 10~15까지 셀 수 있기 때문이다.
- 8bit 로 표현할 수 있는 가장 큰 숫자 : 255
- 255 의 다른 표현 방식
16¹ | 16⁰ | 10진법 |
---|---|---|
0 | 0 | 0 |
⁝ | ⁝ | ⁝ |
0 | 9 | 9 |
0 | A | 10 |
⁝ | ⁝ | ⁝ |
0 | F | 15 |
1 | 0 | 16 |
- RGB : 000000 ~ FFFFFF
- 0x00 : 10진법 등과의 혼동을 방지하기 위해 16진수를 사용할 때는 모든 수 앞에 0x 를 붙여서 표현해야 함 (수학적 의미X)
- " ~ 의 주소" (메모리 속의 위치)
-- ↪ & --- ex) printf("%i\n", &n);
-- ↪ %p : 가리키는 포인터 값을 돌려 받음 -- ex) printf("%p\n", &n);
- "그 주소로 가줘" (& 과 반대) : * -- ex) printf("%i\n", *&n); ⇒ n에 담긴 값 출력
💁♀️ Thinking 💡
Q. CS50 16진법으로 표현한다면?
A. 0x43 0x53 0x32
- 학습목표: 포인터 변수를 정의하고 사용할 수 있다.
- 핵심단어: 포인터
- 변수 주소 저장하기
-- int n = 50;
-- int *p = &n; --int: 포인터가 가르키는 값의 자료형을 뜻함, *p: 포인터라는 표시
⚠ ' * ' 없이 한다면 clang 컴파일러가 경고하므로 주소는 반드시 포인터에 저장해야 함
- 아주 정교한 자료형(가계도, 배열)을 만들 수 있음
- 수 많은 데이터를 관리하기 위해 사용하는 알고리즘의 기초가 됨
포인터의 크기 ❔
- : 최신 컴퓨터는 64bit 포인터로 사용 (= long type 의 크기)되지만, 반드시 그런 것은 아니다. (하드웨어에 따름)
- 학습목표: 문자열 형태의 새로운 자료형인 string이 어떻게 정의 되었는지 설명할 수 있다.
- 핵심단어: 포인터, 문자열
- 문자열의 포인터는 시작 문자의 주소를 저장
E | M | M | A | \0 |
---|---|---|---|---|
0x123 | 0x124 | 0x125 | 0x126 | 0x127 |
-- ↪ 포인터는 0x123
- c에는 사실 문자열이라는 자료형은 없다고 한다. 그렇기에 char의 포인터를 활용하여 문자열이라는 자료형을 만들어야 한다.
typedef char *string;
typedef char * string; 새로운 자료형 선언 값의 형태 (문자의 주소) 자료형의 이름 ↪ char의 주소를 가지는 string 자료형 생성
- 학습목표: 문자열이 저장되어 있는 방식에 근거해서 문자열을 비교하는 방법에 대해 설명할 수 있다.
- 핵심단어: 문자열
-- 문자열은 비교연산자 사용 X
- 학습목표: 문자열을 복사할 수 있다.
- 핵심단어: malloc
char *s = "emma"; char *t = s; t[0] = toupper(t[0]); printf("%s\n", s); // Emma printf("%s\n", t); // Emma
s는 'emma' 에서 첫글자인 'e'의 주소가 담기는데 그 주소를 가르키는 포인터 t가 있다. 즉 두 포인터는 같은 주소를 가르키고 있으므로 t를 수정하게 되면 s도 같이 수정된다.
서로 다른 메모리 공간에 복사하려면?
↪ 메모리를 추가로 사용해서 동일한 크기의 변수를 만들고 글자를 하나씩 복사해야 함
메모리 할당 함수
↪ 인자: 할당받을 메모리 크기 --- ex) malloc(strlen(s)+1);
for (int=i; n=strlen(s); i<=n; i++){ t[i] = s[i]; }
위 for 구문을 간단히 할 수 있는 함수 ex) strcopy(t, s);
- 학습목표: 메모리를 할당하고 해제할 수 있다.
- 핵심단어: free, valgrind
-- malloc 사용 후 free를 사용하여 메모리 할당 해제를 해주어야 함. 만약, 해제하지 않고 계속 호출한다면 느려지고 error가 발생함
-- 이를 방지하기 위해 valgrind를 사용함 --ex) $ valgrind ./-out 파일 이름-
# include <stdio.h> void f(void){ int *x = malloc(10 * sizeof(int)); x[10] = 0; } void main(void){ f(); return 0; }
① sizeof (자료형) : 자료형의 크기
-- ↪ sizeof(int) : 4byte
② malloc (10 * sizeof(int)) : 10개의 정수를 담을 수 있는 메모리 할당
-- ↪ 10 * 4byte : 40byte
③ x[10] : error
-- ↪ x에는 10개의 정수 즉, index 0~9
④ free(x) : 메모리 할당 해제를 위해 추가 필요
-- ↪ 'x[10] = 0;' 밑에 추가
- 학습목표: 메모리에 저장된 두 값을 교환하는 코드를 작성할 수 있다.
- 핵심단어: 스택, 힙, 포인터
- 함수에 인자를 전달할 때 그 값을 복사해서 전달
- memory in computer : 조직적으로 메모리를 사용
- 값을 복사해서 전달하므로 원하는 결과를 얻을 수 없음
- 인자를 전달할 때 값이 아닌 주소를 전달 (포인터)
- 학습목표: 사용자로부터 값을 입력받아 파일에 출력하는 프로그램을 작성할 수 있다.
- 핵심단어: scanf, fopen, fprintf, fclose
- 학습목표: 파일을 읽고 JPEG 파일인지를 검사하는 프로그램을 작성할 수 있다.
- 핵심단어: JPEG, fread
- fopen, malloc, get_string 과 같은 함수는 error 발생시 NULL 을 return
- fread(배열, 읽을 바이트, 읽을 횟수, 읽을 파일)
- JPEG 형식에 관한 설명문서에 따르면, 카메라로 사진을 찍을 때 생기는 모든 JPEG 파일의 첫 세 바이트는 무조건 'FF', 'D8', 'FF' 로 시작한다고 함
- file I/O (파일 입출력)
-- ↪ 사진 또는 비트맵이 이미지의 픽셀을 나타냄