# C 언어의 포인터와 자바스크립트

---

## 🖐🏻  포인터 공부를 하기 전에,

CTO님께서 휴일에 뭘 하셨냐고 물어보셔서 얕은 복사와 깊은 복사를 공부했다고 말씀드리니, C언어의 포인터를 공부해보면 더 이해가 쉬울 것이라고 말씀을 해주셔서 포인터와 함께 불금을 보냈다. 하하! C언어에서의 포인터가 뭐길래 이걸 공부해보라고 말씀해주신건지 이해해보려고 부단히 노력했던 것들에 대한 기록을 남겨보자…

### 📝  데이터 타입

* 원시 타입
    
    * 실제 데이터의 값을 저장하는 타입
        
* 참조 타입
    
    * 메모리 번지 값을 통해 객체를 참조하는 타입
        

---

## 👉🏻  포인터란?

### 📝  포인터와 메모리 주소

* 포인터
    
    * 변수의 메모리 주소를 가리키는 변수
        
* 메모리 주소
    
    * 메모리 위치에 대한 식별자로, 컴퓨터 프로그램이나 하드웨어 장치가 데이터를 저장하고 나중에 이를 가져오는 장소
        
    * 해당 데이터가 저장된 메모리의 시작 주소
        

### 📝  포인터에 대해 더 알아보자

* 메모리의 주소값을 저장하는 변수 (포인터 변수)
    

```c
int n = 100; // 변수 선언
int *ptr = &n; // 포인터 선언

/*
n 이라는 변수를 선언하고 변수는 100 이라는 값을 가짐
ptr 이라는 포인터는 n의 주솟값을 참조함...
개섹시하다 근본 언어라 그런걸까
*/
```

---

## 🧮  포인터 연산자

### 📝  포인터 연산자의 종류

* 주소 연산자 : `&`
    
* 참조 연산자 : `*`
    

### 📝  주소 연산자 ( `&` )

* 변수의 이름 앞에 사용, 해당 변수의 주소값을 반환
    
* `&` 기호는 앰퍼샌드라고 읽으며, 번지 연산자로고도 불림
    

### 📝  참조 연산자 ( `*` )

* 포인터의 이름이나 주소 앞에 사용하여, 포인터에 가리키는 주소에 저장된 값을 반환
    
* 기호의 사용 위치에 따라 다양한 용도로 사용됨
    
    * 이항 연산자로 사용하면 곱셈 연산으로 사용
        
    * 포인터 선언 시나 메모리에 접글할 때도 사용됨
        

## 🙋🏻‍♀️  포인터 선언

---

```c
타입* 포인터이름;
```

* 타입 : 포인터가 가리키고자 하는 변수의 타입을 명시
    
* 포인터 이름 : 포인터가 선언된 후 포인터에 접근하기 위해 사용됨
    

```c
type* ptr = &variable;
type* ptr = 주소값;
```

---

## 👀  포인터 참조

* 포인터는 참조 연산자를 사용해 참조가 가능함
    
* \[ 예제 \] 포인터의 주소값과 함께 포인터가 가리키고 있는 주소값의 데이터를 참조
    

```c
int x = 7; // 변수 선언
int *ptr = &x;  // 포인터 선언
int *pptr = &ptr; // 포인터 참조

/*
x 라는 변수를 선언하고 7이라는 값을 할당 ( 0x12 )
ptr 이라는 포인터는 x의 주소의 주소값을 반환 ( 0x12 )
pptr 이라는 포인터는 x의 주솟값이 저장된 주소값을 반환 ( x의 주소값 )
*/
```

```c
int num = 123;
int* num_address = &num;

printf("%p", &num);
printf("%p", num_address);
printf("%p", &num_address);
printf("%d", *num_address);

/*
int형 num 값이 저장된 주소값을 가리키는 포인터 num_address

"%p", 0x00DF0213 : 123이 저장된 주소값 반환
"%p", 0x00DF0213 : num_address = &num
"%p", 0x00FA0255 : 0x00DF0213이 저장된 주소값 반환
"%d", 123        : num_address에 저장된 주소값에 저장된 값을 반환
*/
```

```c
int num01 = 1234;
double num02 = 3.14;  
int* ptr_num01 = &num01;
double* ptr_num02 = &num02;

/*
num01 은 1234 를 가짐 (대충 &7번방)
num02 는 3.14 를 가짐 (대충 &8번방)
ptr_num01 => &7
ptr_num02 => &8
*/
```

---

## 👩🏻‍💻  자바크스립트에서의 pointer

자바스크립트를 공부를 하고 있는데, C언어에서의 pointer 를 공부해보라고 말씀을 해주신 것에는 그만한 이유가 있으실 것이라 생각을 해서 그 이유를 찾아보려고 포인터의 관점(?) 에서 다시 한번 JavaScript 의 깊은 복사, 얕은 복사를 바라보려고 해봤다.

### 📝  원시 타입에서의 복사

