변수와 메모리 위치의 차이점은 무엇입니까? [닫은]


38

최근에는 포인터를 시각적으로 플래시 카드와 같이 설명하려고 노력했습니다.

질문 001 : 컴퓨터 메모리의 위치를 ​​나타내는 그림입니다. 그것의 주소가 사실 0x23452입니까? 왜?

여기에 이미지 설명을 입력하십시오

답변 :0x23452. 컴퓨터가이 위치를 찾을 수있는 위치를 설명 하기 때문 입니다.


질문 002 : 캐릭터 b가 메모리 위치에 저장되어 0x23452있습니까? 왜?

여기에 이미지 설명을 입력하십시오

답 : 아니요. 캐릭터 a가 실제로 그 안에 저장되어 있기 때문입니다.


질문 003 : 포인터가 메모리 위치에 저장되어있는 것이 사실 0x23452입니까? 왜?

여기에 이미지 설명을 입력하십시오

답변 : 예. 메모리 위치의 주소가 0x34501그 안에 저장되어 있기 때문입니다.


질문 004 : 포인터가 메모리 위치에 저장되어있는 것이 사실 0x23452입니까? 왜?

여기에 이미지 설명을 입력하십시오

답변 : 예. 다른 메모리 위치의 주소가 그 안에 저장되어 있기 때문입니다.


이제 걱정했던 부분이 있습니다. 소프트웨어 엔지니어가 다음과 같이 포인터를 설명했습니다.

포인터는 값이 다른 변수의 메모리 주소 인 변수입니다.

모두 보여 드린 네 개의 플래시 카드를 기반으로 포인터를 약간 다르게 정의합니다.

포인터는 값이 다른 메모리 위치의 메모리 주소 인 메모리 위치입니다.

변수가 메모리 위치와 동일하다고 말하는 것이 안전합니까?

그렇지 않다면 누가 옳습니까? 변수와 메모리 위치의 차이점은 무엇입니까?


37
이 암시 적 가정은 상자에서 16 진수는 메모리 주소는 것을 당신의 의도를 알 수 그 그림을 읽는 모든 사람은 여기, 그리고 그 a, 0x23453. nil그 안에있는 것들이 가치입니다. 그것은 당신에게 명백해 보일지 모르지만, 나는 그 필드가 어떻게 정의되어 있는지 보지 않고 그 질문에 결정적인 대답을하는 것이 편안하지 않을 것입니다. a두 번째 이미지에서 문자, 문자열 (다른 경우) 또는 변수 이름 인지 알 수 있는 방법이 없습니다 . 문자열이면 nil문자열입니까? 아니면 "널"값?
ilkkachu

39
질문 1은 나쁜 질문입니다. 그것은 독자들이 다른 질문에 대답하기 전에 독자들에게 알려 주어야 할 것입니다. 질문이 아니라 독자에게 제공되는 정보 여야합니다. "다음 질문에서 상자는 메모리 위치이고 아래의 16 진수는 주소입니다."
26

15
질문 3은 상황에 따라 대답 할 수 없습니다. 바이트 레벨에서 메모리에 저장된 값이 애플리케이션 레벨에서 해석 / 사용되는 방법을 알 수있는 방법이 없습니다.
12

