[학습 노트] 입력 버퍼에 관하여.규범에 맞지 않는 문자 값 부여 문장에 대한 토론

1. 이런 부치문구는 내가 연습할 때 쓴 오류 코드로 규범에 부합되지 않고 실제 코드를 쓸 때 나타나지 말아야 한다.다만 결과가 공교롭게도'옳았다'는 이유로 꺼내 논의했다.
따라서 이 노트는 실제 코드 능력을 향상시키는 데 큰 도움이 되지 않는다.
다음 코드는 4개의 printf 문장의 출력 결과가 각각 얼마입니까?
#include
int main()
{
                 char *a = 'abc' ;                                          
                 char b = 'abc' ;
                printf( "%s", &a);      //c
                printf( "%c", a);        //cba
                printf( "%s", &b);    //c !@$#$cba
                printf( "%c", b);        //c
                 return 0;
}
----------------------------------------------------------------------------------------------------------------------------------------------------
처음에 C 언어의char 변수 형식을 배웠을 때, 거의 모든 교재가 우리에게 경고하는데, 따옴표 안에는 한 글자만 저장할 수 있다
예:
  
char a = '1' ;
char a = '1' ;
그러나 인용부호의 내용이 몇 글자일 때, 예를 들어
char a = '123' ;
char a = 'abc' ;
이 때 컴파일러는 오류를 보고하지 않고 컴파일러를 할 때 경고를 팝업합니다.(테스트 환경: VS2015, VC++6.0,vim)
그러나 주의해야 할 것은 이런 부치문구는 규범에 부합되지 않고 실제 코드를 쓸 때 나타나서는 안 된다는 것이다.
다음 코드는 다음과 같습니다.
int main()
{
                 char b = 'abcd' ;
                printf( "%c", b);
                 return 0;
}
printf 문장 출력 결과 문자 d
이를 통해 알 수 있듯이 우리가 이런 규범에 맞지 않는 방식으로char 유형의 변수에 값을 부여하면 이 변수가 실제적으로 얻은 값은 우리가 부여한 abcd의 마지막 문자 d이다
----------------------------------------------------------------------------------------------------------------------------------------------------
이제 처음 코드를 살펴보겠습니다.
#include
int main()
{
                 char *a = 'abc' ;                                          
                 char b = 'abc' ;
                printf( "%s", &a);      //c
                printf( "%c", a);        //cba
                printf( "%s", &b);    //c !@$#$cba
                printf( "%c", b);        //c
                 return 0;
}
디버그 중에 메모리를 열고 모니터링된 메모리는 다음과 같습니다.
0x0018FC93  63     cc     cc     cc     cc     cc     cc     cc     cc    (&b)
0x0018FC9C  63    62     61    00    cc     cc     cc     cc     b8    (&a)
감시된 메모리를 통해 printf 함수가 왜 이렇게 출력되었는지 이해할 수 있습니다.
그런데 여기서 또 하나의 문제가 생겼다.
              char *a = 'abc' ;     
다음과 같을 수 있습니다.
              char *a = NULL;    
 a = 'abc' ;     
마찬가지로 변수에 값을 부여하는데 왜 메모리에 저장하는 방식이 다르죠?
값이 같으면 변수 유형에 문제가 생깁니다.
b는char유형의 변수입니다.
a는char타입의 바늘로 본 코드에서*a의 값을 얻을 수 없지만 정의에 따라 *a는char타입의 변수입니다.a는 포인터로서 기본적으로 int 형식의 변수입니다.
이것 또한 & a가 메모리에 있는 00의 출처를 설명한다. int 형식 변수는 4바이트를 차지하고, 방금 값을 부여한 것은 3바이트를 사용했고, 나머지 한 바이트는 컴파일러가 00으로 보충했다
바로 그'00', 코드의 printf('%c', a) 때문이다.정상적으로 출력할 수 있습니다.
이 점을 명확히 하여 코드를 수정하다.
int main()
{
                 char *a = 'abcd' ;
                 char b = 'abcd' ;
                printf( "%c", a);
                printf( "%s", &a);
                printf( "%c", b);
                printf( "%s", &b);
                 return 0;
}
이 코드를 실행하면, 과연 4 바이트가 printf ('%s', & a) 로 가득 차서,이 문장도 정상적으로 출력할 수 없다
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
우리 모두 알고 있지만,
정상적인 상황에서,char 형식의 변수는 값을 받을 때, 문자의 마지막 바이트만 받는다.
그러나 실제 코드가 실행될 때 마지막 문자를 직접 찾는 것은 아니다.
첫 번째 문자부터 하나하나 읽고 한 글자를 읽을 때마다 이전 문자를'없애버리기'합니다. 그래서 우리가 본 것은 영원히 마지막 입력의 내용입니다.
이제 마지막 문제만 남았습니다. 마지막 문자를 제외하고 다른 문자는 어디에 저장되었습니까? 또 어떻게 저장되었습니까?
방금 디버깅했을 때의 코드의 메모리를 다시 한 번 보십시오:
0x0018FC93  63     cc     cc     cc     cc     cc     cc     cc     cc    (&b)
0x0018FC9C  63    62     61    00    cc     cc     cc     cc     b8    (&a)
알 수 있듯이 int 형식의 a 변수는 4바이트를 수용할 수 있기 때문에 여분의 문자를 '삭제'하지 않았다.
char 형식의 변수 b는 한 바이트만 수용할 수 있지만, 처음부터 끝까지 63 (c) 만 저장합니다.
6162는 입력 버퍼 안에서 선후로'충돌'되었다.
즉, 변수에 값을 부여하는 것은'쓰기'작업에 속하는데 이런 작업은 메모리를 직접 조작하는 것이 아니라
입력 버퍼라고 불리는 메모리 구역에서 데이터를 복제하는 것은 기계의 작업 효율을 향상시키는 데 유리하다.
int 형식 변수에 값을 부여할 때, 상응하는 입력 버퍼 길이는 4이고, 4바이트를 가득 썼을 때, 이 4바이트를 부여할 변수가 있는 메모리에 한꺼번에 보냅니다.
char 형식 변수에 값을 부여하는 것은 같은 이치입니다. 다만 이 때 입력 버퍼의 길이는 1이고, 한 바이트를 쓸 때마다 앞의 바이트를 대체합니다. 그래서 마지막으로 얻은 것은 마지막 바이트입니다.
최후
이런 부치문구는 내가 연습할 때 쓴 오류 코드로 규범에 부합되지 않고 실제 코드를 쓸 때 나타나서는 안 된다.
이런 부치문구는 내가 연습할 때 쓴 오류 코드로 규범에 부합되지 않고 실제 코드를 쓸 때 나타나서는 안 된다.
이런 부치문구는 내가 연습할 때 쓴 오류 코드로 규범에 부합되지 않고 실제 코드를 쓸 때 나타나서는 안 된다.
 

좋은 웹페이지 즐겨찾기