이것이 C 언어다, 서현우의 C 프로그래밍 정복-미리보기

Page 1


w w w. h a n b i t . c o . k r

이것이 프로그래밍이다! 저자 직강 동영상 제공!

이것이 안드로이드다

이것이 C언어다

이것이 자바다

진정한 안드로이드 개발자로 이끌어줍니다.

세상에 없던 새로운 C언어 입문서 탄생!

가장 중요한 프로그래밍 언어를 하나 배워야 한다면, 결론은 자바다!

SDK 5.0 롤리팝 호환!

삼성, LG에서 펼쳐졌던 전설의 명강의를 풀타임 동영상 강좌로!

중급 개발자로 나아가기 위한 람다식, JavaFX, NIO 수록

이보다 더 확실한 방법은 없다, 칠판강의

책만 보고, 동영상 강좌로도 만족하지 못했다면 Daum 카페 '슈퍼드로이드'에서 만나요

전체 동영상 강좌 유투브 전격 공개!

자바의 모든 것을 알려주는 인터넷 강의 궁금한 것은 카페에서!

cafe.daum.net/superdroid

http://goo.gl/tJK3Tu

cafe.naver.com/thisisjava

박성근 저 | 1,164쪽 | 45,000원

서현우 저 | 708쪽 | 25,000원

신용권 저 | 1,224쪽 | 30,000원


w w w. h a n b i t . c o . k r

지금은 모던 웹 시대! 모던 웹 디자인을 위한

모던 웹을 위한

HTML5 + CSS3 입문 HTML5 분야 부동의 1위 도서

JavaScript + jQuery 입문

HTML5 표준안 확정에 맞춘 완전 개정판의 귀환!

자바스크립트에서 제이쿼리, 제이쿼리 모바일까지 한 권으로 끝낸다!

HTML5 권고안과 최신 웹 브라우저 환경 대응

시대의 흐름에 맞춰 다시 쓴 자바스크립트 교과서

윤인성 저 | 624쪽 | 30,000원

윤인성 저 | 980쪽 | 32,000원

모던 웹을 위한

HTML5 + CSS3 정복

Node.js

프로그래밍 페이스북, 월마트, 링크드인은 왜 Node.js를 선택했는가?

필요한 것만 배워 바로 현장에서 쓰는 HTML5

이 물음에 대한 답은 Node.js가 보여주는 빠른 처리 능력 때문이다.

순서대로 읽으며 실습할 수 있는 HTML5 자습서

윤인성 저 | 484쪽 | 25,000원

김상형 저 | 700쪽 | 32,000원




이것이 C 언어다, 서현우의 C 프로그래밍 정복 : 인터넷 강의 무상 제공, C 언어 표준 라이브러리 함수 완벽 수록 초판발행 2014년 05월 20일 3쇄발행 2015년 04월 01일 지은이 서현우 / 감수자 박상현, 김성훈, 김대정 베타리더 김영목, 김원재, 이찬우, 조명주, 조민철, 홍지호, 황대선 / 펴낸이 김태헌 펴낸곳 한빛미디어 (주) / 주소 서울시 마포구 양화로 7길 83 한빛미디어(주) IT출판부 전화 02 – 325 – 5544 / 팩스 02 – 336 – 7124 등록 1999년 6월 24일 제10 – 1779호 / ISBN 978-89-6848-102-4 13000 책임편집 배용석 / 기획 최현우 디자인 표지 강은영, 내지 여동일 조판 이경숙 영업 김형진, 김진불, 조유미 / 마케팅 박상용, 서은옥, 김옥현 이 책에 대한 의견이나 오탈자 및 잘못된 내용에 대한 수정 정보는 한빛미디어(주)의 홈페이지나 아래 이메일로 알려주십시오. 잘못된 책은 구입하신 서점에서 교환해 드립니다. 책값은 뒤표지에 표시되어 있습니다. 한빛미디어 홈페이지 www.hanbit.co.kr / 이메일 ask@hanbit.co.kr

Published by HANBIT Media, Inc. Printed in Korea Copyright © 2014 서현우 & HANBIT Media, Inc. 이 책의 저작권은 서현우와 한빛미디어 (주)에 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 복제 및 무단 전재를 금합니다.

지금 하지 않으면 할 수 없는 일이 있습니다. 책으로 펴내고 싶은 아이디어나 원고를 메일 ( writer@hanbit.co.kr ) 로 보내주세요. 한빛미디어(주)는 여러분의 소중한 경험과 지식을 기다리고 있습니다.


명쾌한 포인터 설명 | C 언어 표준 라이브러리 함수 완벽 수록 서현우 지음


감수자의 말 제가 C 언어를 처음 접한 것은 약 20년 전, 고등학교 1학년 때의 일입니다. 갓 컴퓨터를 산 컴맹(저 말 입니다. 저요!)이 친구들에게 몇 마디 주워듣고는 서점으로 가서 C 언어 책을 산 것이죠. 정확히 기억 나지는 않지만 아마도 ‘C 언어 21일 완성’ 비슷한 제목이었던 것 같습니다. 책을 붙들고 한 달 정도를 공부했을 겁니다. 우여곡절 끝에 “Hello, World!”를 출력하는 데 성공했습니다. 정말 기쁘고 신기했 습니다. 그러나 제가 대학에 가기 전까지 그 책을 다시 열어보는 일은 없었습니다. 프로그래밍이 멋져 보이긴 했지만, 베개 같은 두께와 이해하기 어려운 내용으로 채워진 책을 마주할 용기가 나지 않았기 때문입니다. 제 컴퓨터는 이해력과 용기가 없는 주인을 둔 죄로 멋진 일을 할 기회를 잃고 고교 3년 동 안 게임기로만 사용되었습니다. 저도 지금보다 더 나은 프로그래머가 될 기회를 놓쳤고 말입니다. 서현우 님의 『이것이 C 언어다, 서현우의 C 프로그래밍 정복』이라면 20년 전의 저에게 C를 제대로 공 부해볼 마음을 먹게 했으리라 생각합니다. 저자는 교육기관과 기업에서의 수많은 강의 경험을 바탕으 로 이 책을 집필했습니다. 독자들이 어떤 내용에서 이해를 힘들어하고 어떤 것을 궁금해하는지를 잘 알고 있습니다. 이 책은 거의 모든 문법 예제에 도식을 넣고 중요한 설명을 적절히 강조하여 독자가 눈 으로 따라가며 문법을 익힐 수 있게 했습니다. 낯선 용어를 접하는 독자들을 배려하고 있음은 물론입 니다. 저는 이미 6권의 C 언어 책을 갖고 있지만 『이것이 C 언어다, 서현우의 C 프로그래밍 정복』이 출간되 면 사무실 책상에 꽂아두려 합니다. 입문자를 위해 집필되었지만 실무자들도 개발 참고서로 쓸 수 있 도록 내용 정리가 잘되어 있기 때문입니다. 이미 많은 C 언어 서적이 나와 있음에도 불구하고 이 책은 출간할 만한 가치가 있습니다. 어려운 주제 는 생략하고 쉬운 책을 표방하는 서적들과는 달리 C 프로그래머로서 알아야 하는 내용을 독자들이 정 면돌파할 수 있게 돕기 때문입니다. 『이것이 C 언어다, 서현우의 C 프로그래밍 정복』을 통해 프로그래 밍과 인연을 맺어보길 여러분에게 권해봅니다. _박상현, 삼성탈레스 전문연구원 『뇌를 자극하는 알고리즘』 (2010 대한민국 우수학술도서), 『뇌를 자극하는 C# 4.0 프로그래밍』 저자

4


C 언어가 나온 지 반세기 가까이 지나고 있고, 자바와 자바스크립트가 세상을 휘어잡고 있지만 그 근 간이 되는 C 언어는 여전히 중요합니다. 제가 처음 프로그래밍 언어를 배웠던 1997년 당시에도 C 언 어는 중요했고, 그 위상이 조금 달라지긴 했지만 여전히 현역이며 대세 언어 중 하나임은 분명합니다. 제가 처음 C 언어에 입문했던 서적은 『터보- C 2.0 길라잡이』라는 책이었습니다. 게다가 제대로된 정 규 교육 과정을 2003년 이후에나 밟았습니다. 한때는 프로그래밍은 커녕 컴퓨터 자체에도 익숙치 않 던 제가 프로그래머가 될 수 있었던 것은 좋은 입문서 덕이었다고 생각합니다. 그중에서도 이미 절판 된 『터보-C 2.0 길라잡이』와 『캠퍼스 C』가 가장 기억에 남습니다. 이 책은 그 두 책을 대체하기에 충분히 쉽고 적절한 입문서입니다. 이 책으로 C 언어의 세계에 발을 들 여보신다면, 앞으로의 프로그래머 생활에 두고 두고 기억에 남을 서적이 되리라 확신합니다. _김성훈, 마이에트 엔터테인먼트 온라인 게임 프로그래머 건즈2, 팡야, 포키포키, 카오스 온라인 외 다수

이 책은 다른 책과 확연히 다르게 ‘소스코드가 어떻게 실행 파일이 되어 실행되는지’에 대해 제일 먼저 다루고 있어 초보자도 실행 원리를 쉽게 이해할 수 있을 겁니다. 그러한 부분은 ‘어떻게 하면 가장 이 해하기 쉽게 설명을 할까?’라는 저자의 고민이 묻어나온 것이며 독자를 향한 배려라고 생각됩니다. 또 한 이해를 돕는 쉬운 예제와 설명은 독자의 프로그래밍 실력을 향상시키고 이해의 폭을 넓혀드릴 거라 확신합니다. 다른 서적에서 찾기 힘든 이 책만의 장점을 또 한 가지 뽑으라고 한다면, 자주 사용하는 표준 입력 함 수의 내부 구동까지 꼼꼼히 설명해서 진정으로 깊이 있게 C를 이해하는 데 큰 도움이 된다는 겁니다. 따라서 기초가 약한 초보자부터 현업 개발자 모두 이 책을 통해 얻을 수 있는 지식이 있다고 생각합 니다. 제대로 C 언어를 배우고 싶은 분들에게 이 책을 추천해드립니다. _김대정, 한양대학교 차세대 네트워크 연구실 석사 과정 코오롱 계열사 근무 중 학업의 꿈을 품어 네트워크 분야 수학 중

5


베타 리더의 말 솔직히 C 언어 책이면 비슷비슷하겠지 하고 별 기대를 안 했습니다. 근데 책을 읽을수록 정말 괜찮다 는 생각이 들었습니다. 기존 책들은 문법을 설명하기 바쁘고 소스를 이해하기 바쁩니다. 하지만 이 책 은 원리를 빠르게 알 수 있도록 친절하게 설명하여 매력적입니다. 게다가 좀 깊게 생각해야겠구나 하 는 부분마다 어김없이 소스로 문제점을 보여주고 원인과 해결 방법을 설명합니다. 책 구성이나 소스 또한 적합해보입니다. 특히 굳이 설명하지 않아도 되거나 많이 쓰지 않는 문법이나 기법을 적절히 제외한 점이 돋보입니다. 처음 C 언어를 접할 때, 문법을 이해하기 바쁘고 원리와 동작을 이해하지 못한 채 코드를 작성했었습 니다. 책으로만 이해하는 데 한계가 있었고 필요 없거나 많이 쓰지 않는 낡은 문법도 있었습니다. 그래 서 시대가 변하는 만큼 책도 변해야 한다고 느꼈습니다. 새로 C 언어를 배우는 입문자에게 정말 필요 한 것은 ‘왜? 어떻게?’ 동작하는지에 대한 원리를 다루는 설명일 겁니다. 바로 이런 부분을 이 책이 담 고 있습니다. 궁금했던 부분들을 시원하게 긁어주고, 하나하나 자세히 설명하고 있습니다. 이 책은 프 로그래머로 첫발을 딛는 데 있어서 필수 지침서로 삼기에 손색이 없다고 생각합니다. _ 홍지호 고려대학교 융합소프트웨어 대학원 석사 과정

실무에서 가장 중요한 것은 기본입니다. 그런 생각은 일할수록, 경험이 늘어날수록 자주 하게 되며, 선 배는 물론이고 (친한) 상사들도 자주 하는 말입니다. 그런 면에서 이 책은 기본기를 다시 다지기에 적 합했습니다. 컴파일러의 실행 순서도를 통해 프로그램의 특징들을 다시 한 번 상기시킬 수 있었고, 메 모리 사용에 대한 설명과 예시가 있는 점도 인상적이었습니다. 제가 처음에 학습할 때는 컴파일러나 메모리 등에는 전혀 관심이 없었는데, 이제는 관심이 생기더라고요 ^^* 내용 설명이 어렵지 않고, 지루하지 않은 것이 장점인 것 같습니다. 특히 예제가 많고, 예제를 이해하 기 쉽게 설명한 덕분에 코드에 대한 이해도를 높일 수 있었고, 중요 포인트들을 한 번씩 더 언급해주어 좋았습니다. 본문에는 저자가 직접 실행해보기를 권유하는 글귀가 반복적으로 있었는데, 매우 공감되 었습니다. 이 책은 C 언어를 섭렵할 수 있게끔 예제가 많아, 직접 소스코드를 코딩하고 실행하면 발전된 자신을 볼 수 있을 거라고 생각됩니다. 게다가 장별로 도전 과제가 있으니, 응용 능력은 떼어 놓은 당상이라 생각되네요.

6


잊고 있었던 기본기를 다시 다져볼 기회를 주신 한빛미디어 관계자분들께 감사의 말씀을 드립니다. _조명주 (주)에어텍시스템, 프로그래머

