[고급 C++]포인터 1편(프로세스/포인터변수/포인터연산/NULL포인터)
- 컴퓨터공학과/Programming
- 2020. 10. 20.
프로세스 |
프로세스
정의
메모리에서 실행중인 프로그램
특징
- 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; |
!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 |
NULL포인터
- 어떤 것도 가리키지 않는 포인터 값
#define NULL 0
#define NULL ((void*)0L)
- 잘못된 번지로 변경하는 것을 막기 위해 포인터 변수를 NULL(0으로 지정)로 초기화
char *ptr = NULL;
char *ptr = 0;
- NULL포인터 사용
1) 포인터 변수 초기화 : 포인터 변수를 NULL로 초기화하고 프로그램 실행 중 포인터 변수가 임의의 주소를 대입받았는지 확인 하고 그에 따른 행위 기술
2) 에러 처리 : NULL 포인터는 에러의 유무를 판단할 때 중요하게 사용
3) 동적 메모리 할당 : 동적 메모리 할당을 요청하고 실패 유무 판단
궁금한 사항은 댓글로 남겨주세요💃💨💫
좋아요와 구독(로그인X)은 힘이 됩니다 🙈🙉
'컴퓨터공학과 > Programming' 카테고리의 다른 글
[고급 C++]포인터 3편(배열 포인터/포인터 배열/문자열 상수 포인터) (2) | 2020.10.22 |
---|---|
[고급 C++]포인터 2편(배열과 포인터) (0) | 2020.10.21 |
[고급 C++]조건 컴파일 / make (0) | 2020.10.19 |
[고급 C++]C컴파일러와 C라이브러리(공유/정적/동적라이브러리) (0) | 2020.10.18 |
[C++]최대공약수 구하기(3가지 방법, 유클리드 호제법) (0) | 2020.05.05 |