Moglobin's
article thumbnail
Published 2021. 1. 20. 11:19
[C++] 포인터(Pointers) (1) 컴공

Pointers

In earlier chapters, variables have been explained as locations in the computer's memory which can be accessed by their identifier (their name). This way, the program does not need to care about the physical address of the data in memory; it simply uses the identifier whenever it needs to refer to the variable.

 

앞의 챕터들에서, 변수들은 그들의 식별자(지정한 이름)에 의해 열람이 가능한 컴퓨터 메모리 상의 위치로 설명되었다. 이 방법으로, 프로그램은  메모리 안의 데이터의 물리적 주소를 신경쓰지 않아도 된다; 식별자는 변수를 참조할 때 아무때나 사용할 수 있는 것이다.

For a C++ program, the memory of a computer is like a succession of memory cells, each one byte in size, and each with a unique address. These single-byte memory cells are ordered in a way that allows data representations larger than one byte to occupy memory cells that have consecutive addresses.

 

C++ 프로그램에서, 컴퓨터의 메모리는 메모리 셀의 연속과 같다. 각각 크기로 한 바이트씩, 고유한 주소를 함께 가지고 있다. 이 싱글-바이트 메모리 셀들은 데이터의 크기가 한 바이트보다 큰 데이터들로 하여금 연속적인 메모리 주소를 차지하는 것을 가능하게 하도록 정렬되어 있다.


This way, each cell can be easily located in the memory by means of its unique address. For example, the memory cell with the address 1776 always follows immediately after the cell with address 1775 and precedes the one with 1777, and is exactly one thousand cells after 776 and exactly one thousand cells before 2776.

 

이 방법으로, 각 셀들은 간단하게 메모리에 그들의 고유한 주소로 위치하게 된다. 예를 들어, 메모리 셀의 1776이라는 주소를 가진 셀은 1775 주소를 가진 셀에 바로 연달아서 위치하고, 1777 주소 앞에 위치한다. 그리고 776의 정확히 천 셀 뒤에 위치하고 2776의 정확히 천 셀 앞에 위치한다.

When a variable is declared, the memory needed to store its value is assigned a specific location in memory (its memory address). Generally, C++ programs do not actively decide the exact memory addresses where its variables are stored. Fortunately, that task is left to the environment where the program is run - generally, an operating system that decides the particular memory locations on runtime. However, it may be useful for a program to be able to obtain the address of a variable during runtime in order to access data cells that are at a certain position relative to it.

 

어떤 변수가 선언되었을 때, 그 변수가 가진 값을 저장할 메모리는 메모리의 특정한 장소에 할당된다 (특별한 메모리 주소). 일반적으로, C++ 프로그램은 능동적으로 정확히 그 변수들이 위치할 주소들을 정하지 않는다. 다행히도, 이 과제는 프로그램이 실행되는 환경에 맡겨진다 - 일반적으로, 운영 시스템이 특정 메모리 장소를 런타임 때 결정한다. 그러나, 프로그램이 런타임 동안 변수의 주소를 지정할 수 있는 것이 특정 위치의 관련있는 데이터에 접근하는 데에 더 유용할 수 있을 것이다.

Address-of operator (&)

The address of a variable can be obtained by preceding the name of a variable with an ampersand sign (&), known as address-of operator. For example:

 

변수의 주소는 그 변수의 이름 앞에 address-of operator라 불리는 기호 (&) 를 붙임으로서 얻을 수 있다. 예를 들어:

 


This would assign the address of variable myvar to foo; by preceding the name of the variable myvar with the address-of operator (&), we are no longer assigning the content of the variable itself to foo, but its address.

 

이것은 foo 에게 변수 myvar의 주소를 할당할 것이다; address-of operator (&) 를 변수 이름 myvar 앞에 놓음으로서 우리는 foo 에게 그 자체의 내용을 지정하는 것이 아니라 주소를 지정해주는 것이다.

The actual address of a variable in memory cannot be known before runtime, but let's assume, in order to help clarify some concepts, that myvar is placed during runtime in the memory address 1776.

 

변수의 메모리 안의 실제 주소는 런타임 이전에는 알 수 없지만, 몇 가지 개념들을 명확히 하기 위해, myvar 이란 변수가 런타임 도중 메모리 주소 1776 에 위치해있다고 가정하자.

In this case, consider the following code fragment:

이 경우, 아래의 코드 조각을 생각해보자.


The values contained in each variable after the execution of this are shown in the following diagram:

 

이것을 실행한 후 각 변수에 들어있는 값들을 아래의 도표에서 볼 수 있다:

 

 

First, we have assigned the value 25 to myvar (a variable whose address in memory we assumed to be 1776).

 

먼저, 우리는 myvar 에게 값 25를 할당하였다 ( 메모리 상의 주소는 1776 로 앞에서 가정 함).


The second statement assigns foo the address of myvar, which we have assumed to be 1776.

 

두 번째 명령문은 foo 에게 myvar 의 주소를 할당해주고 있고, 그 값은 1776 이 될 것이다.


Finally, the third statement, assigns the value contained in myvar to bar. This is a standard assignment operation, as already done many times in earlier chapters.

 

마지막으로, 세 번째 명령문은 bar 에게 myvar 에 들어있는 값을 할당해준다. 이것이 우리가 앞에서 많이 다루었던 표준 변수 할당 방법이다.

The main difference between the second and third statements is the appearance of the address-of operator (&).

 

두 번째 명령문과 세 번째 명령문의 가장 핵심 차이는 연산자 (&) 의 존재 여부 차이일 것이다.