비전공자로 하드웨어를 10년 정도 했더니 하드웨어에 대해서 특별히 공부하지 않아도 대략적인 개념 과 문제점이 눈에 들어왔습니다. 물론 10년 동안 했으면 그 정도는 알아야 하지 않느냐고 할 수 있겠 지만 정확한 지식이 없이 단편적으로 습득하여 어떠한 기능과 연결되는지 고민하는 과정이 쉽지는 않 았습니다. 그런데 이러한 반복적인 과정은 결과적으로 하드웨어의 메커니즘을 머릿속에서 저만의 방 식으로 그림을 그리고 공부하는 데 큰 도움을 주었습니다. 이 책을 접하고 나니 지난 10년의 공부가 떠올라 꺼낸 이야기입니다. 저는 이 책을 통해 소프트웨어에 대한 밑그림을 머릿속에 그리고 C 언어를 편하게 접하게 되었습니다. 비록 2주라는 짧은 기간이었지만 정말 빠른 속도로 머릿속에 C를 넘어 소프트웨어 그림을 그릴 수 있 었습니다. 만일 하드웨어를 공부할 때 이 책처럼 쉽게 이해할 수 있게 쓰인 책을 만났다면 지금 이 시 점에서 제 하드웨어에 대한 지식은 더 높은 수준이 됐을 것이라 확신합니다. 저도 소프트웨어에 대해서는 배워가는 입장이어서 함부로 어떤 책이 좋다 나쁘다를 평할 자격은 못 됩 니다. 또한 자신의 상황에 맞는 책을 보면 매우 잘 쓰인 책으로 보이기도 하고 그렇지 않을 때에는 난 해한 책으로 보이는 상대성이 있다고 생각합니다. 이 책을 빠른 속도로 읽으며 제 나름의 하드웨어 경험과 연관 짓고 상상했습니다. 물론 초보자이기에 이해가 안되는 부분도 있었지만 ‘프로그래밍’에 대한 전체적인 윤곽을 확인할 수 있었습니다. 프로그래 밍에 대해 막연히 공부하고자 하는 주변 사람들에게 이 책을 읽어보라고 권해주고 싶습니다. 적절한 비유와 쉬운 설명으로 이뤄진 이 책이 프로그래밍을 처음 시작하는 사람에게 훌륭한 지침서가 될 수 있을 거라 확신합니다. _김영목 HUGLE

7


책의 구성이 마치 다이어리처럼 하루 분량을 정해서 목표한 D-DAY 안에 일독할 수 있도록 총 19일 로 구성된 점이 눈에 띄었습니다. 또한, 하루 분량 안에는 두 절로 나뉘어 있었고, 한 절은 10페이지 내외로 내용이 알차게 꾸려져 있었습니다. 내용이 너무 많거나, 공부해야 할 분량이 많았다면 부담이 되었을 테지만 다섯 꼭지 정도 가볍게 읽고 나니 한 절을 완독했다는 뿌듯함을 느낄 수 있어, 다음 절 을 공부할 때 부담이 많이 줄고 가벼운 마음으로 계속 책을 읽을 수 있었습니다. 또한, 각 절마다 ‘마무리’로 총평과 내용 정리를 제공하여 개념 이해 또는 사용법 등의 핵심을 다시 한 번 강조해주었는데, 이 점이 매우 신선했습니다. 보통 본문을 본 후에도 중요한 포인트를 몰라서 다시 펼쳐보는 경우가 많고, 연습문제를 풀 때 중요한 힌트를 찾지 못해서 책을 다시 돌려보기 일쑤였는데 ‘마무리’를 통해서 본문과 연습문제가 부드럽게 이어져서 프로그래밍이 익숙하지 않은 제가 책을 완독 하는 데 시의적절한 도움을 줬습니다. ‘연습문제’는 각 절마다 다섯 개가 수록되어 있었는데, 수량은 적당하지만 좀 쉬운 감이 없지 않아 있었 는데, 하루 분량마다 추가로 ‘도전 실전 예제’가 세 문제 제공되어 실전 감각을 익히는 데 도움을 주었 습니다. 단, 도전 실전 예제는 배운 내용을 활용해야 하기에 초심자는 풀기 어려울 수도 있겠다는 생각 이 들었습니다. 또한, 코드마다 매우 상세하게 주석 처리가 되어 있어서 코드만 봐도 어떻게 동작하고, 그 동작이 의미하는 게 무엇인지 좀 더 쉽고 빠르게 파악할 수 있어서 초보자가 책을 차례대로 읽어 가 기 편했습니다. 또, 기초가 중요한 초보자일수록 빠르게 여러 번 반복해서 보는 게 더욱 효과적이라고 생각하는데 그런 측면에서는 이 책의 구성은 내용도 분량도 너무 길지 않고, 읽기에 지루하지 않을 만 큼 적당하고, 글보다 이미지가 많아서 적합했습니다. ‘프로그램이란 하나의 이야기를 엮어나가는 것’이라는 저자의 의도가 참 마음에 와 닿았습니다. 책 요 소마다 반드시 이해하고 넘어가야 할 프로그래밍 원리는 이미지로 쉽게 정의해 놓았으며, 함수마다 간 결한 정의를 해놓아서 책을 완독하고 난 후 C 언어에 대한 어떠한 질문에도 자신 있게 정의와 원리만 큼은 분명하게 설명할 수 있다는 자신감이 들 정도였습니다. 그런 차원에서 취업을 대비하고 있는 초 보 프로그래머의 눈높이에 잘 들어맞는 책이라고 생각합니다. 공공연하게 많은 책을 보고, 프로그래밍은 어렵고 공부할 게 많다고 지레짐작하여 포기하려는 많은 사 람에게 자신 있게 말하고 싶습니다. 이 책으로 프로그래밍을 배워 자신만의 재밌는 이야기를 써내려 가길 바란다고... _이찬우 고려대학교 대학원 석사 과정

8


일반적인 C 언어 책들과는 조금 다른 접근이지 않았나 싶습니다. 보통 C 언어 책에서 나오지 않는 문 법을 다수 다루고 있어 굳이 웹검색을 하는 수고를 할 필요가 없을 정도입니다. 특히 제시되는 예제들 은 너무 짧지 않으면서도 복잡하지 않아서 쉽게 이해하고 빠르게 익히기에 안성맞춤인 듯싶습니다. _ 황대선 창원대학교 정보통신공학과

C 언어는 프로그래밍 입문 언어면서도 필드에서도 두루 쓰이는 기능적인 언어입니다. 한마디로 프로 그램 세계의 기본 언어입니다. 게다가 눈으로 보이지 않는 컴퓨터 내부 연산 때문에 어려움을 뛰어넘 어 두렵기까지 합니다. 이 책은 그러한 내부 연산을 친절히 소개하고 있어 입문자 또는 다른 언어를 이미 공부해본 경험이 있 으면서 C 언어를 배우려 마음먹은 사람들을 위해 친절하고도 세심한 배려가 돋보입니다. 특히 C에서 어렵다고 얘기하는 포인터에 대해서 주소, 변수, 포인터의 관계를 다양한 예제와 수많은 그림으로 자세히 다루어 독자들의 이해를 돕습니다. 예를 들어 12.1.6절에서는 시스템 구조 내 I/O 버퍼와 스트림의 관계를 쉽고 명확하게 보여주는데, 사실 이 부분은 다른 책으로는 쉽게 이해되지 않 았던 부분입니다.

C 언어 입문서의 독자층이 보통 대학교 1학년 또는 갓 프로그래밍을 시작한 입문자라는 점을 고려할 때 이러한 상세한 설명과 그림은 정말로 큰 도움을 줍니다. 각 장의 ‘마무리’에서는 배웠던 것을 다시 한 번 되새김질시켜주고 연습문제는 그 장에서 배운 바를 제대로 습득했는지 갈무리할 수 있게 핵심적 인 내용을 다루고 있습니다. _조민철 인하대학교 10학번

학습 목표로 무엇을 배울지 알아보고 기본 사용법을 익히고 예제로 배운 걸 다듬는 방식으로 짜임새가 잘 짜여 있어서 초보자들이 입문하기에 좋은 책입니다. 그뿐만 아니라 단원마다 도전 실전 예제로 최 종복습을 함으로써 실력이 한층 더 업그레이드되는 느낌이 들었습니다. 특히 초보자(입문자)들이 가장 난해하다는 포인터 부분에서 다양한 예제와 자세한 설명은 이 책의 백 미입니다. 왜 포인터가 필요한지, 어떻게 사용하는지, 어떻게 메모리를 참조하는지 등을 알기 쉽게 풀

9


어놓았기 때문입니다. 저도 입문자로서 여러 책을 읽었지만 포인터 부분을 이해하기가 쉽지 않았는데 요, “진작에 이 책이 나왔더라면 그렇게 오랜 시간 혼돈 속에서 헤매지 않았을 걸”이라는 안타까운 생 각이 들 정도였습니다. 여러분! C 언어 입문서를 고민하고 계시나요? 이 책을 보시라고 감히 추천해드립니다. 이 책이 제시하 는 흐름을 따라가고, 책에 있는 예제를 변형해보고 직접 코딩을 해보세요. 그렇게 하면 저처럼 그동안 이해 못 했던 부분을 분명히 이해하게 될 겁니다. _김원재 호남대학교 컴퓨터 공학과

10


커뮤니티 소개 저자가 직접 운영하는 카페로 오세요. 질답, 강의와 예제 동영상, 최신 소스 파일을 지속적으로 제공받을 수 있습 니다. 또한 책에 미쳐 실지 못한 gcc, Dev-C++, Code Blocks 등의 컴파일러 정보를 확인할 수 있습니다. • http://cafe.naver.com/thisisc

2013년 네이버 대표 카페인 <C 언어를 배우자>의 회원인 감수자 두 분과 베타 리더 열 분이 이 책의 크고 작 은 오류를 잡아주시고, 초보자를 더 쉽게 이해시킬 방법을 알려주었으며, 기술적으로 도움이 되는 조언을 해 주셨습니다. 지면을 통해 다시 한 번 감사의 마음을 전합니다. • http://cafe.naver.com/cafec _ 한빛미디어 & 서현우

11


지은이의 말 하고 싶은 얘기와 듣고 싶어 하는 얘기를 모두 썼습니다. 처음 이 책의 집필을 부탁받았을 때 『뇌를 자극하는 C 프로그래밍』을 통해 C에 대해 하고 싶은 얘기를 다 했는데 새로 C 책을 집필하는 것이 가능한지 의문이었습니다. 그런데 샘플 원고를 통해 돌아온 피 드백은 충격이었습니다. 10여 명의 베타 리더는 원고 가득 메모를 남겼고 메모를 정리하면서 정말 독 자가 원하는 책을 만들기는 쉽지 않겠다는 생각이 들었습니다. 내용이 아무리 좋아도 설명하는 방법과 순서에 따라 독자들의 의견은 180도 달랐습니다. 그래서 많은 독자가 인정하는 책을 만들고 싶은 욕 심이 생겼고 도전하기로 했습니다. 기술적 오류가 없고 알차면서 읽기 쉬운 책을 만들기는 쉽지 않았습니다. 그렇게 시작한 집필은 쉽게 끝나지 않았습니다. 집필 중에 결혼하게 되었고 출산의 경험을 같이 하면 서 가족을 위하는 마음과 독자를 위하는 마음이 충돌했고 많은 고민과 갈등이 생겼습니다. 집필을 포 기하고 싶은 생각도 많았습니다. 그때 전문서팀 배용석 이사님과 송성근 수석팀장님, 최현우 팀장님의 격려와 배려로 집필을 이어갔고 그렇게 3년이 흘렀습니다. 그 시간 동안 강의할 때와 아기 볼 때 이외 에는 좋은 책을 만들기 위한 고민을 멈추지 않았습니다.

C가 필요한 사람에게 C를 알려주고 싶은 진심을 썼습니다. 10년 넘게 강의를 하면서 힘들 때에도 최선을 다할 수 있었던 것은 수강생의 피드백이었습니다. 고맙 다는 한마디 인사는 제게 큰 힘이 되었고 더 많은 것을 알려주게끔 하였습니다. 그래서 책을 통해서도 독자의 칭찬을 듣고 싶었습니다. ‘어떻게 쓰면 좀 더 잘 이해할까?’ 한 문장, 단어 하나도 허투루 쓰지 않았습니다. 그림에 포함된 화살표의 위치가 조금이라도 어긋나면 행여 내용을 오해할까 한 픽셀씩 움 직이며 그렸습니다. 아마도 이 책으로 얻을 수 있는 최고의 행복은 ‘잘 읽었다’는 독자평을 듣는 것이 아닐까 생각합니다. 이제 저의 마음은 마치 집 안을 깨끗이 청소하고 정성껏 요리해놓고 반가운 손님 을 기다리는 것 같습니다. 끝으로 지면을 빌어 또 다른 저자가 있었음을 고백합니다. 출산과 육아로 힘든 상황에서도 집필에 집 중할 수 있도록 지원해주고 힘든 고비마다 마음으로 위로해준 사람이 있습니다. 원고 진행이 더딜 때 마다 직접 아이디어를 내고 마지막 교정까지 꼼꼼히 봐준 사랑하는 아내 예경에게 고마움을 전합니다. 또 집필 중에 쌓인 피로를 해맑은 미소로 한 방에 날려 주었던 딸 하윤에게 사랑한다는 말을 전합니다. _ 서현우

12


지은이 소개 지은이

서현우

컴퓨터공학을 전공하고 12년째 학교와 기업체에서 C 전문강사로 활동 중이다. 아직도 태권브이 를 꿈꾸는 어린아이 같은 면이 있지만, 강의할 때 뿜어 나오는 카리스마는 수강생을 매력적인 C 세계로 이끈다. 쉽고 깔끔한 강의, 전문적이고 기본기를 다져주는 강의, 열정적이면서 명쾌한 강 의, 집중력을 이끌어내는 수강자 중심의 강의로 대학과 기업체에서 인기를 끌고 있다. • (전)대우정보시스템 근무 • 서울대에서 8년간 'C, C++ 대학특강' • 삼성전자, LG전자 C 언어 직무 교육 • MDS 아카데미 『뇌를 자극하는 C 프로그래밍』 저자 직강 • 그 외 수많은 기업, 대학, 국가기관, 교육센터 출강 저서_ 『이것이 C 언어다, 서현우의 C 프로그래밍 정복』(한빛미디어, 2014 ) 『뇌를 자극하는 C 프로그래밍』(한빛미디어, 2005 ) 『객체지향을 위한 C++ 프로그래밍』(웰북, 2010 )

13


책 소개 이 책의 개발 환경 이 책은 다음과 같은 환경을 기반으로 설명했으며, 모든 소스의 구동을 확인했습니다. 이름

버전

운영체제

윈도우 7(64비트)

컴파일러

Visual C ++ 2013

연습문제 절의 끝에는 연습문제가 뒤따릅니다. 해당 절을 잘 이해했는지 확인할 수 있는 알찬 문제로 구성되어 있으니 절대로 빼먹지 말고 차근차근 풀어보세요. 연습문제 바로 뒤에 해답과 친절한 설명이 곁들여져 이어집니다.

도전 실전 예제 도전 실전 예제는 해당 장에서 배운 내용으로 더 난이도 높은 프로그램을 개발할 수 있게 하는 데 그 목적이 있습니다. 도전 실전 예제는 별도의 설명은 제공하지 않지만 한빛미디어 홈페이지에서 소스 파일을 제공합니다. http://www.hanbit.co.kr/exam/2102

