C 언어 포인터 정복하기
TAE-HYONG KIM
COMPUTER ENG, KIT
9강. 포인터로 문자열 다루기
학습 내용
문자열 상수의 정체
문자열처리 함수 분석하기
포인터변수 상수화 하기
포인터를 반환하기
문자열처리 함수 소개
2
문자열 상수를 통한 함수 호출
문자열 상수
저장을 위해서 문자 배열이 필요하다
printf()에 사용시 문자 배열과 같은 변환문자열(“%s”)을 사 용한다
문자 배열(이름)을 함수인자로 사용하면 배열 첫 요소를 가 리키는 포인터 상수가 함수에 넘겨진다
그렇다면 문자열 상수(“hello”) 역시 포인터일까?
3
func(“hello”);
...
Void func(?) {...
Char str[] = “hello”;
printf(“%s”, str); printf(“%s”, “hello”);
문자열 상수의 정체
문자열 상수의 값 확인
저장 값은 주소가 출력됨 포인터 확인
크기는 전체문자 수가 출력됨 배열의 이름과 유사
배열의 이름과 포인터로 사용해 보자
문자열 상수의 정체
문자열 상수는 문자열 상수에 포함된 문자를 요소로 가지는 문자 배열의 가상적인 이름과 같다
• 첫 문자를 가리키는 포인터상수
• 문자 개수 정보를 가짐
4
printf(“%d, %d”, “hello”, sizeof(“hello”));
printf(“%c %c”, “hello”[0], *(“hello”+2));
문자열 상수의 사용
문자 배열 초기화 (문자열 변수)
“abc”가 저장된 공간을 배열 str1의 공간으로 만듦?
문자 포인터 초기화 (문자열 상수)
“abc”의 ‘a’를 가리키는 포인터를 포인터변수 str2가 저장함
포인터 str2를 해당 공간에서 문자 배열의 이름처럼 사용가능
함수 인자로 함수 호출
첫 문자를 가리키는 포인터가 넘겨지므로 문자 포인터변수로 받음
5
char str1[4] = “abc”;
char *str2 = “abc”;
printf(“%c”, str2[1]);
func(“hello”);
void func(char str*) // or func(char str[]);
strcpy()의 분석
반환 값이 있음: dest (char * 형)
복사된 문자열(dest)을 호출과 동시에 사용 수 있도록 해줌
크기 없는 배열([]) 대신 포인터 변수를 인자 형으로 사용
문자 포인터 변수 src 앞에 const (상수) 키워드 사용
주어진 문자열을 변환할 수 없도록 함
6
char *strcpy(char *dest, const char *src) {
int i=0;
while (*(src+i) != ‘\0’) { *(dest+i) = *(src+i);
i++;
}
*(dest+i) = *(src+i); \\ NULL문자 복사 return dest;
}
printf(“%s”, strcpy(str, “hello”));
포인터 변수 앞에 쓰는 const
포인터가 가리키는 변수의 상수화
가리키는 자료형 앞에 const 키워드 사용
포인터 변수(주소)의 상수화
포인터 변수 이름 앞에 const 키워드 사용
7
int a=10, b=20;
const int *p = &a;
*p = 30; // Error!
p = &b; // 주소 값은 바꿀 수 있음
int a=10, b=20;
int * const p = &a;
*p = 30; // OK!
p = &b; // Error!
포인터 변수 앞에 쓰는 const (2)
포인터가 가리키는 변수와 포인터 변수 모두 상수화
가리키는 자료형 및 포인터 변수 이름 앞에 const 키워드 사용
strcpy()에서 const 키워드를 쓴 이유
함수 외부 공간의 포인터를 넘겨주었기 때문에 strcpy() 함수는 해당공간 의 정보를 변경할 수 있다
dest가 가리키는 공간은 변경(복사)해야 하지만 src가 가리키는 공간은 변경하면 안되므로 const 키워드를 char 앞에 두어 상수화한다
프로그램(함수)의 안전성을 높이기 위한 기법으로 사용
8
int a=10, b=20;
const int * const p = &a;
*p = 30; // Error!
p = &b; // Error!
char *strcpy(char *dest, const char *src);
함수에서 포인터 반환하기
함수가 포인터를 반환하여 호출 함수에서 사용하도록 함
반환 형이 포인터 형이 된다
어떤 주소의 포인터를 반환해야 할까?
피호출 함수 내부 변수의 포인터를 반환하면 함수 종료 후 메모리도 반납 되므로 이 공간을 사용할 수 없다
함수가 반환된 후에도 유지되는 기억공간의 포인터만 반환 가능하다
동적할당 공간, 전역변수, 호출함수 공간
strcpy()의 경우
Dest 공간, 즉 호출함수에서 포인터 인자로 주어진 공간을 반환함
함수 호출과 동시에 해당 공간을 사용할 수 있게 해 줌
9
char *strcpy(char *dest, const char *src);
int *ap = add_ten(a);
printf("a : %d\n", *ap);
...
int *add_ten(int b) {
b=b+10;
return &b;
}
문자열 처리함수 예
10
패턴 13 두 문자열을 연결하는 함수(strcat())
#include <stdio.h>
char *strcat(char *, const char *);
int main(void) {
char str[10] = “very”;
printf(“%s”, strcat(str, “ good”));
return 0;
}
char *strcat(char *dest, const char *src) {
char *temp = dest; // dest 대신 temp를 이용해 복사 수행 int i;
while (*temp++ != ‘\0’); // temp를 복사할 위치까지 이동 while (src[i] != ‘\0’) {
temp[i] = src[i];
i++;
}
temp[i] = ‘\0’;
return dest;
}
문자열 처리함수 예
11
문자열 입출력함수(stdio.h)
문자열 조작함수(string.h)
int puts( const char* s );
int fputs( const char* s, FILE* stream );
char* gets( char* s );
char* fgets( char* s, int n, FILE* stream );
size_t strlen( const char* s );
char* strcpy( char* dest, const char* src );
char* strncpy( char* dest, const char* src, size_t n );
char* strcat( char* dest, const char* src );
char* strncat( char* dest, const char* src, size_t n );
문자열 처리함수 예 (2)
12
문자열 비교 함수(string.h)
문자열 검색 함수(string.h)
문자열 변환함수(string.h)
int strcmp( const char* s1, const char* s2 );
int strncmp( const char* s1, const char* s2, size_t n );
int atoi( char *ptr ); // 문자열을 int형 데이터로 변환 long atol( char *ptr ); // 문자열을 long형 데이터로 변환 double atof( char *str ); // 문자열을 double형 데이터로 변환 char *strchr(const char* s1, int c);
char *strstr(const char* s1, const char* s2);