● 문자열 길이 탐색
문자열을 입력받아서 한글자씩 출력하는 프로그램이다.
이때 문자를 모두 출력했는지 여부를 어떻게 하면 좋을까?
다양한 방법 중 하나는 바로 널문자와 같은지의 여부이다.
따라서 for 문의 조건부분에 s[i] != '\0' 를 줘서 s[i] 가 \0 와 같으면 for 문을 종료하는 방식으로 수행하면 된다.
이런 방식으로 %s의 개념을 %c만을 사용해서 구현한 것이다.
그러나 문자열의 길이를 이용하는 방법이 있다.
문자열의 길이를 반환하는 함수인 strlen 을 사용한다. 이때 헤더파일로 string.h 를 포함시켜야 한다.
조건에 i < strlen(s) 를 적고 프로그램을 실행하면 여전히 결과는 같다.
함수를 사용하면서 문자열이 어떻게 구현되는지는 관심없고 복잡한 기계어를 간단하게 처리한 추상화를 통해서 길이를 알아낸 것이다.
하지만, 이 두가지 방법은 잘 디자인되었다고 판단할 수 없다. 여전히 개선의 여지가 남아있기 때문이다. 어떤 문제일까?
for문의 가운데에 있는 조건은 질문을 나타내는 불리언 표현으로 계속 물어보고 확인한다. 그런데 만약 그 조건이 함수라면 그것을 호출하는데 시간이 걸린다. 즉, 이런 과정을 굳이 계속 반복해서 질문하는 것은 비효율적인 것이다.
좀 더 생각해보면 문자열의 길이는 변하지 않는다. 이점을 이용하여 해결하는 방법은 2가지 이다.
1. 따로 변수 선언
for 문에 앞서 int n = strlen(s); 라고 변수를 선언하고 조건에는 i < n 을 적는 방법이다. 이로써 매 반복마다 함수를 호출하는 것이 아닌 그저 int 형태를 지닌 변수 n 과 비교하게 된다.
2. for 문에서 변수를 초기화하여 사용
for(int i = 0, n = strlen(s); i < n; i++)
루프에서 한번만 물어보고 계속 사용하려는 값이 있다면 위와 같은 방식으로 for문 안에서 변수를 선언하여 사용해도 된다.
※ n의 자료형을 선언하지 않은 이유 : 보통은 선언을 해야하지만 i와 n이 같은 자료형이기 때문에 선언을 생략해도 된다.
● 문자열을 모두 대문자로 바꾸는 프로그램
위 코드의 논리구조는 다음과 같다.
사용자에게 string을 입력받아 s에 저장한다.
조건문에서는 i 와 n 변수를 각각 0과 문자열의 길이로 초기화하고, 문자열의 길이만큼 반복한뒤
만약 변수 s 에 저장된 문자열의 문자들이 a ~ z 즉, 소문자라면
문자열의 문자들에 - 32 를 해준 값을 문자로 출력하고,
그렇지 않다면
그냥 문자들을 길이만큼 출력해라.
라는 의미이다.
어떻게 문자에 - 32를 해준다고 그것이 대문자로 나오는 것일까??
이는 ASCII 를 배웠을 당시에 대문자와 소문자는 정수이고 각각 32를 더하거나 빼주는 것으로 대응되는 것을 알 수 있다.
따라서 소문자를 대문자로 바꾸기 위해 -32 를 해주는 것이다.
그런데 굳이 s[i] 를 (int)로 형변환 할 필요 없이 clang이 자동으로 계산해주기 때문에 s[i] - 32 가 성립하는 것이다.
이 방법은 문자열을 대문자로 변환하는 과정을 아주 기계어에 가까운 형태로 구현한 것이다.
위와 같은 과정은 필요이상으로 복잡하다. 이때 사용할 수 있는 함수가 toupper 이다.
toupper 함수를 사용하기 위해 헤더파일로 ctype.h 파일을 추가한다.
toupper 함수에 소문자를 넣으면 대문자로 바꿔서 반환하고, 입력이 소문자가 아니면 그냥 그대로 반환한다.
따라서 printf("%c", toupper(s[i])); 를 입력해준 것이다.
여기서 중요한 것은 ASCII 나 32를 빼는 것에는 신경쓰지 않고 다른 사람이 만든 함수를 사용하여 간단하게 처리한 점이다. 프로그래밍은 추상화를 통해 복잡한 기계어를 간단하게 처리하는 것이다.
자료출처 : 부스트코스 - https://www.boostcourse.org/cs112/lecture/119017?isDesc=false
'cs50 기초강의' 카테고리의 다른 글
4. 알고리즘 - 검색 알고리즘 (0) | 2021.06.07 |
---|---|
3. 배열 - 명령행 인자 (0) | 2021.06.07 |
3. 배열 - 문자열과 배열 (0) | 2021.06.07 |
3. 배열 - 배열(1, 2) (0) | 2021.06.06 |
3. 배열 - 컴파일링 (0) | 2021.06.06 |