Let's kick it

[혼공C]ch.09_포인터 본문

c언어

[혼공C]ch.09_포인터

bloggerddori 2025. 2. 8. 23:42
 
눈사람
아티스트
정승환
앨범
그리고 봄
발매일
2018.02.18
6주차
(2/17 ~ 2/23)
Chapter 09 포인터의 핵심 내용을 정리하고 공유하기 Ch.09 도전 실전 예제(p.289) 풀고 인증하기

 

목차

- 숙제

- 코드 실행 화면


 

- 숙제

포인터변수의 메모리 주소를 저장하는 변수로, 사용 범위를 벗어나도 데이터 공유가 가능하다. 선언과 동시에 초기화 가능하며, 사용된 자료형의 형의 크기만큼 메모리 저장공간이 할당된다.

* 기호를 사용해 포인터를 표시하고, 주소 연산자인 &를 이용해 변수와 함께 사용하면 포인터에게 시작 주소가 전달된다. 주소가 저장되면 가리킨다는 의미 사용 가능한데 -> 화살표를 이용해 포인터가 어디 주소를 가리킨다. 그러면 간접 참조연산자 *를 통해 주소를 저장할 포인터를 변수처럼 선언하고 사용가능한데 포인터 변수가 선언되면 일반 변수와 마찬가지로 저장 공간이 할당되고 변수명으로 사용 가능하다.

즉, * 간접 참조 연산자로 사용하는 경우 포인터가 가리키는 메모리 위치의 값을 읽거나 수정할 때 사용된다.

그리고 포인터에 사용된 const는 변수에 사용된 const와는 달리 포인터가 가리키는 변수는 포인터를 간접 참조해 바꿀 수 없다는 의미로 사용된다. 주로 문자열 상수를 인수로 받는 함수에 주로 사용된다.

포인터끼리 대입 연산 가능하지만 가리키는 변수의 자료형이 같아야 한다. 그리고 포인터의 크기는 가리키는 자료형의 크기 관계없이 주소와 포인터는 모두 같다. 하지만 운영체제의 비트에 따라 고정되는 게 다른데 32비트 시스템에서는 4바이트, 64비트 시스템에서는 8바이트로 고정된다.

 

- 추가 숙제 <도전 실전 예제>

 


9 - 1 포인터의 기본 개념

변수의 메모리 주소 확인

%u가 아닌 %p를 사용하니 바로 밑줄이 사라짐. %p는 주소 출력 전용 변환 문자이다.


%u와 %p의 차이점:

%u를 사용할 때의 제한사항:

  • %u는 unsigned int를 출력하는 서식 지정자
  • 32비트 시스템에서는 잘 동작할 수 있지만, 64비트 시스템에서는 주소값을 정확하게 표현하지 못할 수 있음
  • 64비트 시스템에서는 포인터가 8바이트(64비트)이기 때문

%p를 사용하는 이유:

  • %p는 포인터 주소 출력을 위해 특별히 설계된 서식 지정자
  • 시스템의 비트 수에 관계없이 주소값을 정확하게 출력
  • 보통 16진수 형태로 출력되어 메모리 주소를 표현하는 표준적인 방식

따라서 주소값을 출력할 때는 %p를 사용하는 것이 더 안전하고 표준적인 방법.

설명의 편의를 위해 주소값을 10진수로 출력하고, 주소는 음수가 없으므로 %u 변환 문자를 사용했다는 점은 이해 갔지만 그래도 처음부터 %p를 사용하는 게 아닌 %u를 보여주고 설명하는 이유가 뭘까 궁금함에 클로드에게 물어보니

주소도 결국 숫자라는 개념을 이해시키기 위해 %u를 사용해 주소값이 단순히 unsigned int 형태의 숫자라는 걸 직관적으로 보여주고, 이를 통해 메모리 주소의 본직적인 개념을 더 쉽게 이해할 수 있게 단계적으로 자연스럽게 알려주려는 흐름 같다


266p 여기서 잠깐 부분으로, 주소는 보통 16진수로 표기하는데 주소 출력 시 전용 변환 문자인 %p를 사용하는 게 좋은데 주소값의 데이터 크기에 따라 자릿수를 맞춰 16진수 대문자로 출력한다.

