상세 컨텐츠

본문 제목

pointer-1

개발생활/IT

by 한국인맛집 2021. 4. 13. 20:31

본문

반응형

 

포인터

 

 

포인터

포인터 변수타입이라고합니다.

포인터 변수타입은 기본적으로 메모리의 주소값을 저장합니다.

 

사용방법은 아래와 같습니다.

 

#include<stdio.h>

void main(){

   int number = 10
   int* ptrNumber = &number;
   
   fgetc(stdin);
}

 

포인터 변수를 선언할때는 *, 별모양 심볼을 붙입니다. 부를땐 별표라 하지않고 아스터리스크 심볼 (Asterisk)이라고 부릅니다.

 

특정 타입에 상관없이 아래와같이 사용할수 있습니다.

 

#include<stdio.h>

void main(){

   char* cPtr;
   int* iPtr;
   float* fPtr;
   long* lPtr;
   
}

 

 

기본적으로 포인터는 메모리의 주소값만을 저장합니다. 

메모리의 주소값을 저장해야하는 이유는 무엇일까요?

 

변수를 그냥 선언하게되면, 스택영역에 선언됩니다. 하지만, 스택영역은 컴파일하는 순간 메모리가 회수됩니다. 

즉, 실행하고나면, 소멸하게됩니다.

 

힙영역은 스택영역과 다르게 메모리 회수전까지 계속 남게됩니다.

 

포인터변수를 이용해 동적할당을 하는 행위는 힙영역에 메모리를 생성하는것과 같습니다.

 


포인터 사용하기

 

포인터를 이용하면, 변수에 직접 접근하지 않고, 값을 변경할수 있습니다.

 

변경가능한 이유는 포인터변수는 변수의 메모리값을 저장하고, 메모리를 직접 컨트롤 가능하기 때문입니다.

 

 

포인터변수자체는 변수의 주소값을 저장합니다.

 

하지만 Asterisk( * )를 포인터 변수앞에 붙인다면, 메모리를 저장한 변수에 직접 접근하여 값을 변경및 저장이 가능합니다.

 

 

#include<stdio.h>

void main(){
  
  int a = 10;
  
  int*ptr = &a;
  
  *ptr = 30;
  
  printf("a = %d\n", a);
  
  *ptr = 60;
  
  printf("a = %d\n",a);


  fgetc(stdin);
}

 

 

다음과 같이는 사용할수 없습니다.

 

사용할수 없는이유는 포인터변수는 기본적으로 값을 초기화 해줘야합니다.

 

그래서 다음과 같이 사용한다면 초기화 문제로 에러를 발생할 것입니다.

 

#include<stdio.h>

void main(){

   int a = 10;
   
   int* ptr;
   
   *ptr = 10;
   fgetc(stdin);
}

 

포인터변수는 단순히 하나의 변수의 메모리값을 수정, 저장하는것이 아닙니다.

 

하나의 포인터 변수로 여러변수의 값을 컨트롤 가능합니다.

 

#include<stdio.h>

void main() {

	int a = 10;
	int b = 30;

	printf("Before a = %d , b = %d \n", a, b);

	int* ptr;
	ptr = &a;
	*ptr = 30;
	ptr = &b;
	*ptr = 2;
	printf("after a = %d , b = %d \n", a, b);

	fgetc(stdin);
}

 

 

 

 


Call by value , Call by Reference

 

 

포인터를 배우면 처음 접하는 문제인 call by value, call By Reference 입니다.

 

값교환, 참조값 교환 입니다.

 

 

코드를 보고 실질적인 출력값을 알아보도록하겠습니다.

 

#ifndef __HEADER_H__
#define __HEADER_H__

#include<stdio.h>


void SwapCallByValue(int a, int b);

void SwapCallByReference(int* a, int* b);




#endif

 

#include"Header.h"

void main(){
    int v1= 10, v2 = 20;
    int r1 = 10, r2 = 20;
    
    printf("Before v1 = %d, v2 = %d\n",v1,v2);
    printf("Before r1 = %d, r2 = %d\n",r1,r2);
    
    SwapCallByValue(v1, v2);
    SwapCallByReference(&r1, &r2);

    printf("After v1 = %d, v2 = %d\n",v1,v2);
    printf("After r1 = %d, r2 = %d\n",r1,r2);

    fgetc(stdin);
}




void SwapCallByValue(int a, int b){
    int temp = a;
    a = b;
    b = temp;
}

void SwapCallByReference(int* a, int* b){
   int temp =  *a;
   *a = *b;
   *b = temp;
}

 

 

위 call by Value 즉 값교환은 함수 내부에서선 값이 변경되었으나, 실질적인 변수의 변화가 있지않습니다.

 

하지만 포인터변수를 사용한 참조값 교환에서는 변수에 직접 접근하여 값을 변경한 것을 확인할수 있습니다.

 

즉,포인터 변수를 이용해 값을 직접 변환 가능하다는 것을 알수 있습니다.

 

 


포인터의 초기화

 

 

 

포인터 변수를 그냥 선언만 하는것은 매우 위험한 행동입니다.

 

그럼 값을 초기화해줘야합니다.

 

nullptr 즉, 널포인터, NULL , 널 값으로 기본적으로 초기화 해줍니다.

 

#include<stdio.h>

void main(){
   
   int* ptr = nullptr;
   int* ptr2 = NULL;
}

 

초기화 해주는 이유는 프로그래머가 실수로 초기화 하지않고, 사용할 여지를 막기위함입니다.

 

반드시 포인터를 사용할때는 선언과 동시에 초기화 하는 습관을 가져야만합니다.

 

 

 


혼자 해보기 문제

 

 

1.다음배열에는 5개의 값이 저장되어있습니다.

 

int number[5] = {10,20,30,40,50}

사용자 입력을 5회 받아 값을 변화시켜주세요.

*조건

1.배열에 직접 접근하는것이아닌, Call By Reference를 이용하여 값을 변경시키세요.

2. 헤더파일과 소스파일은 분리되어 있어야합니다.

3. 메인 소스파일에는 main함수만 있어야합니다. 메인함수이외에는 존재해선 안됩니다.

 

 

2. 다음 문제를 해결하세요.

 

배열 charArray 에는 "My Name" 값이 저장되어있다.

#include<stdio.h>

void main() {
    
    char charArray[] = "My Name";

    char* ptr = charArray;
    ptr[0] = "y";
    ptr[1] = "o";
    
    printf("%s", ptr);


    fgetc(stdin);
}

 

코드의 에러를 수정하고, 출력결과값을 yo Name으로 출력하도록 바꿔라.

 

 

 

 

3. 조건을 만족하도록 값을 출력해보세요

 

char str[] = "Hello world";

char reChar[10];

 포인터 변수를 이용하여 reChar배열에 "o wo"를 저장하세요

 

 

출력은 다음과 같이 하면

 printf("%s", ptr);

 

아래와 같은 결과가 나와야합니다.

 

 

 

4. 다음 값을 오름 차순정렬한뒤, myArray에 저장하세요.

 

    int numberArray[] = { 15,2,31,4,8 };
    
    int myArray[5];

*조건

1.배열에 직접 접근하는것이아닌, Call By Reference를 이용하여 하세요.

2. 헤더파일과 소스파일은 분리되어 있어야합니다.

3. 메인 소스파일에는 main함수만 있어야합니다. 메인함수이외에는 존재해선 안됩니다.

 

반응형

관련글 더보기