본문 바로가기
Game DevTip/STL

4. STL : Call by value, Ref, Address & 배열과 포인터에 관련해서.

by LIKE IT.라이킷 2024. 12. 7.

 

배열과 포인터

  • 포인터 : 메모리에 저장된 다른 값의 메모리 주소를 저장하는 변수
  • 배열 : 이름은 주소(사실은 주소임)
  • 포인터 변수 선언 : Type *var_name;(int *ptr; → 인티저 값을 가르키는 포인터 변수.)
  • 포인터 사용 : 다른 변수의 주소를 참조하여 사용가능. 동적 메모리 할당가능. → 함수도 주소이므로 사용가능.

- 주소할당.

int a = 100;
int p = &a;

 


- 동적메모리 할당.

int *p = null;
p = new int ; // 동적 메모리 할당. 
*p = 500; //p가 가르키는 해당 공간에 500이라는 값을 저장해라.

delete p; // 메모리 해제(안하면 누수 ^^7)

Call by value & Call by address & Call by Ref

  • value : 인수가 값이 들어가면 벨류

void fcn(int i) // 해당 i라는 인수(로컬 변수)에 값이 복사됨.
{
	i = 5; // main함쉐 n에 접근을 못함.
}

int main()
{
	int n = 3;
	fcn(n);
	cout << n << endl; //값이 변경되지 못하고 3임.
}

  • address : 인수가 주소값으로 넘어옴.
void fcn(int *pi) // 해당 주소가 포인터 변수에 복사됨.
{
	*pi = 5; // 메인 함수의 n에 접근.(로컬 변수)
}

int main()
{
	int n = 3;
	fcn(&n);
	cout << n << endl; //값이 변경되고서 5임.
}

  • 레퍼런스 : alias(닉네임)

void fcn(int &pi) // 해당 주소가 주소 연산자 변수에 복사됨.
{
	pi = 5; // pi는 n의 닉네임(똑같은 놈이다) -> 로컬 변수가 아니라 n임.
}

int main()
{
	int n = 3;
	fcn(n); //사용시에는 value 처럼 사용.
	cout << n << endl; //값이 변경되고서 5임.
}

배열

  • 변수가 아님 ^^7(근데 사용은 변수 처럼 함.)
  • 동일한 타입의 값들을 저장하는 데이터의 집합.(그래서 사실 주소를 담음.)

int a[5]; → ‘a’는 대충 인티저 값 5개를 담을 수 있음.

  • 배열의 요소 접근

int mark[5]; //초기화 방법 1

mark[0] = 19;
mark[1] = 10;
mark[4] = mark[0] - mark[1];
//배열은 인덱스를 사용하므로 다이렉트로 값에 엑세스가 가능함.

int mark2[5] = {19,10,8,18,9}; // 초기화 방법 2
int mark3[] = {19,10,8,18,9} // 초기화 방법 3(자동으로 배열 사이즈 정해짐.

int *p = null;

*p = *mark[1]; //이렇게 포인터를 이용해서 접근 가능.


  • 클래스 배열을 이용하기

#include <iostream>
#include <string>
using namespace std;

class Obj {
    int m_x;
    int m_y;
    string m_name;
public:
    Obj(int x = 10, int y = 10, string name = "t") : m_x(x), m_y(y), m_name(name) {}
    ~Obj(){}

    int getX() { return m_x; }
    int getY() { return m_y; }
    string getName() { return m_name; }
    void SetXY(int x, int y, string n) { m_x = x; m_y = y; m_name = n; }
    void Draw() {
        cout << m_x << " " << m_y << " " << m_name << endl;
    }
};

int main()
{
    Obj objects[5];
    objects[1].SetXY(200, 200, "Hello World");
    for(int i  = 0; i< 5; i++) {
        objects[i].Draw();
    }
    return 0;
}


  • 2차원 배열

int x[2][3] = {{1,3,0}, {-1,5,9}};

  • 3차원 배열

int x[2][3][4] = {{1,3,0,5}, {-1,5,9,7},{10,20,30,40}
				{1,2,3,4}, {5,6,7,8}, {1,5,3,23}}; //이게 뭐노

  • 문자열 배열

char c = 'H';
char name[10] = "Hong"; //맨뒤에 null 묹자가 들어가므로 문자열은 9개만 저장가능.

  • 배열의 정체는 포인터이다.
  • 배열 이름은 첫 번째 배열 요소가 있는 메모리 주소이다.
  • 배열의 요소를 포인터로 표현 가능

&A[i] = &A[0] + i * sizeof(element Type)
A + i = A + i * sizeof(element Type)

  • 동적할당

int *a = new int[5];
a[0] = 4;
a[1] = 2;
.
.
.


  • 2차원 배열 동적할당

#include <iostream>
#include <string>
using namespace std;

int main()
{
    //[3][4]
    int **gameMap;
    int width = 4;
    int height = 3;

    gameMap = new int *[height]; //width도 넣어야 하므로 포인터 height임.

    for(int h = 0; h < height; h++)
         gameMap[h] = new int[width];

    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            gameMap[y][x] = rand() % 10;
        }
    }

    for(int y = 0; y < height; y++) {
        for(int x = 0; x < width; x++) {
            cout << gameMap[y][x] << " " ;
        }
        cout << endl;
    }

    return 0;
}


  • 배열의 전달 - Call by Address

int SumUp(int A[] , size)//즉 주소가 넘어가므로 이렇게 됩니다.
{
		int Sum = 0;
		for(int i = 0; i< size; i++)
				Sum += A[i];
				
		return Sum;
}

int main()
{
		int Total;
		int Score[5];
		Score[0] = 98; // 배열시작 주소 : 200
		Score[1] = 92;
		Score[2] = 88;
		
		Total = SumUp(Score, 3); //배열의 시작 주소만 넘어가는 것.
}

 

반응형

댓글