SeoulTech 2010-2 nd 프로그래밍입문 2 7 장. 포인터와문자열 박종혁교수 UCS Lab (http://www.parkjonghyuk.net) Tel: 02-970-6702 Email: jhpark1@snut.ac.kr C++ 로C++ 시작하는로객체지향프로그래밍 1 1 1
포인터에대한이해 (7.1) 목차 포인터를선언하고값을대입하는방법 (7.2) 포인터를이용하여각요소에접근하는방법 (7.2) 포인터를사용한참조로인수를전달하는방법 (7.3) 배열과포인터간의관계이해 (7.4) 포인터를사용하여배열요소에접근하는방법 (7.4) 상수포인터와상수데이터를선언하는방법 (7.5) 함수에서포인터를반환하는방법 (7.6) new 연산자를사용한동적메모리할당방법 (7.7) 문자함수를사용하여문자를테스트하고변환하는방법 (7.9.1) 배열과포인터를사용하여문자열을다루는방법 (7.9.2) 키보드에서문자열을읽어들이는방법 (7.9.3) C-문자열함수를사용하여문자열처리 (7.9.4) C++ 로시작하는객체지향프로그래밍 2
포인터는무엇인가? 포인터변수 (pointer variable) 를간단히포인터라고하는데, 포인터는메모리번지 (memory address) 를값으로가진다. 일반적으로변수는데이터값, 즉정수, 실수, 문자를가진다. 그러나포인터는데이터값의메모리번지를가지고있다. C++ 로시작하는객체지향프로그래밍 3
포인터선언 다른변수와마찬가지로포인터도사용하기전에선언되어야한다. 포인터를선언하는구문은다음과같다. datatype *pvarname; 포인터변수를선언할때는변수앞에애스터리스크 (*) 를붙여선언한다. 예를들어, 다음예는 pcount 포인터를선언한것으로정수형변수를가리킬수있다. int *pcount; Address of pcount pcount count Address of variable count Address of variable count 5 TestPointer C++ 로시작하는객체지향프로그래밍 4
포인터값참조 포인터에의해값을참조하는것을간접참조 (indirection) 이라고한다. 포인터로부터값을참조하는구문은다음과같다. *pointer 예를들어, count 변수를증가시킬때, count++; // 직접참조 같이변수를직접사용하는직접참조 (direct reference) 와 (*pcount)++; // 간접참조 C++ 로시작하는객체지향프로그래밍 5
포인터타입 포인터변수는 int, double 등과같은여러유형으로선언할수있으며, 같은유형변수의번지를기억할수있다. 포인터의유형과기억되는번지의유형이서로다르면오류 (error) 가된다. 예를들어, 다음코드는잘못된것이다. int area = 1; double *parea = &area; // 잘못된경우 C++ 로시작하는객체지향프로그래밍 6
포인터초기화 지역변수처럼지역포인터 (local pointer) 도초기화하지않으면임의의값을가지게된다. 포인터가 0으로초기화될수도있는데, 이는포인터가아무것도가리키지않는다는것을의미하는포인터에대한특별한값이된다. 오류방지를위해항상포인터를초기화해야한다. 초기화되지않은포인터를간접참조 ( 역참조 ) 하는것은중대한실행오류를발생시키거나중요한데이터를변경시킬소지가있다. C++ 로시작하는객체지향프로그래밍 7
주의사항 같은줄에두변수를선언할수있다. 예를들어, 다음은두정수형변수를선언한것이다. int i = 0, j = 1; 두포인터변수를다음과같이작성할수있을까? int* pi, pj; 이는잘못된표현이된다. 이와같이선언을하면다음과같이앞변수만포인터변수가된다. int *pi, pj; C++ 로시작하는객체지향프로그래밍 8
포인터참조에의한인수전달 C++ 에서함수로인수를전달하는방법에는세가지방법이있다. 값에의한전달 (pass-by-value), 참조인수를사용한참조에의한전달 (pass-by-reference), 포인터를사용한참조에의한전달이다. TestPointerArgument C++ 로시작하는객체지향프로그래밍 9
배열과포인터 배열을첨자없이이름만사용하면배열이시작되는번지를의미한다는점을상기하자. 이런점에서배열은포인터와같다고볼수있다. 다음과같이 int 배열을선언하였다. int list[6] = {11, 12, 13, 14, 15, 16}; list list+1 list+2 list+3 list+4 list+5 11 12 13 14 15 16 C++ 로시작하는객체지향프로그래밍 10
배열포인터 *(list + 1) 은 *list + 1과는다르다. 간접참조연산자 (*) 는 + 보다우선순위가앞선다. 그래서 *list + 1 은배열의첫번째요소에 1 을더하는것이고, 반면에 *(list + 1) 은 (list + 1) 번지의요소를참조하는것이다. ArrayPointer PointerWithIndex C++ 로시작하는객체지향프로그래밍 11
Const 와포인터 앞에서 const 키워드로상수를선언하는방법을살펴보았다. 상수는선언된다음에는값이변경될수없다. 포인터에서도상수포인터 (constant pointer) 를선언할수있다. 예를들어, 다음코드를살펴보자. ConstParameter double radius = 5; double * const pvalue = &radius; Constant data Constant pointer const double * const pvalue = &radius; C++ 로시작하는객체지향프로그래밍 12
함수에서포인터반환 함수에서포인터를매개변수로사용할수있지만, 함수의반환값으로포인터를사용할수있을까? 답은가능하다. WrongReverse CorrectReverse C++ 로시작하는객체지향프로그래밍 13
실전예제 : 각문자의빈도세기 소문자 100 개를랜덤하게생성한다음, 문자배열에저장한다. 배열에서각문자의빈도를센다. chars[0] [] counts[0] chars[1] counts[1] chars[98] counts[24] chars[99] counts[25] CountLettersInArray C++ 로시작하는객체지향프로그래밍 14
문자와문자열 문자열 (ti (string) 은프로그래밍에서자주사용된다. 문자열리터럴 (literal) 은이미사용한적이있다. 문자열은문자가연속되어있는것이다. C++ 에서문자열을다루는방법은두가지가있다. 한가지는문자열을문자배열로다루는방법으로, 이를포인터기반문자열 (pointer based strings) 또는 C- 문자열이라고한다. 다른방법은 string ti 클래스를사용하여문자열을다루는방법이다. string 클래스는 98 9.8 절 C++ string 클래스 에서소개한다. 이절에서는포인터기반문자열에대해서설명한다. C++ 로시작하는객체지향프로그래밍 15
문자검사함수 Function Description i Example isdigit(c) Returns true if c is a digit. isdigit('7') is true isdigit('a') is false isalpha(c) Returns true if c is a letter. isalpha('7') is false isalpha('a') is true isalnum(c) Returns true if c is a letter or isalnum('7') is true a digit. isalnum('a') is true islower(c) Returns true if c is a lowercase islower('7') is false letter. islower('a') is true isupper(c) Returns true if c is an uppercase isupper('a') is false letter. isupper('a') is true isspace(c) Returns true if c is a whitespace isspace('\t') is true character. isspace('a') is false isprint(c) Returns true if c is a printable isprint(' ') is true character including space. isprint('a') is true isgraph(c) Returns true if c is a printable isgraph(' ') is false character excluding space. isgraph('a') is true ispunct(c) Returns true if c is a printable ispunct('*') is true character other than a digit, ispunct(',') is true letter, or space. ispunct('a') is false iscntrl(c) Returns true if c is a control iscntrl('*') is false character such as '\n', '\f', '\v', iscntrl('\n') is true '\a', and '\b'. iscntrl('\f') is true C++ 로시작하는객체지향프로그래밍 16
대소문자변환함수 Function Description Example tolower(c) Returns the lowercase equivalent of tolower('a') returns 'a' c, if c is an uppercase letter. tolower('a') returns 'a' Otherwise, return c itself. tolower('\t') returns '\t' toupper(c) Returns the uppercase equivalent of toupper('a') returns 'A' c, if c is a lowercase letter. toupper('a') returns 'A' Otherwise, return c itself. toupper('\t') returns '\t' CharacterFunctions C++ 로시작하는객체지향프로그래밍 17
문자열저장과사용 C++ 에서포인터기반문자열은널문자 ('\0') 로끝나는문자배열로서, 널문자는메모리에서문자열이끝나는지점을알려주는역할을한다. 배열은포인터를통해접근할수있으므로문자열도포인터를통해접근이가능하다. 포인터는문자열의첫번째문자를가리킨다. 그러므로배열이나포인터를사용하여문자열을선언할수있다. 예를들어, 다음의두가지선언모두맞는것이다. char city[7] = "Dallas"; // 방법 1 char *pcity = "Dallas"; // 방법 2 C++ 로시작하는객체지향프로그래밍 18
포인터사용방법 배열구문과포인터구문을사용하여 city와 pcity에접근할수있다. 예를들면, cout << city[1] << endl; cout << *(city+1)<<endl; cout << pcity[1] << endl; cout << *(pcity + 1) << endl; 는모두문자열의두번째문자인 a 를출력한다. C++ 로시작하는객체지향프로그래밍 19
문자열읽기 키보드에서문자열을읽어들이기위해서는 cin 객체를사용할수있다. 예를들어, 다음코드를살펴보자. cout << "Enter a city: "; cin >> city; // read to array city cout << "You entered " << city << endl; C++ 로시작하는객체지향프로그래밍 20
getline 으로문자열읽기 iostream 헤더파일의 cin.getline을사용하면문자열을제대로배열로읽어들일수있게된다. 이함수의구문은다음과같다. cin.getline(char array[], int size, char delimitchar) 이함수는구분문자 (delimiter) 가나오거나, size - 1 개의문자를읽으면읽기를종료한다. 배열의마지막문자는널문자 ('\0') \0) 가저장된다. 구분문자가나오면입력은되지만배열에는저장되지않는다. 세번째인수인 delimitchar 의기본값은 ('\n') \n) 이다. C++ 로시작하는객체지향프로그래밍 21
Function Description 문자열 함수 int strlen(char *s1) Returns the length of the string, i.e., the number of the characters before the null terminator. char *strcpy(char *s1, const char *s2) Copies the string s2 to string s1. The value in s1 is returned. char *strncpy(char *s1, const char *s2, size_t n) Copies at most n characters from string s2 to string s1. The value in s1 is returned. char *strcat(char *s1, const char *s2) Appends string s2 to s1. The first character of s2 overwrites the null terminator in s1. The value in s1 is returned. char *strncat(char t( *s1, const char *s2, size_t n) Appends at most n characters from string s2 to s1. The first character of s2 overwrites the null terminator in s1 and appends a null terminator to the result. The value in s1 is returned. int *strcmp(char *s1, const char *s2) Returns a value greater than 0, 0, or less than 0 if s1 is greater than, equal to, or less than s2 based on the numeric code of the characters. int *strncmp(char *s1, const char *s2, size_t n) Returns a value greater than 0, 0, or less than 0 if the n characters in s1 is greater than, equal to, or less than the first n characters in s2 based on the numeric code of the characters. int atoi(char *s1) Converts the string to an int value. double atof(char *s1) Converts the string to a double value. long atol(char *s1) Converts the string to a long value. void itoa(int value, char *s1, int radix) Converts the value to a string based on specified radix. C++ 로시작하는객체지향프로그래밍 22
문자열예제 CopyString CombineString CompareString StringConversion C++ 로시작하는객체지향프로그래밍 23
부분문자열만들기 문자열로부터부분문자열의작성이필요한경우가있다. 그러나 <cstring> 헤더파일에는이런함수가없기때문에부분문자열을추출하는함수를작성해서사용해야한다. 함수의헤더를다음과같이하도록한다. char * substring(char *s, int start, int end) Substring.h TestSubstring C++ 로시작하는객체지향프로그래밍 24
실전예제 : 회문 ( 回文 ) 검사 앞에서읽으나뒤로부터읽으나같은문자열을회문 ( 回文 ) 이라고한다. mom, dad, d noon, 등이회문이된다. CheckPalindrome C++ 로시작하는객체지향프로그래밍 25