```jsx
let dobby = "is Free";
let leetrue = dobby;

console.log(leetrue); // "is Free";
 
dobby = "is not Free!";
console.log(leetrue); // "is Free";
console.log(dobby); // "is not Free!";
```

원시 타입의 경우에는 실제 데이터의 값 자체를 저장하기 때문에 `leetrue` 라는 변수는 `dobby` 라는 변수가 복사 당시 가지고 있단 `"is Free"` 라는 데이터 값 자체의 주소를 저장하게 된다. 따라서 `dobby` 변수의 값이 새로 할당이 되었다고 하더라도 `dobby` 변수가 가지고 있는 데이터 주소만 달라질 뿐, `leetrue` 는 여전히 자유인 상태이다.

### 📝  참조 타입에서의 복사

```jsx
let dobby = {
  isFree : true,
};
let leetrue = dobby;
console.log(leetrue);
leetrue.isFree = false;

console.log(leetrue); // { isFree : false }
console.log(dobby); // { isFree : false }
```

```jsx
let dobby = {
  isFree : true,
};
let leetrue = dobby;
console.log(leetrue);
dobby.isFree = false;

console.log(leetrue); // { isFree : false }
console.log(dobby); // { isFree : false }
```

참조형의 경우에는 이야기가 달라진다. 참조형은 데이터의 값 자체가 아닌 메모리 번지 값을 통해 객체를 참조하기 때문에 `leetrue` 라는 변수는 `dobby` 라는 변수의 데이터 주솟값을 참조한다. 따라서 `dobby` 의 데이터 또는`leetrue` 변수에 값을 조작을 한다면 두 변수는 같은 주소를 바라보고 있기 때문에 모두의 값이 바뀌어 보이게 된다.

### 📝  그래서 pointer 는 왜 공부했을까..

사실 CTO님의 의도를 명확하게 이해한 것은 아니지만 나름 이해를 하려고 노력했던 건 결국은 JavaScript 에서 얕은 복사라고 불리는 것이 곧 포인터의 개념을 따라가고 있는 것이라는 생각이 들었다. JavaScript 에 이런 문법은 없겠지만, C언어의 포인터 개념으로 JavaScript 코드를 작성한다면,

```jsx
/* JavaScript의 얕은 복사(참조 복사) */
let dobby = {
  isFree : true,
};
let leetrue = dobby; // leetrue 변수는 dobby의 주솟값을 참조한다.

/* Pointer의 개념으로 바라봤을 때,
  - 아래와 같은 문법은 존재하지 않고, C언어 포인터와 참조 연산자를 자바스크립트에 대입해봤을 뿐임
*/
let dobby = {
  isFree : true,
};
let* leetrue = *dobby; // leetrue 는 dobby 라는 변수의 주솟값에 담긴 값을 참조
```

위와 같이 `leetrue` 라는 포인터 변수가 `dobby` 의 주솟값이 가지고 있는 데이터의 주솟값을 참조해 저장하고 있는 모습이 아닐까? 라고 생각을 해봤다. 그렇기 때문에 `dobby` 의 값이 바뀌게 된다면 `leetrue` 는 이를 참조하고 바라보고 있기 때문에, 함께 값이 바뀐 것으로 확인이 되는 것 같다.

---

## 💜 결론

너무 답답해서 CTO 님께 오밤중에 내가 이해한 것이 CTO님께서 의도하신 바와 방향이 맞는지 여쭤보는 장문의 슬랙을 남겼는데, 얼른 답을 받고 싶다. 그게 아니라면 새로운 무언가를 또 얻을 수 있을 것이고 이게 맞았다면 뭔가 뿌듯하게 불금을 마무리한 느낌에 기분이 참 좋을 것 같다!

C언어는 처음이었는데 근본 언어는 뭔가 다르구나 싶기도하고..? 🤔 ㅋㅋㅋ 나중에 또 키워드를 얻는다면 더 공부를 해봐야겠다! 오늘은 이만 마무리!

### 👩🏻‍💻 후일담…

어제 CTO님께 질문드렸던 것에 대한 답변을 받았다. 참조형이 무엇인지 이해하는데 포인터의 개념이 도움이 될 것이라고 생각이 되셔서 이야기를 해주셨다고..! 주소를 갖는 변수라는 것이 프로그래민에서 왜 필요한가에 대해 가장 많은 레퍼런스를 갖는게 포인터여서 좋을 것 같아서 추천을 해주셨던!

추가로 포인터에서 메모리 릭이 왜 많이 발생하는지에 대해 한 번 찾아보고 이러한 릭을 어떻게 없애려고 하는지 보면 좋을 것 같다고 이야기를 해주셔서 이번엔 이 부분에 대해 공부를 해볼까 싶다. 좋아좋아 파이튕

---

### 참고

* [https://www.youtube.com/watch?v=dhdWn\_QDP0M](https://www.youtube.com/watch?v=dhdWn_QDP0M)
    
* [http://www.tcpschool.com/c/c\_pointer\_intro](https://www.youtube.com/watch?v=dhdWn_QDP0M)
