본문 바로가기
[ C언어 ]/- C언어 문법공부

C언어 4장(printf()와 변수)

by MRG 2020. 4. 7.
728x90
반응형
728x90

안녕하세요. 오늘은 저번장에 이어서 바로 변수와 상수를 진행하려고 했지만, printf에 대한 개념을 조금이나마 아시고 가는 게 좋을 거 같아 먼저 저번에 했던 printf()printf() 함수에 대해 조금은 어려울 수 있지만 필요한 부분이니 한번 진행해 보도록 하겠습니다.

 

 

우선 저번 시간에 했던 코딩을 한번 보겠습니다.



▣ 컴퓨터는 스스로 아무것도 할 수 없습니다. 하나하나 우리가 다 명령을 해줘야 컴퓨터가 그걸 자신들에 언어로 바꿔서 그 신호를 가지고 연산하고 처리합니다. 저번시간에 했던 거 잠시 복습하면

#include <stdio.h> 컴파일하기 전에 포함해라라는 의미이고 stdio.h 헤더 파일을 표준 입출력을 내가 쓸 거야라고 선언하는 것이다라고 말씀드렸습니다. 그리고 int main(void){} 함수 여기 안에서 프로그램을 시작하고 printf는 출력해라 형식에 맞게라고 말씀드렸습니다. 그래서 우리가 보는 콘솔화면에 Hello World라는 문구가 나오게 되는겁니다. 



▣ printf 과정에 대해 설명하겠습니다. 먼저 스트림에 대해서 알아보겠습니다. 

위키백과에서 데이터 스트림 (data stream)은 연결 지향 통신에서,, 전송된 정보를 수집하거나 정보를 전송할 때 사용되는 디지털 방식으로 암호화된 일관된 신호의 흐름을 말한다. 데이터 스트림은 데이터 제공자로부터 추철된 정보의 집합이다.이라고. 합니다. 무슨말인지 모르겠죠? 



저도 컴퓨터공학을 공부하면서 항상 이렇게 어렵게 설명하는 게 너무 힘들었습니다. 그래서 코딩을 공부할 때 많은 자료와 강사분들 교수님들 선생님분들 그리고 여러 영상 자료들을 보면서 저만에 방식으로 이해하려고 노력했던 거 같습니다.



스트림은 신호에 흐름이라는 것에 초점을 맞추면 될꺼같습니다.



우리가 코딩을 할 때 그리고 컴퓨터를 사용할 때 입력과 출력을 하죠?

입력은 우리가 마우스로 클릭하거나 키보드로 클릭해서 컴퓨터한테 신호를 전달해주는걸 의미합니다.

출력은 우리가 모니터로 보는 화면에 결과 값을  출력해주는 것이라고 생각하면 될 거 같습니다.

그럼 왜 스트림 이야기를 했느냐, 우리가 보는 출력은 일정한 속도로 보여줍니다. 하지만 입력을 해서 전달해주는건 출력에 속도를 다를 수 있습니다. 왜냐하면 저 밑에 그림처럼 입력을 해주면 바로 출력을 해서 보여주기도 하지만 컴퓨터가 처리하고 연산을 해야하는 시간이 있기 때문에 일정한 속도를 가진 출력에 비해 입력에 속도는 다를 수 있습니다. 그래서 스트림에 흐림 과정이 있다고 생각하시면 될꺼같습니다. 

 

그림판이라 다시 한번 이해 부탁드리겠습니다. ^^;;



다시 정리하자면 입력과 출력하는 속도는 컴퓨터에 환경에 따라 다를 수 있습니다.
이건 쉽게 이야기하면 유튜브 스트리밍 서비스를 생각하시면 될꺼 같습니다.
우리가 출력을 하는 속도는 일정합니다. 그렇게 때문에 입력으로 값을 전달해주고 인터넷으로 바로바로 전달해주면 인터넷 환경에 따라 입력과 출력에 속도가 충돌이 나게 됩니다.
예를 들어 일정하게 10으로 출력하는 컴퓨터라고 생각하면 10을 계속 전달해줘야하는데 입력으로 인터넷속도에 의해 입력받는 속도는 3이라고 해보겠습니다. 7이라는 속도가 충돌이 생기겠죠? 그렇기 때문에 버퍼에 임시적으로 보관을 해서 출력과 입력에 속도를 맞춰준다라고 생각하시면 될꺼같습니다. 자 그럼 버퍼에 대해 알아보겠습니다.



