본문 바로가기
개발&코딩/C

[C] 포인터와 메모리 기초 &,*

by 우동이 2020. 9. 10.
300x250

Pointer는 C언어가 가진 대표적인 기능 중 하나이다 

포인터 말 그대로 가리킨다 라는 의미를 충실히 수행하는 기능으로써

말 그대로 변수와 변수의 주소를 가리키는 의미를 가진다

scanf()에서 변수를 입력받을 때에 &연산자를 사용하는 이유도 여기서 알 수 있다.

C언어 - 포인터란? 그리고 메모리의 구조

#include <stdio.h>

int main()
{
    char ch;
    int in;
    double db;
	
    printf("%u\n", &ch);
    printf("%u\n", &in);
    printf("%u\n", &db);
	
    return 0;
}
>>> 6487579, 6487575, 6487567

우리가 변수를 생성하면 그 변수는 메모리상의 한 부분에 할당이 된다

그 할당된 부분을 가리키는 것이 포인터 위치한 메모리상의 공간이 주소값이 된다.

즉 우리가 실제 메모리 주소를 사용하기 위해 포인터로 가리킴으로써 사용하게 되는데

 

위 코드에서는 %u를 통해 출력했다 ( %u -> 부호없는 십진수)

그리고 각각 int형 double형 char형 변수의 &(주소연산자) 메모리 상에 위치한 주소를 출력했는데

 

출력된 숫자를 잘 살펴보면 각각 변수간의 위치에 차이가 나는 값을 살펴볼 수 있다.

int <-> double 변수간의 사이에는 8bytes( double형의 크기) 차이가 나고

char <-> int 변수간의 사이에는 4bytes(int형의 크기) 공간 차이가 발생함을 알 수 있다.

C언어 - 포인터 사용해서 변수에 값 대입하기

#include <stdio.h>

int main()
{
    char ch;
    int in;
    double db;
    
    printf("값 대입전\n");
    printf("ch의값 : %c\n", ch);
    printf("in의값 : %d\n", in);
    printf("db의값 : %lf\n", db);
    
    *&ch='p';
    *&in=30;
    *&db=3.14;
    
    printf("값 대입후\n");
    printf("ch의값 : %c\n", ch);
    printf("in의값 : %d\n", in);
    printf("db의값 : %lf\n", db);
	
    return 0;
}

>>> 
값 대입전
ch의값 :
in의값 : 1
db의값 : 0.000000
값 대입후
ch의값 : p
in의값 : 30
db의값 : 3.140000

위 코드는 포인터를 사용해 변수들에 값을 대입하는 프로그램이다.

값을 대입하기 전에는 각 변수에 초기화하지 않은 상태에서 출력한 일명 "쓰레기값"이 들어가있는데

*&변수 즉 실제 메모리를 참조한 곳에 값을 대입하게 되면 

우리가 변수를 선언한 후 값 초기화하는 결과와 동일하게 값이 대입된다.

 

&주소연산자에 *참조연산자를 더하면 int *&a(a변수의 주소를 참조한다)

C언어 - 포인터변수

#include <stdio.h>

int main()
{
    int a=10;
    int *ap;
    ap=&a;
    
    printf("%d\n", a);
    printf("%d", *ap);
	
    return 0;
}
>>>
10
10

포인터변수는 변수의 시작주소값을 담아 참조한다

즉 포인터변수를 선언한 후 참조할 변수의 주소를 참조해야 한다 &연산자를 통해서 말이다.

그리고 포인터변수가 변수의 시작주소값을 참조한다는 게 중요한 이유가 따로 있다

 

포인터를 사용할 수 있는 영역이 단일 변수가 아닌 배열인 경우에도 사용할 수 있는데

다양한 변수들의 합이 존재함을 생각할때 시작주소를 참조하는 것이 배열을 사용할 수 있게 해주는 포인트이다

 

또한 변수의 주소값 즉 시작주소값을 포인터변수에만 담아 사용하는 이유가 무엇인가

왜 일반 정수형 변수에 담지 않는가라는 의문을 가질 수도 있는데

시작주소라는 값이 담긴 메모리의 기억공간은 기억공간으로써 고유한 주소값으로 존재해야만 하는데

일반 변수에만 값을 담으면 그 고유함이 사라지기 때문이다.

 

C언어 - 포인터예제1 // 세 변수의 값 정렬

#include <stdio.h>
void sort(double *, double *, double *);
void exchange(double *, double *);

int main()
{
    double num1, num2, num3;
    
    printf("세 실수를 입력하시오 >> ");
	scanf("%lf%lf%lf", &num1, &num2, &num3);
	
	sort(&num1, &num2, &num3); 
	
    return 0;
}
void sort(double *max, double *mid, double *min)
{
	double temp;
	if(*max < *mid) exchange(max, mid);
	if(*max < *min) exchange(max, min);
	if(*mid < *min) exchange(mid, min);

	
	printf("최대값 : %.1lf\t중간값 : %.1lf\t 최소값 : %.1lf\n",  *max,*mid, *min);
}
void exchange(double *ap, double *bp)
{
	double temp;
	temp = *ap;
	*ap=*bp;
	*bp=temp;
}
>>>
세 실수를 입력하시오 >> 3 2 1
최대값 : 3.0    중간값 : 2.0     최소값 : 1.0
세 실수를 입력하시오 >> 1 2 3
최대값 : 3.0    중간값 : 2.0     최소값 : 1.0

위 코드는 세 변수의  값을 입력받아 

각각 Max, Mid, Min 최댓값, 중간값, 최솟값으로 정렬하는 코드이다

함수와 포인터 조건문등을 이용하여 작성했고

exchange()함수는 값을 변경해주는 기능을 수행하고

sort() 함수는 값의 크기를 조건문으로 걸러 정렬해주는 함수이다

 

main함수에서 sort()를 호출하여 값을 보내줄때 변수의 주소를 보내준다

그렇게 포인터를 통해 값을 참조하게 되면 메모리 자체에서의 값이 변경된다.

 

300x250

댓글