6
주목할만한 점 : 여기서 쓰는 모든 것은 C 또는 C ++에서는 사실이지만 기본적으로 명시 적 포인터 참조 / 역 참조가없는 모든 언어에서는 거짓입니다. 값이 들어가는 슬롯이라는 변수의 전체 은유는 할당이 변수를 복사하지 않고 객체를 가리 키도록하는 언어 (Python, Java, C #, Ruby, JavaScript 등)에 대해 분류됩니다. , 객체에 대한 돌연변이는 객체를 가리키는 모든 변수를 통해 볼 수 있습니다. 파이썬의 문서는 이런 이유로 객체에 매달려있는 이름표로 변수의 대체 은유를 사용합니다.
Mark Amery 12

19
BTW, 당신이 이미 이것을 이해한다면 저를 용서하십시오. 그러나 이것이 혼동의 여지가있는 것처럼 보일 것입니다.이 "0x23452"표기법은 숫자를 16 진수 형식으로 나타내는 방법 일 뿐이며, 편의상 완료되었습니다. 그러나 그것은 단지 숫자 일뿐입니다 .0x 접두사는 그것이 포인터임을 나타내지 않습니다. 메모리에 저장된 것은 말 그대로 의미가없는 숫자입니다 (메모리 위치를 일반 10 진수로 레이블 할 수 있습니다). 의미 (즉, 숫자를 해석하는 방법)는 언어-변수 유형 및 사용 방법에서 비롯됩니다.
Filip Milovanović

답변:


69

변수는 알고리즘의 의도로가는 논리적 구성이고, 메모리 위치는 컴퓨터의 작동을 설명하는 물리적 구성입니다. 일반적으로 프로그램을 실행하기 위해 변수의 논리적 개념과 컴퓨터의 저장소 사이에 (컴파일러 생성) 매핑이 있습니다.

(어셈블리 언어에서도 알고리즘과 의도에 이르는 (논리적) 변수와 (물리적) 메모리 위치에 대한 개념이 있지만 어셈블리에서는 더 복잡합니다.)

변수는 높은 수준의 개념입니다. 변수는 알 수 없음 (수학 또는 프로그래밍 할당에서와 같이) 또는 값으로 대체 할 수있는 자리 표시 자 (프로그래밍 : 매개 변수에서와 같이)를 나타냅니다.

메모리 위치는 저수준 개념입니다. 메모리 위치는 때때로 변수의 값을 저장하기 위해 값을 저장하는 데 사용될 수 있습니다. 그러나 CPU 레지스터는 일부 변수의 값을 저장하는 또 다른 방법입니다. CPU 레지스터도 낮은 수준의 저장 위치이지만 주소가없고 이름 만 있으므로 메모리 위치가 아닙니다.

어떤 의미에서, 변수는 프로그램의 의도를 표현하기위한 추상화 메커니즘이며, 메모리 위치는 저장 및 검색을 제공하는 처리 환경의 물리적 개체입니다.

질문 003 : 포인터가 메모리 위치 0x23452 안에 저장되어있는 것이 사실입니까? 왜?

우리는 확실하게 말할 수 없습니다. 주소로 작동하는 값이 있다고해서 해당 주소임을 의미하는 것은 아니며 정수 (10 진수) ‭144466‬ 일 수 있습니다. 우리는 단순히 수치 적으로 어떻게 보이는지에 기초하여 가치의 해석에 대한 가정을 할 수 없습니다.

질문 004 : 포인터가 메모리 위치 0x23452 안에 저장되어있는 것이 사실입니까? 왜?

이것은 실제로 이상한 질문입니다. 그들은 상자를 기반으로 몇 가지 가정을 예상하지만 각 상자마다 주소가 1 씩 증가한다는 점에 유의하십시오. 현대 컴퓨터에서, 그것은 각 박스가 바이트를 보유 할 수 있음을 의미 할 것입니다. 그러나 바이트는 8 비트에 불과하며 0에서 255 사이의 범위 (서명되지 않은 값의 경우) 일 수 있습니다. 그러나 그들은이 주소들 중 하나에 저장된 훨씬 더 큰 값을 보여 매우 의심 스럽다. (이것이 단어로 주소 지정된 기계라면 가능할 수 있지만, 그렇게 말하지는 않으며 오늘날 일부 기계는 있지만 일부 기계는 그렇지 않습니다.)

모두 보여 드린 네 개의 플래시 카드를 기반으로 포인터를 약간 다르게 정의합니다.

포인터는 값이 다른 메모리 위치의 메모리 주소 인 메모리 위치입니다.

이 생각이 맞는 상황이 있지만 여기서 은유를 섞고 있습니다. 변수의 개념은 알고리즘과 의도로갑니다. 모든 변수에 메모리 위치가 있다고 가정 할 필요는 없습니다. 메모리 위치는 주소 지정을 지원하기 때문에 일부 변수 (특히 배열)에는 메모리 위치가 있습니다 (CPU 레지스터는 이름을 지정할 수 없음).

실행을 위해 변수 및 명령문과 프로세서 메모리 위치 및 프로세서 명령어 시퀀스간에 논리적 매핑이 있습니다. 값이 변하지 않는 변수 (예 : 상수)는 메모리 위치가 필요하지 않습니다. 값은 마음대로 재생산 할 수 있기 때문입니다 (예 : 컴파일러에서 생성 한 코드 시퀀스에 필요).


4
심지어 8 비트 바이트도 여전히 보편적이지 않습니다.
중복 제거기

14
@JimmyJames for컴파일러가 루프를 완전히 풀기로 결정할 때 루프 인덱스 의 경우를 고려하십시오 . 생성 된 출력 코드 (어셈블리 또는 기계 코드 또는 바이트 코드)에는 루프 카운터가 저장되는 메모리 위치가 없습니다. 그러나 여전히 변수입니다.
dmckee

4
@JimmyJames, unrolled-loop 포인터의 경우 코드가 실제로 카운터 값을 사용하는 경우 어딘가에 로드해야 하지만 (a) 해당 위치는 레지스터 일 수 있으며 (b) 언 롤링 된 루프의 모든 반복 에서 왜 동일한 위치에 있어야하는지 이유는 없습니다 .
솔로몬 느린

3
루프가 고정 길이 배열에 복사 같은 일을하는 경우 source동일한 길이의 배열을 dest코드화 루프 for (int i=0; i<8; ++i) dest[i] = source[i];힘이 아니라 반복에 뭔가 동등한 아래로 컴파일 dest++ = source++;시간의 적절한 수. 루프 카운터 자체를 사용하면 증거가 어디에도 없습니다 (레지스터조차도 아님). 반복 횟수 만 루프 조건에 대해 알려줍니다.
dmckee

2
그 의미는 메모리가 번호가 매겨진 위치로 구성된 기계의 추상화에 밀접하게 기초하는 C와 같은 언어에 의해 다소 혼동된다.
마이클 케이

20

변수가 메모리 위치와 동일하다고 말하는 것이 안전합니까?

아니요. 변수 및 메모리 위치는 두 개의 서로 다른 추상화 수준에서 두 개의 추상화입니다. 변수 및 포인터는 코드 / 언어 레벨에서 상위 레벨 개념이며, 메모리 위치는 기계 레벨에서 하위 레벨 개념입니다. 코드가 실행 파일로 컴파일되면 더 이상 변수가 없습니다. 이런 방식으로 메모리 위치와 변수에 대해 이야기하려고 시도하는 것은 범주적인 오류입니다.

변수는 메모리를 사용하여 구현할 수 있지만 컴파일러가 계산을 최적화하고 변수와 관련된 모든 계산을 레지스터에 완전히 수행하거나 단일 변수를 여러 메모리 위치에 배치하거나 단일 메모리를 사용할 수있는 것은 아닙니다 여러 변수의 위치.

포인터는 값이 다른 메모리 위치의 메모리 주소 인 메모리 위치입니다.

이 일련의 플래시 카드는 너무 혼란 스러우며 옳지 않을뿐만 아니라 잘못되었습니다.


1
Once a code had been compiled into an executable, there's no longer any variables.그것은 내가 반론에 동의하지 않는 것입니다. 변수 가 아는 것처럼 (즉, 해당 이름으로) 더 이상 존재하지 않는 것이 맞지만, 구문 분석은 컴파일 된 실행 파일이 메모리 주소 만 사용한다고 제안하는 것 같습니다. 맞지 않습니다. 컴파일되었지만 실행되지 않는 실행 파일은 실행될 때 사용할 메모리 주소를 모릅니다. 변수의 개념 (즉, 런타임에 할당 될 메모리 주소에 대한 재사용 가능한 참조)은 여전히 ​​컴파일 된 실행 파일 내에 존재합니다.
Flater

2
또는 컴파일러는 다양한 방법으로 변수를 완전히 멀리 최적화 할 수 있습니다. 불필요한 변수를 제거하여 미리 계산합니다. 변수가 상수이면 컴파일러는 상수를 사용하는 CPU 명령어를 사용하여 끝날 수 있으며 더 이상 변수가 더 이상 어디에도 포함되지 않는다고 주장합니다.
kutschkem

16

변수는 언어 구조 입니다. 그것들은 이름을 가지고 있고, 범위 내에 있으며, 코드의 다른 부분들에 의해 참조 될 수 있습니다. 그것들은 논리적 인 엔티티입니다. 관찰 가능한 동작이 언어 표준에 의해 규정 된 한 컴파일러는 원하는 방식으로이 언어 구문을 자유롭게 구현할 수 있습니다. 따라서 컴파일러가 필요하지 않다는 것을 증명할 수 있다면 변수를 어디에도 저장할 필요가 없습니다.

메모리 위치는 하드웨어 개념 입니다. 그들은 가상 / 물리적 기억의 장소를 나타냅니다. 모든 메모리 위치에는 정확히 하나의 물리적 주소와이를 조작하는 데 사용할 수있는 가상 주소가 있습니다. 그러나 각 메모리 위치에는 항상 정확히 1 바이트가 저장됩니다.

포인터는 특별한 종류의 입니다. 무언가를 말하는 것은 어떤 것이 유형이라고 말하는 것과 유사하다 double. 값에 사용되는 비트 수와 해당 비트가 해석되는 방법을 나타내지 만이 값이 변수에 저장되어 있거나이 값이 메모리에 저장되어 있다는 의미는 아닙니다.


C의 예를 제공하려면, I는 2 차원 배열이 때 int foo[6][7];난과의 요소를 액세스 foo[1][2]한 후 foo배열을 유지하는 변수이다. foo이 컨텍스트에서 사용 되면 배열의 첫 번째 요소에 대한 포인터로 바뀝니다. 이 포인터는 변수에 저장되지 않으며 메모리에 저장되지 않으며 값은 CPU의 레지스터 내에서만 생성되어 사용 된 다음 잊어집니다. 마찬가지로, foo[1]이 문맥에서 표현식 은 또 다른 포인터로 바뀌며, 다시 변수에 있지 않고 메모리에 저장되지 않고 CPU에서 계산되어 사용 및 잊혀집니다. 세 가지 개념 변수 , 메모리 위치포인터 는 실제로 세 가지 다른 개념입니다.


Btw, 나는 정말로 "각 메모리 위치에 항상 정확히 1 바이트가 저장되어있다"는 것을 의미했습니다. 50 년 전의 컴퓨팅 시대에는 그렇지 않았지만 오늘날 사용되는 거의 모든 하드웨어에 적용됩니다. 1 바이트보다 큰 메모리에 값을 저장할 때마다 실제로 여러 개의 연속 메모리 위치를 사용합니다. 즉, 빅 엔디안 바이트 순서를 가정하면 숫자 0x01234567은 다음과 같이 메모리에 저장됩니다.

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(X86 아키텍처와 같은 리틀 엔디 언 머신은 바이트를 역순으로 저장합니다.) 이것은 포인터에도 적용됩니다. 64 비트 머신의 포인터는 각각 고유 한 메모리 주소를 가진 8 개의 연속 바이트로 저장됩니다. 메모리 셀을보고 "아, 이것은 포인터입니다!"라고 말할 수 없습니다. 메모리를 볼 때 항상 바이트 만 표시됩니다 .


연속적인 메모리 위치 그룹이 언제 시작하고 끝나는 지 컴퓨터는 어떻게 알 수 있습니까?
progner

6
@progner 그렇지 않습니다. 그것은 해석 이 얻는 지침에 따라 메모리에 바이트를. 이러한 명령어는 일련의 바이트 자체에만 저장됩니다. CPU에서 명령어를 보유한 바이트, 문자를 보유한 바이트 및 일부 부동 소수점 비트를 보유하는 바이트 간의 유일한 차이점은 이 바이트를 사용하도록 지시받은 방법 입니다. 프로그램 카운터가 바이트를 가리 키기 때문에 바이트가 페치되면 명령으로 사용됩니다. 명령어가 부동 소수점 레지스터로로드하라는 명령으로 인해 페치 된 경우 부동 소수점 데이터로 사용됩니다.
cmaster

7
@progner 실제로 폰-뉴먼 아키텍처의 핵심 혁신이었습니다. 명령어와 데이터를 동일한 메모리에 저장하여 나중에 명령어가 더 많은 명령어로 실행되는 데이터를 변경할 수 있도록합니다. 이를 통해 자체 수정 코드를 사용할 수 있었지만 시스템 커널이 일부 프로그램을 메모리에로드 한 다음 CPU에게 해당 프로그램을 실행하도록 지시 할 수 있습니다. 폰-뉴 우먼 이전에 Zuse 머신과 같은 컴퓨터는 자신이 조작 한 데이터와 완전히 독립적 인 채널을 통해 지시를받습니다.
cmaster

5

당신의 실제 질문에 집중하도록하겠습니다 – "누가 맞습니까?" 이 두 문장을 비교할 때 :

  • 포인터는 값이 다른 변수의 메모리 주소 인 변수입니다
  • 포인터는 값이 다른 메모리 위치의 메모리 주소 인 메모리 위치입니다.

이것에 대한 대답은 none 입니다. 첫 번째는 "다른 변수의 메모리 주소"에 대해 말하지만, 다른 답변이 이미 설명한 것처럼 변수에 반드시 메모리 주소가있는 것은 아닙니다. 두 번째 포인터는 "포인터는 메모리 위치입니다"라고 말하지만 포인터는 문자 그대로 숫자로 변수에 저장 될 수 있지만 이전과 마찬가지로 변수에 반드시 메모리 주소가있는 것은 아닙니다.

보다 정확한 진술을위한 몇 가지 예 :

  • "포인터는 메모리 위치의 메모리 주소를 나타내는 숫자"또는

  • "포인터 변수는 값이 메모리 위치의 메모리 주소 인 변수입니다."

  • "메모리 주소는 메모리 위치의 메모리 주소를 나타내는 포인터를 보유 할 수 있습니다."

때때로 "포인터"라는 용어는 "포인터 변수"의 바로 가기로 사용되는데, 이는 혼동되지 않는 한 괜찮습니다.


포인터가 자신을 가리킬 수 있으므로 "다른"을 "a"로 변경할 수 있습니다.
피터 B

@PieterB : nitty, nitty ;-) 이것이 원래의 문구를 실제로 합리적으로 만드는 데 필요한 정도로만 변경하고 싶었 기 때문에 이것이 실제로 명확하게되는지 확실하지 않습니다. 그러나 아아, 나는 편집했다.
Doc Brown

