🏷️문자열
- 말 그대로 문자들의 나열이다.
- 단, 정상적인 문자열은 첫 문자부터 첫 널문자를 만날 때까지(널문자 포함)를 의미한다.
- 문자열의 데이터 형은 array of char(char [])다.
- 문자열은 마지막이 널문자라는 것만 제외하면 완전히 배열과 똑같다.
- 따라서 문자열은 배열 대상체다.
- 문자열이 만들어지는 방법은 크게 두가지다.
- 배열의 선언을 통해 생성한다.
- 문자열 상수를 통해 생성한다.
- 표준에서 문자열 상수로 인해 만들어진 문자열 대상체의 요소의 값을 바꾸려는 시도는 정의되지 않는다.
- 이는 문자열 상수가 실제 ROM에 존재하거나, 겹치는 문자열이 있을 경우 메모리를 공유 할 수 있게 해준다.
- 🖇️cf. 메모리를 공유한다는 의미는 다음과 같다.
- 다음 코드에서 a가 가리키는 문자열의 일부인
world
와 b의 world
가 같은 메모리 공간을 가질 수 있다는 것이다.
- 만일 문자열 상수로 통해 생성된 문자열이 수정이 가능하다면, b가 가리키는 문자열의 값(
world
)을 다른 문자열로 바꿨을 때, a가 가리키는 문자열의 일부(world
쪽)가 바뀌는 참사가 벌어질 수 있다.
char *a = "hello world";
char *b = "world";
- 문자열 상수로 만들어진 문자열 대상체나, 수정할 일이 없는 문자열 대상체를 가리키는 포인터를 pointer to const char로 선언하는 것은 좋은 습관이다.
- 문자열 상수로 만들어진 문자열 대상체의 데이터 타입을 이제와서 array of const char로 만들어 버리기엔 너무 늦었다.
- 🖇️cf. 굳이 따지자면, 언어 설계상 아쉬운 점이다.
- 지금 바꾸면 과거에 작성되었던 수많은 프로그램을 한 순간 잘못된 프로그램이 되버린다.
🏷️문자열 상수
""
(큰 따옴표)로 둘러 쌓인 format이다.
- 문자열 대상체를 지정하는 lvalue다.
- 문자열 대상체는 배열이므로 따라서 배열을 지정하는 lvalue가 된다.
- 배열을 지정하는 lvalue는 많은 문맥에서 첫번 째 요소를 가리키는 포인터 값으로 decay한다.
- 배열 decay규칙과 유사하게, decay하지 않는 경우는 다음과 같다.
- sizeof의 연산자인 경우
- array of char을 초기화하는데 초기치로써 문자열 상수가 사용되는 경우
- 문자열 상수는 정수 상수나 부동 상수 같은 상수가 아니라 lvalue라는 사실을 잊어서는 안된다.