문자열은 문자들의 나열이고 문자열 끝에 반드시 '\0'(혹은 NULL, 0) 을 저장한다.
따라서 배열을 생성할때 반드시 null문자 자리까지 한개 더 잡아줘야 한다.
NULL은 C언어에서 0과 동등하다고 정했기 때문에 교차사용이 가능하다.
#DEFINE NULL 0
근데 0으로 써야하지 '0'으로 쓰면 문자로 인식해서 문자 0의 ASCII값인 48이 된다.
<외워두자 ASCII 코드>
0은 48
대문자 A는 65
소문자 a는 97
그래서 문자열을 초기화 할때는 이렇게 한다.
char sentence_1[4] = {‘A', ‘B', ‘C', '\0'};
char sentence_2[4] = {‘A', ‘B', ‘C', 0};
char sentence_3[4] = {‘A', ‘B', ‘C', NULL};
char sentence_4[4] = {“ABC"};
끝에 null문자를 넣어주거나 배열크기보다 하나 작은 단어를 저장한다.
""와 ''의 차이점(철저하게 구분)
" "(큰 따옴표)
큰 따옴표는 문자열 (한 개 이상의 문자)를 지정할 때 사용된다.
' '(작은 따옴표)
작은 따옴표는 한 개의 문자를 지정할 때 사용된다.
#include <stdio.h>
int main(void)
{
char word[30]={"long sentence"};
char *str = word;
printf("%s \n", str);
return 0;
}
여기서 %s를 쓰게되면 문자열을 자동으로 NULL이 나올때까지 출력해주기 때문에 문자열을 for문을 돌리지 않고도 출력할 수 있다.
문자열 리터럴
리터럴이란 소스코드 상에서 고정된 값(상수)을 가지는 것이다.
고정된 값이란 절대 고치지 못하는 것이고 따라서 문자열 리터럴은 고칠 수 없다.
문자열 리터럴 즉, 상수 문자를 고치려면 배열에 집어넣어야 한다.
char str[ ] = "hello";
char *pstr = "goodbye";
여기서 ptsr은 포인터이고 "goodbye"는 상수이다.
문자열 배열과 포인터의 차이
배열로 문자열을 저장할때
char s[ ] = “HelloWorld”;
s = “Goodbye”; //실행 오류가 발생
s[0] = ‘a’; //가능
배열의 이름의 속성은 상수포인터이기 때문에 ->
이 말인 즉슨, 배열의 이름은 배열의 주소를 담고 있고
그 주소는 변할 수 없는 상수이기 때문에
s="goodbye"를 실행한다는 것은
s=1 처럼 변수의 값을 저장하는 것과 달리
goodbye라는 문자열의 주소값을 s라는 변수에 담는 것이기 때문에
불가능하다.
그러나 char s[]라는 배열 자체는 읽기 쓰기가 가능한 stack 부분에 저장되어 있기 때문에
개별적으로 접근하여 문자를 고치는 것은 가능하다.
(사실 메모리 부분을 안배워서 100%이해하지 못했는데 제가 이해한 것을 최대한 적어보았습니다.)
포인터로 문자열을 저장할 때
char *p = “HelloWorld”;
p = “Goodbye”; //”Goodbye”가 저장된 주소로 포인터의 값을 변경
p[0] = ‘a’; //p가 가리키는 공간은 변경할 수 없다. 실행오류
반면 포인터는 상수가 아니기때문에
포인터에 새로운 주소를 대입하는 것이 얼마든지 가능하다.
하지만 포인터가 가리키는 문자열 자체는 상수의 영역으로 들어가기 때문에
문자열을 참조하여 변경은 불가능 하다.
문자열 연산
char str1[ ] = {"abc"};
char str2[ ] = {"def"};
str1 = str1 + str2;
str1+str2는 각 배열의 주소 값을 더하는 것인데 배열의 이름은 결국 상수 포인터이기 때문에
연산을 수행할 수 없다-> 포인터끼리의 연산이 안돼기 때문에!
<그 외 안되는 것>
if(str1 == str2)
-> 안됨.
애초에 주소값은 같을 수 가 없기 때문에 영원히 같지 않을 것이고 그렇기 때문에 불가능하게 만들었음.
if(str1=="abc")
->안됨.
문자열은 주소값으로 변환되기 때문에 결국 주소값과 주소값을 비교하는 것이 된다.
str1=str2
->안됨.
배열의 이름은 바뀔 수 없는 상수 포인터이기 때문에 대입이 불가능함.
char str[100];
str = "HelloWorld";
->안됨.
마찬가지로 배열의 이름은 상수 포인터이기 때문에 대입이 불가능함.
char str[100]="HelloWorld";
->됨.
선언하자마자는 가능.