◈ 이 글은 강의를 위하여 제가 직접 작성한 내용입니다. 따라서 퍼가실 경우, 출처를 명확히 해주시기 바랍니다!!
◈ This ariticle was written by me for teaching. So if you want to copy this article, please clarify the source!!
◈ This ariticle was written by me for teaching. So if you want to copy this article, please clarify the source!!
포인터 변수에 대해서 이해하자.
#includeusing namespace std; void main() { // 변수란? 메모리이다. // 타입마다 메모리의 크기와 용도(무엇을 저장하느냐)가 다르다. int a = 100; char b = 'a'; double c = 3.14; // 포인터 변수. -> 변수이므로 메모리를 사용. // 포인터는 타입을 의미한다. // int -> 4byte, 정수를 저장. // int* -> 4byte, 정수를 저장하고 있는 int형 변수(메모리)의 주소를 저장. int* pa = &a; /* int* paa = 100; // X : 100은 일반적인 값으로 분류되므로 불가능. int* paa = a; // X : a역시 일반적인 값으로 분류되므로 불가능. int* paa = pa; // O : pa가 가지고 있는 값은 주소로 분류되므로 가능. int* paa = (int*)a; // O : a의 값을 주소인것처럼 속이면 가능. */ // char -> 1byte, 문자를 저장. // char* -> 4byte, 문자를 저장하고 있는 char형 변수(메모리)의 주소를 저장. char* pb = &b; // double -> 8byte, 실수를 저장. // double* -> 4byte, 실수를 저장하고 있는 double형 변수(메모리)의 주소를 저장. double* pc = &c; // 포인터 타입 변수들의 2가지 공통점. // 1. 주소를 저장한다. -> 다른 변수를 가위함이다. // - 일반적인 값은 저장할 수 없다. ( int* pa = 100;은 불가능 ) // - 일반적인 값과 주소(번지수)를 구분할 수 있어야 한다. // - 예외) 주소외에 저장할 수 있는 유일한 수 : 0(NULL) // 2. 4byte의 크기를 가진다. // - 메모리의 주소의 최대값을 저장하기 위해 4byte가 필요하므로. //int normal_var = &a; // 일반 변수는 주소를 저장할 수 없다. int normal_var = (int)&a; // 주소가 아닌 것처럼 속이면 가능하다. int abc = 1024; int* pabc = &abc; // *(타입지정자) -> pabc변수를 포인터 타입 변수로 만들어라. abc = 2048; *pabc = 4096; // *(연산자) -> 해당 주소로 찾아가라!! // *(연산자)다음에는 무조건 주소만 와야된다. // pabc[0] = 4096; // (int*)* -> 4byte, // int형 변수의 주소를 저장하고 있는 int*형 변수(메모리)의 주소를 저장. // 포인터의 포인터는 주소의 주소가 절대 아니다.(이런건 있을 수 없다. 단, 포인터 변수의 주소를 의미할 뿐이다.) // 예를 들어 일반 변수 int a = 100;이 있을 때, &&a와 같이 주소의 주소라는 건 존재할 수 없다. // 포인터의 포인터가 가능한 이유?? 포인터변수도 하나의 독립적인 변수이기 때문에 자기 자신만의 메모리를 가지고 있다. int** ppabc = &pabc; // (int**)* -> 4byte, // int*형 변수의 주소를 저장하고 있는 int**형 변수(메모리)의 주소를 저장. int*** pppabc = &ppabc; int ary[] = {1,12,23,34,45}; int* pary = &ary[0]; //&ary[0] -> ary. // 배열과 포인터의 공통점 : 이름자체가 주소를 의미한다. // 배열과 포인터의 차이점 : 포인터는 변수지만 배열은 변수가 아니다. cout << pary << endl; // 배열의 시작주소가 출력된다. cout << ary << endl; // 배열의 시작주소가 출력된다. cout << *pary << endl; // '1' 이 출력된다. cout << sizeof(ary) << endl; // 20 출력. cout << sizeof(pary) << endl; // 4 출력. for(int i=0; i < 5; i++) { cout << ary[i] << endl; cout << pary[i] << endl; cout << *(pary+i) << endl; // 100 + 1 = 104. } int inc_num = 100; cout << inc_num << " / " << inc_num+1 << endl; // 100 / 101 출력. int* inc_pnum = &inc_num; cout << inc_pnum << " / " << inc_pnum+1 << endl; // 주소 / 주소+4 출력. int var = 100; // var변수는 주소가 1000, 값은 100 int* pvar = &a; // pvar변수는 주소가 2000, 값은 1000 int** ppvar = &pa; // ppvar변수는 주소가 3000, 값은 2000 }
아래 코드를 실행하기 전에 그 결과를 예측해보자.
#includeusing namespace std; int main() { int num[]={1,2,3,4,5,6,7,8,9,0}; int *copy; int *d; int a=5; int c=a; //기본 타입 --> 깊은 복사 int *e=&a; //기본 타입의 *와 &--> 얕은 복사 double f=10.0; double *g; g=&f; //기본 타입의 *와 &--> 얕은 복사 copy=num; //참조타입 []와 * --> 얕은 복사 d=num; cout << "num[0] 값: " << num[0] << " 주소: " << &num[0] << " = " << num << endl; cout << "num[1] 값: " << num[1] << " 주소: " << &num[1] << endl; cout << "num[2] 값: " << num[2] << " 주소: " << &num[2] << endl; cout << "num[9] 값: " << num[9] << " 주소: " << &num[9] << endl; cout << "*num 값: " << *num << " 주소: " << &num << " = " << num << endl; cout << "a 값: " << a << " 주소: " << &a << endl; cout << "c 값: " << c << " 주소: " << &c << endl; cout << "*e 값: " << *e << " 주소: " << &e << " 주소: " << e << endl; cout << "f 값: " << f << " 주소: " << &f << endl; cout << "*g 값: " << *g << " 주소: " << &g << " 주소: " << g << endl; cout << "*copy 값: " << *copy << " 주소: " << © << " != " << copy << endl; cout << "*d 값: " << *d << " 주소: " << &d << " != " << d << endl; return 0; }
연습문제 1.
/* 1. int형 변수 num과 int형 포인터 변수 refNum을 선언하시오. 2. refNum을 이용해서 num변수에 숫자 1004를 입력하시오. 3. 출력화면은 아래와 같이 되도록 작성하시오. num의 값 : 1004 num의 주소 : 0012FF60 refNum의 값 : 0012FF60 refNum의 주소 : 0012FF54 refNum이 참조하는 값 : 1004 */ #includeusing namespace std; void main() { int num; int*refNum = # *refNum = 1004; cout << "num의 값 : " << num << endl; cout << "num의 주소 : " << &num << endl; cout << "refNum의 값 : " << refNum << endl; cout << "refNum의 주소 : " << &refNum << endl; cout << "refNum이 참조하는 값 : " << *refNum << endl; }
연습문제 2.
/* 1. int형 변수 num1과 num2를 선언하고 각각 100과 200으로 초기화하시오. 2. int형 포인터변수 2개를 입력받아 그 값을 서로 스왑하는 Swap함수를 작성하시오. 3. Swap함수를 이용하여 아래와 같이 출력되도록 작성하시오. 스왑 전 : 100 / 200 스왑 후 : 200 / 100 */ #includeusing namespace std; void Swap(int* a, int* b); void main() { int num1 = 100, num2 = 200; cout << "스왑 전 : " << num1 << " / " << num2 << endl; Swap(&num1, &num2); cout << "스왑 후 : " << num1 << " / " << num2 << endl; } void Swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; }
연습문제 3.
/* 1. int형 배열 num1[5]과 num2[10]를 선언하시오. 2. 배열과 배열의 크기를 인자로 받아 배열을 [0, 1, 2, ..., 배열의크기-1]로 초기화 하는 함수 InitArray를 작성하시오. 3. InitArray를 이용하여 배열초기화 후 아래와 같이 출력되도록 작성하시오. num1[0] = 0 num1[1] = 1 num1[2] = 2 num1[3] = 3 num1[4] = 4 ------------- num2[0] = 0 num2[1] = 1 num2[2] = 2 num2[3] = 3 num2[4] = 4 num2[5] = 5 num2[6] = 6 num2[7] = 7 num2[8] = 8 num2[9] = 9 */ #includeusing namespace std; void InitArray(int* ary,int counts ); void main() { int num1[5]; int num2[10]; int n1=sizeof(num1)/sizeof(int); int n2=sizeof(num2)/sizeof(int); InitArray(num1, n1); InitArray(num2, n2); for(int i=0; i < n1; i++) { cout << "num1[" << i << "] = " << num1[i] << endl; } cout << "-------------" << endl; for(int i=0; i < n2; i++) { cout << "num2[" << i << "] = " << num2[i] << endl; } } void InitArray(int* ary,int counts ) { for(int i=0;i < counts;i++) { ary[i] = i; } }