[고급 C++]포인터 1편(프로세스/포인터변수/포인터연산/NULL포인터)

 

  프로세스

 

프로세스

정의

메모리에서 실행중인 프로그램

 

특징

- xx번지라고 하는 주소 개념을 가짐

- 메모리 주소 공간은 스택 세그먼트 / 힙세그먼트 / 데이터 / 코드 세그먼트로 구분

- 제한된 공간에 적재하기 위해 운영체제가 관리

 

 

메모리 주소공간

 

- 메모리에 할당된 모든것은 시작주소가 있음

- 메모리 공간

  1) 스택 세그먼트 : 지역변수 저장(임시데이터 저장공간)

  2) 힙 세그먼트 : 동적메모리 할당 요청시 사용되는 공간

  3) 데이터 세그먼트 : 전역변수, 정적변수 저장

  4) 코드 세그먼트 : 프로그램의 실행코드와 함수 저장

 

 

 

 

  포인터

 

포인터

정의

실행중인 프로세스의 임의의 주소

 

특징

메모리 공간의 주소를 확인하고 제어할 수 있는 자료형으로 메모리를 직접 조작할 수 있음

 

 

포인터 자료형

- 1) 포인터 선언 방법  2) 포인터 가져오는 방법  3) 포인터 사용 방법에 따라 자료형에 따라

- 포인터 변수 / 배열 포인터 / 포인터 배열 / 다중 포인터 /함수 포인터 / void형 포인터로 구분★

 

★ 포인터 자료형 식별하는 꿀팁  

 

① 변수니? 주소니? 구분하기 

→ 선언문으로 구분

 - int a;  : 변수

 - int b[1]; : 주소

 

② 주소라고? 그럼 포인터 타입 확인하기

 주소를 따라가서 어떤 타입의 데이터가 들어있는지 확인. 즉, 포인터 타입은 주소에 저장된 대상에 따라 결정.

 

③ 1) 포인터 선언 2) 포인터 가져오기 3) 포인터 사용

 

포인터변수

정의

- 다른 객체(변수)의 메모리 주소를 저장하는 변수

* cf) 변수 : 데이터 값 저장

 

선언

자료형 *변수이름;

 

예시

#include <stdio.h>

// 포인터 : 실행중인 프로세스의 임의의 주소
int main()
{
	double d, *dp;	//선언시* : 컴파일러에게 포인터 변수임을 알림

	d = 1.5;
	printf("%lf, %p \n", d, &d); 

	dp = &d;  
	printf("%lf, %p \n", *dp, dp);	//사용시 *(참조연산자) : dp에 저장된 값

	return 0;
}

※  & (주소연산자) : 변수에 할당된 메모리의 시작주소를 의미하는 연산자

※  *(포인터 연산자) : 포인터 변수가 가리키는 곳의 내용을 참조하는 연산자(실행문)

 

 

주의사항

- 포인터 변수 자료형은 가리킬 것과 같은 자료형이어야 함

- 포인터 변수가 가리키는 번지로 가서 몇바이트로 읽어오는가 즉, 포인터 변수의 자료형 정보 크기만큼 접근

     8     char *ptr;
   ...
    16     ptr = &d;
    17     printf("%lf, %p \n", *ptr, ptr);

!cc pointer1.c

"pointer1.c", line 16: warning #2513-D: a value of type "double *" cannot be assigned to an entity of type "char *"

        ptr = &d;

            ^

* 가리키는 변수의 자료형과 포인터 변수의 자료형이 다르므로 경고

0.000000, 7ffff100

* 주소값을 갖지만 쓰레기 값 존재
가리키는 변수에 할당된 메모리의 시작주소만 알고 자료형의 크기는 알수없으므로 포인터 변수의 크기만큼 데이터를 가져오게 됨
즉, 자신이 가리킬 자료형과 동일한 자료형이어야함

 

#include <stdio.h>

// 포인터 : 실행중인 프로세스의 임의의 주소

