C 언어 에서 입 출력 흐름 과 버퍼 에 대한 심도 있 는 설명

머리말
버퍼 는 캐 시 라 고도 부 르 며 메모리 공간의 일부분 입 니 다.즉,메모리 공간 에 일정한 저장 공간 을 남 겨 두 었 는데 이런 저장 공간 은 입력 이나 출력 데 이 터 를 버퍼 링 하 는데 이 부분 에 남 겨 진 공간 을 버퍼 라 고 한다.
버퍼 는 입력 장치 인지 출력 장치 인지 에 따라 입력 버퍼 와 출력 버퍼 로 나 뉜 다.
원리 소개:
  • 입력 함수 scanf()를 호출 할 때 입력 함 수 는 우리 가 입력 한 숫자 를 입력 버퍼 에 입력 합 니 다.
  • 우리 의 입력 버퍼 에 내용 이 있 을 때 다시 입력 하면 실행 되 지 않 습 니 다.
  • 실행 을 직접 건 너 뛰 고 버퍼 의 내용 을 변수 에 부여 합 니 다.
  • 1.버퍼 를 왜 도입 합 니까?
    예 를 들 어 우 리 는 디스크 에서 정 보 를 얻 습 니 다.우 리 는 먼저 읽 은 데 이 터 를 버퍼 에 두 고 컴퓨터 는 버퍼 에서 데 이 터 를 직접 찾 습 니 다.버퍼 의 데 이 터 를 다 찾 은 후에 디스크 에서 읽 습 니 다.그러면 디스크 의 읽 기와 쓰기 횟수 를 줄 일 수 있 습 니 다.게다가 컴퓨터 가 버퍼 에 대한 조작 이 디스크 에 대한 조작 보다 훨씬 빠 릅 니 다.따라서 버퍼 를 사용 하면 컴퓨터 의 운행 속 도 를 크게 높 일 수 있다.
    예 를 들 어 우 리 는 프린터 로 문 서 를 인쇄 합 니 다.프린터 의 인쇄 속도 가 상대 적 으로 느 리 기 때문에 우 리 는 먼저 문 서 를 프린터 에 해당 하 는 버퍼 에 출력 하고 프린터 는 스스로 점차적으로 인쇄 합 니 다.이때 우리 의 CPU 는 다른 일 을 처리 할 수 있 습 니 다.
    이제 기본적으로 알 겠 죠?버퍼 는 입 출력 장치 와 CPU 사이 에서 데 이 터 를 캐 시 하 는 메모리 영역 입 니 다.이 는 저속 입 출력 장치 와 고속 CPU 가 작업 을 조율 하고 저속 입 출력 장치 가 CPU 를 차지 하지 않도록 하 며 CPU 를 해방 시 켜 효율 적 인 작업 을 할 수 있 도록 한다.
    2.버퍼 의 종류
    버퍼 는 세 가지 유형 으로 나 뉜 다.전체 버퍼,줄 버퍼,버퍼 없 음.
    1)풀 버퍼
    이 경우 표준 I/O 캐 시 를 채 워 야 실제 I/O 작업 을 할 수 있다.전체 버퍼 의 전형 적 인 대 표 는 디스크 파일 에 대한 읽 기와 쓰기 이다.
    2)줄 버퍼
    이 경우 입 출력 에서 줄 바 꿈 자 를 만 났 을 때 진정한 I/O 작업 을 수행 합 니 다.이때 우리 가 입력 한 문 자 는 버퍼 에 저장 하고 Enter 키 를 누 르 고 줄 을 바 꿀 때 실제 I/O 작업 을 합 니 다.전형 적 인 대 표 는 표준 입력(stdin)과 표준 출력(stdout)이다.
    3)버퍼 없 음
    즉,버퍼 링 을 하지 않 고 표준 오류 상황 stderr 는 전형 적 인 대표 로 오류 정 보 를 신속하게 표시 할 수 있 습 니 다.
    3.버퍼 크기
    만약 우리 가 스스로 버퍼 를 설정 하지 않 았 다 면 시스템 은 기본적으로 표준 입 출력 에 버퍼 를 설정 합 니 다.이 버퍼 의 크기 는 보통 512 바이트 의 크기 입 니 다.
    버퍼 크기 는 stdio.h 헤더 파일 의 매크로 BUFSIZ 에서 정의 합 니 다.크기 를 보 려 면 헤더 파일 을 포함 하고 값 을 직접 출력 하면 됩 니 다.printf("%d", BUFSIZ);버퍼 의 크기 는 변경 할 수 있 고 파일 을 사용자 정의 버퍼 에 연결 할 수도 있 습 니 다.자세 한 내용 은setvbuf() setbuf() 함 수 를 볼 수 있 습 니 다.
    4.버퍼 의 새로 고침(비우 기)
    다음 경우 버퍼 의 새로 고침 을 유발 합 니 다:버퍼 가 가득 찼 을 때;행 버퍼 가 리 턴 을 만 났 을 때;파일 닫 기;특정 함 수 를 사용 하여 버퍼 를 새로 고 칩 니 다.
    5.버퍼 와 결합 하여 C 언어 getchar(),getche(),getch()의 차 이 를 이야기 합 니 다.
    먼저 살 펴 보 자getchar() .그 원형 은 다음 과 같다.int getchar(void);프로그램 이 getchar()함 수 를 호출 할 때 프로그램 은 사용자 의 버튼 을 기다 리 고 있 습 니 다.사용자 가 입력 한 문 자 는 키보드 버퍼 에 저 장 됩 니 다.사용자 가 리 턴 을 누 를 때 까지(리 턴 문자 도 버퍼 에 놓 여 있 습 니 다).사용자 가 Enter 를 입력 한 후에 야 getchar()함수 가 키보드 버퍼 에서 매번 문 자 를 읽 기 시작 합 니 다.즉,후속getchar()함수 호출 은 사용자 버튼 을 기다 리 지 않 고 버퍼 에 있 는 문 자 를 직접 읽 고 버퍼 에 있 는 문 자 를 다 읽 은 후에 야 사용자 버튼 을 다시 기다 리 는 것 이다.예 를 들 어 키보드 버퍼 는 마치 하나의 수도관 이 당신 의 프로그램 과 연결 되 어 있 는 것 과 같 습 니 다.프로그램 호출getchar()함수 사용자 가 문 자 를 입력 하 는 것 은 수도관 에 물 을 주입 하 는 것 과 같 습 니 다.이 물 을 얼마나 입력 하 느 냐 에 달 려 있 습 니 다.당신 이 Enter 를 누 르 면 물 을 주입 하 는 것 을 멈 출 때getchar()함수 가 키보드 버퍼,즉 우리 의 수도관 에서 물 을 얻 기 시작 합 니 다.그러면 매번 한 글자 만 읽 습 니 다.즉,매번 일 정량의 물 을 가 져 옵 니 다.그 후에getchar()함 수 를 계속 호출 할 때,이어서 수도관 에서 지난번 에 다 쓰 지 않 은 물 을 가 져 옵 니 다.왜냐하면 수도관 이 비 워 지지 않 았 기 때 문 입 니 다.(버퍼 의 새로 고침)이 단 계 는 더 이상 입력 하지 않 아 도 됩 니 다.getchar()함 수 를 호출 하면 물 을 가 져 올 수 있 기 때 문 입 니 다.수도관 에 물이 없 을 때 까지.getchar()함 수 를 호출 하면 이 럴 때 물 을 주입 해 야 합 니 다.즉,프로그램 이 버튼 을 기다 리 는 것 입 니 다.
    쉽게 말 하면 프로그램 이 getchar()함 수 를 호출 할 때 프로그램 은 사용자 의 버튼 을 기다 리 고 사용자 가 Enter 키 를 누 르 고 돌아 오 기 를 기다린다.그 동안 누 른 문 자 는 버퍼 에 저장 되 고 첫 번 째 문 자 는 함수 로 값 을 되 돌려 줍 니 다.getchar()함 수 를 계속 호출 하면 사용자 버튼 을 기다 리 지 않 고 방금 입력 한 두 번 째 문 자 를 되 돌려 줍 니 다.버퍼 에 있 는 문 자 를 다 읽 을 때 까지 세 번 째 문 자 를 되 돌려 줍 니 다.getchar()함수 의 집행 은 바로 줄 버퍼 를 사용 한 것 이다.getchar()함 수 를 처음 호출 하면 프로그램 사용자(사용자)가 한 줄 의 문 자 를 입력 하고 Enter 키 함 수 를 눌 러 야 돌아 갑 니 다.이 때 사용자 가 입력 한 문자 와 리 턴 부 호 는 줄 버퍼 에 저 장 됩 니 다.getchar()함 수 를 다시 호출 하면 줄 버퍼 의 내용 을 점차적으로 출력 합 니 다.
    다음 예 를 보십시오.

    실행 결 과 는 다음 과 같 습 니 다.

    다시 프로그램 을 미세 하 게 바 꾸 고,다시 보고,깊이 이해 해라.

    실행 결과:

    위 에서 두 번 째 인쇄 할 때 2 가 아니 라 빈 칸 이 었 는데 왜 그런 지 생각 나 시 죠?
    자,예 를 하나 더 봅 시다.

    실행 결과:
    getchar()함 수 는 입력 스 트림 버퍼 에서 데 이 터 를 읽 는 것 이지 키보드(터미널)버퍼 에서 읽 는 것 이 아 닙 니 다.읽 기 가 Enter()가 끝 났 을 때 이''는 입력 스 트림 버퍼 에 같이 읽 기 때문에 첫 번 째 입력 을 받 을 때 문 자 를 가 져 간 후에 문 자 를 남 깁 니 다.그러면 두 번 째getchar()는 버퍼 에서 직접 가 져 갑 니 다.분명히 읽 기 에 성 공 했 기 때문에 터미널 에서 읽 지 않 습 니 다!사실 여기 10 은 딱 리 턴 부적 이 야!이것 이 바로 이 프로그램 이 입력 조작 을 한 번 만 실행 하고 끝 난 이유 입 니 다!
    getch()와 getche()함수
    TC 2.0 시대 에 C 프로그래머 는 항상 프로그램 끝 에getch()를 더 해서 프로그램 이 실행 되 고 일시 정지 되 고 종료 되 지 않 는 효 과 를 실현 하 는 것 을 좋아 했다.이렇게 하지 않 으 면 TC 2.0 환경 에서 Ctrl+F9 를 컴 파일 하고 실행 한 후 바로 프로그램 을 종료 합 니 다.결 과 를 보지 못 합 니 다.이때 결 과 를 보 려 면 Alt+F5 를 눌 러 DOS 환경 으로 돌아 가 야 하기 때문에 매우 번거롭다.프로그램의 끝 에 한 줄getch();문 구 를 추가 하면 DOS 로 돌아 가 결 과 를 보 는 절 차 를 줄 일 수 있 습 니 다.프로그램 이 실행 되 었 을 때 종료 하지 않 고 프로그램 마지막 에 화면 을 멈 추고 임 의 버튼 을 눌 러 서 프로그램 을 종료 할 수 있 습 니 다.
    실제로getch() 키보드 에서 한 문 자 를 받 고 표시 되 지 않 는 역할 을 한다.즉,키 를 누 르 면 화면 에 누 른 것 을 표시 하지 않 고 뒤의 코드 를 계속 실행 하기 때문에 C 언어 에서'임의의 키 를 누 르 면 계속'효 과 를 실현 할 수 있다.즉,프로그램 에서getch();문 구 를 만나면 멈 추고 임의의 키 를 누 르 면 이 문자 키 를 받 은 후에 뒤의 코드 를 계속 실행 할 수 있다.이것 은 위 에서 윈도 에서 사용 하 는 시스템("PAUSE")기능 과 같 지만 화면 에 표시 되 지 않 습 니 다.(즉,"임의의 키 를 누 르 고 계속 하 라"는 힌트 가 없 을 것 입 니 다)이렇게 하면getch()리 턴 이 없 는 특성 을 이용 하여 어떤 키 를 누 르 더 라 도 화면 에 흔적 을 남기 지 않 고 화면 을 아름 답 게 만 들 수 있 습 니 다.getche()getch()는 비슷 하 다.헤더 파일 conio.h 를 도입 해 야 한다.이들 의 차 이 는 바로getch()회 현 이 없고getche()회 현 이 있다 는 것 이다.
    다음은 하나의 예 를 보 겠 습 니 다.

    우선 5 회 연속 순환 으로 5 회 중단 을 실현 하고 입력 을 기다 리 고 있 습 니 다.이 프로그램 을 컴 파일 하고 실행 합 니 다.입력 한 것 이 abcde 라 고 가정 하면 화면 에 표 시 된 결과 도 abcde 입 니 다.이 abcde 는 ch=getch()가 아 닙 니 다.중간 출력의printf("%c",ch);이 줄 의 문 구 를 없 애 면 임 의 키 를 5 번 누 르 면 프로그램 이 끝 나 는 것 을 발견 할 수 있 지만 화면 에는 아무것도 표시 되 지 않 았 다.
    너 는 코드 중의getch()getche()로 바 꾸 어 어떤 차이 가 있 는 지 볼 수 있다.만약 에 abcde 를 입력 한다 면 화면 에 표 시 된 결 과 는 aabbccddee 입 니 다.우 리 는printf("%c",ch);이 줄 의 문 구 를 다시 지 웠 습 니 다.표 시 된 결 과 는 abcde 입 니 다.프로그램 이ch=getche();이 문 구 를 실행 할 때 우리 가 입력 한 키 를 화면 에 되 돌려 보 여 주 는 것 이 유일한 차이 점 입 니 다.
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기