공평하게 말하면, nitpicky를 얻었을 때 "포인터는 문자 그대로 숫자입니다."도 정확하지 않습니다. 실제로 포인터는 숫자를 나타내는 식별자입니다. 세부.
자이 비스

2
포인터는 잠재적으로 일부 객체를 참조하는 값입니다 (번호는 이미 일부 구현에 너무 구체적입니다). 널 포인터, 와일드 포인터 및 매달린 포인터도 있지만 잠재적으로 사용되는 언어에 의해 일부 또는 전부가 제외 될 수 있습니다.
중복 제거기

2
@ 중복 제거기 : 당신 말이 맞지만, 숫자의 포인터의 정신 모델 이이 질문의 목적에 충분하다고 생각합니다. 따라서 일을 단순하게 유지합시다.
Doc Brown

5

포인터가 주소를 포함하는 메모리 위치라고 말하지 않을 것입니다. 하나, 나는 0x23453단일 바이트에 맞는 아키텍처를 알지 못합니다 . :) 바이트 / 워드 구분을 핸드 웨이드로 분리하더라도 모든 메모리 위치에 주소가 포함되어 있다는 문제가 여전히 있습니다 . 주소는 숫자 일 뿐이며 메모리 내용은 숫자 일뿐입니다.

여기서의 트릭은 "포인터" 가 아키텍처의 특정 기능이 아니라 인간 의도를 설명하는 것이라고 생각합니다 . "문자"또는 "문자열"이 메모리에서 볼 수있는 구체적이지 않은 방식과 비슷합니다. 모두 숫자 일 뿐이지 만 처리되는 방식이기 때문에 문자열로 작동합니다. "포인터"는 단순히 주소로 사용되는 값을 의미합니다.