▣ 버퍼는 위키백과에서  컴퓨팅 에서, 버퍼 (buffer, 문화어 : 완충기억기)는 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는  메모리 의 영역이다. 버퍼링 (buffering)이란 버퍼를 활용하는 방식 또는 버퍼를 채우는 동작을 말한다. 다른 말로 '큐(Queue)'라고도 표현한다.라고. 이야기합니다. 
우리가 영상을 볼 때에도 입출력 전송신호를 일시적으로 버퍼에 보관을 하고 다시 버퍼에 전달해서 그걸 하나하나 꺼내서 출력합니다.
한꺼번에 받아와서 한꺼번 출력을 하는건 스트리밍이 아니겠죠? 그건 모든걸 다운받는다고 이야기해야 할 겁니다.



그렇게 해서 우리가 입력을 하고 서버든 컴퓨터든 버퍼에 임시저장을 해서 전달을 해주고 다시 버퍼에 임시저장을 해서 그 임시저장을 한것을 하나하나 꺼내서 출력을 해주는 과정입니다. 하지만 중간에 출력 버퍼에 보관을 과정에서 인터넷이 끊기거나 서버가 문제가 생기면 버퍼링이 걸리는 겁니다.  
버퍼링은 쉽게 이야기하면 버퍼를 채워주는걸 의미입니다.
정리하자면 출력을 할때 출력에 값들을 버퍼에 보관을 하겠죠?
그리고 하나하나 꺼내서 출력으로 값에 결과를 보여주게 됩니다.
그런데 인터넷이 끊기면 일정하게 출력을 하다가 출력할때 쓰는 버퍼가 비어서 더이상 전달하지 못하게 되겠죠?
그걸 우리는 버퍼링걸린다고 이야기를 하는거구요. 
정리가 되셨나요? 쉽게 설명한다고 했는데 이해가 되셨는지 모르겠네요ㅠ.ㅠ
다시 스트림은 input, ouput 입출력에 과정에 흐름을 스트림이라고 합니다.
버퍼는 입출력할때 중간에 임시적으로 저장하는 장소이고 이걸 통해서 속도를 완화 완충기 역할을 합니다.
버퍼링은 버퍼를 채워주는 걸 이야기합니다.
또 여기서 flushing라는것도 있는데 이건 버퍼를 비우는 것, 지우는것 이라고 생각하시면 될꺼같습니다. 
쉽게 설명한다고 했는데 이해가 되셨는지 모르겠네요.
여기까지하시고 이해가 안되시면 다시 한번 그림을 보고 한번더 읽어주시고 조금이라도 이해하고 넘어가시면 좋을꺼 같습니다.



그럼 printf로 넘어가면 우리가 stdio.h 파일을 사용해서 자동적으로 스트림을 사용해서 표준 출력 스트림으로 우리 모니터에 출력하게 되는 겁니다. 여기서 그럼 형식이 있는 출력이 있다면 입력도 있겠죠? 네 있습니다. 바로 scanf입니다.



▣ 그리고 형식이 없는 표준 입출력도 있습니다.

getchar() - 문자 입력 함수 

putchar() - 문자 출력 함수

gets() - 문자열 입력 함수

puts() - 문자열 출력 함수 



이렇게 형식이 없는 표준 입출력도 있습니다. 여러 종류가 많죠? 그건 C언어에서 코딩을 하다 보면 여러 상황과 필요한 코딩들이 있었을 겁니다. 그럼 그때마다 필요한 코딩들을 저렇게 만들어 갔을 겁니다. 그러니 우리가 필요할 때 저 부분들을 사용하면 됩니다. 너무 부담 갖지 마시고 이렇구나라고만 생각하시고 넘어가시면 될꺼같습니다. C언어에 모든 기능을 사용하는 사람도 있겠지만 모든 기능을 알고 사용하는 사람은 많이 없다고 생각합니다. 우리가 상황에 맞게 필요한 부분들을 사용해서 그걸 프로그램하면 된다고 저는 생각합니다.

다시 한번 정리해서 스트림은 정보가 in out 바이트 단위에 흐르는 흐름이 스트림이다라고 우선 이해하시고 넘어가시면 될꺼같습니다. 바이트가 무엇인지는 밑에서 설명하도록 하겠습니다.



▣ 자 그럼 변수에 대해 진행해보도록 하겠습니다. 
변수는 무엇일까요? 
위키백과에서는  컴퓨터 프로그래밍 에서  변수 (變數, variable) 또는  스칼라 (scalar)는 아직 알려지지 않거나 어느 정도까지만 알려져 있는 양이나 정보에 대한 상징적인 이름이다. 컴퓨터  소스 코드 에서의 변수 이름은 일반적으로  데이터 저장 위치 와 그 안의 내용물과 관련되어 있으며 이러한 것들은 프로그램 실행 도중에 변경될 수 있다.라고. 나와있습니다.
여기서 주목해봐야 할 건 데이터 저장 위치,, 내용물 그리고 실행 도중 변경이 가능하다는 것에 주목하면 좋을 거 같습니다. 

 

