1. 문자열 상수 구현 및 방법
1) 문자열은 컴파일러가 특별한 방식으로 다룬다.
문자열은 크기가 일정하지 않다. 따라서 컴파일러가 문자열을 처리할 때 특별한 방법으로 처리한다. 컴파일 과정에서 문자열을 char 배열 형태로 따로 보관하고, 문자열 상수가 있던 곳에는 배열의 위치 값을 사용한다. 예를 들어 문자열 "apple"은 따로 리터럴 영역에 수정할 수 없는 문자열 상수로 저장되고, 이 자리는 'a' 문자가 저장된 메모리의 주소값으로 바뀐다.
2) 문자열이나 문자열을 저장한 포인터를 주소로 접근하여 문자열 자체를 바꿔서는 안 된다.
*"apple" = 't' 등으로 첫 번째 문자가 저장된 공간에 다른 문자를 대입해 그 값을 바꾸려는 시도는 위험하다. 연산 자체는 문제가 없어 정상적으로 컴파일 되지만, 실행할 때 운영체제에 의해 강제 종료될 가능성이 있다. 운영체제는 문자열을 읽기 전용 메모리 영역에 저장하기 때문이다.(리터럴, literal 값)
문자열을 주소로 바꾸면 쉽게 문자열에 접근하여 시작위치부터 길이 제한 없이 사용할 수 있다. 하지만 문자열 끝을 알아야 할당되지 않은 영역을 침범하지 않으므로, 컴파일러는 자동으로 문자의 끝에 널문자를 사용한다. 따라서 문자열 상수로 따로 저장할 때 마지막에 항상 널 문자를 붙여준다.
2. char 포인터로 문자열 사용
1) 다른 문자열로 변경 및 이름 지정
char 포인터를 이용해 문자열을 저장하면 문자열에 이름을 붙여 사용할 수 있고, 입력 받지는 못하지만(문자열 자체 수정) 다른 문자열로 쉽게 바꿀 수 있습니다.
3. scanf 함수를 사용한 문자열 입력
1) 공백 등의 white space는 입력되지 않는다.
scanf 함수는 중간에 white space(Enter, Space bar, Tab)이 오면 그 이전까지만 저장한다. 그리고 자동으로 마지막에 널 문자를 붙인다. 그래서 Space bar나 개행문자를 버퍼에 남겨두면 그 다음 입력 함수를 입력했을 때 가져와서 원하지 않은 방식으로 문자를 가져올 수 있다.
4. gets 함수를 사용한 문자열 입력
1) 공백이나 탭 문자를 입력 가능하다.
그러므로 한 문장을 한 번에 가져올 수 있습니다. 이어져 있는 한 단어만 가져오고 싶다면 scanf를 써도 되지만, 문자열 전용 입력 함수인 gets를 사용하면 더 가볍게 가져올 수 있다.
결국 scanf 함수는 엔터 등의 white space를 누르면 문자열을 구분하는 용도로 쓰이기 때문에 입력을 계속 기다리지만, gets 함수는 엔터만 눌러도 입력을 끝냅니다. 그리고 널문자로 바꿔버리고 배열의 첫 번째 요소에는 개행 문자 대신 널 문자만 있게 됩니다.
2) 버퍼에서 개행 문자를 가져오지만 배열에는 널 문자로 바꿔 저장한다.
fgets 함수와 다른 점인데 fgets 함수는 개행 문자까지 저장하고 마지막에 널 문자를 붙이는 반면, gets 함수는 개행 문자를 널 문자로 바꿔버린다.
5. 예제
다음과 같이 배열과 포인터가 선언되어 있다.
char str[20] = "apple";
char *pa = str;
char *pb = "pineapple";
다음에 나오는 명령문의 실행결과를 작성한다면?
1) printf("%s", "apple");
문자열에 저장되어 있는 문자열의 처음 문자 'a'의 주소값을 printf의 인수로 줘서 변환 문자 %s를 만나면 주소 연산을 하여 'a'부터 '\0'전 까지 출력한다.
2) printf("%s", str[0]);
str[0]에 저장된 문자 'a'의 아스키 문자 97을 printf의 인수로 줘서 변환 문자 %s를 만나면 97을 주소로 인식하여 97번지 메모리로 접근한다. 이곳엔 무엇이 있는지 모르므로 매우 위험한 연산이다.
3) printf("%s", pa);
포인터 변수 pa에 저장된 배열 str의 첫 번째 요소의 주소를 printf 인수로 넘겨 변환 문자 %s를 만나면 주소 연산을 하여 'a'부터 '\0'전 까지 출력한다.
4) printf("%s", pb + 4);
문자열은 컴파일러가 char형 배열로 따로 저장하고, 문자열 자리에는 문자열 첫 번째 문자의 주소값을 주므로 변수 pb를 배열 명처럼 사용할 수 있다. 즉, 주소 연산하여 문자열을 배열처럼 사용할 수 있다. pb + 4는 &pb[4]와 같은 의미이고, 배열의 다섯 번째 요소인 'a'부터 '\0'전 까지 출력한다.
'C언어' 카테고리의 다른 글
[혼공C] 11-2 scanf 함수의 int 자료형 변수 입력과 stdio.h의 EOF (0) | 2021.10.07 |
---|---|
[혼공C] 11-2 입출력 함수가 버퍼를 사용하면 좋은 점 (0) | 2021.10.07 |
혼공c 11-1 변환문자 %c (0) | 2021.09.01 |
혼공c 함수의 매개변수 자리에 배열을 선언하는 경우 (0) | 2021.08.31 |
[백준] 2588번 : 곱셈 c언어 (0) | 2021.08.27 |