솔직히, 당신의 목표가 특정 언어 를 가르치는 것이라면 (객관적 C?), 나는 고전적인 메모리 테이프를 그리는 것이 그다지 유용하지 않다고 확신합니다. 이미 입력 한 값과 바이트에 비해 너무 큰 값을 표시하여 하얀 거짓말을하고 있습니다. 역학이 아닌 시맨틱을 가르치십시오. 포인터에 대한 핵심 통찰력은 포인터를 간접적으로 제공한다는 것 입니다. 이는 매우 유용한 도구입니다.

나는 데이터 를 어디 에서 찾을 수 있는지 알려주는 URL과 비교할 수 있지만 데이터 자체는 아닙니다. 내 말을 들어 :

  • 당신은 거의 URL이 실제로하든 상관 없습니다 이다 ; 그들 중 대다수는 이름과 관련하여 멀리 떨어져 있습니다. 많은 사람들 이 URL이 페이지에 어떤 영향을 미치는지 정확히 몰라도 인터넷을 사용합니다 . 어떤 사람들은 URL을 완전히 모르고 있습니다.

  • 모든 문자열이 URL이거나 URL로 사용되는 것은 아닙니다.

  • 가짜 URL 또는 존재했지만 삭제 된 페이지를 방문하려고하면 오류가 발생합니다.

  • URL은 이미지, 일부 텍스트, 음악 또는 기타 여러 개별 항목을 가리 키거나 다양한 내용이 포함 된 페이지를 가리킬 수 있습니다. 레이아웃은 비슷하지만 데이터가 다른 전체 페이지를 갖는 것이 매우 일반적입니다.

  • 웹 페이지를 만들고 다른 웹 페이지의 데이터를 참조하려는 경우 해당 웹 페이지를 모두 복사하여 붙여 넣을 필요는 없습니다. 당신은 그것에 링크를 만들 수 있습니다.

  • 다른 수의 다른 페이지는 동일한 URL에 연결할 수 있습니다.

  • 유사한 페이지 모음이있는 경우 모든 페이지에 대한 링크를 나열하는 색인 ​​페이지를 만들거나 1 페이지 하단에 2 페이지로 이동하는 "다음"링크가있을 수 있습니다. 특히 웹 마스터가 다양한 장소에서 페이지를 추가하거나 제거하기 위해해야 ​​할 일을 고려할 경우 두 가지 방법의 장점과 단점이 즉시 명백합니다.