동영상 강좌 저자의 명강의를 인터넷 강의로 만나실 수 있습니다. 지금 유투브 인터넷 강의로 접속해보세요! http://me2.do/xWmYDjVY

VC++ 무료 버전 다운로드 및 설치 방법 안내 개발사 정책에 따라 바뀔 수 있어 해당 내용을 PDF로 만들어 제공합니다. 한빛미디어 홈페이지에서 무료로 내려받으실 수 있습니다. http://www.hanbit. co.kr/exam/2102

14


바로바로 찾아보는 QR코드 1장  프로그램 만들기

2장  상수와 데이터 출력

1절

1절

4장  연산자

2절

1절

5장  선택문

1절

2절

7장  함수

1절

2절

10장  배열과 포인터

1절

2절

2절

13장  변수의 영역과 데이터 공유

1절

1절

2절

16장  메모리 동적 할당

1절

2절

2절

17장  사용자 정의 자료형

2절

1절

2절

1절

2절

12장  문자열

14장  다차원 배열과 포인터 배열

2절

1절

9장  포인터

11장  문자

1절

2절

6장  반복문

8장  배열

1절

1절

3장  변수와 데이터 입력

2절

1절

2절

15장  응용 포인터

1절

2절

18장  파일 입출력

1절

2절

19장  전처리와 분할 컴파일

1절 ❶

1절 ❷

2절

15


차례

감수자의 말 • 4

베타 리더의 말 • 6

커뮤니티 소개 • 11

지은이의 말 • 12

지은이 소개 • 12

책 소개 • 14

PAR T

1

C 언어 기본

1장 프로그램 만들기 • 29 1.1 프로그램과 C 언어 • 30 1.2 컴파일러 사용법 • 32 1.2.1 소스 파일( source file ) 작성 • 33 1.2.2 컴파일 • 38 1.2.3 실행 • 40 연습문제 • 42

정답 및 해설 • 42

2장 상수와 데이터 출력 • 43 2.1 C 프로그램의 기본 형태와 데이터 출력 방법 • 44 2.1.1 main 함수 구조 • 44 2.1.2 출력 함수( printf )의 사용법 • 46 2.1.3 printf 함수로 제어 문자 출력 • 47 2.1.4 printf 함수로 정수와 실수 출력 • 49 연습문제 • 51

2.2 상수와 데이터 표현 방법 • 53 2.2.1 정수 상수 표현법 • 53 2.2.2 실수 상수 표현법 • 55 16

정답 및 해설 • 52


2.2.3 문자와 문자열 상수 표현법 • 57 2.2.4 상수가 컴파일된 후의 비트 형태 • 58 2.2.5 정수형 상수가 컴파일된 후의 비트 형태 • 59 2.2.6 실수형 상수가 컴파일된 후의 비트 형태 • 60 연습문제 • 63

정답 및 해설 • 64

3장 변수와 데이터 입력 • 65 3.1 변수 • 66 3.1.1 변수 선언 방법 • 67 3.1.2 쓰레기값과 초기화 • 69 3.1.3 정수를 저장하는 자료형 • 71 3.1.4 unsigned 정수 자료형 • 74 3.1.5 실수 자료형 • 76 3.1.6 문자열 저장 • 78 3.1.7 const를 사용한 변수 • 80 3.1.8 예약어와 식별자 • 81 연습문제 • 83

정답 및 해설 • 84

3.2 데이터 입력 • 86 3.2.1 scanf 함수의 사용법 • 87 3.2.2 scanf 함수의 응용 • 88 3.2.3 문자와 문자열의 입력 • 90 연습문제 • 92

정답 및 해설 • 94

4장 연산자 • 97 4.1 산술, 관계, 논리 연산자 • 98 4.1.1 연산자와 피연산자 • 99 4.1.2 산술 연산자와 대입 연산자 • 99 4.1.3 나눗셈 연산자와 나머지 연산자 • 102

17


4.1.4 증감 연산자 • 103 4.1.5 관계 연산자 • 106 4.1.6 논리 연산자 • 108 4.1.7 연산의 결과값은 어떻게 되나요? • 109 연습문제 • 111

정답 및 해설 • 112

4.2 비트 연산자와 그 외의 멋진 연산자 • 115 4.2.1 형변환 연산자 • 116 4.2.2 sizeof 연산자 • 117 4.2.3 복합대입 연산자 • 119 4.2.4 콤마 연산자 • 121 4.2.5 조건 연산자 • 122 4.2.6 비트 연산자 • 123 4.2.7 연산자 우선순위와 연산 방향 • 127 연습문제 • 129

정답 및 해설 • 129

도전 실전 예제 • 132

5장 선택문(if, switch~case) • 133 5.1 if문 • 134 5.1.1 if문의 기본 형식 • 135 5.1.2 if ~ else문 • 137 5.1.3 if ~ else if ~ else문 • 139 연습문제 • 144

정답 및 해설 • 145

5.2 if문의 활용과 switch~case문 • 149 5.2.1 if문 중첩 • 150 5.2.2 if문을 중첩해서 쓰는 이유 • 152 5.2.3 else 결합 문제 • 154 5.2.4 switch ~ case문 • 156 연습문제 • 160 도전 실전 예제 • 164

18

정답 및 해설 • 162


6장 반복문 • 167 6.1 while, for, do~while • 168 6.1.1 while문 • 169 6.1.2 for문 • 172 6.1.3 do ~ while문 • 175 연습문제 • 178

정답 및 해설 • 179

6.2 반복문 활용 • 183 6.2.1 중첩 반복문 • 183 6.2.2 break와 continue 분기문 • 188 연습문제 • 192

정답 및 해설 • 193

도전 실전 예제 • 196

7장 함수 • 199 7.1 함수의 작성과 사용 • 200 7.1.1 함수 정의 • 201 7.1.2 함수 호출과 반환 • 203 7.1.3 함수 선언 • 205 연습문제 • 207

정답 및 해설 • 208

7.2 여러 가지 함수 유형 • 211 7.2.1 매개변수가 없는 함수 • 212 7.2.2 반환값이 없는 함수 • 214 7.2.3 반환값과 매개변수가 모두 없는 함수 • 215 7.2.4 재귀호출 함수 • 216 7.2.5 재귀호출이 반복문과 다른 점은 무엇인가? • 219 연습문제 • 222

정답 및 해설 • 223

도전 실전 예제 • 226

19


8장 배열 • 227 8.1 배열의 선언과 사용 • 228 8.1.1 배열 선언과 배열 요소 사용 • 228 8.1.2 배열 초기화 • 231 8.1.3 배열과 반복문 • 233 8.1.4 sizeof 연산자를 활용한 배열 처리 • 235 연습문제 • 237

정답 및 해설 • 238

8.2 문자를 저장하는 배열 • 241 8.2.1 char형 배열의 선언과 초기화 • 241 8.2.2 문자열 대입 • 245 8.2.3 문자열 전용 입출력 함수(gets, puts) • 247 연습문제 • 249

정답 및 해설 • 251

도전 실전 예제 • 252

9장 포인터 • 253 9.1 포인터의 기본 개념 • 254 9.1.1 주소 연산자(&) • 254 9.1.2 포인터와 간접참조 연산자( * ) • 257 9.1.3 여러 가지 포인터 • 260 9.1.4 const를 사용한 포인터 • 262 연습문제 • 264

정답 및 해설 • 265

9.2 포인터에 관한 궁금한 이야기 • 266 9.2.1 주소와 포인터의 차이 • 267 9.2.2 주소와 포인터의 크기 • 268 9.2.3 포인터의 대입 규칙 • 270 9.2.4 포인터가 필요한 이유 • 272 연습문제 • 277 도전 실전 예제 • 280

20

정답 및 해설 • 279


PAR T

11

C 언어 고급

10장 배열과 포인터 • 283 10.1 배열과 포인터의 관계 • 284 10.1.1 배열명의 정체 • 284 10.1.2 배열명으로 배열 요소 사용하기 • 286 10.1.3 배열명 역할을 하는 포인터 • 289 10.1.4 배열명과 포인터의 차이 • 291 10.1.5 포인터의 뺄셈과 관계 연산 • 296 연습문제 • 298

정답 및 해설 • 300

10.2 배열을 처리하는 함수 • 302 10.2.1 배열의 값을 출력하는 함수 • 302 10.2.2 배열 요소의 개수가 다른 배열도 출력하는 함수 • 305 10.2.3 배열에 값을 입력하는 함수 • 307 연습문제 • 310

정답 및 해설 • 311

도전 실전 예제 • 313

11장 문자 • 315 11.1 아스키 코드값과 문자 입출력 함수 • 316 11.1.1 문자 상수 구현 방법 • 316 11.1.2 아스키 코드 • 318 11.1.3 scanf 함수를 사용한 문자 입력 • 321 11.1.4 getchar 함수와 putchar 함수 • 324 연습문제 • 326

정답 및 해설 • 327

21


11.2 버퍼를 사용하는 입력 함수 • 329 11.2.1 scanf 함수가 문자를 입력하는 과정 • 329 11.2.2 scanf 함수 반환값 활용 • 332 11.2.3 getchar 함수를 사용한 문자열 입력 • 335 11.2.4 fflush 함수 • 337 연습문제 • 339

정답 및 해설 • 340

도전 실전 예제 • 342

12장 문자열 • 343 12.1 문자열과 포인터 • 344 12.1.1 문자열 상수 구현 방법 • 344 12.1.2 char 포인터로 문자열 사용 • 346 12.1.3 scanf 함수를 사용한 문자열 입력 • 348 12.1.4 gets 함수를 사용한 문자열 입력 • 350 12.1.5 fgets 함수를 사용한 문자열 입력 • 352 12.1.6 표준 입력 함수의 버퍼 공유 문제 • 354 12.1.7 문자열을 출력하는 puts, fputs 함수 • 356 연습문제 • 358

정답 및 해설 • 359

12.2 문자열 연산 함수 • 361 12.2.1 문자열을 대입하는 strcpy 함수 • 361 12.2.2 strcpy 함수 구현 방법 • 364 12.2.3 원하는 개수의 문자만을 복사하는 strncpy 함수 • 366 12.2.4 문자열 길이를 계산하는 strlen 함수 • 367 12.2.5 문자열을 붙이는 strcat, strncat 함수 • 369 12.2.6 문자열을 비교하는 strcmp, strncmp 함수 • 372 연습문제 • 375 도전 실전 예제 • 379

22

정답 및 해설 • 377


13장 변수의 영역과 데이터 공유 • 381 13.1 변수 사용 영역 • 382 13.1.1 지역 변수 • 382 13.1.2 블록 안에서 사용하는 지역 변수 • 385 13.1.3 전역 변수 • 387 13.1.4 정적 지역 변수 • 389 13.1.5 레지스터 변수 • 392 연습문제 • 394

정답 및 해설 • 396

13.2 함수의 데이터 공유 방법 • 398 13.2.1 값을 복사해서 전달하는 방법 • 398 13.2.2 주소를 전달하는 방법 • 400 13.2.3 주소를 반환하는 함수 • 401 연습문제 • 404

정답 및 해설 • 406

도전 실전 예제 • 408

14장 다차원 배열과포인터 배열 • 411 14.1 2차원 배열 • 412 14.1.1 2차원 배열 선언과 요소 사용 • 412 14.1.2 2차원 배열 초기화 • 417 14.1.3 2차원 char 배열 • 421 14.1.4 2차원 char 배열 초기화 • 423 14.1.5 3차원 배열 • 425 연습문제 • 428

정답 및 해설 • 429

14.2 포인터 배열 • 432 14.2.1 포인터 배열 선언과 사용 • 432 14.2.2 2차원 배열처럼 활용하는 포인터 배열 • 435 연습문제 • 438

정답 및 해설 • 440

도전 실전 예제 • 442

23


15장 응용 포인터 • 445 15.1 2중 포인터와 배열 포인터 • 446 15.1.1 2중 포인터 개념 • 446 15.1.2 2중 포인터 활용 예 1 • 451 15.1.3 2중 포인터 활용 예 2 • 454 15.1.4 배열 요소의 주소와 배열의 주소 • 455 15.1.5 2차원 배열과 배열 포인터 • 458 15.1.6 2차원 배열의 요소를 참조하는 원리 • 461 연습문제 • 463

정답 및 해설 • 466

15.2 함수 포인터와 void 포인터 • 469 15.2.1 함수 포인터의 개념 • 469 15.2.2 함수 포인터의 활용 • 472 15.2.3 void 포인터 • 475 연습문제 • 477

정답 및 해설 • 479

도전 실전 예제 • 481

16장 메모리 동적 할당 • 485 16.1 동적 할당 함수 • 486 16.1.1 malloc, free 함수 • 487 16.1.2 동적 할당 영역을 배열처럼 쓰기 • 491 16.1.3 기타 동적 할당 함수 • 493 연습문제 • 496

정답 및 해설 • 497

16.2 동적 할당 저장 공간의 활용 • 500 16.2.1 동적 할당을 사용한 문자열 처리 • 501 16.2.2 동적 할당 영역에 저장한 문자열을 함수로 처리하는 예 • 502 16.2.3 main 함수의 명령행 인수 사용 • 505 16.2.4 명령행 인수를 사용한 문자열 입력 예 • 508 연습문제 • 513 도전 실전 예제 • 517

24

정답 및 해설 • 514


17장 사용자 정의 자료형• 519 17.1 구조체 • 520 17.1.1 구조체 선언과 멤버 사용 • 521 17.1.2 다양한 구조체 멤버 • 524 17.1.3 구조체 변수의 초기화와 대입 연산 • 529 17.1.4 구조체 변수를 함수 매개변수에 사용하기 • 531 17.1.5 비트 필드 구조체 • 533 연습문제 • 537

정답 및 해설 • 539

17.2 구조체 활용, 공용체, 열거형 • 542 17.2.1 구조체 포인터와 -> 연산자 • 543 17.2.2 구조체 배열 • 545 17.2.3 구조체 배열을 처리하는 함수 • 547 17.2.4 자기 참조 구조체 • 549 17.2.5 공용체 • 552 17.2.6 열거형 • 554 17.2.7 typedef를 사용한 형 재정의 • 555 17.2.8 구조체, 공용체, 열거형을 사용한 프로그램 • 557 연습문제 • 560

정답 및 해설 • 564

도전 실전 예제 • 567

