C - 포인터

markyang92·2024년 3월 14일
0

C

목록 보기
8/10

'&'


int '*'

  • int* num_address
    • 주소를 따라가면 int형 자료가 있다는 뜻
    • 코딩 표준은 int* 변수
      • int *변수 (x)

반환형으로서의 포인터

지역변수 포인터 반환 -> 댕글링포인터 유발

int* func(const int op1, const int op2);
  • 지역 변수의 주소를 반환: 매우 위험
  • 당연히.. 지역변수는 스택메모리! 함수 호출이 끝나면 유효한 메모리가 아니다.
  • 유효하지 않은 포인터 = 댕글링포인터
    • 절대 작성하면 안되는 코드

반환형 포인터 되는 경우

  1. 전역 변수
  2. 파일속 static 전역 변수
  3. 함수내 static 변수
  4. 힙 메모리에 생성한 데이터
    즉, 함수 스택프레임에 들어가지 않으면 괜찮다.

NULL 포인터 문제점

매개변수 편

  • 함수 매개변수로 NULL이 안들어온다고 가정하고 함수 작성할 것
  • NULL이 들어올 수 있는 함수는 매개변수명에서 분명히 밝힐 것
  • 함수의 매개변수가 NULL 포인터를 허용한다면, 매개변수 이름 끝에 '_or_null을 붙인다.
  • NULL이 안 들어온다고 가정한 경우 assert()를 사용해 검증
#include <assert.h>

#define PRICE (2)

void increase_price(int* current_price)
{
	assert(current_price != NULL);
    
    *current_price += PRICE;
}    

반환값 편

  • NULL을 반환해야 한다면 함수 이름에 NULL을 반환하는 것을 명시할 것

NULL 언제 사용하나?

  1. 포인터 변수를 초기화하고 싶을 때
void do_somthing(void)
{
	int* ptr = NULL; /* 당장 사용하지 않으므로 널 포인터로 초기화 */
    
    ptr = &g_monster_count;
}

  1. 포인터 변수가 유효한 주소를 참조하고 있는지 확인하고 싶을 때

  1. 댕글링 포인터를 막기위해
  • 동적 메모리 할당된 메모리 free 후, 포인터 변수는 NULL!을 이용해 리셋

포인터의 크기

  • 모든 포인터는 동일한 크기를 가진다.
  • 포인터 크기 = 시스템 아키텍처에 따라 결정
    • CPU가 한번에 처리할 수 있는 데이터의 크기 = word
      - 32bit arch = 4Byte
      - 64bit arch = 8Byte
  • 다 같은 크기면 왜 int*, char* 나눈 건가?
    • 위에서도 설명했겠지만, int* => 주소를 따라가면 int형 자료가 있다는 뜻

포인터에 배열을 넣어도 배열크기 나오지 않는다.


포인터 연산

  • 포인터에 정수 1을 더하다.1 * sizeof(int) Byte가 더해짐

  • short *라면?
    • 2Byte씩 증가 = +1 * sizeof(short)

  • 억지로 1Byte만 옮기려면
    • (char*)로 캐스팅

포인터 용도

많은(큰) 데이터 매개변수

  • 배열이 매개변수로 전달될 때, 첫 번째 요소의 주소가 전달이 될 뿐 링크

반환 값이 둘 이상일 때


동적 메모리 할당


포인터 배열

  • 포인터를 담는 배열
    • int* 형을 담을 배열
    int* arr[3];

  • 물론 링크 처럼, 포인터에 배열을 할당해도, sizeof()로 배열 크기가 구해지지 않는다.

함수로 활용

  • 링크: 배열을 함수 매개변수로 전달햇을 때, 사실은 배열의 첫번째 포인터가 전달되는 것
  • 링크: 배열을 함수 매개변수로 전달했을 때, 왜 sizeof()로 봤을 때 다른가?
  • +) 포인터 배열내에는 각 내부 배열의 idx를 모르기 때문에 전달해주어야한다.
profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글