이 비유는 매우 명확하게 포인터가 무엇인지 에 대해 그렇지 않으면 그냥 복잡, 임의 및 무의미한 것 -을 이해하는 데 중요하다. 이미 무엇을하고 왜 유용한 지 이해한다면 어떤 것이 어떻게 작동 하는지 이해하는 것이 훨씬 쉽습니다. 당신은 이미 포인터가 뭔가 다른 곳을 알려줍니다 일부 블랙 박스는, 그 내면화 한 경우 다음 당신이 주소가 상당히 알 수있는 바와 같이 다음 포인터를 대표하는 메모리 모델의 복잡한에 대해 알아보세요. 또한 시맨틱 스를 가르치면 학생들이 다른 형태의 간접 지식을 이해하고 발명 할 수있는 훨씬 더 나은 장소에있게됩니다. 대부분의 주요 언어에 포인터가 전혀 없을 때 좋습니다!


every memory location contains an address-모든 메모리 위치 에는 주소가 있습니다. 포인터 변수를 제외하고는 어디에도 포함되어 있지 않습니다 .
Robert Harvey

@RobertHarvey 모든 메모리 위치 (단어, 적어도)는 숫자로 구성 되며 , 주소 사소하게 해석 될 수 있습니다 . 요점은 하드웨어의 어떤 주소도 주소와 다른 주소를 구별하지 않는다는 것입니다
Eevee