18장 파일 입출력• 571 18.1 파일 개방과 입출력 • 572 18.1.1 파일 개방과 폐쇄 • 573 18.1.2 스트림 파일과 파일 포인터 • 576 18.1.3 문자 입력 함수 fgetc • 579 18.1.4 문자 출력 함수 fputc • 582 18.1.5 기본적으로 개방되는 표준 입출력 스트림 파일 • 584 18.1.6 텍스트 파일과 바이너리 파일 • 588

25


18.1.7 + 개방 모드, fseek, rewind, feof 함수 • 591 연습문제 • 595

18.2 다양한 파일 입출력 함수

정답 및 해설 • 596 • 599

18.2.1 한 줄씩 입출력하는 fgets와 fputs • 600 18.2.2 다양한 형태로 입출력 하는 fscanf, fprintf • 604 18.2.3 스트림 파일의 버퍼 공유 문제와 fflush 함수 • 607 18.2.4 fread와 fwrite 함수 • 609 연습문제 • 613

정답 및 해설 • 615

도전 실전 예제 • 618

19장 전처리와 분할 컴파일 • 621 19.1 전처리 지시자 • 622 19.1.1 파일을 포함하는 #include • 623 19.1.2 매크로명을 만드는 #define • 626 19.1.3 #define을 사용한 매크로 함수 • 628 19.1.4 이미 정의된 매크로 • 631 19.1.5 매크로 연산자 #과 ## • 633 19.1.6 조건부 컴파일 지시자 • 634 19.1.7 #pragma 지시자 • 637 연습문제 • 639

정답 및 해설 • 642

19.2 분할 컴파일 • 644 19.2.1 분할 컴파일 방법 • 645 19.2.2 분할 컴파일에서 extern과 static의 용도 • 649 19.2.3 헤더 파일의 필요성과 중복 문제 해결 방법 • 653 연습문제 • 657 도전 실전 예제 • 662

26

정답 및 해설 • 660


부록 부록 A 아스키 코드표 • 665 부록 B 선택정렬 알고리즘 • 666 부록 C 날짜와 시간 함수, 난수 함수, 가변 인수 함수 • 672 부록 D C 표준 라이브러리 함수와 매크로• 678 부록 E 실전 프로젝트• 702

찾아보기 • 705

27


PART

1

C 언어 기본 두루미와 여우의 우화는 누구나 다 아실 겁니다. 물고기를 담기에는 호루병이, 스 프를 담기에는 접시가 알맞습니다. 실생황에서처럼 프로그램의 세계에게도 다양 한 무언가를 담을 그릇이 있어야 합니다. 프로그램 세계에서 물고기나 스프는 데 이터, 그릇은 변수입니다.


1

프로그램 만들기 사또~ 전국에 의적이

도대체 그 의적이

출몰하여 탐관오리를

누구란 말이냐?

벌 준다고 합니다.

조선조 세종 시절 서자로 태어난 길동은 '활빈당'을 자처하며 팔도 지방 수령들의 불의의 재물을 탈취하여 가난한 백성들에게 나누어 주었습니다. 길동은 자신이 다녀간 자리에 이름과 나이, 키, 혈액형을 남기며 자신을 쫓는 이들을 웃음거리로 만들었다고 합니다. 그 당시 메모를 남기는 프로그램이 있었다면 길동이 매일 밤 메모를 적는 수고는 덜 수 있지 않았을까요? 1.2 컴파일러 사용법 29

1장 프로그램 만들기

1장


1.1 프로그램과 C 언어 프로그램은 일의 순서를 말합니다. 예를 들어 옥수수로 팝콘을 만드는 과정을 나열하면 프로 그램이 됩니다. 팝콘을 만드는 과정은 다양한 방법으로 설명할 수 있는데 말이나 글로 표현할 수 있고 그림을 그리는 것도 가능합니다. 글로 표현한 프로그램

순서도로 표현한 프로그램 시작

1. 냄비를 준비한다. 2. 옥수수 알갱이를 냄비에 담는다.

냄비 준비

3. 버터와 소금을 넣는다. 4. 가열한다.

옥수수 알갱이 담기

5. 알갱이가 모두 터질 때까지 4번을 반복한다.

버터와 소금 넣기

6. 팝콘을 꺼낸다.

가열

No

알갱이가 모두 터졌나 Yes

팝콘을 꺼낸다

그러나 이러한 방법들은 컴퓨터가 이해하기 어렵고 명확하지 못한 표현이 많습니다. ‘짭조름하 게 소금을 넣는다’는 어느 정도의 소금을 넣는 것일까요? 따라서 컴퓨터 프로그램은 더 간결하 고 명확한 표현을 써야 하며 그 규칙을 정의해 놓은 것이 프로그래밍 언어입니다. 프로그래밍 언어는 용도에 따라 많은 종류가 있으며 C 언어도 그중에 하나입니다.

C 언어는 1972년 데니스 리치(Dennis Ritchie)가 유닉스(UNIX) 시스템에 사용하기 위해 켄 톰슨(Ken Thompson)이 만든 B 언어를 발전시킨 언어입니다. 1969년 개발된 초기 유닉스 30 1부 C 언어 기본


었습니다. 따라서 유닉스를 컴퓨터의 기종에 상관없이 개발하기 위해 C 언어를 만들게 됩니 다. C 언어는 운영체제(Operating System)를 개발할 목적으로 만든 언어이므로 하드웨어를 제어하는 시스템 프로그래밍이 가능합니다. 또한 기종이 다른 컴퓨터에도 사용할 수 있는 이 식성(portability)을 갖는 프로그램을 만들 수 있습니다. 무엇보다 함수를 사용하여 기능별로 프로그래밍이 가능하므로 개발 과정에서 에러를 수정하기 쉽고 개발된 후에도 프로그램의 유 지보수에 도움이 됩니다. 물론 잘 만들어진 함수는 새로운 프로그램의 개발에 재활용할 수 있 습니다. C 언어가 갖는 장점들을 충분히 활용하기 위해 필요한 전제조건은 표준을 지키는 것 입니다. 예를 들어 표준에 정의되지 않은 문법을 사용한 프로그램은 특정 컴파일러에서만 컴 파일될 가능성이 높으므로 이식성을 유지하기 힘듭니다. 여기서는 1999년에 제정된 C 언어의 국제 표준인 ISO/IEC 9899:1999(줄여서 C99)를 바탕으로 설명합니다. 따라서 표준에 따라 구현된 컴파일러라면 그 종류와 상관없이 이 책의 내용을 공부하고 실습하는 데 큰 문제가 없 습니다. 다만 모든 예제는 윈도우 7(64비트)에 Visual C++ Express 2013 컴파일러를 사용 하여 실행했음을 밝혀둡니다.

C 언어의 주요 연혁은 다음과 같습니다. • 1972년 데니스 리치와 켄 톰슨 C 개발 • 1989년 ANSI X3.159 -1989 표준 지정 - ANSI C • 1999년 ISO/IEC 9899 : 1999 표준 발표 - C99 • 2011년 ISO/IEC 9899 : 2011 표준 발표 - C11

C 언어의 개발자인 켄 톰슨과 데니스 리치(출처 : 위키피디아)

1.1 프로그램과 C 언어 31

1장 프로그램 만들기

는 대부분 어셈블리어로 작성되어 컴퓨터의 하드웨어가 바뀌면 새로 개발해야 하는 문제가 있


1.2 컴파일러 사용법 학.습.목.표

프로그래밍 언어를 배우는 가장 좋은 방법은 직접 만들어보는 것입니다. 따라서 C 언어를 배우기

전에 프로그램을 만드는 데 필요한 도구인 컴파일러의 사용법을 익히고 컴파일 과정을 연습하도록 합시다.

C 언어를 컴파일하면 기계어가 된다.

프로그램을 만드는 과정을 간단히 요약하면 다음과 같습니다. 소스 파일 작성 int main (void ) { … return 0 ; }

실행 파일 생성

컴파일

01100101010001 11010111010100 110101001

가장 먼저 할 일은 소스 파일(source file)을 만드는 것입니다. 소스 파일은 C 언어로 작성된 문서로 사람이 그 내용을 읽거나 수정할 수 있으나 컴퓨터로 실행하는 것은 불가능합니다. 컴 퓨터는 0과 1로 된 특별한 신호인 기계어만을 이해하기 때문입니다. 따라서 파일의 형태를 바 꾸는 과정이 필요합니다. C 언어로 된 소스 파일을 기계어로 바꾸는 과정이 컴파일입니다.

컴파일은 컴파일러라는 프로그램으로 수행하며 다양한 종류의 컴파일러가 있습니다. 여기에 서는 Visual Studio Express 2013 for Windows Desktop을 사용하며 편의상 VC++로 줄여서 쓰도록 하겠습니다. 해당 컴파일러는 2014년 현재 http://www.visualstudio.com/

downloads/에서 로그인하면 무료로 사용할 수 있습니다. 다만 앞으로 컴파일러의 이름이 바 뀌거나 제조사의 라이선스 정책에 따라 무료로 사용하지 못할 수도 있음을 미리 밝혀둡니다. 설치를 마쳤으면 이제 컴파일러를 사용하여 직접 프로그램을 만들어 봅시다.

32 1부 C 언어 기본


1장 프로그램 만들기

1.2.1 소스 파일(source file) 작성 VC++ 컴파일러를 설치하고 최초 실행하면 다음과 같은 화면을 볼 수 있습니다.

첫 번째 할 일은 프로젝트를 만드는 일입니다.

프로젝트는 프로그램을 만들기 위한 작업 공간을 확보하고 관련 파일들을 하나로 묶어주는 역 할을 합니다. 따라서 새로운 프로그램을 만들 때마다 항상 프로젝트부터 만들어야 합니다. 메 뉴에서 [파일] - [새로 만들기] - [프로젝트]를 선택합니다. ‘새 프로젝트’ 창이 열리면 왼쪽 템플릿에서 ‘Visual C++’를 클릭하고 ‘Win32 콘솔 응용 프로 그램’을 선택합니다. 이어서 프로젝트 이름을 입력하고 프로젝트 폴더를 만들 위치를 설정합니다. 위치는 기본적으 로 설정된 경로를 사용해도 되지만 기억하기 쉽도록 별도의 폴더를 만드는 것이 좋습니다. ‘찾 아보기’ 버튼을 클릭하여 폴더를 만들고 바꿉니다. 우측 하단의 ‘솔루션용 디렉터리 만들기’는 체크하지 않습니다. 이곳에 체크하면 프로젝트 폴더 위에 솔루션 폴더가 하나 더 만들어지므 로 폴더 구조가 복잡해집니다. 필자는 프로젝트 이름을 ‘first’로 위치는 ‘C:\shu’ 폴더를 만들 어 바꾸었습니다. ‘확인’ 버튼을 클릭하면 프로젝트의 설정 내용을 보여주는 창이 나오는데 ‘다 음’ 버튼을 클릭하여 넘깁니다.

1.2 컴파일러 사용법 33


여기 선택

프로젝트 이름 입력 체크하지 않음

프로젝트 폴더 위치 설정

이어서 Win32 응용 프로그램 마법사 창이 나오면 ‘콘솔 응용 프로그램’을 선택하고 ‘빈 프로젝 트’에 체크합니다. 반면에 ‘SDL 검사’에는 체크하지 않습니다. 이곳에 체크하면 일부 경고 메 시지가 에러 메시지로 처리되어 컴파일 과정이 설명과 다를 수 있습니다. 설정이 끝나면 ‘마침’ 버튼을 누릅니다.

34 1부 C 언어 기본


있습니다. 여기까지가 프로젝트를 만드는 과정입니다.

솔루션 탐색기

다음은 프로젝트에 소스 파일을 추가할 차례입니다.

솔루션 탐색기의 항목 중에 ‘소스 파일’을 마우스 오른쪽 버튼으로 클릭하고 [추가] – [새 항 목]을 선택합니다.

1.2 컴파일러 사용법 35

1장 프로그램 만들기

프로젝트 생성이 끝나면 오른쪽 솔루션 탐색기에서 ‘first’ 프로젝트가 생성되었음을 확인할 수


새 항목 추가 창이 나오면 ‘C++ 파일 (.cpp)’항목을 선택하고 이름 칸에 파일명을 넣습니다. 파일명은 확장자를 ‘.c’로 해서 작성합니다. 확장자 없이 이름을 입력하면 자동으로 cpp가 붙는 데 이 경우 C++문법이 적용되어 프로그램에 따라 실행 결과가 책과 다를 수 있습니다. 파일이 저장될 위치는 프로젝트 폴더로 자동 설정됩니다. 입력이 끝나면 ‘추가’ 버튼을 클릭합니다.

여기 선택

파일명 입력

그림 오른쪽의 솔루션 탐색기 창을 보면 소스 파일 항목에 ‘main.c’ 소스 파일이 추가된 것을 확인할 수 있습니다. 또한 문서를 작성할 수 있는 편집창이 열리고 커서를 깜박이며 입력을 기 다립니다.

편집 공간 소스 파일 추가

36 1부 C 언어 기본


해 넣은 것이므로 실제 코드에는 포함되지 않습니다. 예제 1-1 “Be happy!”를 화면에 출력하는 프로그램

1. #include <stdio.h> 2. 3. int main(void) 4. { 5. printf("Be happy!"); 6 7. return 0; 8. }

지금은 컴파일러의 사용법을 익히는 과정이므로 당장 프로그램의 내용에 대해 궁금해할 필요 는 없습니다. 다만 오타가 나면 컴파일 과정에서 에러가 발생하므로 주의하여 입력합시다. 모 두 입력한 후에 저장하면 프로젝트 폴더에 저장됩니다. 여기까지가 소스 파일을 작성하는 단 계입니다. 소스 파일을 메모장으로 작성할 수 있나요?

소스 파일은 형태가 텍스트 파일이므로 메모장으로 작성하는 것도 가능합니다. 또는 전문 편 집기나 일반 워드 프로그램을 사용할 수도 있습니다. 어떤 편집기를 사용하던 파일의 형태 를 텍스트 파일로 저장하면 됩니다. 텍스트 파일은 아스키 코드(ASCII, American Standard

Code for Information Interchange)값으로 저장된 파일이며, 아스키 코드는 사람이 사용하 는 기호를 컴퓨터 안에서 표현하는 방법을 약속한 것입니다. 예를 들어 소스 파일에 A라는 문 자를 사용하면 컴퓨터는 8개의 비트를 01000001과 같은 상태로 저장합니다. 또한 컴퓨터에

01000001과 같은 비트 열이 있으면 모니터는 화면에 A라는 문자를 보여줍니다. 결국 사람은 키보드로 문자를 입력하고 모니터로 확인하지만 컴퓨터 안에서는 약속된 비트 상태로 저장하 고 처리됩니다.

