전역변수에 대한 질문입니다

ch0nn0m의 이미지

#include<stdio.h>
char buf[20];
int main()
{
        sprintf(buf,"%s","success");
        printf("%s\n",buf);
        printf("%d\n",strlen(buf));
 
        sprintf(buf,"%s","Fail");
        printf("%s\n",buf);
        printf("%d\n",strlen(buf));
}

이렇게 했을경우

success
7
Fail
4
이렇게 나옵니다...


궁금한게 2가지가 있는데요..

1) 전역변수는 다른 함수내에서 초기화가 가능한지요...??

2) 위와같이 할경우 전역변수 buf에는 success가 들어간뒤 fail이 들어가게 되는데...failess와 같이 나와야하는게 아닌지요??

select99의 이미지

1질문은 물론 가능하구요.

2는.. \n 을 넣었을뿐만아니라..

스트링이기때문에 안나오죠..

님이 예상하신 결과는 memcpy 했을때 나옵니다.

Risty의 이미지

sprintf 명령에서는 대상 버퍼에 들어가는 생성 결과 마지막에 널 문자('\0')를 덧붙이게 되어 있습니다.

klutzy의 이미지

1. 전역변수는 아무 함수에서나 쓸 수 있습니다. 편리하기는 하지만 남발하면 코드를 엉망으로 만드는 원인이기도 하니 조심해서 써야 합니다.

참고로 전역 변수는 초기화하지 않아도 항상 0으로 초기화됩니다. 이 성질은 2번과도 어느정도 관계가 있습니다.

2.
sprintf(buf,"%s","success");
buf == {'s', 'u', 'c', 'c', 'e', 's', 's', '\0', '\0', ... }

sprintf(buf,"%s","Fail");
buf == {'F', 'a', 'i', 'l', '\0', 's', 's', '\0', '\0', ... }

C의 문자열은 항상 마지막에 \0이 붙습니다. "Fail" 등의 큰따옴표 문법은 사실 {'F', 'a', 'i', 'l', '\0'}의 5개짜리 문자를 편의적으로 줄인 것이고요. 의미상으로는 4개지만 메모리상으로는 5개입니다.

sprintf의 경우 \0을 떼야 할 때는 떼고 붙여야 할 때는 붙입니다. 예를 들어,
sprintf(buf,"%s","success");
sprintf(buf,"%s%s","Fail", "x");
이렇게 했다면
buf == {'F', 'a', 'i', 'l', 'x', \0', 's', '\0', '\0', ... }
이 됩니다. \0은 단순히 문자열의 끝을 알리는 값이기 때문에 이렇게 동작하게 됩니다.