#include <stdio.h>
#include <unistd.h>
int main(){
char *sentence = "writing down something \n";
write(1, sentence, sizeof(sentence));
return 0;
}
처음에 생각으로는 결과 출력이 sentence 전체가 될 줄 알았는데,
writing까지만 되었다.
우분투 매뉴얼 상에서 write의 시놉시스는 다음과 같다.
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
파라미터 중 size_t count는 문자열의 바이트 수이다.
sizeof를 이용해 측정한, 문자열의 바이트 값이 실제 문자열보다 작았다는 것이다.
문자열의 size를 string.h의 strlen() 함수를 이용해 구하니 원하는 결과를 얻을 수 있었다.
sizeof의 return값을 write의 인자로 주었을 때의 결과와, strlen의 return값을 주었을 때를 비교해보았다.
더불어 sizeof와 strlen은 어떤 크기로 문자열의 크기를 측정하고 있는지 출력해 보았다.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(){
char *sentence = "writing down something";
int _sizeof, _strlen;
printf("**case of sizeof : \n");
write(1, sentence, sizeof(sentence));
printf("\n**case of strlen : \n");
write(1, sentence, strlen(sentence));
_sizeof = sizeof(sentence);
_strlen = strlen(sentence);
printf("\n**at sizeof : %d, **at strlen : %d", _sizeof, _strlen);
return 0;
}
결과는 다음과 같다.
**case of sizeof :
writing
**case of strlen :
writing down something
**at sizeof : 8, **at strlen : 22
sizeof()로 sentence의 크기를 측정했을 때에는 값이 8,
strlen()로 측정했을 때에는 값이 22가 나왔다.
이유는 간단했다. sentence라는 변수 때문이고, sizeof와 strlen의 차이 때문이었다.
char *sentence 라고 문장을 넣으려는 변수를 선언했다. 포인터 변수이기 때문에, sentence 자체는 8바이트의 크기를 가진다. (64-bit pc에서) 그렇기 때문에 변수 데이터타입의 크기를 출력하는 sizeof는 포인터의 크기인 8바이트를 출력한 것이고, 문자 개수를 세는 strlen은 22라는 문자 수를 출력한 것이다.
sentence에 대한 정의를 달리하면(char sentence[]), sizeof로도 문자열의 크기를 측정할 수 있다.
다만, sizeof는 문자열 뒤의 null값까지 개수로 센다. strlen은 문자열 뒤의 null값을 제외하고 문자의 개수를 센다.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(){
//char *sentence = "writing down something";
char sentence[] = "writing down something"; //코드 수정
int _sizeof, _strlen;
printf("**case of sizeof : \n");
write(1, sentence, sizeof(sentence));
printf("\n**case of strlen : \n");
write(1, sentence, strlen(sentence));
_sizeof = sizeof(sentence);
_strlen = strlen(sentence);
printf("\n**at sizeof : %d, **at strlen : %d", _sizeof, _strlen);
return 0;
}
이번에 결과는 내가 예상하던, 바라던 대로 나왔다.
**case of sizeof :
writing down something
**case of strlen :
writing down something
**at sizeof : 23, **at strlen : 22
sizeof()와 strlen()의 차이는 무엇일까?
우선 sizeof()는 함수가 아니다. 연산자이다.
sizeof()는 데이터의 크기를 null값을 포함하여 센다.
문자열의 끝에는 null값이 들어있기 때문에, 일반적으로는 생각되는 문자열 크기보다 1만큼 가산한 크기를 return한다고 생각하면 된다.
strlen()은 문자열의 크기를 null값을 제외하고, 측정해주는 함수이다. 문자열의 바이트 수를 return해준다.
여기서 중요한 건, sizeof(str)일 경우, str이라는 데이터 타입 자체의 길이를 return해주고,
strlen(str)일 경우, str이 포인터이면 이 포인터 str이 가리키는 값의 길이를 return해준다는 차이가 있다는 것이다.
char *str = "1234"는 str이라는 포인터가 가리키는 자리에 "1234"라는 값을 넣으라는 얘기이다.
즉, str은 포인터이다. 그러니, 64-bit에서의 포인터 크기는 8byte이므로, sizeof에서는 8을 return한다.
strlen은 str이라는 포인터가 가리키고 있는 값의 길이를 return하므로, "1234"의 (null을 뺀 길이인) 4를
알맞게 return할 수 있었던 것이다.
<참고>
https://en.wikipedia.org/wiki/Sizeof
linux man page