A 01000001

1.2 컴파일러 사용법 37

1장 프로그램 만들기

여기에 다음과 같이 소스 파일을 만듭니다. 소스코드의 왼쪽에 있는 번호는 설명의 편의를 위


아스키 코드는 컴퓨터에서 필요한 128개의 문자를 코드화했으며 여기에는 영문 대문자, 소문 자, 아라비아 숫자, 특수 문자, 제어 문자 등이 포함됩니다. C 언어는 아스키 코드값을 프로그 램에 직접 사용하기도 하므로 필요할 때는 부록 A에 있는 아스키 코드표를 참고합시다.

1.2.2 컴파일 이제 컴파일러가 제 역할을 할 단계입니다. 소스 파일을 컴파일하여 실행 파일을 만듭니다.

메뉴에서 [빌드] – [솔루션 빌드]를 선택하여 컴파일합니다. 단축키는 Ctrl+ Shift+ B를 사용 하며 컴파일러 버전에 따라 ‘빌드’ 메뉴 항목이 보이지 않으면 [도구] – [설정] – [전문가 설 정]으로 메뉴 설정을 바꿉니다.

성공적으로 컴파일하면 아랫부분의 출력 창에 메시지로 알려줍니다. 컴파일에 실패하면 에러 메시지를 표시합니다. 예를 들어 5행 끝에 있는 세미콜론을 빠뜨리고 컴파일하면 다음 그림의 메시지 창에서와 같은 에러 메시지를 보게 됩니다.

38 1부 C 언어 기본


1장 프로그램 만들기

에러 위치 표시 에러 메시지

이 경우 컴파일이 계속 진행되지 않으므로 에러를 수정해야 합니다. 에러를 수정하는 것을 디 버깅(debugging)이라고 하며 에러의 위치를 찾는 방법은 간단합니다. 에러 메시지를 더블클 릭하면 소스코드에 문제가 있는 부분을 표시합니다. 단, 컴파일러가 표시하는 위치와 에러가 발생한 곳이 정확히 일치하지 않을 수 있습니다. 즉, 그림에서는 return 0; 문장의 왼쪽에 표 시가 있지만 그 윗줄인 printf(“Be happy”)의 끝에 세미콜론(;)이 생략되어 다음 줄까지 한 문 장으로 해석하므로 다음 줄에 에러를 표시합니다. 여기까지 에러 없이 무사히 왔다면 첫 번째 프로그램을 완성한 것입니다. 컴파일 과정을 좀 더 자세히 살펴보면 3단계로 나눠집니다.

VC++ 컴파일러를 사용하면 메뉴 선택을 통해 쉽게 컴파일할 수 있지만 사실 컴파일 과정은 ‘전처리(preprocess) – 컴파일(compile) – 링크(link)’의 세 단계로 나눠집니다. 소스 파일

전처리

전처리된 소스 파일

컴파일

링크 개체 파일

실행 파일

startup code

전처리 과정은 전처리 지시자에 따라 소스 파일을 가공하는 과정으로 구체적인 내용은 19장 에서 다룹니다. 이 과정은 단지 소스 파일을 편집하는 것이므로 전처리가 끝나도 파일의 형태 1.2 컴파일러 사용법 39


에는 변함이 없습니다. 전처리가 끝난 파일을 컴파일하면 개체 파일(object file)이 됩니다. 개 체 파일은 CPU가 해석할 수 있는 명령어(instruction)들로 이루어진 기계어 파일이지만 바 로 실행하는 것은 불가능합니다. 프로그램은 운영체제(Operating System)에 의해서 실행되 므로 설치된 운영체제가 인식할 수 있는 형태로 바꿔야 하기 때문입니다. 따라서 개체 파일에 ‘startup code’를 결합하는 과정을 수행하는데 이 과정을 ‘링크(link)’라고 합니다.

1.2.3 실행 남은 일은 완성된 프로그램을 실행하는 것입니다.

VC++컴파일러에서 Ctrl + F5를 누르면 실행하여 결과를 확인할 수 있습니다.

결과는 “Be happy!”입니다. ‘계속하려면 아무 키나 누르십시오...’는 출력 창을 닫는 방법을 안 내하는 메시지입니다. 메뉴로 실행할 때는 ‘디버그’ 메뉴의 ‘디버깅하지 않고 시작’ 서브메뉴를 선택합니다. 컴파일러에서 직접 실행하면 결과를 바로 확인할 수 있고 프로그램을 수정하거나 다시 컴파일 하는 작업들이 편리합니다. 그러나 기본적인 실행 방법은 실행 파일을 찾아서 더블클릭하는 것입니다. 소스 파일을 컴파일하면 프로젝트 폴더에 Debug 폴더가 생기는데 그 안에 프로젝 트명과 같은 이름으로 실행 파일이 저장됩니다. 그 위치를 찾아 직접 실행할 수 있습니다.

40 1부 C 언어 기본


도 창이 곧바로 사라지지 않았으면 좋겠습니다. 그렇다면 소스 파일에 다음과 같이 두 줄을 추 가한 후에 다시 컴파일합시다. 예제 1-2 출력 결과를 확인하는 프로그램

1. #include <stdio.h> 2. #include <stdlib.h> 3. 4. int main(void) 5. { 6. printf("Be happy!"); 7. system("pause"); . 8 9. return 0; 10. }

여기

여기

2행에서 사용한 # include는 지정한 파일을 추가하는 지시자입니다. 자세한 사항은 19.1.1절 에서 다룹니다. 7행에서 사용한 system은 시스템 명령을 수행하는 함수입니다. 큰따옴표 안 에 시스템에서 지원하는 명령을 쓰면 그대로 실행됩니다. 시스템 명령은 운영체제마다 다르고 이 책의 범위를 벗어나기 때문에 더 자세히 다루지는 않습니다. 기본적인 설명은 부록 C [표

C-4]에서 확인할 수 있습니다. 그 후에 실행 파일을 찾아 더블클릭하면 컴파일러에서 실행한 것처럼 창을 띄운 상태에서 결 과를 확인할 수 있습니다.

마무리 지금까지 컴파일러의 사용법과 컴파일 과정을 살펴보았습니다. 복잡해 보이지만 프로그래밍 연습을 하다보면 자연스럽게 익숙해집니다. 프로그램을 직접 작성하고 실행시켜보는 것이 C 언어를 배우는 지름길입니다. 앞으로 나오는 예제들은 직접 컴파일하고 실행시켜보는 것이 좋 습니다. 그러기 위해 컴파일러의 사용법을 정확히 배워둡시다.

1.2 컴파일러 사용법 41

1장 프로그램 만들기

이 경우 실행된 후에 결과 창이 순식간에 닫히므로 눈으로 확인하기가 힘듭니다. 실행된 후에


1 다음 단어들을 컴파일 과정에 맞게 나열하시오.

① 링크

② 전처리 ③ 소스 파일 작성 ④ 컴파일

2 다음 중에서 보기의 설명과 일치하는 것을 찾아봅시다.

아스키 코드

기계어

링크

개체 파일

① 컴퓨터가 바로 이해할 수 있는 언어로 0과 1로 기호화하여 표현하는 언어 ② 소스 파일이 컴파일된 후에 생성되는 파일로 바로 실행시킬 수 없는 파일 ③ 사람이 사용하는 기호를 컴퓨터 안에서 표현하는 방법 ④ 개체 파일에 startup code를 붙여 실행 파일을 만드는 과정

1 정답 : ③  ②  ④  ① 2 ① 기계어

② 개체 파일

③ 아스키 코드 ④ 링크

42 1부 C 언어 기본


2

2장 2절

상수와 데이터 출력

중국 후한 승상 제갈량은 비장한 각오로 황제 유선에게 출정의 뜻을 밝힌 상소문 을 씁니다. ‘신 량이 아뢰옵니다’로 시작하는 이 글은 한의 충신이라면 읽고 눈물 을 흘리지 않는 사람이 없었다고 합니다. 당시에는 지필묵을 사용해서 출사표라 불리는 이 글을 정성스레 적어 내려갔을 텐데요, 프로그래머라면 printf 함수로 훨씬 빠른 속도로 출력할 수 있을 겁니다. 1.2 컴파일러 사용법 43

1장 프로그램 만들기

2장 1절


2.1 C 프로그램의 기본 형태와

데이터 출력 방법

학.습.목.표

프로그래밍 언어는 약속된 규칙이므로 C 프로그램이 지켜야 할 기본 형식을 살펴보고 C 프로그램

의 실행 결과를 화면으로 확인할 수 있도록 출력 함수의 사용법도 살펴봅니다. 1 main 함수 하나만으로 프로그램을 만들 수 있다. 2 문장의 끝은 세미콜론(;)으로 표시하며 한 줄에 한 문장씩 작성하는 것이 좋다. 3 //는 한 줄 주석문이고 /* * /는 여러 줄을 한꺼번에 주석처리할 수 있다. 4 printf 함수는 데이터를 콘솔 화면에 출력할 때 사용한다.

C 프로그램은 main 함수로 시작한다.

표 2-1 printf 함수의 사용법 출력 데이터

사용 예

출력 결과

문자열

printf ( "Be happy!") ;

화면에 "Be happy!" 출력

제어 문자

printf ( "Be happy!\n") ;

"Be happy!" 출력 후 줄 바꿈

정수

printf ( "% d", 10) ;

화면에 정수 "10" 출력

실수

printf ( "% lf", 3.5) ;

화면에 실수 "3.500000" 출력

수식

printf ( "% d", 10 + 20) ;

10과 20을 더한 결과인 "30" 출력

2.1.1 main 함수 구조 C 프로그램은 함수들로 만듭니다. 함수는 일정한 기능을 수행하는 코드 단위로 보통은 많은 함수가 사용되지만 간단한 프로그램은 main 함수 하나만으로 만들기도 합니다. main 함수는 프로그램이 시작되는 곳으로 프로그램에 반드시 있어야 합니다.

간단한 예제를 통해 프로그램의 구조를 더 자세히 살펴봅시다. 44 1부 C 언어 기본


예제 2-1 상수값을 더하는 프로그램

2장 상수와 데이터 출력

1. /* 작성자 : 홍길동 제목 : 10과 20을 더하는 프로그램 * / 2. 3. 4. int main(void) 5. { // 10과 20을 더한다. 6. 10 + 20; 7. 8. return 0; // 프로그램 종료 . } 9

4행부터 9행까지가 main 함수며 머리(head)와 몸체(body)로 구성됩니다. 머리

int main(void) {

몸체 실행코드

return 0; }

머리는 함수 원형(funtion prototype)이라고 하며 함수의 이름과 필요한 데이터 등을 표시합 니다. 함수에서 실행할 일들은 몸체의 중괄호 안에 작성하며 필요에 따라 7행과 같이 한 행을 비워 보기 좋게 할 수도 있습니다. 몸체의 마지막에는 return 0;를 넣어 프로그램을 끝냅니다. 함수는 7장에서 자세히 다루므로 당장 함수에 대해 이해할 필요는 없습니다. main 함수의 형 태를 기억해두었다가 그대로 사용하는 것으로 충분합니다.

1행과 2행은 주석문입니다. 주석문은 소스코드를 설명하는 내용을 담게 되는데 두 가지 형태 가 있습니다. ‘/ * ’ 와 ‘ * /’ 사이의 모든 내용은 주석처리되고 ‘//’ 이후 해당 줄의 끝까지 주석처리됩니다.

따라서 1행과 2행은 모두 주석문이고 6, 8행은 // 이후 그 줄의 끝까지 주석문입니다. /* * / 는 보통 여러 행을 한 번에 주석처리할 때 사용하지만 행의 중간 부분을 주석처리할 때도 쓰 입니다. 예를 들어 6행에 다음과 같이 주석을 넣을 수 있습니다.

2.1 C 프로그램의 기본 형태와 데이터 출력 방법 45


10 /* 정수형 상수 */ + 20 /* 정수형 상수 */ ;

주석문은 전처리 단계에서 모두 제거되므로 컴파일러에 의해 번역되지 않습니다. 단지 사람이 읽고 수정하기 쉽도록 설명하는 것이므로 자세히 넣는 것이 좋습니다. 나머지는 main 함수의 형태를 그대로 사용하였고 단지 6행에 문장을 추가하였습니다. 6행은 10과 20을 더하는 문장 이며 문장을 마칠 때는 다음과 같은 규칙이 있습니다. 세미콜론(;)을 사용하여 문장의 끝을 표시합니다.

만약 6행의 끝에 세미콜론이 없으면 컴파일러는 8행까지를 한 문장으로 인식하므로 에러를 표 시하게 됩니다. 컴파일러는 세미콜론으로 문장을 구분하므로 한 줄에 여러 문장을 작성하거나 한 문장을 여러 줄에 작성하는 것도 가능합니다. 그러나 다음 관례를 따르는 것이 보기 좋고 읽기도 쉽습니다. 한 줄에 한 문장씩 작성하고 일정한 간격으로 들여씁니다.

들여쓰는 칸 수는 정해져 있지 않으므로 적당한 간격을 띄우면 됩니다. VC++는 기본적으로

4칸 자동 들여쓰기를 해주며 이 책의 모든 예제는 4칸 들여쓰기하여 작성합니다. 예제를 컴파 일하고 실행하면 결과로 아무것도 확인할 수 없습니다. 단지 10과 20을 더할 뿐 그 결과를 어 떻게 하라는 명령이 없기 때문입니다. 연산 결과를 화면으로 확인하려면 출력을 담당하는 함 수를 사용해야 합니다.

2.1.2 출력 함수(printf)의 사용법 화면에 데이터를 출력할 때는 다음 원형을 갖는 printf 함수를 사용합니다. int printf(const char *format, ...)

main 함수에서 printf 함수를 호출하면 여러 형태의 값을 출력할 수 있으며 기본 기능은 다음 과 같습니다. printf 함수는 문자열을 화면에 출력합니다.

46 1부 C 언어 기본


함수명

printf ( "Be happy" ) ;

"Be happy"를 화면에 출력

출력할 문자열 2장 상수와 데이터 출력

예제를 통해 사용 결과를 확인해봅시다. 예제 2-2 문자열을 화면에 출력하는 프로그램

1. #include <stdio.h> 2. 3. int main(void) 4. { 5. printf("Be happy"); 6. printf("My friend"); 7. 8. return 0; 9. }

// 문자열 "Be happy" 출력 // 문자열 "My friend" 출력

Be happyMy friend