▣ 변수는 쉽게 이야기해서 데이터를 담는 그릇, 박스라고 생각하시면 될꺼같습니다.. 더 심플하게 이야기하면 메모리라고 생각하시면 될꺼같습니다..
그리고 변화는 수라는 말도 맞습니다.
저기 박스(그릇) 안에 있는 값은 언제나 변화할 수 있습니다.
그리고 변수는 자료형으로 형식으로 정합니다. 이건 그릇에 종류를 정한다라고 생각하시면 편할 텐데요.. 예를 들어 우리가 컵에 밥을 넣어서 먹는다고 생각해봅시다.  컵에 크기도 작아서 밥도 많이 담을 수 없고 먹기도 불편합니다. 그렇기 때문에 밥그릇으로 그릇을 정해서 먹어야 합니다.. 데이터도 마찬가지입니다. 



우리가 데이터에 형식을 구분하지 않고 모든 데이터를 컴퓨터한테 준다고 해봅시다. 그럼 컴퓨터가 알아서 하는 게 아니라 여기저기 구분 없이 데이터를 넣어서 박스를 막 포장하고 여기저기 놓는다고 해봅시다. 공감도 낭비되고 찾을 때에 속도도 안 좋을 거라 생각합니다. 그리고
그 결과를 보는 우리들도 구분하기 어렵고 효율적으로 사용할 수도 없습니다.
그래서 변수를 만들 때에는 자료형을 정합니다. 

 

이런 식에 자료형들이 있습니다. 여기에는 unsigned도 있습니다. unsigned char를 하게 되면 표현 범위는 0~255가 됩니다. 저 이야기는 나중에 메모리에 대한 이야기를 할 때 더 자세하게 이야 하도록 하겠습니다. 우선 저 정도가 있다고 생각해 주시면 될꺼같습니다.
먼저 위에서 크기라는 건 byte를 이야기합니다. byte는 데이터에 최소 단위를 이야기하는데 이게 무슨 말이냐면

 

▣ 스위치를 on, off 해본다고 생각해보겠습니다. 이걸 이렇게 두 가지를 신호를 저장하는 게 1bit라고 합니다. 쉽게 이야기하면 그럼 2bit는 2에 2승이니깐 4개에 신호를 표현할 수 있겠죠? 그렇게 계속 표현을 하다가 4bit를 또 다른 말로 1 nibble이라고 표현합니다.
그리고 8bit를 우리가 아까 이야기했던 1byte라고 이야기하는 겁니다. 그래서 2^8을 하면 256입니다.
0부터 시작하면 0~255 signed는 -128 ~ 127이 되는 것입니다. 
밑에 이미지를 참고해주시면 이해가 빠를 거 같습니다.

 

출저 : https://mindnet.tistory.com/entry/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-1%ED%8E%B8-Bit-%EC%99%80-Byte-%EC%B0%A8%EC%9D%B4%EC%A0%90

 

 

그럼 왜 다 bit로 하면 되지 이렇게 어렵게 단위가 나뉘어 있느냐 하면 쉽게 생각하면 우리 인간이 구별하기 쉽게 하기 위해서입니다. 그럼 엄청 큰 bit를 표현할 때에도 간단한 용어로 그 큰 비트를 표현할 수 있겠죠?
어쨌든 그래서 1byte라는 말은 꼭 기억해주세요. 

 

 

이 그림은 변수가 가지고 있는 구성들을 만들어보았습니다. 이렇게 데이터 자료를 보관하고 형식을 가지고 있고 변수 이름과 변수 주소까지 가지고 있습니다. 이건 변수를 만들면서 더 자세하게 이야기하겠습니다.



▣ 변수는 먼저 자료형을 정합니다. 위에서 간단하게 이야기했듯이 어떤 형식에 그릇으로 정해줄지 정해줍니다.
자료형을 먼저 정해주고 그다음에 변수 이름을 정합니다.
이건 안에 어떤 내용이 있는지를 그릇(박스)에 표시해준다고 생각하시면 될꺼같습니다. 그럼 그 변수 이름은 곧 값이 되겠죠? 이 말은 꼭 기억해주세요.
그다음에 그 박스를 값을 저장했으면 그 박스들을 모아 보관해 두겠죠? 메모리에?
그런데 변수라는 게 한두 개가 아닐 겁니다. 엄청 많겠죠? 
택배 하는 곳을 가더라도 박스들이 어디 있는지 알기 어렵습니다. 그럼 어떻게 할까요? 네 바로 보관해준 장소를 표시해두겠죠?
그것과 같이 변수도 메모리 고유 주소를 가집니다. 이점 꼭 기억해주시고 지금부터 제가 한 코딩을 그대로 작성해주세요.

 

 

