포인터 (1)

라이라·2023년 6월 22일
0

포인터는 주소를 저장하는 변수로 일반 변수와 마찬가지로 선언한 후에 사용한다.

방법은 변수 앞에 *를 붙여주는 것으로 완료된다.

	int a; //일반 변수 선언
    int *pa // 포인터 선언
	
	pa -> a // 포인터 pa는 변수 a를 가리킨다.

포인터가 가리키는 변수를 사용할 때는 간접참조 연산자 (*)를 사용한다.

포인터에 const를 사용하는 이유

  • 해당 변수의 값이 포인터를 통해 변하는 것을 방지하기 위해서.
int num = 10;
int num2 = 20;

1) const int* ptr
	const int* ptr = #
    ptr = 40;  // 에러발생
    num = 40 // 에러발생x, 값 변경

2) int *const ptr
	int const ptr = #
    ptr = &num2; //ptr은 num1만을 가리키는 포인터로 고정했으므로 에러
    ptr = 30; // ptr이 num1을 가리키고있고, 주소에 접근해서 변경은 할 수 있다.
    
 3) const int* const ptr
 const int* const ptr = # // 값을 변경할 수 없고 참조만 가능하다.

포인터는 주소를 저장하는 메모리의 공간이다.

따라서 언제든지 다른 주소를 저장하거나 포인터끼리 대입할 수 있다.

int a,b;
int *p = &a;
p = &b;

포인터의 크기는 컴파일러에 따라 다를 수 있으므로 sizeof 연산자로 확인한다.

int *p;
sizeof(p);

포인터는 가리키는 자료형이 일치할 때만 대입한다.

int *p;
double *pd;
pd = p; // 에러발생

주소는 변수에 할당된 메모리 저장 공간의 시작 주소값 자체이고 포인터는 그 값을 저장하는 또 다른 메모리 공간이다.

특정 변수의 주소값은 변하지 않지만 포인터는 다른 주소를 대입하여 그 값을 바꿀 수 있다.

즉, 주소는 상수이고 포인터는 변수이다.

두 포인터가 같은 주소를 저장하는 일 또한 가능하다.

int a;
int *pa, *pb;
pa = pb = &a;

포인터의 크기는 컴파일러에 따라 다를 수 있으나 모든 주소와 포인터는 가리키는 자료형과 관계없이 크기가 같다.

포인터는 가리키는 변수의 형태가 같을 때만 대입해야한다.

int a = 10;
int *p = &a;
double *pb;
pb = p; // -92559532139583000000...

그러나 형변환을 사용한 포인터의 대립은 언제나 가능하다.

double a = 3.4;
double *pa = &a;
int *pd;
pd = (int *)pa; //	가능

포인터는 항상 정상적으로 할당받은 메모리 공간의 주소를 저장해서 사용해야만 한다.

포인터를 초기화하지않고 사용하는 것은 매우 위험한데, 이 경우 포인터에 간접참조 연산을 수행하면 알 수 없는 곳으로 찾아가 데이터를 바꾸게 될 수 있다.

int *p;	// 초기화 되지 않은 포인터
*p = 10 // 쓰레기값으로부터 4바이트 공간에 10을 대입

포인터가 필요한 이유

모든 경우에 포인터를 사용할 이유는 없다.

포인터를 사용하려면 추가적인 변수 선언이 필요하고 각종 연산을 해야하기 때문이다.

그러나 임베디드 프로그래밍을 할 때 메모리를 직접 접근하는 경우나 동적 할당한 메모리를 사용하는 경우에는 포인터가 반드시 필요하다.

	void main(void){
    	void swapValues(int *pa, int *pb);
    
    	int a = 10, b = 20;
    
	    swapValues(&a, &b);
  	 	printf("a : %d, b : %d \n", a, b);
    
    
    	return 0;
    }
    
    void swapValues(int *pa, int *pb){
    	int tmp;
        tmp = *pa;
        *pa = *pb;
        *pb = tmp;
   }
   
  >> a : 20, b : 10

포인터 없이 두 변수의 값을 바꿀 수는 없을까?

	int main(void){
        int a = 10, b = 20;
        
        swap();
        return 0;
    }
    
    void swap(void){
        int tmp;
        tmp = a;
        a = b;
        b = tmp;
    }
    
    >> error C2065: 'a' : 선언되지 않은 식별자입니다.
       error C2065: 'b' : 선언되지 않은 식별자입니다. 
    ...

함수 안에 선언된 변수의 이름은 사용 범위가 변수가 선언된 함수 내부 블록{}에 제한되므로 main 함수 내부에 있는 변수 a,b는 다른 함수인 swap()에서 사용할 수 없다.

때문에 컴파일 단계에서 에러를 내게된다.

profile
혼자 보려고 올리는 용도

0개의 댓글