2

이미 답변을 수락했으며이 질문에 5 개의 답변이 이미 있지만 그들이 언급하지 않은 점이 있습니다. CS 교재는 종종 프로그래밍 언어의 선택에 대해 불가지론적인 태도를 취하려고 시도하는데, 이는 사물을 설명하는 데 사용되는 용어가 보편적이라는 암시적인 가정으로 이어집니다. 그렇지 않습니다.

C에서는 단항 앰퍼샌드 연산자를 "주소"연산자라고합니다. C 프로그래머는 표현식 &x이 변수 x의 주소로 평가 된다고 주저하지 않을 것 입니다. 물론 그들은 "변수 x의 값이 저장되는 메모리 주소"를 의미하지만 아무렇지도 않은 대화에서 그와 같은 사람은 아무도 없습니다. C에서 단어 "포인터"는 일반적으로 메모리 주소를 값으로 갖는 변수의 데이터 유형을 나타냅니다. 또는 값의 데이터 유형과 동일합니다. 그러나 어떤 사람들은 "포인터"를 가치 자체로 사용합니다.

Java에서 객체 또는 배열 유형의 모든 변수는 C 포인터와 비슷하게 동작하지만 (포인터 산술 제외) Java 프로그래머는 포인터가 아닌 참조를 호출합니다.

C ++은 참조와 포인터를 다른 개념으로 간주합니다. 그것들은 관련이 있지만 완전히 같은 것은 아니기 때문에 C ++ 프로그래머는 대화에서 구별해야합니다. 앰퍼샌드는 일부 상황에서는 "주소"로, 다른 상황에서는 "참조"로 읽습니다.

포인터는 값이 다른 변수의 메모리 주소 인 변수입니다.