이렇게 작성해보셨으면 코드를 설명해보도록 하겠습니다. 



▣ int x; 이렇게 하면 되면 int 자료형에 x라는 변수 이름으로 그릇을 선언하겠다라는 의미입니다.
그럼 저런 박스가 생겨나겠죠?
거기에 x = 10이라는 값을 저장해라는 의미입니다. 여기서 중요한 건 = 이건 데요 이건 
대입 연산자입니다.
우리가 수학에서 알고 있는 =같다는 의미가 아닙니다. 저것도 연산을 하는 겁니다. 꼭 기억해주세요. 오른쪽에서 있는 값을 왼쪽에 있는 변수에 대입 넣어라라는 의미입니다. 
컴퓨터는 우리가 보는 것처럼 논리적으로 무엇을 처리하는 게 아니라 연산을 하는 겁니다. 꼭 기억해주세요. 그래서 
x = 10;이라고 할 때 =이라는 대입 연산자가 하나 있기 때문에 우선적으로 그 구문에 =을 연산한 것입니다. 
이 이야기는 꼭 기억해주세요.



그다음에 printf는 기억하시죠? 그런데 먼가 문구가 달라졌습니다. 우선 쉽게 이야기하면 %d는 형식입니다. 
그놈에 형식 ^^;; 참 ㅎㅎ 
하지만 형식이 존재하는 건 우리가 정해서 컴퓨터한테 명령을 주기 위해서 하는 것이기 때문에 다 의미가 있습니다. 
형식에 맞게 출력해라라는 의미 기억하시죠? %d 안에 , 따옴표 밖에 있는 저 변수에 값을 넣어서 출력하라는 의미입니다. 그렇다고 진짜 %d에 값을 넣는 건 아닙니다. 
쉽게 이야기해서 그렇지 지목을 한다?라고 생각하시면 좀 더 편하겠네요. 
이 부분은 계속 입출력을 다룰 때 이야기하겠습니다.



d는 Decimal 10진수에 약자입니다. 10진수로 출력해라는 겁니다. 

 

출저 : https://blog.naver.com/rkdign/220934362631


이런 형식들이 있습니다. 모두 외우실 필요는 없지만 내가 이런 형식으로 출력하고 싶다라는 하시면 이런 걸 참고해서 하시면 될꺼같습니다.
그럼 밑에 있는 %p도 아시겠죠? x에 포인터를 출력 해인데 x앞에 (&)앤퍼센트 표시가 있습니다.
여기서는 이 기호는 주소를 나타내는 표시입니다. 그래서 x에 주소를 보여줘라는 의미라고 생각하시면 될꺼같습니다.
이렇게 디버그 하지 않고 시작을 하게 되면  

 

첫 번째 x안에 있는 값이 나오고 두 번째 그 변수에 메모리 주소가 나옵니다. 이건 너무너무 중요한 내용이니 꼭 기억해주시면 좋을 거 같습니다. 



자 다시 정리하면 변수는 메모리(그릇, 박스)이다라고 생각해주시고, 그 필요 형식에 맞게 자료형을 정해주고 변수 이름을 정해줍니다. 이건 그 안에 무엇이 들어있는지를 알려주기 위해 사용하고 그리고 변수는 고유에 주소를 가지고 있다고 생각해주시면 될꺼같습니다. 



그럼 숙제
자료형 변수 이름 그리고 값을 바꿔서 다른 형식으로 출력해보는걸 꼭 해보세요.
위에 있는 형식들을 꼭 참고해서 해주시면 될꺼같습니다.
그리고 제가 설명한 내용이 전부가 아닙니다. 아직 이야기 못한 부분은 다음 장에서 진행하도록 하겠습니다.
너무 깊이 있게 가다 보니 너무 많은 이야기를 했네요 하지만 저 부분들을 알고 있어야 나중에 코딩을 하실 때 이해가 되실 겁니다.
어렵지만 꼼꼼하게 읽어주시고 꼭 실습 숙제해주시면 감사하겠습니다. 저도 좀 더 쉽게 글을 올리도록 노력하도록 하겠습니다. 질문 있으시거나 궁금하신 거 있으시면 댓글이나 메일 주시면 최대한 빠르게 답 드리도록 하겠습니다. 
다시 말씀드리지만 제 블로그가 정답이 아닙니다. 꼭 다른 좋은 분들에 자료들도 살펴보시고 함께 공부하시면 이해도 빠르고 더 빠르게 실력이 향상될 겁니다.



▣ 포기하지 마세요!!! 저도  했습니다 했습니다.!!! 그럼  다음장에서 뵙겠습니다.

728x90
반응형

댓글