금오공과대학교 C++ 프로그래밍 jhhwang@kumoh.ac.kr 컴퓨터공학과 황준하
5 강. 배열, 포인터, 참조목차 배열 포인터 C++ 메모리구조 주소연산자 포인터 포인터연산 배열과포인터 메모리동적할당 문자열 참조 1 /20
5 강. 배열, 포인터, 참조배열 배열 같은타입의변수여러개를하나의변수명으로처리 int Ary[10]; 총 10 개의변수 : Ary[0]~Ary[9] for (int i = 0; i < 10; i++) cout << " 정수입력 : "; cin >> Ary[i]; 변수인덱스를통해해당원소접근가능 for (int i = 0; i < 10; i++) cout << "Ary[" << i << "] = " << Ary[i] << endl; 2 /20
5 강. 배열, 포인터, 참조배열 2 차원배열, 3 차원배열, int Ary[3][4]; Ary[0][0] Ary[0][1] Ary[0][2] Ary[0][3] Ary[1][0] Ary[1][1] Ary[1][2] Ary[1][3] Ary[2][0] Ary[2][1] Ary[2][2] Ary[2][3] Ary[0][0] ~ Ary[2][3] 의총 12개의 int형변수가생김 Ary[1][2] 와같이각원소에접근가능 다차원배열의사용방법동일 배열선언및초기화 int Ary1[5] = 1, 2, 3, 4, 5 ; int Ary2[5] = 1, 2 ; int Ary3[2][3] = 1, 2, 3, 4, 5, 6 ; int Ary4[2][3] = 1, 4, 5 ; int Ary5[2][3] = 1, 2 ; 나머지는 0 으로자동초기화 3 /20
하나의프로그램실행 ( 프로세스 ) 시생성되는메모리 구조 메모리구조 int a = 1; 데이터영역 ( 전역, 정적변수 : a, c) 스택영역 ( 지역변수 : x, y, b, p) 힙영역 ( 동적변수 : new int) 코드영역 ( 함수 : Sum, main) int Sum(int x, int y) static int c; c = x + y; return c; int b = 2; int *p = new int(3); 결론 : 변수와함수모두 메모리에올라감 cout << Sum(b, *p) << endl; 4 /20 delete p;
메모리주소 주소 : 바이트단위의번호, 4바이트로표현 0번지 ~ 2 32-1번지 변수, 함수는메모리를차지함 배열은연속적인메모리공간을차지함 5 /20
변수와함수가올라가있는메모리주소값알아내기 변수 : 주소연산자 (&) 사용 함수 : 함수명자체가주소값을의미 int Sum(int x, int y) return (x + y); int Num1 = 3; Num1 변수의주소 6 /20 cout << "Num1 변수의주소 : " << &Num1 << endl; cout << "main 함수의주소 : " << main << endl; cout << "Sum 함수의주소 : " << Sum << endl;
포인터 ( 변수 ) 주소값을저장하는변수 주소값에도타입이있음 int a; &a int형주소값 double b; &b double형주소값 int형포인터 == int형주소값을저장하는변수 int *p; 포인터도변수다! 7 /20
역참조연산 (*) int a = 3; int *p = &a; *p = 5; 역참조연산 : 현재포인터가가리키는변수를의미 : *p == a 포인터연산 덧셈, 뺄셈만가능 : +, -, ++, -- int *p = &a; p = p + 1; int 타입의크기인 4만큼증가 다음 int 변수를가리키는모양 8 /20
다음프로그램의출력결과는? Num1 의주소는 1000 번지, pnum 의주소는 2000 번지로가정 int Num1 = 3; int *pnum = &Num1; *pnum Num1 2000 1000 3 1000 9 /20 cout << Num1 << endl; cout << &Num1 << endl; cout << pnum << endl; cout << &pnum << endl; *pnum = 5; pnum++; cout << Num1 << endl; cout << &Num1 << endl; cout << pnum << endl; cout << &pnum << endl; 실행결과 3 1000 1000 2000 5 1000 1004 2000
배열이름 첫번째원소의주소를의미하는상수 int Ary[5]; Ary == &Ary[0] int Ary[5]= 1, 2, 3, 4, 5 ; int *p = Ary; 첫번째원소를가리킴 for (int i = 0; i < 5; i++) cout << *p << endl; p++; 다음원소를가리킴 10 /20
배열은포인터처럼, 포인터는배열처럼사용가능! 단, 배열명은상수이므로변경불가 int Ary[5]= 1, 2, 3, 4, 5 ; int *p = Ary; for (int i = 0; i < 5; i++) 포인터를배열처럼사용 cout << p[i] << " "; p[i] == *(p + i) cout << *(Ary + i) << endl; 배열을포인터처럼사용 *(Ary + i) == Ary[i] 11 /20
다차원배열명의의미 첫번째원소의주소! int Ary[2][3]; Ary == &Ary[0], int (*p)[3] = Ary; p++ 12만큼증가 (int [3] 단위 ) P[0][2] 와같이 2차원배열처럼사용가능 int Ary[2][3][4]; Ary == &Ary[0], int (*p)[3][4] = Ary; 복잡한포인터 Ary[0] Ary[0][0] Ary[0][1] Ary[0][2] Ary[1] Ary[1][0] Ary[1][1] Ary[1][2] int **p; 포인터에대한포인터 int *p[3]; int 포인터 3개를원소로배열 int (*p)[3]; int [3] 배열단위로가리키는포인터 해석요령 : pointer of array [3] of int int 형1차원배열 ([3]) 에대한포인터 12 /20
int Ary[3][4] 가있다. Ary[2][3] = 5; 와동일한의미가되도록 Ary를포인터방식으로사용해보라. *(*(Ary + 2) + 3) = 5; *(Ary[2] + 3) = 5; (*(Ary + 2))[3] = 5; 다음각변수가무엇을뜻하는지말해보라. int **a[3]; int (*b)[3][4]; int *(*c)[3]; int 포인터의포인터를원소로갖는 1 차원배열 [3] 2 차원배열 [3][4] 에대한포인터 int 포인터를원소갖는 1 차원배열 [3] 에대한포인터 13 /20
14 /20 메모리동적할당 메모리가필요할때변수를사용하지않고동적으로할당 받음 포인터변수를통해가리키고사용함 new( 메모리할당 ) 와 delete( 해제 ) int *p; int 1개 (4바이트) 할당 p = new int; *p = 5; cout << *p << endl; delete p; 동적메모리해제 p = new int[5]; int 5개 (20바이트) 할당배열 for (int i = 0; i < 5; i++) p[i] = i + 1; cout << p[i] << " "; delete [] p; 배열로할당받은경우반드시 [] 사용
5 강. 배열, 포인터, 참조문자열 15 /20 문자열표현방식 char 문자의집합 단, 마지막문자로널문자 ( \0 ) 포함 문자열의저장 문자열상수 : char * 로가리킬수있음, 불변 문자열변수 : 1 차원배열 char str1[6] = "Hello"; char *str2 = "Hello"; cout << str1 << endl; cout << str2 << endl; str2 * str1 Hello H e l l o str1[0] str1[1] \0 H e l l o \0 H e l l o \0
5 강. 배열, 포인터, 참조문자열 문자열변수에대한조작함수사용 헤더파일 : <cstring> strlen : 문자열의길이 strcpy : 문자열복사 strcat : 문자열뒤에추가 strcmp : 문자열비교 char str1[255] = "C++ "; char str2[255] = "Programming"; char str3[255]; strcat(str1, str2); strcpy(str3, str1); cout << "str1 : " << str1 << endl; cout << "str2 : " << str2 << endl; cout << "str3 : " << str3 << endl; if (strcmp(str1, str3) == 0) cout << "Str1 과 Str3 은같다." << endl; 16 /20 같으면 0, str1 이크면양수 Str3 이크면음수반환 cout << "str1 의길이 : " << strlen(str1) << end
5 강. 배열, 포인터, 참조참조 참조변수 기존변수 ( 변수하나 ) 의또다른이름 혼자존재할수없음 선언과동시에초기화필수 초기화이후에는일반변수와 100% 동일하게사용! int Num1 = 3; int &Num2 = Num1; Num2 = 5; 참조변수 Num2는 Num1과동일 이후 Num2는일반변수와동일함 ( 사용방법등 ) cout << Num1 << endl; cout << Num2 << endl; 17 /20
5 강. 배열, 포인터, 참조참조 참조변수의예 a, b, c 모두동일 int a; int &b = a; int &c = b; c = 5; 포인터변수 p, q 동일 int *p = &a; int *&q = p; *q = 7; int ary[3]; 배열 ary와 raray int (&rary)[3] = ary; 동일 rary[1] = 3; 18 /20
5 강. 배열, 포인터, 참조프로그래밍연습 사용자로부터행과열의개수를입력받아해당행- 열을갖는 2차원배열을만들고 0 또는 1 중임의의값으로채운후출력해보라. int ** 변수를사용하여행의개수만큼 int * 변수를만들고 각 int * 변수를사용하여열의개수만큼만든다. 그다음부터는 int ** 변수를 2차원배열과동일하게사용하면된다. 19 /20
5 강. 배열, 포인터, 참조프로그래밍연습 #include <iostream> #include <cstdlib> #include <ctime> using namespace std; srand(time(null)); int **Ary; int row, col; 각각의 int * 를이용해 int 배열생성 int ** 를 2 차원 배열처럼사용 메모리해제 cout << " 행과열의개수입력 : "; cin >> row >> col; Ary = new int *[row]; for (int i = 0; i < row; i++) Ary[i] = new int[col]; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) Ary[i][j] = rand() % 2; cout << Ary[i][j] << " "; cout << endl; for (int i = 0; i < row; i++) delete [] Ary[i]; delete [] Ary; int * 배열생성 20 /20