int main()
{
	// *로 포인터 알려라
	double d, *dp;
	char *ptr;

	d = 1.5;
	printf("%lf, %p \n", d, &d);

	// 주소는 실행 중에 얻어옴. 실행이 되어야 주소를 아니까
	// dp 공간에 d의 주소를 넣어줘
	dp = &d;	
	// 실행시 *는 가리키는 주소의 값을 참조하라!
	// 즉 dp가 가리키는 곳(d)의 값 출력
	printf("%lf, %p \n", *dp, dp);

	// 포인터 변수의 자료형
	// ptr = &d;
	// d에는 double형의 값이 들어있는데 char형만큼만 읽어와?? ->스레기값
	// printf("%lf, %p \n", *ptr, ptr);	// 0.000000, 7ffff100

	// 메모리 조작 가능 d변경
	*dp = 5.9;
	printf("%lf, %p \n", d, &d);

	// 포인터 사이즈는 운영체제가 결정
	// 포인터에 할당되는 크기는 선언되는 자료형과는 무관
	printf("%d, %d, %d \n", sizeof(d), sizeof(dp), sizeof(ptr));
	
    return 0;
}

/data/it/it03]a.out

1.500000, 7ffff100

1.500000, 7ffff100

5.900000, 7ffff100

8, 4, 4

-  sizeof(포인터) :  메모리에 할당되는 크기는 선언되는 자료형과는 무관하며 운영체제 플랫폼에서 결정 (x86: 4byte / x64 : 8byte)

 

 

 

 포인터연산

- 주소를 대상으로 연산(+, -, ++, --)을 처리하는 것

- 포인터 변수의 자료형 크기에 맞춰 증감

 

#include <stdio.h>

int main()
{
	char ch = 'A', *cp;
	int num = 100, *ip;
	float fnum = 1.1, *fp;
	double dnum = 5.3, *dp;
    
	cp=&ch, ip=&num, fp=&fnum, dp=&dnum;
    
	printf("%c, %d, %f, %lf \n", ch, num, fnum, dnum);
	printf("%p, %p, %p, %p \n", cp, ip, fp, dp);
        
	ch++, num++, fnum++, dnum++;	// 값의 연산
	cp++, ip++, fp++, dp++;		// 포인터 연산


	// 값이 1만큼씩 증가
	printf("%c, %d, %f, %lf \n", ch, num, fnum, dnum);
    
	// 주소값이 자료형만큼씩 증가 (각 1, 4, 4, 8만큼 증가)
	printf("%p, %p, %p, %p \n", cp, ip, fp, dp);

	return 0;
}

A, 100, 1.100000, 5.300000
7ffff0f0, 7ffff0f4, 7ffff0f8, 7ffff100
B, 101, 2.100000, 6.300000
7ffff0f1, 7ffff0f8, 7ffff0fc, 7ffff108

 

 

NULL포인터

- 어떤 것도 가리키지 않는 포인터 값

#define NULL 0
#define NULL ((void*)0L)

 

- 잘못된 번지로 변경하는 것을 막기 위해 포인터 변수를 NULL(0으로 지정)로 초기화

char *ptr = NULL;
char *ptr = 0;


- NULL포인터 사용

 1) 포인터 변수 초기화 : 포인터 변수를 NULL로 초기화하고 프로그램 실행 중 포인터 변수가 임의의 주소를 대입받았는지 확인 하고 그에 따른 행위 기술

 2) 에러 처리 : NULL 포인터는 에러의 유무를 판단할 때 중요하게 사용

 3) 동적 메모리 할당 : 동적 메모리 할당을 요청하고 실패 유무 판단

 


 

 

 

궁금한 사항은 댓글로 남겨주세요💃💨💫
좋아요와 구독(로그인X)은 힘이 됩니다 🙈🙉

 

 

 

[고급 C++]C컴파일러와 C라이브러리(공유/정적/동적라이브러리)

C 컴파일러 #include int main() { printf("Hello World. \n"); return 0; } 컴파일러 종류 cc 유닉스에서 사용하는 표준 C 컴파일러 gcc GNU C 컴파일러로 주로 리눅스 시스템에서 사용함 컴파일 과정 1) 전처..

mk28.tistory.com

 

 

[고급 C++]조건 컴파일 / make

조건 컴파일 전처리기의 이해 전처리란 원시 소스파일을 컴파일하기 전에 행해야 할 작업 특징 - 프로그램이 컴파일되기 전에 선행 - #으로 시작 - ;로 끝나면 안됨 매크로 상수 - #define 문을 이��

mk28.tistory.com

 

 

반응형
그리드형

댓글

❤️김세인트가 사랑으로 키웁니다❤️