The variable that stores the address of another variable (like foo in the previous example) is what in C++ is called a pointer. Pointers are a very powerful feature of the language that has many uses in lower level programming. A bit later, we will see how to declare and use pointers.

 

다른 변수의 주소를 저장하고 있는 변수가 ( 앞서 나왔던  foo 처럼) 바로 C++ 에서 말하는 포인터 라는 것이다. 포인터는 컴퓨터 언어에서 매우 강력한 특성을 갖고 있으며 낮은 단계의 프로그래밍으로 갔을 때 많은 쓰임이 있다. 조금 이따, 우리는 포인터를 선언하는 방법과 사용하는 방법에 대해 알아볼 것이다.

Dereference operator (*)

As just seen, a variable which stores the address of another variable is called a pointer. Pointers are said to "point to" the variable whose address they store.

 

방금 본 대로, 다른 변수의 주소를 저장하는 변수를 포인터 라고 부른다. 포인터들은 자신이 저장하고 있는 변수의 주소를 "가리키고 있는" 것으로 말할 수 있다.

An interesting property of pointers is that they can be used to access the variable they point to directly. This is done by preceding the pointer name with the dereference operator (*). The operator itself can be read as "value pointed to by".

 

포인터의 흥미로운 특성 중 하나는 그들이 가리키고 있는 변수에 직접 접근하는 용도로 쓰일 수 있다는 것이다. 이것은 포인터의 이름 앞에 역참조 연산자 (*) 를 앞에 붙임으로서 시현된다. 연산자 자체는 "~가 가리키는 값" 으로 읽을 수 있을 것이다.


Therefore, following with the values of the previous example, the following statement:

 

그러므로, 앞의 예제의 값들을 계속 이어서, 뒤의 명령문:

 

This could be read as: "baz equal to value pointed to by foo", and the statement would actually assign the value 25 to baz, since foo is 1776, and the value pointed to by 1776 (following the example above) would be 25.

 

이것은 "baz 는 foo 가 가리키고 있는 값과 동일하다" (foo 의 값이 아닌 foo 가 갖고 있는 값의 주소가 갖고 있는 값) 로 읽힐 수 있고 해당 명령문은 실제로 baz 에게 25 의 값을 할당한다. foo 가 1776 이고, 1776 이 가리키는 값은 (위의 예제를 이어보면) 25가 되기 때문이다. 

 

It is important to clearly differentiate that foo refers to the value 1776, while *foo (with an asterisk * preceding the identifier) refers to the value stored at address 1776, which in this case is 25. Notice the difference of including or not including the dereference operator (I have added an explanatory comment of how each of these two expressions could be read):

 

foo 자체는 값 1776 을 의미하고, 반면에 *foo (식별자 앞에 별표 * 가 있는 구조) 는 '주소 1776' 에 있는 값, 이 경우에는 25, 를 의미함을 명확히 구분하는 것이 중요하다.  

 

The reference and dereference operators are thus complementary:

  • & is the address-of operator, and can be read simply as "address of"
  • * is the dereference operator, and can be read as "value pointed to by"

참조 연산자와 역참조 연산자는 고로 상호 보완적이다:

  • & 는 "-의 주소 연산자" 이고, 간단히 "-의 주소" 로 읽을 수 있다.
  • * 는 역참조 연산자이며, "-가 가리키고 있는 값" 으로 읽을 수 있다. (값에 해당하는 주소로 가서 주소에 저장된 값을 참조함 => 역으로 참조하는 느낌)

Thus, they have sort of opposite meanings: An address obtained with & can be dereferenced with *.

 

그러므로, 그 둘은 약간 반대의 의미를 갖고 있다고 볼 수 있다: & 에 의해 참조된 주소는 * 로 역참조될 수 있다.

Earlier, we performed the following two assignment operations:

 

앞서, 우리는 이어지는 두 명령문 연산을 했었다:

Right after these two statements, all of the following expressions would give true as result:

 

그 두 명령문 바로 뒤에 이어지는 표현들은 모두 결과로 'true' 를 반환할 것이다.

 

The first expression is quite clear, considering that the assignment operation performed on myvar was myvar=25. The second one uses the address-of operator (&), which returns the address of myvar, which we assumed it to have a value of 1776. The third one is somewhat obvious, since the second expression was true and the assignment operation performed on foo was foo=&myvar. The fourth expression uses the dereference operator (*) that can be read as "value pointed to by", and the value pointed to by foo is indeed 25.

 

첫번째 표현문은 처음에 myvar 을 25 로 선언했으니 자명하다고 볼 수 있다. 두 번째는 참조 연산자 (&)를 이용하는데, 이것은 myvar 의 주소를 반환하고, 이것은 1776 으로 생각할 수 있을 것이다. 세 번째 역시 당연한 듯 보이는데, 두 번째 표현이 참이고 foo 에게 시행된 연산이 foo=&myvar 이기 때문이다. 네 번쨰 표현은 역참조 연산자 (*) 를 사용하는데, 이는 "-가 가리키는 값"으로 읽을 수 있고, foo 가 가리키는 값은 25 임이 틀림 없다.

So, after all that, you may also infer that for as long as the address pointed to by foo remains unchanged, the following expression will also be true:

 

그래서, 이 모든 것을 통해, foo 가 가리키고 있는 주소가 변하지 않는 한, 다음의 표현은 참이라고 추론할 수 있을 것이다.

 

 

 

http://www.cplusplus.com/doc/tutorial/pointers/

 

profile

Moglobin's

@슈플로프

Take your time 🍋