사이먼's 코딩노트
[C언어] 포인터 본문
[포인터]
[컴퓨터의 구성]
1. CPU : 연산 기능
- 데이터 처리속도 : 매우 빠름
- Read / Write 속도 : 매우 빠름
2. L1 Cache(캐시) 메모리 : 저장 기능
- 저장용량 : 작음 (보통 8 ~ 64KB)
- Read / Write 속도 : 매우 빠름 (L2보다 빠름)
3. L2 Cache 메모리 : 저장 기능
- 저장 용량 : 작음 (보통 64KB ~ 4MB)
- Read / Wrtie 속도 : 매우 빠름
4. 메모리 : 저장 기능
- 저장 용량 : 작음 (8GB)
- Read / Write 속도 : 빠름
5. 하드디스크 : 저장 기능
- 저장 용량 : 큼
- Read / Write 속도 : 느림
6. PC를 관리하는 소프트웨어 : 운영체제(OS)
- OS가 메모리를 관리한다.
- 우리가 만든 C 프로그램은 운영체제의 관리하에 실행된다.
- 즉, 우리가 만든 프로그램은 운영체제에 메모리를 구걸한다.
- 우리가 만든 변수는 메모리에 할당된다. 예를 들어 우리가 변수에 숫자 10을 넣으면, 그것은 메모리 어딘가에 저장된다.
- 메모리는 크게 2개의 구역으로 나뉜다.
- 힙은 객체들의 세계, 위에서 내려온다.
- 스택은 지역변수들의 세계, 아래에서 올라간다.
[포인터의 구조]
- 포인터는 메모리 상 데이터가 저장되어 있는 주소값이다.
- 포인터 변수는 포인터 값을 저장하는 변수일 뿐이다.
#include <stdio.h>
void pointerPlus(int *num) {
*num += 5;
}
void numPlus(int num) {
num += 5;
}
int main() {
int* p1;
int * p2;
int *p3;
int a = 15;
p1 = &a;
printf("변수 a의 값 : %d\n", a);
printf("int변수 a의 주소 : %d\n", &a);
printf("포인터변수 p1의 값 : %d\n", p1);
printf("p1 주소에 들어있는 실제 값 : %d\n", *p1);
int *p = NULL;
int num = 15;
p = #
*p += 5;
printf("%d\n", *p);
printf("%d\n", num);
(*p)++;
printf("%d\n", *p);
*p++;
printf("%d\n", *p);
int num2 = 15;
numPlus(num2);
printf("numPlus 사용 : %d\n", num2);
pointerPlus(&num2);
printf("pointerPlus 사용 : %d\n", num2);
return 0;
}
- p1, p2, p3는 포인터 변수이며, 포인터 변수를 선언할 때는 타입에 맞춰 *을 붙혀준다.
- 각 포인터 변수에는 값이 아닌 주소값이 들어간다.
- 정수 a에는 15라는 값이 들어가 있지만, &a 와 같이 15를 가진 a의 실제 주소값은 159943921924와 같은 주소값이 들어있다.
- p1 = &a; 같이 작성하면 p1에는 a의 주소가 들어간다.
- p1의 주소로 가서 값을 보기 위해서는 *p로 출력문을 출력해보면 된다. 여기서 *의 뜻은 해당 주소로 간다. 라는 의미이다.
- 포인터 변수인 p는 15라는 정수를 가진 num의 주소인 &num를 가지고있다.
- *p += 5; 는 직접 num에 접근하지 않고 이미 포인터 변수인 p가 num의 주소를 가지고 있기 때문에 *p를 통해 해당 주소로 이동해서 가지고 있는 15라는 값에 5를 더한다는 의미이다.
- 그렇게 되면 출력문을 통해 *p나 num을 출력해보면 둘 다 20이라는 값을 가지고있다.
- 현재까지 p는 20이라는 정수 값을 가지고 있다.
- (*p)++; 연산은 포인터 변수인 p의 주소로 가서 1을 증가하기 때문에 값이 21이 된다.
- *p++; 연산은 ++ 연산자가 더 우선적으로 계산이 되기 때문에 포인터 변수인 p의 주소값에 1을 더하고 해당 주소의 값을 출력한다.
- 주소값에 1을 더하면 기존 num을 주소를 가르키는 p가 아닌 새로운 주소를 가르키기 때문에 해당 주소에 가서 값을 출력해보면 아무것도 들어있지 않다.
- 이렇게 직접 변수에 접근하지 않고 원하는 값을 컨트롤하기 위해서 포인터를 사용한다.
[포인터타입 변수의 크기]
#include <stdio.h>
int main(void) {
// 정수 계열
char* c;
short* s;
int* i;
long* l;
// 실수 계열
float* f;
double* d;
// 여기서 구현
printf("sizeof char : %lu\n", sizeof(char));
// 포인터변수는 타입과 상관없이 크기가 무조건 8바이트이다.
printf("sizeof char : %lu\n", sizeof(c));
printf("sizeof short : %lu\n", sizeof(short));
printf("sizeof short : %lu\n", sizeof(s));
printf("sizeof int : %lu\n", sizeof(int));
printf("sizeof int : %lu\n", sizeof(i));
printf("sizeof long : %lu\n", sizeof(long));
printf("sizeof long : %lu\n", sizeof(l));
printf("sizeof float : %lu\n", sizeof(float));
printf("sizeof float : %lu\n", sizeof(f));
printf("sizeof double : %lu\n", sizeof(double));
printf("sizeof double : %lu\n", sizeof(d));
return 0;
}
- 위 코드에서 각 변수는 포인터 변수들이다.
- 정수 계열과 실수 계열의 크기를 sizeof를 통해 출력한 출력문이다.
- 출력문을 통해 각 타입별로 크기를 출력해보면 정수 계열인 char는 1바이트, short는 2바이트, int는 4바이트, long은 8바이트이다.
- 실수 계열인 float은 4바이트, double은 8바이트이다.
- 하지만 각 타입에 맞는 포인터 변수들의 크기를 출력해보면 모두 8바이트를 나타낸다.
- 포인터 변수들은 주소를 나타내기 때문에 크기가 모두 8바이트이다. 하지만 해당 주소로 이동했을 때의 값들이 서로 다른 타입을 가지고있다는 것이다.
반응형
'C언어' 카테고리의 다른 글
[C언어] 다중 포인터 (0) | 2024.02.06 |
---|---|
[C언어] 포인터 문제풀이 (0) | 2024.02.02 |
[C언어] 함수 문제풀이(2) / 서식지정자와 자료형 (0) | 2024.01.29 |
[C언어] 함수 문제풀이(1) (0) | 2024.01.24 |
[C언어] 함수 (1) | 2024.01.23 |