1행은 전처리 단계에서 처리되는 문장으로 stdio.h 파일의 내용을 프로그램 안에 복사합니다. printf 함수가 stdio.h 파일에 있으니 그 기능을 사용하기 위해 프로그램 안으로 가져오는 것 으로 생각하면 됩니다(자세한 내용은 19장에서 설명합니다). 출력 문장은 5행과 6행 두 줄에 작성했으나 화면에는 한 줄로 출력됩니다.

2.1.3 printf 함수로 제어 문자 출력 제어 문자는 일반 문자와 구분하기 위해 백슬래시(\, 키보드에서 ₩)와 함께 사용합니다. 표 2-2 제어 문자의 종류 제어 문자

의미

기능

\n

개행( new line)

줄을 바꾼다.

\t

탭( tab)

출력 위치를 다음 탭( tab) 위치로 옮긴다.

\r

캐리지 리턴( carriage return)

출력 위치를 줄의 맨 앞으로 옮긴다.

2.1 C 프로그램의 기본 형태와 데이터 출력 방법 47


\b

백스페이스( back space)

출력 위치를 한 칸 왼쪽으로 옮긴다.

\a

알럿( alert)

경보 벨( bell) 소리를 낸다.

제어 문자를 문자열 안에 포함시키면 그 기능에 따라 출력 형태가 바뀝니다.

예제 2-3 제어 문자를 사용한 출력

1. #include <stdio.h> 2. 3. int main(void) 4. { 5. printf("12345678901234567890\n"); // 화면에 칸 번호 출력 // "Be happy"를 출력하고 줄을 바꿈 6. printf("Be happy\n"); . (" \ \ "); // "My"를 출력하고 탭 위치로 이동 후에 "friend" 출력 7 printf My tfriend n 8. printf("Goot\bd\tchance\n"); // t를 d로 바꾸고 탭 위치로 이동 후에 "chance" 출력 // C를 W로 바꾸고 벨 소리를 낸다. 9. printf("Cow\rW\a\n"); 10. 11. return 0; 12. }

5행은 화면의 열 번호를 확인하기 위해 출력한 것입니다. 7행은 “My”를 출력하고 제어 문자 ‘\t’에 의해 커서가 다음 탭 위치로 이동합니다. 모니터 화면은 8칸씩 나누어 각 영역의 첫 번째 열에 탭 위치가 설정되어 있으므로 “My”를 출력한 후에 커서는 두 번째 탭 위치인 9번 열로 이 동합니다. 이어서 “friend”가 출력되고 마지막으로 제어 문자 ‘\n’에 의해 줄이 바뀝니다. ‘\t’ 는 현재의 커서 위치에서 다음 탭 위치로 이동하는 것이므로 커서가 1번에서 8번 사이에 있다 면 모두 다음 탭 위치인 9번으로 이동합니다. 따라서 열을 맞춰 출력할 때 사용하면 좋습니다. 탭 위치

1234567890123456789012345678901234567890 My

48 1부 C 언어 기본

f r i end


8행은 “Goot”가 출력된 후에 ‘\b’에 의해 커서가 한 칸 왼쪽으로 이동합니다. 그리고 d를 출력 하면 t가 d로 바뀌어 “Good”이 출력된 상태가 됩니다. 이어서 ‘\t’에 의해 다음 탭 위치인 9번 으로 이동하고 “chance”가 출력되고 줄이 바뀝니다. 2장 상수와 데이터 출력

왼쪽으로 한 칸 이동 "Goot\bd\tchance\n" 다음 탭 위치로 이동

줄 바꿈

9행은 “Cow”가 출력되고 ‘\r’에 의해 커서가 첫 번째 칸으로 이동합니다. 그 자리에 W를 출력 하면 C가 W로 바뀝니다. 그리고 ‘\a’에 의해 벨 소리를 내고 줄이 바뀝니다. 맨 앞 칸으로 이동 "Cow\rW\a \n" 벨 소리를 낸다

줄 바꿈

2.1.4 printf 함수로 정수와 실수 출력 printf 함수는 기본적으로 문자열을 출력하는 함수이므로 숫자를 출력할 때는 문자열로 변환 하는 과정이 필요합니다. 변환 방법은 데이터의 형태에 따라 다릅니다. 정수는 % d, 실수는 % lf(엘 에프)를 사용하여 출력합니다.

예제 2-4 정수와 실수의 출력

1. #include <stdio.h> 2. 3. int main(void) 4. { // % d 위치에 10 출력 5. printf("% d\n", 10); // % lf 위치에 3.4를 소수점 이하 6자리까지 출력 6. printf("% lf\n", 3.4); 7. printf("%.1lf\n", 3.45); // 소수점 이하 첫째 자리까지 출력 8. printf("%.10lf\n", 3.4); // 소수점 이하 10자리까지 출력 9. 10. printf("% d과 % d의 합은 % d입니다.\n", 10, 20, 10 + 20);

2.1 C 프로그램의 기본 형태와 데이터 출력 방법 49


11. 12. 13. 14. }

printf("%.1lf - %.1lf = %.1lf\n", 3.4, 1.2, 3.4 - 1.2); return 0;

10 3.400000 3.5 3.4000000000 10과 20의 합은 30입니다. 3.4 - 1.2 = 2.2

숫자를 출력할 때는 괄호 안에 변환문자열과 숫자를 콤마로 구분하여 사용하며 숫자는 변환문 자열의 위치에 출력됩니다. printf(" % d\n", 10); 10이 % d 위치에 출력된다.

printf(" % lf\n", 3.4); 3.4가 % lf 위치에 출력된다.

실수는 기본적으로 소수점 이하 6자리까지 출력되며 소수점의 자릿수를 바꿀 때는 8행에서처 럼 %와 lf 사이에 소수점을 찍고 자릿수를 지정합니다. 잘리는 값은 반올림하여 출력됩니다.

10행과 11행은 문자열과 변환문자열, 제어 문자 등이 함께 사용되고 여러 개의 값을 한꺼번에 출력하는 경우입니다. 이때 변환문자열의 개수와 출력할 값의 개수가 일치해야 하며 앞에서부 터 차례로 출력됩니다. printf(" % d과 % d의 합은 % d입니다.\n", 10, 20, 10 + 20);

printf 함수의 기본 출력 기능은 여기까지 설명합니다. 그 밖의 기능은 필요한 곳에서 추가로 설명합니다.

50 1부 C 언어 기본


마무리 지금까지 C 프로그램의 형태를 살펴보고 값이나 연산 결과를 화면으로 출력하는 방법에 대해

머릿속에 충분히 들어왔는지 연습문제를 통해 확인해봅시다.

1 다음 중 설명이 옳지 못한 것을 고릅니다.

① 프로그램에는 하나의 main 함수가 있어야 한다. ② 세미콜론으로 구분하기만 하면 한 줄에 여러 문장을 작성할 수 있다. ③ / * * / 주석문과 달리 // 주석문은 main 함수 안에서만 사용할 수 있다. ④ printf 함수는 문자열 이외에 정수나 실수도 출력할 수 있다.

2 프로그램의 실행 결과가 다음과 같도록 빈칸을 채웁니다. #include <stdio.h>

