4. 고급변수 사용 : 포인터와 관련하여 메모리 바라보기
차 례 포인터 변수 배열 문자열 포인터 : 메모리 주소 레퍼런스 변수 동적 할당
포인터 컴퓨터는 처리하는 모든 데이터를 주기억장치에 저장한다. 포인터 : 주기억장치의 주소 포인터 변수 : 주소를 저장 일반 변수 : 값을 저장 ….. 값 주소 0012FF60 300 …...
포인터 변수 1 변수 저장장소 변수는 사용하기 전에 미리 선언해야 한다. 변수는 사용하기 전에 초기화 되어야 한다. 초기화하지 않은 경우 쓰레기 값이 저장되어 있다. 값을 저장하려면 일반 변수로 선언되어야 함!! 주소를 저장하려면 포인터 변수로 선언되어야 함!!
소스 4-2 (ch04_01_1.cpp) #include <iostream> using namespace std; int main() { int sum=0, i=0; for (i=1; i<=10; i++) sum=sum+i; cout << "1~10까지의 합 : " << sum << endl; return 0; } 중단점 찍고 단계별로 실행하면서 sum 변수의 주소, 변수 값 확인해보기
포인터 변수 2 변수 값 참조 – 일반변수 이름 사용 변수의 주소 확인(주소지정 연산자 & 사용) int a=100;; 소스 4-2 (ch04_01_1.cpp) int a=100;; cout << "a에 저장된 값 : " << a << endl; cout << "a의 주소 : " << &a << endl; return 0; 실행 결과 a에 저장된 값 : 100 a의 주소 : 0012FF60
포인터 변수 3 포인터 변수 일반변수와 마찬가지로 사용 전 선언해야 함 변수의 주소를 저장 포인터 변수에 저장할 주소에 저장될 자료형과 포인터 변수의 자료형은 일치해야 함 (정수형 포인터 변수는 정수형 변수의 주소, 문자형 포인터 변수는 문자형 변수의 주소를 저장함) 일반변수와 마찬가지로 사용 전 선언해야 함 자료형 일반변수이름; 자료형 *포인터변수이름;
일반변수와 포인터 변수 일반변수 : 값을 저장해야 할 경우 필요 포인터변수 : 변수의 주소를 저장해야 할 경우 (동적 할당 또는 6장 함수에서 다뤄짐) 일반변수 포인터 변수 비고 선언 자료형 변수이름; 자료형 *포변수이름; & : 주소지정 연산자 * : 간접 연산자 값 할당 변수이름=값; 포변수이름=주소; *포변수이름=값; 선언과 동시에 초기화 자료형 변수이름=값; 자료형 *포변수이름=주소; ‘포인터변수이름’을 ‘포변수이름’으로 표기함
소스 4-4 (ch04_03.cpp) #include <iostream> using namespace std; int main() { int a=100;; int *pa; pa=&a; cout << "a에 저장된 값 : " << a << endl; cout << "a의 주소 : " << &a << endl; cout <<"******************************"<< endl; cout << "a에 저장된 값 : " << *pa << endl; cout << "a의 주소 : " << pa << endl; return 0; }
배열 1 변수 배열 하나의 기억 공간 예) 나이, 점수, 성별 등의 데이터를 저장 연속적인 기억 공간 예) 30명의 총점을 저장, 세 과목의 성적을 저장 선언할 때 연속적으로 필요한 기억 공간의 개수를 표시
배열 2 배열 선언 : 자료형, 배열이름, 크기 배열 첨자는 0부터 시작 int score[3]; 의 경우 score[0], score[1], score[2] char name[30];의 경우 name[0], name[1], …. , name[28], name[29] 자료형 배열이름[크기];
배열 3 배열이름 = 주소 int score[3]; &score[0] == score &score[1] == score+1 char name[5]; &name[0] == name &name[1] == name+1 &name[2] == name+2 &name[3] == name+3 &name[4] == name+4 정수형 배열의 경우 각 기억장소가 4바이트 단위로 증가함 문자형 배열의 경우 각 기억장소가 1바이트 단위로 증가함
소스 4-8 (ch04_05.cpp) int score[3]={99,88,100}; cout << "score[0]의 주소 : " << &score[0] << endl; cout << "score[1]의 주소 : " << &score[1] << endl; cout << "score[2]의 주소 : " << &score[2] << endl; cout << "******************************************" << endl; for (int i=0; i<3; i++) cout << "score[" << i << "]의 주소 : " << &score[i] << endl; cout << "score[0]의 주소 : " << score << endl; cout << "score[1]의 주소 : " << score+1 << endl; cout << "score[2]의 주소 : " << score+2 << endl; cout << "score[" << i << "]의 주소 : " << score+i << endl;
배열 초기화 선언과 동시에 초기화 자료형 배열이름[크기]={초기값1, 초기값2, ….}; 자료형 배열이름[크기]={초기값1, 초기값2, ….}; 자료형 배열이름[크기]={초기값, }; int s[3]={10,20, 30}; int a[5]={0,};
문자열 문자열 : 문자의 모음 문자 배열 문자열 상수는 쌍따옴표 “”로 표기 문자열 마지막을 알리는 널(NULL)문자가 자동으로 입력됨 char string[30]=“computer”; char string[30]={‘c’, ‘o’, ‘m’, ‘p’, ‘u’, ‘t’, ‘e’, ‘r’, ‘\0’};
소스 4-11 (ch04_10.cpp) #include <iostream> using namespace std; int main() { char string[30]="computer"; int i=0; cout << string << endl; for (i=0; string[i]!='\0'; i++) cout << string[i]; cout << endl; return 0; }
문자열 함수 1 자주 사용하는 문자열 처리 함수를 라이브러리에서 제공함 문자열 길이 구하기 문자열 복사하기 strlen(const char *_Str) 문자열 복사하기 strcpy(char *_Dest, const char *_Str) strcpy_s(char *_Dest, rsize_t SizelnBytes, const char *_Str)
문자열 함수 2 문자열 결합하기 문자열 비교하기 strcat(char *_Dest, const char *_Str) strcat_s(char *_Dest, rsize_t Sizeln Bytes, const char *_Str) 문자열 비교하기 strcmp(const char *str1, const char *str2)
소스 4-18 (ch04_14.cpp) char s_string[100]="C++ programming is very interesting!!!"; char d_string[100]; cout << "s_string = " << s_string << endl; strcpy_s(d_string, _countof(d_string), s_string); //s_string를 d_string에 복사하기 cout << "d_string = " << d_string << endl; strncpy_s(d_string, _countof(d_string), s_string, 3); //s_string에서 3개의 문자를 d_string에 복사하기 strcat_s(d_string, _countof(d_string), "*****"); strncat_s(d_string, _countof(d_string), s_string, 3);
주민등록번호 입력 받아 생년월일 출력 실행 결과 : 주민등록번호 입력: 000000-0000000 당신은 0000년 00월 00일에 태어나셨습니다. 필요한 변수 : 주민등록번호를 저장할 문자 배열 생년월일에서 연도를 저장할 문자 배열 생년월일에서 월을 저장할 문자 배열 생년월일에서 일을 저장할 문자 배열 작업 순서를 정리하면 다음과 같다. 필요한 변수를 선언한다. 주민등록번호 입력 메시지를 출력한다. 주민등록번호 문자열을 입력받는다. 첨자 7의 문자가 1, 2 또는 3, 4인가를 확인해서 연도 배열 변수에 '19' 또는 '20'을 할당한다. 주민등록번호에서 연도에 해당하는 문자열을 연도 배열 변수에 덧붙인다. 주민등록번호에서 월에 해당하는 문자열을 월 저장 배열 변수에 할당한다. 주민등록번호에서 일에 해당하는 문자열을 일 저장 배열 변수에 할당한다.
소스 4-19 (ch04_15.cpp) char jumin[30]={0,}; char year[5]={0,}, month[3]={0,}, day[3]={0,}; cout << "주민번호 입력 : "; cin >> jumin; if (jumin[7]=='1' || jumin[7]=='2') strcpy_s(year, _countof(year), "19"); else strcpy_s(year, _countof(year), "20"); strncat_s(year, _countof(year), jumin, 2); strncpy_s(month, _countof(month), jumin+2, 2); strncpy_s(day, _countof(day), jumin+4, 2); cout << "당신은 " << year << "년 " << month << "월 " << day << "일 입니다." << endl;
포인터 : 메모리 주소 포인터의 크기 주기억장치에서의 자료 처리 기본 단위 운영체제에 의해 결정, 윈도우 XP(32비트 운영체제) int *pi; char *pc; float *pf; double *pd; cout << "정수형 포인터 크기 : " << sizeof(pi) << endl; cout << "문자형 포인터 크기 : " << sizeof(pc) << endl; cout << "실수형 포인터 크기 : " << sizeof(pf) << endl; cout << "배정도형 포인터 크기 : " << sizeof(pd) << endl;
레퍼런스 변수 이미 선언한 변수를 다른 이름을 부르는 것 레퍼런스 변수 선언시 반드시 초기화 해야 함! 자료형 &변수이름=변수;
소스 4-22 (ch04_18.cpp) #include <iostream> using namespace std; int main() { int a=100; int &ra=a; cout << "a= " << a << endl; cout << "ra=" << ra << endl; cout << "****************" << endl; ra=200; return 0; }
동적 할당 1 자료 저장을 위한 기억장소 할당 방법 정적 할당 동적 할당 프로그램에서 필요한 변수를 선언 프로그램 실행 시작에서 필요한 변수에 대한 기억공간이 할당됨 동적 할당 프로그램에서 필요한 기억공간의 크기를 할당하여 그 시작 주소를 기억 (포인터변수 사용!!) 프로그램 실행 중 기억공간이 할당되고, 사용을 마친 후 할당한 기억공간을 해제
동적 할당 2 기억장소 할당 : new 기억장소 해제 : delete 자료형 *포인터변수 = new 자료형[개수]; double *dp = new double; //한 개의 배정도형 기억공간 할당 delete dp; int *ip=new int[20]; delete [] ip;
소스 4-23 (ch04_19.cpp) int *pi = new int; *pi=100; cout << *pi << endl; delete pi; int *pj = new int[3]; int i; pj[0]=10; pj[1]=20; pj[2]=30; for (i=0; i<3; i++) cout << pj[i] << endl; delete [] pj;