
Hexadecimal
그래픽이나 색상등 아트와 관련한 것을 컴퓨터로 표현할 때
hexadecimal 16진수 를 주로 사용한다.
흔히 흰색을 RGB(255, 255, 255) --> #FFFFFF 로 표현하는 것이다.
16진수에서 한 칸은 16개가 존재한다.
0, 1 ==> Binary 이진수
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ==> Decimal 10진수
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F ==> Hexadecimal 16진수
16진수를 사용하는 이유는 편리하기 때문이다.
컴퓨터에서 16을 표현하기 위해선 4개의 bit를 사용해야한다.
보통 컴퓨터에서 메모리를 표현하고 사용할때 8bit / 1byte 가 기준이 된다.
따라서 16진수를 사용하면 11111111 로 표현해야하는 것을 FF 이렇게 줄일 수 있게 된다.
16진수는 10진수와 혼동하기 쉬워서 이를 구분해줘야하는데
0x 가 16진수를 나타내는 표시이다. 28 = 0x1C = 11100
Pointers
앞으로 자주 쓰게 될 기호가 새롭게 등장한다. & *
& = 엠퍼센트 , &n = n의 메모리 주소
* = 역참조자, 1. *n = 포인터(주소)임을 선언/설정 , 2. *값이 온 주소로 거슬러 감
* 의 경우 맥락에 따라 2가지 의미를 갖는다.
#include <stdio.h>
int main(void)
{
int n = 50;
//여기서는 "여기는 포인터(주소)임을 알려주는 역할"
int *p = &n;
//여기서는 p의 주소로 거슬러 올라가라는 역할
printf("%i\n", *p);
}
포인터의 경우 보통 8bytes 를 사용한다 64bit 인데 어마어마하게 큰 숫자이다.
많은 bytes 를 할당하는 이유는 컴퓨터가 발전함에 따라 점점 메모리 주소의 숫자가 커지고 있다.
포인터는 메모리의 주소를 담아야 하기 때문에 모든 주소를 커버할 수 있어야 한다.

포인터에 대해 너무 깊게 생각하지 않아도 될 것 같다.
포인터로 선언된 변수는 어떤 변수의 메모리 주소를 담고 있고
*포인터 변수 를 하면 담고 있는 그 메모리 주소를 따라 그 안에 담겨 있는 것을 가르킬 뿐이다.
Strings
전에 type 에서 string에 다루긴 했지만
C는 string 이라는 type을 제공하지 않는다.
string 이라는 type 을 제공하지 않는다고 해서
문자열 이라는 개념이 없는 것은 아니다.
분명히 C는 "" 와 '' 를 구분하며 "" 로 선언 될 시
추가적으로 1bit를 더 할당해서 감시값을 넣어 종료 시점을 확인한다.
stdio 라이브러리에도 string 에 대한 것은 없다.
강의 보조 라이브러리에만 string 에 대한 것이 있는데
사실 string 은 하나의 포인터 이다.