int main(void) {

printf("

로 나누면

입니다.", 1, 2, 0.5);

return 0; }

1을 2로 나누면 0.500000입니다.

3 다음 프로그램의 출력 결과를 적어봅시다. #include <stdio.h>

int main(void) { /*

printf("Hello world!\n"); */

printf("Be\rHappy!\nBaby"); return 0; }

2.1 C 프로그램의 기본 형태와 데이터 출력 방법 51

2장 상수와 데이터 출력

배웠습니다. C 언어의 가장 기본을 살펴본 것이지만 무엇보다 중요한 과정이라 생각합니다.


1 정답 : ③

주석문은 함수와 관계없이 소스코드 어디서나 사용할 수 있습니다.

2 정답 : ➊ % d 3

➋ %d

➌ % lf

Happy! Baby

printf (" Hello world ! \ n" ) ; 문장은 주석기호 / * * / 안에 있으므로 주석문이 됩니다. Be가 출력된 후에 \r에 의해 커서가 B의 위치로 이동하여 Happy!가 출력되므로 Be가 지워집니다. 그 후에 \n에 의해 줄이 바뀌고 Baby가 출력됩니다.

52 1부 C 언어 기본


데이터 표현 방법

학.습.목.표

C 언어는 메모리에 직접 접근하거나 비트 단위의 연산을 수행하여 데이터를 효율적으로 처리할 수

있습니다. 이런 장점을 잘 활용하려면 데이터가 메모리에 저장되는 방식을 알아야 합니다. 이 절에서는 정수, 실 수, 문자가 컴파일된 후에 어떤 형태로 바뀌는지 살펴봅니다.

1 상수는 그 값을 바꿀 수 없다. 2 10은 정수 상수, 10.0은 실수 상수, 'a'는 문자 상수, "a"는 문자열 상수다. 3 양수는 4바이트 크기의 2진수로, 음수는 2의 보수로 번역된다. 4 실수는 IEEE 754 표준의 double 형식에 따라 번역된다.

모든 데이터는 컴퓨터 안에서 0과 1의 비트열로 바뀐다.

함수는 일의 순서를 적은 것이며 데이터는 함수가 처리하는 대상입니다. C 언어에서 다루는 데이터는 정수, 실수, 문자, 문자열이 있는데 그 값이 바뀌지 않는 데이터를 상수(constant)라 고 합니다. 상수는 값이 변하면 위험한 경우에 주로 사용합니다. 표 2-3 상수 종류 종류

표현 방법

사용 예

정수

0~9, + , - 기호 사용

10, - 5, + 20, 0

실수

0~9, + , -, . ( 소수점) 기호 사용

3.4, -1.7, .5, 10.0

문자

문자를 작은 따옴표로 묶음

'A', 'b', '0', ' * ',

문자열

하나 이상의 문자를 큰 따옴표로 묶음

"A", "banana"

2.2.1 정수 상수 표현법 상수에는 정수, 실수, 문자, 문자열이 있는데 우선 정수의 사용 규칙은 다음과 같습니다.

2.2 상수와 데이터 표현 방법 53

2장 상수와 데이터 출력

2.2 상수와


정수는 10진수, 8진수, 16진수로 쓸 수 있습니다.

즉, 같은 값을 진법에 따라 세 가지로 표현할 수 있습니다. 예제를 통해 확인해봅시다. 예제 2-5 세 가지 진법의 정수형 상수

1. #include <stdio.h> 2. 3. int main(void) 4. { 5. printf("% d\n", 12); . 6 printf("% d\n", 014); 7. printf("% d\n", 0xc); 8. 9. return 0; 10. }

// 10진수 정수형 상수 출력 // 8진수 정수형 상수 출력 // 16진수 정수형 상수 출력

12 12 12

정수는 아라비아 숫자 0~9, ‘+’, ‘-’ 기호를 사용하며 세 가지 진법으로 표현할 수 있습니다. 5 행의 12를 포함하여 10, + 20, -5, 0 등은 모두 10진법으로 표현된 정수형 상수입니다. 8진 수는 10진수와 구분하기 위해 숫자 앞에 0(영)을 붙이며 16진수는 0x(영엑스)를 붙여 사용합 니다. 결국 다음 세 개의 값은 진법에 따라 다르게 표현한 것일 뿐 모두 같은 값입니다. 10진수

8진수

16진수

12

014

0xc

진법은 수를 표현하는 방법입니다.

10진법은 0~9까지 10가지 숫자를 사용하고 8진법은 0~7까지 8가지 숫자를 사용합니다. 8진 수는 단위 숫자의 개수가 적으므로 8을 8진수로 표현하면 자리수가 올라가서 10(일영)이 됩니 다. 반면에 16진수는 아라비아 숫자 0~9의 10개와 영문자 a~f의 6개를 더하여 총 16개의 단위 숫자를 사용합니다. 따라서 0~15까지를 하나의 단위 숫자로 표현할 수 있습니다. 10진수 상수

1~15까지를 진법에 맞게 표로 정리하면 다음과 같습니다. 2진수 표기법은 값이 컴퓨터 안에서 저장되는 상태를 표현하기 위해 추가한 것이며 C 언어는 2진수 상수를 사용하지 않습니다. 54 1부 C 언어 기본


표 2-4 진법별 수의 표현 방법 8진수

16진수

2진수

0

00

0x0

0000

1

01

0x1

0001

2

02

0x2

0010

3

03

0x3

0011

4

04

0x4

0100

5

05

0x5

0101

6

06

0x6

0110

7

07

0x7

0111

8

010

0x8

1000

9

011

0x9

1001

10

012

0xa

1010

11

013

0xb

1011

12

014

0xc

1100

13

015

0xd

1101

14

016

0xe

1110

15

017

0xf

1111

2장 상수와 데이터 출력

10진수

2.2.2 실수 상수 표현법 실수는 소수점 형태와 지수 형태로 표현합니다.

실수는 아라비아 숫자 0~9, ‘+’, ‘-’ 기호와 소수점을 사용하여 표현합니다. 예를 들어 3.4, -1.5, + 10.0과 같이 사용할 수 있고 .5나 -10.과 같이 소수점 앞이나 뒤의 무의미한 0은 생 략할 수 있습니다. 소수점 형태는 값이 아주 크거나 작은 경우 사용하기 불편합니다. 이 경우 지수 형태로 사용할 수도 있습니다. 지수 형태를 사용한 예를 살펴봅시다. 예제 2-6 지수 형태의 실수형 상수

1. #include <stdio.h> 2.

2.2 상수와 데이터 표현 방법 55


3. int 4. { 5. 6. 7. 8. 9. }

main(void) // 지수 형태의 실수를 소수점 형태로 출력 printf("%.1lf\n", 1e6); printf("%.7lf\n", 3.14e - 5); // 소수점 이하 7자리까지 출력

return 0;

1000000.0 0.0000314

5행의 1e6은 실수형 상수 1000000.0을 지수 형태로 표현한 것입니다. 소수점 형태를 지수 형 태로 바꾸는 방법은 다음과 같습니다. 밑수

1000000.0

1.0 X 10

6

1.0 e 6 소수점 지수

소수점 형태를 과학적 표기법으로 바꾸었을 때 소수점 부분과 지수 부분을 영문자 e와 함께 사 용합니다. e는 밑수 10을 의미하며 대문자로 쓸 수도 있습니다. 소수점 부분에서 무의미한 0 이나 소수점은 생략할 수 있으며 지수 부분에는 소수점을 사용할 수 없습니다. 지수형태는 지 수값의 크기에 따라 무수히 많은 표현 방법이 가능합니다. 그중에 소수점 앞에 0이 아닌 한 자 리만을 사용하여 지수 형태로 바꾼 것을 특히 정규화(normalization) 표현식이라고 합니다. 소수점 형태

0.0000314

같은 값을 표현한 다양한 지수 형태

3.14e-5

0.0314e-3

0.00000314e1

314e-7

정규화

실행 결과에서 알 수 있듯이 출력값을 지수 형태로 사용해도 printf 함수는 기본적으로 소수점 형태로 출력합니다. 따라서 6행과 같이 값이 작은 경우는 소수점 이하 자릿수를 충분히 잡아 서 유효숫자가 잘리지 않도록 해야 합니다. 3.14e-5는 소수점 형태로 0.0000314이므로 기본 출력 방식을 따르면 소수점 이하 6자리까지만 출력되어 0.000031가 출력됩니다.

56 1부 C 언어 기본


2.2.3 문자와 문자열 상수 표현법 문자는 작은 따옴표로 묶고 문자열은 큰 따옴표로 묶습니다.

예제 2-7 문자와 문자열 데이터의 출력

1. #include <stdio.h> 2. 3. int main(void) 4. { // 문자 상수 출력 5. printf("% c\n", 'A'); // 문자열 상수 출력 6. printf("% s\n", "A"); 7. printf("% c은 % s입니다.\n", '1', "first"); // 문자와 문자열을 함께 출력 8. 9. return 0; 10. } A A 1은 first입니다.

7행에서 ‘1’은 문자 상수이고 “first”는 문자열 상수입니다. 문자와 문자열을 구분하는 것은 문 자의 수가 아니고 따옴표의 종류입니다. 즉, 6행의 “A”와 같이 하나의 문자라도 큰따옴표가 붙 으면 문자열 상수가 됩니다. 문자 상수

'A'

문자열 상수 "A"

문자를 출력할 때는 % c 변환문자열을 사용합니다. 문자열은 변환문자열 없이 바로 출력할 수 도 있으나 변환문자열이 필요한 경우는 % s를 사용합니다.

2.2 상수와 데이터 표현 방법 57

2장 상수와 데이터 출력

예제를 통해 사용법을 살펴봅시다.


2.2.4 상수가 컴파일된 후의 비트 형태 소스코드는 편집기에서 입력한 문자들이 모두 아스키 코드값으로 저장됩니다. 예를 들어

10+ 20;과 같은 문장을 사용했다면 ‘1’, ‘0’, ‘+’, ‘2’, ‘0’, ‘;’이 모두 하나의 문자로서 저장됩니 다. 소스코드가 CPU에 의해 실행될 수 없는 이유도 +는 ‘덧셈을 하라’는 명령이 아니라 단지 문자일뿐이며 10과 20도 연산이 가능한 값이 아니기 때문입니다. 따라서 컴파일러는 컴파일 할 때 연산자를 명령어로 바꾸고 상수들은 연산이 가능한 형태로 바꾸는데 이때 상수의 종류 에 따라 각각 다른 형태로 바꿉니다. 표 2-5 상수의 번역 형태 상수 종류

크기(byte)

바뀌는 형태

정수

4

2진수

실수

8

IEEE 754 표준 double형

문자

4

아스키 코드값과 같은 2진수

예를 들어 정수형 상수 10과 실수형 상수 10.0은 각각 다음과 같은 형태로 번역됩니다. • 10 : 00000000 00000000 00000000 00001010 • 10.0 : 01000000 00100100 00000000 00000000 00000000 00000000 00000000 00000000

수학적으로 10과 10.0은 같은 값이지만 컴퓨터는 처리하는 방식이 다르므로 어떤 상수를 쓰 느냐에 따라 실행 속도나 정확도에 차이가 날 수 있습니다. 정수는 가장 빠르고 정확하게 연산 될 수 있는 형태로 번역되므로 프로그래밍할 때 가능하면 정수형 상수를 사용하는 것이 좋습 니다. 문자 상수는 그 아스키 코드값이 2진수 형태로 번역됩니다. 즉, ‘A’는 아스키 코드값이

65이므로 정수형 상수 65와 같은 형태로 번역됩니다. • 65 : 00000000 00000000 00000000 01000001 • 'A' : 00000000 00000000 00000000 01000001

결국 문자 상수는 소스코드에서 문자임을 표현하는 방법이며 컴퓨터 안에서는 정수와 같은 방 식으로 처리됩니다. 상수의 번역 형태는 값의 범위나 컴파일러에 따라 다를 수 있습니다. 예 를 들어 4바이트로 표현할 수 없는 큰 범위의 정수를 사용하면 8바이트로 번역합니다. 문자 상수도 C++ 컴파일러는 1바이트로 번역합니다. 만약 상수의 크기를 확인할 필요가 있다면

sizeof 연산자를 사용하며 연산자는 4장에서 자세히 다룹니다. 58 1부 C 언어 기본


2.2.5 정수형 상수가 컴파일된 후의 비트 형태 정수는 0을 포함한 양수와 음수가 있습니다. 음수는 데이터의 표현 방법이 독특하므로 먼저 2장 상수와 데이터 출력

양수를 기준으로 설명하고 음수는 따로 설명합니다. 정수는 컴파일되면 4바이트 크기의 2진수로 변환됩니다.

예를 들어 정수 13이 컴파일되면 다음과 같은 비트열로 바뀝니다. 10진수 13

0000 0000 0000 0000 0000 0000 0000 1101 MSB

나머지 비트는 0으로 채움

LSB

정수는 10진수를 그대로 2진수로 바꾼 것이므로 1값을 갖는 비트가 왼쪽에 위치할수록 값 의 크기가 커집니다. 결국 가장 왼쪽에 위치한 비트는 전체 값에서 차지하는 비중이 가장 크 므로 MSB(Most Significant Bit)라 하고 반대로 가장 오른쪽에 위치한 비트는 LSB(Least

Significant Bit)라 합니다. 만약 정수를 8비트로 표현한다면 오른쪽의 7비트가 전부 1인 값보 다 가장 왼쪽의 비트가 1인 값이 더 큰 값이 됩니다. 1000 0000

0111 1111

(십진수 128)

(십진수 127)

그렇다면 8비트로 정수를 표현할 때 최솟값과 최댓값은 각각 얼마일까요? 쉽게 알 수 있듯이 모든 비트가 0일 때 가장 값이 작고 모든 비트가 1일 때 가장 큰 값이 됩니다. 모든 비트가 1 인 2진수를 10진수로 바꾸면 255이므로 결국 1바이트(8비트)로 표현할 수 있는 값의 범위는

0~255가 됩니다. 이 범위는 비트 수가 많을수록 더 넓어지겠지만 다음 규칙에 따라 쉽게 계 산할 수 있습니다. 비트 수

•0~2

-1

이 계산에 따르면 4바이트로 표현할 수 있는 정수의 최댓값은 232-1로 4294967295가 됩니 다. 따라서 4294967295보다 큰 상수를 사용하면 컴파일러는 자동으로 데이터의 크기를 8바 이트로 늘려 처리합니다. 만약 값의 크기와 상관없이 데이터의 크기를 8바이트로 만들고 싶을 때는 정수에 접미사 LL(또는 소문자 ll)을 붙여 사용합니다.

2.2 상수와 데이터 표현 방법 59


13 13LL

// 4바이트 크기로 처리

// 8바이트 크기로 처리

음수는 절대값을 2의 보수로 바꾸어 처리합니다.

2의 보수란 2진수의 0과 1을 바꾼 상태(이 상태를 1의 보수라 함)에서 1을 더한 값을 말합니 다. 예를 들어 -13은 그 절대값인 13을 2진수로 바꾸고 1의 보수를 구한 후에 다시 1을 더하 여 2의 보수로 만듭니다. • 절대값 13의 2진수

 00000000 00000000 00000000 00001101

• 0과 1을 바꿈(1의 보수)  11111111 11111111 11111111 11110010 • 1의 보수에 1을 더함

 11111111 11111111 11111111 11110011

음수를 2의 보수로 처리하는 이유는 특별한 변환 과정 없이 바로 양수와 음수를 더할 수 있기 때문입니다. 실제로 10과 -10의 모든 비트를 더하면 가장 왼쪽의 비트에서 자리올림이 발생 하고 남은 32비트는 모두 0이 되어 결과적으로 값 자체가 0이 됩니다.

자리올림 1 11111111 11111111 11111111 1111111

13 -13

00000000 00000000 00000000 00001101

0

00000000 00000000 00000000 00000000

결과값

11111111 11111111 11111111 11110011

2.2.6 실수형 상수가 컴파일된 후의 비트 형태 2진수로 값을 표현하는 방식은 값의 크기에 비례하여 데이터의 크기도 커지므로 아주 큰 값이 나 소수점 이하를 표현하는 데 한계가 있습니다. 따라서 실수는 데이터를 표현하는 효과적인 방법을 만들고 그 규칙에 따라 표현합니다. 실수는 제한된 크기에 효율적으로 수를 표현하기 위해 IEEE 754 표준을 따릅니다.

이 표준에는 single, double, quad의 세 가지 형식이 있으며 그중에 가장 많이 사용하는

double 형식에 대해서만 간단히 살펴보도록 합시다. double 형식은 실수를 8바이트(64비트)

60 1부 C 언어 기본


로 표현하며 다음 규칙을 따릅니다. 부호 비트

지수 저장

소수 저장

11비트

52비트 2장 상수와 데이터 출력

첫째, 가장 왼쪽의 비트는 부호비트며 양수는 0, 음수는 1로 표시합니다. 둘째, 부호비트 다음부터 11비트는 지수값을 의미합니다. 셋째, 나머지 52비트는 소수값을 의미합니다.

이 규칙에 따라 최댓값과 최솟값을 생각해봅시다. 최댓값은 지수 부분과 소수 부분이 모두 가 장 큰 값을 가질 때며 최솟값은 최댓값에 부호만 바꾸면 됩니다. 계산에 의하면 대략 다음과 같은 범위의 실수를 표현할 수 있습니다. • -1.79 × 10308 ~ 1.79 × 10308

결국 표현할 수 있는 값의 범위는 상당히 큽니다. 그러나 값의 크기와 달리 정확한 값을 표현 하는 데에는 한계가 있습니다. 실제로 다음과 같이 유효숫자가 많은 값은 정확히 표현하지 못 하고 오차가 발생합니다. • 0.1234567890123456789

오차가 발생하는 이유는 소수 부분을 나타내는 비트가 정확한 값을 표현할 수 없기 때문입니 다. 예를 들어 소수 부분을 4비트로 표현할 때 각 비트가 나타내는 10진수값은 다음과 같습 니다. 부호 비트

지수부

소수부

11비트

1

21 ( 0.5 ) -

1

22 ( 0.25 ) -

1

1

23 ( 0.125 ) -

24 ( 0.0625 ) -

이 소수 부분의 값들을 모두 조합하여 더해도 10진수로 소수점 이하 첫 째짜리까지만 정확하 게 표현할 수 있습니다.

2.2 상수와 데이터 표현 방법 61


소수부 2진수

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

10진수 값 계산식 0 0.0625 0.125 0.125 + 0.0625 0.25 0.25 + 0.0625 0.25 + 0.125 0.25 + 0.125 + 0.0625 0.5 0.5 + 0.0625 0.5 + 0.125 0.5 + 0.125 + 0.0625 0.5 + 0.25 0.5 + 0.25 + 0.0625 0.5 + 0.25 + 0.125 0.5 + 0.25 + 0.125 + 0.0625

소수부 10진수

0 0.0625 0.125 0.1875 0.25 0.3125 0.375 0.4375 0.5 0.5625 0.625 0.6875 0.75 0.8125 0.875 0.9375

따라서 0.09와 같은 값은 가장 가까운 값인 0.0625나 0.125로 저장할 수밖에 없습니다. 물론 비트 수가 늘어날수록 정확하게 표현할 수 있는 유효숫자 수는 늘어납니다. 그러나 자료형의 크기는 정해져 있으므로 유효숫자 수도 한계가 있습니다. 결론적으로 IEEE 754 표준 계산식 에 의하면 double형의 경우 15자리까지 유효숫자를 사용할 수 있습니다. 값에 따라 더 많은 자릿수를 정확히 표현할 수 있으나 항상 정확하게 표현한다는 보장이 없으므로 15자리 범위에 서 사용하는 것이 바람직합니다.

마무리 지금까지 C 프로그램 상수 데이터의 종류를 정리하고 컴파일된 후에 표현되는 비트열에 대해 살펴봤습니다. 정수는 빠르고 정확하게 연산되며 실수는 오차가 발생할 수 있음을 기억합시 다. 쉽지 않은 내용이지만 정확하고 효율적인 프로그램을 만드는 데 도움이 되는 내용이므로 연습문제를 통해 내용을 정리해둡시다.

62 1부 C 언어 기본


1 각 진법에 맞게 빈칸을 채웁니다. 8진수

16진수

2장 상수와 데이터 출력

10진수

2진수 1011

17 1a 101

2 다음 중 정수형 상수와 실수형 상수를 구분해봅시다. - 10 1e4 - 1 . - 1 . 5e - 3 + 032 3 . 14 0xff

3 다음 프로그램의 실행 결과를 적어봅시다. #include <stdio.h>

int main(void) {

printf("% d % d % d % d", 1101, 13, 0xd, 015); return 0; }

4 정수형 상수 -5가 번역된 후의 비트열을 적어봅시다. 신의 학번, 이름, 학점을 출력하는 프로그램을 작성합니다. 학번은 정수, 이름은 문자열, 학점은 문자 상수를 사 5 자용합니다. 학번 : 32165 이름 : 홍길동 학점 : A

2.2 상수와 데이터 표현 방법 63


1

10진수

8진수

16진수

2진수

11

13

b

1011

17

21

11

10001

26

32

1a

11010

65

101

41

1000001

2 정수형 상수 : -10

+ 032 0xff

실수형 상수 : 1e4 - 1. - 1.5e- 3 3.14

3 정답 : 1101

13 13 13

C 언어는 소스코드에 2진수를 사용하지 않으므로 1101은 10진수 천백일

4 정답 : 11111111 11111111 11111111 11111011

• 5

 00000000 00000000 00000000 00000101

• 5의 1의 보수  11111111 11111111 11111111 11111010 • 5의 2의 보수  11111111 11111111 11111111 11111011 

5

#include <stdio.h>

int main(void) {

printf("학번 : % d\n", 32165); // 정수는 % d로 출력 printf("이름 : % s\n", "홍길동"); // 문자열은 % s로 출력 // 문자는 % c로 출력 printf("학점 : % c\n", 'A'); return 0; }

64 1부 C 언어 기본

-5


3장 1절

2장 상수와 데이터 출력

3

3장 2절

변수와 데이터 입력

내가 고구려 19대 왕이니라! 다들 무릎을 꿇어라!

광개토대왕! 명 받잡겠습니다!

18살의 어린 나이로 고구려 19대 왕위에 오른 광개토대왕(374~412년)은 백성을 괴롭히는 무리를 쓸어 없애고 북으로는 연나라, 남으로는 백제와 왜까지 그 위엄이 떨치지 않는 곳이 없었다. 이에 생업에 온 힘을 쏟아 삶이 윤택해진 백성이 광개토대 왕을 왕 중의 왕으로 칭송하였으나, 아쉽게도 39세라는 젊은 나이에 세상을 등지게 되었다. 이렇게 위대한 광개토대왕의 신상 정보를 담으려면 어떻게 해야 할까?

2.1 C 프로그램의 기본 형태와 데이터 출력 방법 65


3.1 변수 학.습.목.표

프로그램이 처리하는 데이터는 형태가 다양하고 연산 방법도 다릅니다. 이런 특징을 잘 이해하면

효율적이고 신뢰성 있는 프로그램을 만들 수 있습니다. 이 절에서는 데이터형에 따른 변수 선언과 사용 방법에 대해 살펴봅니다. 1 변수 선언으로 메모리에 저장 공간을 확보한다. 2 대입 연산자는 변수에 값을 저장한다. 3 초기화하지 않은 변수는 쓰레기값을 갖는다. 4 변수의 형태를 자료형이라 하며 기본적으로 정수형과 실수형으로 나눈다. 5 변수에 const를 사용하면 상수처럼 사용할 수 있다. 6 예약어는 컴파일러와 약속된 단어며 식별자는 사용자가 새롭게 만들어낸 단어다.

변수는 데이터를 넣는 저장 공간이다.

데이터를 메모리에 저장해 놓으면 필요할 때 꺼내어 반복 사용할 수 있습니다. 이때 변수 선언 을 통해 메모리에 저장 공간을 확보합니다. 변수는 데이터의 종류에 따라 각각 다른 형태를 사 용하며, 다음과 같은 것들이 있습니다. 표 3-1 데이터 종류에 따른 대표 자료형 데이터 종류

자료형

크기(Byte)

저장 값의 범위

정수

int

4

-2147483648 ~ 2147483647

실수

double

8

-1.79 X 10308 ~ 1.79 X 10308

문자

char

1

-128 ~ 127

문자열

char 배열

가변적

‘배열의 크기 – 1’개의 문자

자료형에 대한 호기심은 잠시 접어두고 일단 변수를 선언하는 방법부터 하나씩 이야기를 풀어 갑시다.

66 1부 C 언어 기본


A

아스키 코드표

표 A-1 아스키 코드표(ASCII code, American Standard Code for Information Interchange) 값

문자

문자

문자

Ctrl-@ NUL

0

space

32

@

64

`

96

Ctrl-A SOH

1

!

33

A

65

a

97

Ctrl-B STX

2

"

34

B

66

b

98

Ctrl-C ETX

3

#

35

C

67

c

99

Ctrl-D EOT

4

$

36

D

68

d

100

Ctrl-E ENQ

5

%

37

E

69

e

101

Ctrl-F ACK

6

&

38

F

70

f

102

Ctrl-G BEL

7

'

39

G

71

g

103

Ctrl-H BS

8

(

40

H

72

h

104

Ctrl-I HT

9

)

41

I

73

i

105

Ctrl-J LF

10

*

42

J

74

j

106

Ctrl-K VT

11

+

43

K

75

k

107

Ctrl-L FF

12

,

44

L

76

l

108

Ctrl-M CR

13

-

45

M

77

m

109

Ctrl-N SO

14

.

46

N

78

n

110

Ctrl-O SI

15

/

47

O

79

o

111

Ctrl-P DLE

16

0

48

P

80

P

112

Ctrl-Q DC1

17

1

49

Q

81

q

113

Ctrl-R DC2

18

2

50

R

82

r

114

Ctrl-S DC3

19

3

51

S

83

s

115

Ctrl-T DC4

20

4

52

T

84

t

116

Ctrl-U NAK

21

5

53

U

85

u

117

Ctrl-V SYN

22

6

54

V

86

v

118

Ctrl-W ETB

23

7

55

W

87

w

119

Ctrl-X CAN

24

8

56

X

88

x

120

Ctrl-Y EM

25

9

57

Y

89

y

121

Ctrl-Z SUB

26

:

58

Z

90

z

122

Ctrl-[ ESC

27

;

59

[

91

{

123

Ctrl-\ FS

28

<

60

\

92

|

124

Ctrl-] GS

29

=

61

]

93

}

125

Ctrl-^ RS

30

>

62

^

94

~

126

Ctrl-_ US

31

?

63

_

95

DEL

127

A 아스키 코드표 665

부록

문자


B

선택정렬 알고리즘

정렬은 데이터를 일정한 규칙에 따라 나열합니다. 작은 값부터 큰 값 순서로 나열하면 오름 차순 정렬(ascending sort)이며 반대로 큰 값에서 작은 값 순서로 나열하면 내림차순 정렬 (descending sort)입니다. 정렬하는 방법은 다양하지만 비교적 쉽게 사용할 수 있는 선택정 렬(selection sort)을 소개합니다. 예를 들어 다음과 같이 배열이 초기화되었을 때 배열의 값 을 오름차순으로 정렬해봅시다. int a[5] = {3, 2, 1, 6, 5};

3

2

1

6

5

a [0]

a [1]

a [2]

a [3]

a [4]

우선 배열에서 가장 작은 값을 첫 번째 요소에 저장합니다.

방법은 간단합니다. 첫 번째 요소를 기준으로 나머지 요소들을 차례로 비교하면서 기준 요소 의 값이 비교하는 값보다 크면 두 값을 바꿉니다. 이 과정을 단계별로 살펴보면 다음과 같습 니다. ➊ 기준이 되는 a [0]이 a [1]보다 크므로 두 요소의 값을 바꿉니다. 3

2

1

6

5

2

3

1

6

5

a [0]

a [1]

a [2]

a [3]

a [4]

a [0]

a [1]

a [2]

a [3]

a [4]

이 과정이 끝나면 a [0], a [1] 두 요소 중에 작은 값이 a [0]에 저장됩니다. 이 상태에서 a [0]를 기준으로 다음 요소 인 a [2]와 비교하고 바꾸는 과정을 반복합니다.

666 부록


C

날짜와 시간 함수, 난수 함수, 가변 인수 함수 C.1 시스템의 날짜와 시간 구하기 시스템의 현재 날짜와 시간을 구할 때는 time 함수와 localtime 함수를 사용하며 원형은 다음 과 같습니다. time_t time(time_t *t); struct tm * localtime(const time _ t * timer);

예제 C-1 시스템의 날짜와 시간 출력

1. #include <stdio.h> // time과 localtime을 위한 인클루드 2. #include <time.h> 3. 4. int main(void) 5. { 6. char * day[7] = { "일", "월", "화", "수", "목", "금", "토" }; // time이 반환하는 시간 저장 7. time _ t res; // localtime이 반환하는 주소 저장 8. struct tm * pt; 9. // 초 계산 10. time(& res); // 초로 날짜와 요일, 시간 계산 11. pt = localtime(& res); 12. 13. printf("% d년 ", pt -> tm _ year + 1900); // tm의 각 멤버로 날짜와 시간 출력 14. printf("% d월 ", pt -> tm _ mon + 1); 15. printf("% d일 ", pt -> tm _ mday); 16. printf("% s요일 ", day[pt -> tm _ wday]); 17. printf("% d:% d:% d\n", pt -> tm _ hour, pt -> tm _ min, pt -> tm _ sec); 18. 19. return 0; 20. }

672 부록


D

C 표준 라이브러리 함수와 매크로 D.1 헤더 파일별 표준 함수 표 D-1 표준 입출력 함수 : stdio.h 헤더 파일 인클루드 함수명

구분

설명

fclose

기능

스트림 파일의 버퍼를 비우고 개방된 파일을 닫는다.

원형

int fclose ( FILE * stream);

인수

파일 포인터

반환값

성공하면 0, 실패하면 EOF

기능

파일의 끝이나 에러 발생 시 설정되는 스트림 파일의 표시자 초기화

원형

void clearerr ( FILE * stream);

인수

파일 포인터

반환값

없음

기능

파일의 데이터를 모두 읽었는지 확인한다.

원형

int feof ( FILE * stream);

인수

파일 포인터

반환값

파일의 데이터를 모두 읽은 경우 0, 그렇지 않으면 0이 아닌 값

기능

파일에 데이터를 읽거나 쓸 때 에러가 발생했는지 확인한다.

원형

int ferror ( FILE * stream);

인수

파일 포인터

반환값

에러가 발생한 경우 0이 아닌 값, 그렇지 않으면 0

기능

출력 스트림 파일의 버퍼를 비운다.

원형

int fflush ( FILE * stream);

인수

파일 포인터

반환값

성공하면 0, 에러가 발생하면 EOF를 반환하고 에러 표시자 설정

clearerr

feof

ferror

fflush

678 부록


E

실전 프로젝트

E.1 로또 프로그램 구입한 로또 복권의 번호와 추첨 번호를 비교하여 당첨금액을 출력합니다. 복권은 최대 10회 차에 걸쳐 100게임을 구입할 수 있으며 추첨 회차는 최대 10회차로 구입한 회차와 일치하지 않을 수 있습니다. 1 구입한 로또 번호는 다음 세 가지 방법으로 입력할 수 있으며 추첨 번호는 수동 입력과 파일 입력만 가능합니다. • 자동 입력 : 난수를 구해 서로 중복되지 않는 6개의 번호를 사용합니다. • 수동 입력 : 키보드로 직접 중복되지 않는 6개의 번호를 입력합니다. • 파일 입력 : 로또 번호가 저장된 파일로부터 입력합니다. 2 로또 복권의 당첨 규칙은 다음과 같습니다. • 구입한 로또 번호 6개가 추첨한 번호 6개와 모두 같으면 1등 • 5개의 번호가 같고 다른 하나의 번호가 보너스 번호와 일치하면 2등 • 5개의 번호가 같으면 3등 • 4개의 번호가 같으면 4등 • 3개의 번호가 같으면 5등 3 메뉴 구성은 다음과 같습니다. ---------------------------------

1. 2. 3. 4.

구입한 로또 번호 자동 입력 구입한 로또 번호 수동 입력 구입한 로또 번호 파일 입력

구입한 로또 번호 확인 ---------------------------------

5. 추첨 번호와 배당 금액 수동 입력 6. 추첨 번호와 배당 금액 파일 입력 7. 추첨 번호와 배당 금액 확인 ---------------------------------

702 부록


w w w. h a n b i t . c o . k r

Hanbit eBook

Realtime w w w. h a n b i t . c o . k r / e b o o k

DRM free! 어떤 디바이스에서도 자유롭게

eBook Oriented! 전자책에 꼭 맞는 최적의 내용과 디자인

Hanbit eBook

Hanbit eBook

Realtime 70

Realtime 89 49

MFC 프로그래밍 주식분석 프로그램 만들기 김세훈 지음

Hanbit eBook

Hanbit eBook

Realtime 90

Realtime 92 49

자바 개발자를 위한

Vert.x JavaScript Promise​ azu​지음 /​주우영​옮김

애플리케이션 개발 모바일/웹 메시징 STOMP와 MQTT로 개발하는 IoT 모바일/웹 애플리케이션 Mobile and Web Messaging 제프 메스닐 지음 / 조건희 옮김

이연복 지음


w w w. h a n b i t . c o . k r

즐거운 상상이 가득! 2015년 화제의 신간

즐거운 상상이 가득! 2015년 화제의 신간

전자부품 백과사전 vol.1 찰스 플랫 지음 / 배지은 옮김 / 30,000원

취미공학에 필요한 핵심 전자부품을 사전식으로 정리한 안내서.

전자부품 백과사전 vol.1 찰스 플랫 지음 / 배지은 옮김 / 30,000원

처음 시작하는 센서

취미공학에 필요한 핵심 전자부품을 사전식으로 정리한 안내서.

전자부품 백과사전 vol.2

찰스 플랫 지음 / 가격미정

키모 카르비넨, 테로 카르비넨 지음 임지순 옮김 / 13,000원

세상을 수치로 읽어내는

<전자부품 백과사전> 시리즈의 두 번째 도서다.

부품인 센서를 알려주 는 책. 이 책을 통해 자신 만의 프로젝트에 다양한 처음 센서를 사용해보자.

Zero to Maker

: 누구나 메이커가 될 수 있다 데이비드 랭 지음 / 장재웅 옮김 / 14,000원

전자부품 백과사전 vol.2

찰스 플랫 지음 / 가격미정

일반인에서 메이커로. 날백수에서 무인 잠

<전자부품 백과사전> 시리즈의 수정 회사 CEO 가 된 사나이, 데이비드두 번째 도서다. 랭의 메이커 도전기.

Make: 센서

시작하는 센서

키모 카르비넨, 테로 카르비넨 지음 임지순 옮김 / 13,000원

세상을 수치로 읽어내는 부품인 센서를 알려주

키모 카르비넨, 테로 카르비 넨, 빌 발토카리 지음 는 책. 이 책을 통해 자신 / 가격미정

만의 프로젝트에 다양한

필수 전자부품인 센서를

센서를 사용해보자. 마이크로 컨트롤러 보드

Zero to Maker

: 누구나 메이커가 될 수 있다

에 응용하는 방법을 담

데이비드 랭 지음 / 장재웅 옮김 / 14 ,000원 Maker Pro

았다.

베이첼 지음 / 가격미정 일반인에서 메이커로.존날백수에서 무인 잠

메이커라면 반드시 읽어야 할 필수 계발

수정 회사 CEO가 된 사나이, 데이비드 서. 프로 메이커들과의 인터뷰 및 에세이 랭의 메이커 도전기. 수록.

프로젝트로 배우는 라즈베리 파이

도날드 노리스 지음 / 임지순 옮김

다양한 실전 프로젝트를 통해 라즈베리 파이를 쉽고 재미있게 배워본다.

Maker Pro 존 베이첼 지음 / 가격미정

메이커라면 반드시 읽어야 할 필수 계발

Make: 센서 키모 카르비넨, 테로 카르비 넨, 빌 발토카리 지음 / 가격미정

필수 전자부품인 센서를 마이크로 컨트롤러 보드 에 응용하는 방법을 담 았다.



Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.