C 프로그래머가 "int"와 같은 의미로 "포인터"를 사용하여이를 설명 할 수있는 방법입니다. ( "in 포인터는 메모리 주소를 보유하고 int는 특정 범위 내의 정수를 보유합니다."

포인터는 값이 다른 메모리 위치의 메모리 주소 인 메모리 위치입니다.

"is"에 대한 매우 느슨하고 비공식적 인 정의가 필요하기 때문에 그것은 이상한 방법입니다.

변수가 메모리 위치와 동일하다고 말하는 것이 안전합니까?

메모리 주소가 변수의 값이 저장된 메모리의 위치라고 말하는 것이 더 분명합니다. (컴파일러 최적화로 인해 모든 변수가 메모리에 저장되는 것은 아니지만 주소가 사용되는 모든 변수가 저장됩니다 &x.)


우리가 pedantic되고있는 동안 : 무언가가 저장되는 주소. 어떤 것도 저장할 수없는 주소 외에, 종종 물건이 여러 인접 위치에 저장되는데, 그 중 하나 (일반적으로 다소 일관된 규칙에 의해 선택됨) 중 하나만 주소가 지정됩니다 (및 잠재적으로 많은 주소 중 하나만 사용).
중복 제거기

@ 중복 제거기 나는 pedantic하려고하지 않습니다.
gatkin

C 표준은 공식적으로 스레드 안전을 위해 모든 "시퀀스 포인트"에서 추상 머신의 단계를 엄격하게 따라야하는 변수와 메모리 매핑 된 하드웨어의 특정 저수준 작업과 그렇지 않은 변수를 구별합니다. t는 레지스터로 자유롭게 이동하거나 완전히 최적화됩니다.
Davislor

@Davislor : C 표준은 변수가 아닌 다른 것들을 설명 할뿐만 아니라 다른 언어 사양이 "변수"를 사용하는 곳에서 "개체"라는 용어를 사용합니다. 일부 논의에서는 언어에 구애받지 않는 용어 "변수"를 사용할 수 있지만, 어떤 이유로 든 표준에는 명명 된 분리 할당 (변수)과 중첩 된 할당 (구조 / 연합 멤버) 또는 명명되지 않은 객체와 같은 다른 종류의 객체를 구별 할 용어가 없습니다. 포인터를 역 참조함으로써. 비공식적으로 "가변"은 훌륭한 용어이지만 표준에서는 사용하지 않습니다.
슈퍼 캣

@supercat 맞지 않습니다. C11 표준은 "가변"이라는 용어를 백 번 이상 사용하는데, 그 중 수십 개가 명사입니다. 예를 들어 "원자 연산을 통해 초기화되는 변수에 대한 동시 액세스는 데이터 레이스를 구성합니다."
Davislor

1

명령문 A 포인터는 값이 다른 변수의 메모리 주소 인 변수 입니다. 그러나 독자는 메모리 위치가 정확히 무엇인지, 그것이 변수와 어떻게 다른지 이해할 때까지 포인터가 정확히 무엇인지 이해하므로 더 이상이 부정확 한 설명에 의존 할 필요가 없습니다.

명령문 A 포인터는 값이 다른 메모리 위치의 메모리 주소 인 메모리 위치 입니다. 포인터의 값은 메모리 위치에 저장 될 필요가 없으며, 의도 된 "메모리"의 정의에 따라 포인터가 메모리 위치를 가리켜 야하는 경우에는 논란의 여지가 있습니다.

변수와 메모리 위치의 차이점

메모리 위치는 데이터를 저장할 수있는 여러 가능한 장소 중 하나입니다. 해당 데이터는 변수이거나 변수의 일부일 수 있습니다. 변수는 데이터에 레이블을 지정하는 방법입니다.


0

이 답변은 C 및 C ++에 중점을 둡니다. 귀하의 질문이 다른 언어보다 C / C ++의 더 중요한 부분 인 포인터와 관련되어 있기 때문에 적절합니다. 이 게시물의 대부분은 정교한 런타임 (파스칼 또는 Ada와 같은 Java 또는 C #과 같은)없이 대부분의 컴파일 된 언어에 적용됩니다.

이미 주어진 좋은 답변은 변수가 물리적 메모리보다 더 추상적 인 수준의 언어 구성이라는 것을 강조합니다. 이 추상화에는 특정 이론적 근거와 시스템이 있음을 강조하고 싶습니다.

추상화는 주로 리터럴 주소 대신 이름을 사용하는 것으로 구성됩니다.

기본 아이디어는 변수가 유형이 지정된 개체의 명명 된 핸들이라는 것입니다. C / C ++의 객체는 일반적 으로 메모리에 있습니다. 그런 다음 언어는 수명 관리 및 형식 변환을위한 데이터 마샬링과 관련된 유용한 기능을 추가합니다. 변수의 개념은 실제 주소보다 더 추상적입니다. 실제로 주소의 숫자 값이나 메모리에서 함수의 정확한 위치는 신경 쓰지 않기 때문입니다. 우리는 단순히 이름을 짓고 나중에 이름으로 주소를 지정하며 컴파일러, 링커 및 런타임 시스템은 세부 사항을 처리합니다.

그리고 C / C ++가 메모리와 무관하다고 가정하지 마십시오. 결국 보편적으로 적용되는 주소 연산자가 있습니다. 예, 사실, 레지스터 스토리지 클래스에서 C 변수의 주소를 사용할 수 없습니다. 하지만 언제 마지막으로 사용한 적이 있습니까? 논쟁의 도매 해고가 아니라 일반적인 개념에 대한 특별한 예외입니다. 반대로, 일반적으로 변수의 주소를 취하면 실제로는 그렇지 않은 경우에도 (예를 들어 상수를 사용하여) 컴파일러가 실제로 메모리에 객체를 생성해야합니다. "명명 된 핸들"개념은 C ++ 참조에 대한 패러다임이기도합니다. 참조는 동일한 객체에 대한 또 다른 이름 일뿐 입니다.

68k에 대한 인라인 어셈블러를 작성할 때 레지스터를 주소 지정하기 위해 변수 이름을 오프셋으로 사용하는 방법을 알 수있었습니다 (그리고 register베어 메탈 레지스터 이름 대신 선언 된 변수 이름을 사용할 수 있습니다 !). 컴파일러 에게 변수는 상수 주소 오프셋입니다. 반복 : 변수는 일반적으로 메모리의 객체에 대해 핸들로 명명됩니다.


포인터는 C #, Java, JS 및 기타 언어의 매우 기본적인 부분입니다. PR이라고하더라도 다르게 호출해도 변경되지 않습니다.
중복 제거기

@Deduplicator :-) Good ol 'Tony ...
Peter-Reinstate Monica

0

"표준의 일부 또는 구현 문서가 일부 동작의 동작을 설명하고 일부는 정의되지 않은 것으로 분류하는 경우" "가 지배적이다."는 물론 다른 언어의 용어 사용과 일치하는 "가변"의 정의.

이 언어에서 각 메모리 위치는 항상 몇 개의 비트 (보통 8 개)의 비트를 보유하는 번호가 매겨진 사서함으로 볼 수 있으며, 각 비트는 독립적으로 0 또는 1 일 수 있습니다. 메모리 위치는 일반적으로 2, 4 또는 8 행으로 구성됩니다. 일부 작업은 여러 연속 메모리 위치에서 한 번에 처리됩니다. 머신에 따라 2 개, 4 개 또는 8 개의 메모리 위치 그룹에서 작동하는 일부 작업은 단일 행 내의 위치에서 작동하도록 제한 될 수 있습니다. 또한 일부 컴퓨터에는 연속적으로 번호가 매겨진 사서함이있는 단일 방이있을 수 있지만 다른 컴퓨터에는 여러 개의 분리 된 번호가 지정된 사서함 그룹이있을 수 있습니다.

변수는 독점적으로 연관된 메모리 위치 범위와 해당 메모리 위치를 해석해야하는 유형을 식별합니다. 변수를 읽으면 관련 저장 위치 내의 비트가 변수 유형에 적합한 방식으로 해석되고 변수를 쓰면 관련 비트가 해당 유형 및 값에 적합한 방식으로 설정됩니다.

주소는 사서함을 식별하는 데 필요한 모든 정보를 캡슐화합니다. 이 번호는 간단한 숫자로 저장되거나 해당 그룹 내의 사서함 수와 함께 일종의 그룹 지정자로 저장 될 수 있습니다.

&연산자를 변수에 적용하면 주소와 유형을 캡슐화하는 포인터가 생성됩니다. 단항 *또는 []연산자를 포인터에 적용하면 캡슐화 된 주소에서 시작하는 사서함 비트가 캡슐화 된 유형에 적합한 방식으로 해석되거나 설정됩니다.


질문을 지나치게 생각하는 것처럼 들립니다.
Robert Harvey

0

나는이 파티에 늦게 올 것이다. 그러나 나는 나의 2 센트를 넣는 것을 저항 할 수 없다.

이때 메모리 위치에 저장된 값의 차이는 무엇입니까?

시간 1

여기에 이미지 설명을 입력하십시오

시간 2

여기에 이미지 설명을 입력하십시오

정답 : 없음. 그것들은 모두 의미가 다른 해석으로 제시된 동일한 값입니다.

어떻게 알 수 있습니까? 내가 이것을 만든 사람이기 때문에. 당신은 아직 그것을 정말로 모른다.

내가 대역 외 문제 라고 부르는 것이 있습니다. 이러한 값의 의미를 올바르게 해석하는 방법은 여기에 저장되지 않습니다. 그 지식은 다른 곳에 저장됩니다. 그러나이 값들을 종이에 제시 할 때 그 해석에 넣습니다. 즉, 이러한 메모리 위치에 존재하지 않는 정보를 추가했음을 의미합니다.

예를 들어, 여기의 값은 동일하지만 ASCII / UTF-8 문자 인코딩이 EBCDIC이 아니라 첫 번째 문자를 얻은 방법 이라고 가정 할 때 올바른 경우에만 사실임을 알고 있습니다 . 또한 두 번째는 메모리 위치에 저장된 숫자 값의 16 진수 표현이라고 가정해야합니다.이 값은 모두 "0x"로 시작하는 문자열에 대한 참조가 아니라 다른 주소에 대한 포인터 일 수 있습니다. :피

이 메모리 위치에 저장된 내용은 해당 가정 중 어느 것이라도 정확하지 않습니다. 해당 정보를 저장할 수 있습니다. 그러나 다른 곳에 저장 될 것입니다.

이것이 프리젠 테이션 문제 입니다. 제시 방법에 먼저 동의하지 않으면 어떤 숫자도 표현할 수 없습니다. 가정, 규칙 및 컨텍스트에 의존 할 수 있지만 프레젠테이션을 명시 적으로 정의하지 않은 경우 깊이 긁으면 "충분한 정보"가 유일합니다.


동일한 메모리가 다른 일정한 것들에 동시에 사용될 때 훨씬 더 재미 있습니다.
중복 제거기

@ 중복 제거기 True. 그것은 항상 c ++의 재 해석 캐스트를 생각하게합니다 . 동일한 비트가 다른 방식으로 보입니다.
candied_orange

@Deduplicator, 또는 생각하면, c의 노동 조합
candied_orange
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.