%c와 %s의 차이는 %c는 파라미터로 전달되는 값에 해당하는 ASCII 코드를 출력하는 것이고 %s는 파라미터로 전달되는 값의 주소 위치에서부터 NULL문자(0)를 만날때까지 문자열을 출력합니다.
예를 들어 tbl[0] = 'c' 라고 가정하면....
문자 'c' 는 ASCII 테이블에서 찾아보면 숫자로 143입니다. tbl[0]에 143이 들어있다는 말입니다.
printf("tbl[0] = %c\n", tbl[0]);
여기서 %c에서는 인자로 넘어온 tbl[0]의 값 143에 해당하는 ASCII 문자인 c 가 출력됩니다.
결과는 tbl[0] = c 이렇게 나옵니다.
printf("tbl[0] = %s\n", tbl[0]);
여기서 %s는 인자로 넘어온 tbl[0]의 값 143을 주소로 해석하여 메모리 상에서 143 (0x8F) 위치에 있는 문자부터 시작하여 NULL을 만날때 까지 문자열을 출력합니다.
김병주님의 코드에서 tbl[0]에 무슨값이 들어있는지 모르겠지만 우연히도 메모리상 그 위치에 orland Intl. 이라는 문자열이 있는것입니다. 아마 저 문자열은 볼랜드 컴파일러로 컴파일했을때 볼랜드 컴파일러가 컴파일 했다는 표시로 들어가 있는 문자열중 일부일것입니다.(실제 볼랜드에서 컴파일하고 링크한 실행파일을 메모장 같은데서 열어보면 Borland Intl. 어쩌고 저쩌고 하는 문장이 포함되어 있습니다.)
tbl[0]의 값을 1을 뺀값으로 (위의 예로 하자면 'c'에서 1빼서 'b' 로 바꿔서) 두번째 printf코드를 다시 실행해보세요. 메모리 주소가 한칸 당겨져서 Borland Intl.로 orland Intl. 앞에 있는 B 까지 출력될것입니다.
이제 %s를 이해하셨으면 두번째 printf가 잘못된 사용이라는걸 아셨을것입니다.
tbl[0]의 문자를 풀력하기 위해 두번째처럼 %s를 사용하면 tbl[0]의 값은 커녕 tbl[0] 값을 주소로 인식하여 원치않는 결과가 나올것이고 거기다가 tbl[0]값이 다른 보호된 메모리를 가리키게 되면 메모리 침범으로 Access Violation (Segment fault) 오류를 발생시킵니다.
김병주 님이 쓰신 글 :
: 원래 정상소스가 아래와 같을때
: printf("tbl[0] = %c\n", tbl[0]);
:
: printf("tbl[0] = %s\n", tbl[0]);
: 로 바꾸면
: 출력값이 tbl[0] = orland Intl.
: 로 나오네요
:
: 왜 이런 값이 나오는거죠?
:
: 그리고 %s와 %c의 차이는 모죠?
: 이 소스상에서 바꾸면 안되는 건가요?
:
:
|