그것도 문자열의 문자중 첫 번째 문자를 가르키는 포인터이다.
따라서 string s = "hi!" 라고 썼던 코드는
char *s = "hi" 와 같아지게 된다.
애초에 C언어를 개발했을 때는 string 이라는 타입이 필요하지 않았다.
Pointer Arithmetic
포인터 주소는 연산도 가능하다.
#include <stdio.h>
int main(void)
{
char *s = "HI!";
printf("%c\n", *s);
printf("%c\n", *(s + 1));
printf("%c\n", *(s + 2));
}
s의 주소는 0x5631a5f77004 예를 들면 이런 값이 되는데
0x5631a5f77004 = s[0] 를 가르키고
0x5631a5f77005 = s[1] 을 가르킨다.
메모리 주소에 직접 연산을 해서 그 위치에 있는 값을 찾아 올 수 있다.
String Comparison
만약 두 문자열을 비교하는 경우
char *s = "hi";
char *t = "hi";
이렇게 선언 되었을 때 s == t 는 false 같지 않음이다.
그 이유는 char * 자체가 문자를 가르키는 것이 아니고
주소를 가르키고 있기 때문이다.
변수가 생성되었을 때 컴퓨터는 메모리 어딘가에 4바이트 짜리 메모리 덩어리를
어디인가에 생성한다. 당연히 s 와 t 가 생성된 위치는 다르므로 같지 않은 것이다.
즉 s == t 는 문자 끼리의 비교가 아니고 주소의 비교이다.
그러면 여기서 *s == *t 는 성립할까 궁금해졌다.
실행해본 결과 성립한다. *s 는 h 를 나타내고, *t 도 마찬가지이다.
하지만 이건 문자열 전체가 같다는 것이 아니라 맨 앞자리만 비교한 것으로
반복문을 통해 *(s+i) == *(t+i) 를 순차적으로 비교해줘야
문자열 비교가 이뤄질 것이다.
강의에서는 strcmp 를 통해 간단히 구현했지만 strcmp 함수 자체도 구현 가능한 것이다.
String Copy , Melloc, Free
문자열을 복사하는 경우 그냥 단순히
char *s = "hi!";
char *t = s;
이렇게 해버리면 t에는 s 주소 값이 들어가 있고
결과적으로 다른 이름의 두 변수가 같은 메모리를 가르키고 있는 모양이 된다.
그러면 문자열을 복사하는 것이 아니게 된다.
문자열을 복제하고 싶은 경우
복사하려고 하는 문자열과 같은 크기의 메모리 공간을 새로 생성하고 - melloc
for 문을 통해 t[i] = s[i] 로 각각의 문자들을 복사하고 - strcpy(라이브러리 함수)
*for 문을 통해 복사할 때는 반드시 s의 센티널 값 까지 복사를 해줘야 한다.
임의로 생성한 메모리를 다시 풀어줘야 한다 - free
이런 과정을 거쳐야한다.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
// Get a string
char *s = get_string("s: ");
if (s == NULL)
{
return 1;
}
// Allocate memory for another string
char *t = malloc(strlen(s) + 1);
if (t == NULL)
{
return 1;
}
// Copy string into memory
strcpy(t, s);
// Capitalize copy
if (strlen(t) > 0)
{
t[0] = toupper(t[0]);
}
// Print strings
printf("s: %s\n", s);
printf("t: %s\n", t);
// Free memory
free(t);
return 0;
}
Swapping

컴퓨터 메모리를 단적으로 떼서 본다면 이런식으로 구성된다.
만약 main 함수에서 swap 함수를 호출하는 형태로 코드를 짜면
stack 맨 아래에 main 이 존재하고 그 위에 swap 이 존재한다.

main 에서 int x = 1; int y = 2 이런식으로 변수를 설정하고
swap(x ,y) 이런식으로 매개 변수를 통해 x, y를 넘겨주면
그것은 x, y 그 자체가 아니라 복사본 이다. 그래서 swap 에서 x 와 y 로 하는 작업은
실제 main의 x, y 에 영향을 미치지 않는다.
여기까지는 어떻게 보면 당연한 얘기였는데 그 다음은 굉장히 신선했다.
C에서는 메모리에 직접 접근할 수가 있는데 main 에서 x , y 의 주소를 넘기면
swap 에서 그 메모리 주소를 타고 가서 그 곳에 위치한 값에 접근이 가능한 것이다.
주소만 전달해주면 * 를 통해 역참조해서 그 값을 바꿀 수 있고 scope를 뛰어 넘을 수 있다.
#include <stdio.h>
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;
}

'입문 > CS50X' 카테고리의 다른 글
[CS50X] Week3 번외편(Sort 구현 - Selection, Bubble, Merge, 비트연산자 ) (0) | 2024.03.05 |
---|---|
[CS50X] 2024 Week4 Memory Problem Set 4 (Volume, Filter, Recover) (0) | 2024.02.29 |
[CS50X] 2024 Week3 Algorithms Problem Set 3 (Sort, Plurality, Tideman) (0) | 2024.02.23 |
[CS50X] 2024 Week3 Algorithms (1) | 2024.02.23 |
[CS50X] 2024 Week2 Arrays Problem Set 2 (Scrabble, Readability, Substitution) (0) | 2024.02.22 |