문자열

우리는 문자열을 저장하기 위해 CS50 라이브러리에 포함된 string 자료형을 사용했다.

아래와 같이 s에 “EMMA”라는 값을 저장한다고 생각해 보면,

 

문자열은 결국 문자의 배열이고, s[0], s[1], s[2], … 와 같이 하나의 문자가 배열의 한 부분을 나타낸다.

( ※ 가장 마지막의 \0은 0으로 이루어진 바이트로, 문자열의 끝을 표시하는 약속 )

여기서 변수 s는 결국 이러한 문자열을 가리키는 포인터

더 상세히는 문자열의 가장 첫번째 문자, 즉 주소 0x123에 있는 s[0]를 가리키게 된다.

 

실제 CS50 라이브러리를 보면 string 자료형은 아래와 같이 정의되어 있다.

여기서 typedef는 새로운 자료형을, char *은 문자에 대한 포인터를, string은 자료형의 이름을 의미

 

따라서 아래 두 코드는 동일하게 동작할 것

① string 자료형을 이용하여 “EMMA” 출력

char 포인터를 이용하여 “EMMA” 출력

 

2번 코드의 char *s에서 s라는 변수는 문자에 대한 포인터가 되고, “EMMA”라는 문자열의 가장 첫 번째 값을 저장하기 때문

// 내가 이해한 바 : string = char*, 즉 문자열 첫 주소에대한 포인터

 

 문자열 비교

 

위 코드를 실행하면, s라는 포인터의 값, 즉 “EMMA”라는 문자열의 가장 첫 값인 “E”에 해당하는 메모리 주소를 출력하게 될 것

 

그렇다면 아래 코드들은 무엇을 출력할까?

s가 가리키는 곳을 시작으로 “EMMA”라는 문자열로 이루어진 문자들의 배열이 있으니, 각각

s라는 문자열의 첫 번째 문자에 해당하는 주소값,

s라는 문자열의 두 번째 문자에 해당하는 주소값,

s라는 문자열의 세 번째 문자에 해당하는 주소값,

s라는 문자열의 네 번째 문자에 해당하는 주소값을 출력

( &s[0]는 “E”의 주소값을, &s[1]은 “M”의 주소값을,  &s[2]은 “M”의 주소값을,  &s[3]은 “A”의 주소값을 의미 )

 

문자열은 첫번째 문자를 시작으로 메모리상에서 바로 옆에 저장되어 있다.

다시 말해, 가장 첫 번째 문자에 해당하는 주소값을 하나씩 증가시키면 바로 옆에 있는 문자의 값을 출력할 수 있는 것

따라서 아래 코드는 E M M A를 순서대로 출력할 것

 

 

문자열을 비교할 때도 아래 코드와 같이 문자열이 저장된 변수를 바로 비교하게 되면

그 변수가 저장되어 있는 주소가 다르기 때문에 다르다는 결과가 나올 것

정확한 비교를 위해서는 실제 문자열이 저장되어 있는 곳으로 이동하여, 각 문자를 하나하나씩 비교해야 한다.

 

 

문자열 복사

문자열을 복사하기 위해 아래 코드를 실행하면?

 

  • 사용자에게 입력값을 받아 string s에 저장하고, string t를 s로 정의
  • 그리고 t의 첫 번째 문자를 toupper 함수를 이용하여 대문자로 바꾼다면 s와 t는 각각 어떻게 출력 될까?
  • 입력값으로 “emma”를 주게 된다면, 단순한 예상과는 다르게 s와 t 모두 “Emma”라고 출력이 된다.
  • 그 이유는  s라는 변수에는 “emma”라는 문자열이 아닌 그 문자열이 있는 메모리의 주소가 저장되기 때문
  • string s 는 char *s 와 동일한 의미
  • 따라서 t도 s와 동일한 주소를 가리키고 있고, t를 통한 수정은 s에도 그대로 반영이 되게 되는 것

 

그렇다면 두 문자열을 실제로 메모리상에서 복사하려면 어떻게 해야 할까?

아래 코드와 같이 메모리 할당 함수를 사용하면 됩니다

 

 

  • 위의 코드와 다른 점은 malloc이라는 함수를 이용해서 t를 정의한다는 것
  • malloc 이라는 함수는 정해진 크기 만큼 메모리를 할당하는 함수
  • 즉 s 문자열의 길이에 널 종단 문자(\0)에 해당하는 1을 더한 만큼 메모리를 할당
  • 그리고 루프를 돌면서 s 문자열 배열에 있는 문자 하나 하나를 t 배열에 복사해준다.
  • 이 코드를 컴파일 후 실행시키고 입력값으로 “emma”를 주면 우리가 예상한 대로 s는 “emma”가, t는 “Emma”가 성공적으로 출력

 

+ Recent posts