주소값 자릿수 16자리로 출력되는데 16진수 한 자리는 4비트에 해당한다는 부분이 한 번에 이해가 가질 않았는데 직접 계산해 보며 이해하니 이해가 대충 가긴 했는데 맞게 한건지 확인하기 위해 클로드에게 물어본 후 맞다고 해서 수식으로 명확히 설명을 첨부한다.

64비트(8바이트) 시스템에서의 주소 표현:

  • 8바이트 = 8 × 8비트 = 64비트

16진수로 변환 시:

  • 16진수 1자리 = 4비트
  • 필요한 16진수 자릿수 = 64비트 ÷ 4비트 = 16자리

따라서 64비트 주소를 16진수로 표현하면 16자리가 필요하다. 16진수를 사용하면 긴 비트열을 더 간단하고 읽기 쉽게 표현할 수 있다.

 

포인터의 선언과 사용

자료형 적을 때 주의점 : 주소 위치에 있는 변수의 자료형 적기

포인터를 사용한 두 정수의 합과 평균 계산

 

포인터에 const 사용

포인터에 사용된 const는 변수를 상수화시켜 고정되는 값이 아니라 포인터가 가리키는 변수를 포인터 변수를 간접 참조해 바꿀 수 없다는 뜻이다. *pa=20;과 같이 pa를 통해 a값을 바꾸고자 한다면 에러 발생. 하지만 다른 변수의 주소는 저장하고 그 값을 간접 참조 가능하다. 이게 변수의 const와의 차이점


 

9 - 2 포인터 완전 정복을 위한 포인터 이해하기

주소와 포인터의 크기

포인터도 저장 공간이므로 그 크기가 있다. 포인터의 크기는 저장할 주소의 크기에 따라 결정되지만 모든 주소와 포인터는 가리키는 자료형과 상관없이 그 크기가  같다.

 

이해가 되는 듯 안되어서 클로드에게 쉽게 설명해달라고 부탁함

우체통과 주소 시스템에 비유해서 설명하자면
우편 주소는 작은 편지를 보내도, 큰 소포를 보내도 주소는 똑같은 길이로 씀.
우체통 번호(주소)의 길이는 안에 들어있는 물건의 크기와 관계 x. 컴퓨터 메모리도 비슷함.

즉, 포인터는 '주소'만 저장하는 변수이기 때문에 가리키는 데이터의 크기와 관계없이, 시스템이 주소를 처리하는 크기(32비트/64비트)에 따라 결정된다.

 

위에 코드와 같은 코드인데 밑줄 표시를 지우기 위해 %zd를 사용함.

 

허용되지 않는 포인터의 대입

포인터지만 가리키는 자료형이 달라 이 경우는 할당된 영역 이후의 할당되지 않은 영역까지 사용하게 됨.

 

- 포인터 없이 두 변수의 값을 바꾸는 함수는 불가능한가?

다른 함수의 변수 사용하기

함수 안에 선언된 변수명은 사용 범위가 함수 내부로 제한되므로 main 함수에 있는 변수는 swap 함수에서 그 이름을 사용할 수 없다.

변수의 값을 인수로 주는 경우

함수 호출 시 main 함수의 변수의 값이 복사되어 매개 변수에 저장되는데 결국 swap 함수 안에는 변수의 복사본을 바꾸므로 값은 변함이 없다. 즉, 이름이 같아도 함수가 다르면 메모리에 별도의 저장 공간을 확보하므로 전혀 다른 변수로 사용됨. 

또, 함수는 오직 하나의 값만을 반환할 수 있으므로 한 번의 함수 호출을 통해 두 변수의 값을 바꾸는 것은 불가능하다.

'c언어' 카테고리의 다른 글

혼공학습단 13기_혼공C 회고  (2) 2025.02.24
[혼공C]ch.10_배열과 포인터  (0) 2025.02.11
[혼공C]ch.08_도전 실전 예제 문제  (0) 2025.02.03
[혼공C]ch.08  (0) 2025.02.02
[혼공C]4주차_ch.07  (0) 2025.02.01