C Programming C 언어개요 (C Language Overview) Seo, Doo-Ok Clickseo.com clickseo@gmail.com
목 차 C 언어개요 C 언어기본문법 콘솔입출력 C 프로그램구조 2
C 언어개요 C 언어개요 C 언어의역사및특징 C 프로그램단계 C 언어기본문법 콘솔입출력 C 프로그램구조 3
C 언어의역사및특징 (1/3) C 언어의역사 : B 언어와 C 언어 ALGOL(ALGOrithmic Language) 1960년, ALGOL 60 제정 1958년, ALGOL 58 ( 원래는 IAL) 1973년, ALGOL 68 개정 BCPL(Basic Combined Programming Language) 1966년, 캠브리지대학교의마틴리처드 (Martin Richard) 가설계 절차적명령형, 구조적컴퓨터프로그래밍언어 자료형을지원하지않고자료객체만지원 B 프로그래밍언어 1969 년, AT&T Bell 연구소의켄톰슨 (Ken Thomson) C 프로그래밍언어 1972년, AT&T Bell 연구소의데니스리치 (Dennis Ritchie) UNIX 운영체제에서사용하기위해개발된프로그래밍언어 BCPL과 B언어를결합, 자료형지원 4
C 언어의역사및특징 (2/3) C 언어의역사 : 표준화 C 언어의표준화역사 1989년, 미국국립표준화협회 (ANSI) 에서표준으로지정 : ANSI C, 표준 C, C89 1990년, 국제표준화기구 (ISO) 가 ANSI 표준채택 : ISO/IEC 9899:1990(C90) 1995년, 일종의부록형태로 C90의확장발표 : Normative Addendum 1 (NA1) 유럽을중심으로터져나온 C90 이지나치게미국적 이라는불만을잠재우기위해 C90과 NA1을합해 C95 라고부르기도한다. 1999년, ISO/IEC 9899:1999(C99) 를발표 다양한변화 ( 예를들면 C++ 와유니코드의발전등 ) 를수용하기위해 단일행주석 :// 새로운자료형 : long long int, complex inline 함수, 가변길이배열 2007 년, C 표준화위원회에서새로운기능채택을제안한가이드라인발표 (C1X) 2011 년, 새로운 C 언어표준발표 : ISO/IEC 9899:2011(C11) 5
C 언어의역사및특징 (3/3) C 언어의특징 이식성이좋다. 유연성 고급언어와저급언어의특징을동시에가진언어이다. 기계중심의언어 : Assembly 사용자중심의언어 : C, C++, Java, FORTRAN, COBOL, PASCAL 등 구조적프로그래밍을지원하는함수언어이다. 풍부한내장함수라이브러리를제공한다. 프로그래밍구조가간결하고명료하다. 실행파일의크기가작고빠른성능을자랑한다. 분할컴파일기능을지원한다. 6
C 프로그램개발단계 (1/2) 라이브러리모듈파일 (Library Module File) 컴파일러 (Compiler) 링커 (Linker) 로더 (Loader) 원시파일 (Source File) 목적파일 (Object File) 실행파일 (Executable File) 실행 (Execution) hello.c hello.obj hello.exe 7
C 프로그램개발단계 (2/2) C 프로그램구조 /* */ 간단한 C 프로그램구조 작성자 : 서두옥 #include <stdio.h> // 헤더파일 : 전처리기 (preprocessor) int main(void) // main 함수시작 { printf("hello World!\n"); } // main 함수끝 return 0; // 함수종료 ( 반환값 : 0) 8
C 언어기본문법 C 언어개요 C 언어기본문법 식별자 변수와상수 자료형 콘솔입출력 C 프로그램구조 9
C 언어의구문과어휘 식별자 (1/4) 문자 종류 영문소문자 영문대문자 a, b, c, d,, x, y, z A, B, C, D,, X, Y, Z 숫자 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 특수문자 +, =, _, -, (, ), *, &, %, $, #,!,, <, >,., [, ], ^, ~,,, ;, :,,,... whitespace blank, new line, tab 10
식별자 (identifier) 식별자 (2/4) 프로그래머가임의로정의하여사용하는변수, 함수, 상수등에부여한명칭 식별자에사용될수있는문자 영문소문자 (lowercase letters) : a, b, c,, z 영문대문자 (uppercase letters) : A, B, C,, Z 숫자 (digits) : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 _ 문자 식별자를작성하는규칙 첫번째문자 : 영문대소문자또는 _ 숫자는첫번째문자로사용불가능 ( 두번째문자부터가능 ) 사용불가능 : 예약어 (keyword) 와특수문자 변수의이름은최대 63자까지가능하다. 변수이름의길이가 63자를초과하면 63번째문자까지인식한다. C 언어에서식별자는대소문자를정확히구분한다. 11
식별자 (3/4) 식별자 : 예제 식별자작성예 SUM, Sum, sum : 서로다른식별자로인식 ( C 언어는대소문자를구분 ) i5clickseo : 두번째문자로숫자사용 name_of_variable, _Clickseo getnumber, printsum, clickseo // 낙타체스타일 CustomerName, ClickSeo // 파스칼스타일 inumber, iclickseo // 헝가리안스타일 잘못작성된예 5iClickseo : 숫자는첫번째문자로사용불가 Clickseo#35 : 특수문자는사용불가 Click-seo : -(hyphen) 사용불가 12
식별자 (4/4) 예약어 (keyword) C 언어에서특별한의미로사용되는단어 프로그램내에서재정의되거나다른용도로사용되어서는안된다. C89/C90 : 32 개예약어 auto do goto signed unsigned break double if sizeof void case else int static volatile char enum long struct while const extern register switch continue float return typedef default for short union C99 : 추가된 5 가지예약어 _Bool, _Complex, _Imaginary, inline, restrict C11 : 추가된 7 가지예약어 _Alignas, _Alignof, _Atomic, _Generic, _Noreturn, _Static_assert, _Thread_local 13
변수 (variable) 변수와상수 (1/7) 프로그램에서사용되는자료를저장하기위한공간 할당받은메모리의주소대신부르는이름 사용자가변수이름을만들어저장하기위한자료의형태를지정하면, 컴파일러는컴퓨터메인메모리의주소값과연결시켜준다. 프로그램실행중에값을변경하는것이가능하다. 사용되기이전에선언되어야한다. 1000 A ch 2000 char int i; ch; 1001 1002 1003 2001 2002 2003 100 i 프로그램 메모리 14
변수 : 선언및초기화 #include <stdio.h> 변수와상수 (2/7) int main(void) { // 변수선언 int a; char ch; // 변수는선언과초기화를동시에할수있다. #include <stdio.h> } // 데이터저장 a = 10; ch = 'A'; return 0; int main(void) { int a = 10; char ch = A ; return 0; } 15
상수 (constant) 변수와상수 (3/7) 프로그램수행중에값을변경할수없는데이터 리터럴상수 (literal constant) 정수형상수 (integer constant) 실수형상수 (real constant) 문자상수 (character constant) 문자열상수 (string constant) 기호상수 (symbolic constant) 예약어 const 를이용하는방식 매크로상수 (macro constant) 전처리의매크로를이용하는방식 16
변수와상수 (4/7) 문자상수 (character constant) 영문자나숫자, 특수기호등을숫자로표현하기위해사용 작은따옴표 ( ) 를이용 내부적으로는문자형상수도숫자로취급된다. #include <stdio.h> int main(void) { char ch1 = A ; char ch2 = 65; printf( %d %d \n, ch1, ch2 ); printf( %c %c \n, ch1, ch2 ); } return 0; 17
문자상수 : 확장문자열 변수와상수 (5/7) 확장문자열 : 이스케이프 (escape) 문자 확장문자열 ASCII 코드의미 \0 0 NULL 널문자 (null character) \a 7 BEL 경고음 (alarm) 소리발생 (alert) \b 8 BS 커서를뒤로한칸이동한효과 (backspace) \t 9 HT Tab 키를누른만큼커서이동 (tab : 보통 4 열 ) \n 10 LF 커서를다음행으로이동 (new line, line feed) \v 11 VT 수직탭 (vertical tab) \f 12 FF 인쇄시프린터의종이를한장넘김 (form feed) \r 13 CR 커서를줄의처음으로이동 (carriage return) \ 34 큰따옴표 (double quote) 출력 \ 39 작은따옴표 (single quote) 출력 \\ 92 역슬래시 (literal backslash) 출력 18
변수와상수 (6/7) 문자열상수 (string constant) 큰따옴표내에하나이상의문자를묶어서표현하는문자열 문자열상수는문자열끝에널문자 ( \0 ) 가자동으로삽입되는문자상수 A A A A \0 \0 문자 A 문자열 A 빈문자열 (1 byte) (2 bytes) 19
변수와상수 (7/7) 기호상수 (symbolic constant) 예약어 const 를이용하는방식 const int MAX = 100; ( 주의할점 ) 1) 자료형한정자가제일먼저나타나야한다. 2) 초기화가반드시되어야한다. 3) 상수로선언되었으므로그값이바뀔수없다. 매크로상수 (macro constant) 전처리의매크로를이용하는방식 전처리기명령어 define 을사용 #define MAX_SIZE 1024 20
C 언어기본문법 자료형 21
자료형 (1/11) 부울형 _Bool // since C99 문자형 char, unsigned char 정수형 short int, unsigned short int int, unsigned int long int, unsigned long int long long int, unsigned long long int // since C99 실수형 float, double, long double 형없음 void 22
자료형 (2/11) 자료형크기 (byte) 데이터표현범위 char int long char (signed char) 1-2 7 ~ 2 7-1:-128 ~ 127 unsigned char (8비트) 0 ~ 2 8 1: 0~255 short int 2-2 15 ~ 2 15-1 : -32,768 ~ 32,767 unsigned short int (16비트) 0 ~ 2 16 : 0 ~ 65,535 int 4-2 31 ~ 2 31-1 : -2,147,483,648 ~ 2,147,483,647 unsigned int (32비트) 0 ~ 2 32-1 : 0 ~ 4,294,967,295 long int 4-2 31 ~ 2 31 1:-2,147,483,648 ~ 2,147,483,647 unsigned long int (32비트) 0 ~ 2 32 1: 0 ~ 4,294,967,295 long long long long int unsigned long long int 8 (64 비트 ) -2 63 ~ 2 63 1 : -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 0 ~ 2 64 1 : 0 ~ 18,446,744,073,709,551,615 float float 4 (32 비트 ) -10 128 ~ 10 127 : 소수 6 자리표현 double double 8 (64비트) -10 128 ~ 10 127 : 소수 15자리표현 long double 8 또는그이상 차이를많이보임 : double의정밀도와같거나크다. 23
자료형 (3/11) 예제 1-1 : 다양한자료형의메모리크기 Visual Studio Community 2017 #include <stdio.h> int main(void) { printf("char : %d \n", sizeof(char) ); printf("int : %d \n", sizeof(int) ); printf("long : %d \n", sizeof(long) ); printf("long long : %d \n", sizeof(long long) ); printf("float : %d \n", sizeof(float) ); printf("double : %d \n", sizeof(double) ); printf("long double : %d \n", sizeof(long double) ); } return 0; 24
자료형 (4/11) 예제 1-2 : 다양한자료형의메모리크기 #include <stdio.h> int main(void) { // warning: format '%d' expects argument of type 'int, // but argument 2 has type 'long unsigned int // printf("char : %d \n", sizeof(char) ); printf("char : %ld \n", sizeof(char) ); printf("int : %ld \n", sizeof(int) ); printf("long : %ld \n", sizeof(long) ); printf("long long : %ld \n", sizeof(long long) ); printf("float : %ld \n", sizeof(float) ); printf("double : %ld \n", sizeof(double) ); printf("long double : %ld \n", sizeof(long double) ); GCC(GNU Compiler Collection) } return 0; 25
자료형 (5/11) 부울형 (boolean type) : _Bool C99 에서추가된부울유형의자료형 <stdbool.h> 헤더파일 : C99 에서추가된헤더파일 _Bool 의별칭으로 bool 을정의 true 및 false 에대한매크로제공 #include <stdio.h> #include <stdbool.h> // bool, true, false int main(void) { _Bool state = true; // bool state = true; state = false; printf("state : %d \n", state ); printf("true : %d \n", true ); printf("false : %d \n", false ); } return 0; 26
문자형 (character type) 자료형 (6/11) 컴퓨터에서문자는정수값을부여하여처리 ASCII(American Standard Code for Information Interchange) 컴퓨터는문자상수를자동적으로내부에서 ASCII 코드값으로변환한다. 문자도기본적인산술연산이가능하다. char ch = A ; 128 64 32 16 8 4 2 1 가중치 0 1 0 0 0 0 0 1 부호비트 (MSB) 0:+ 1:- 8 비트 signed : -2 7 ~ 2 7 1 (-128 ~ 127) unsigned : 0 ~ 2 8 1 (0 ~ 255) 27
정수형 (integer type) 자료형 (7/11) 정수, 즉분수 ( 소수점이하 ) 부분을가지지않는수 int i = 65; 128... 16 8 4 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 최상위비트 (MSB : Most significant Bit) 32 비트 최하위비트 (LSB: Least Significant Bit) 정수표현범위 : 4bytes(32bits) int 로선언시 : -2,147,483,648 ~ 2,147,483,647 (-2 31 ~ 2 31 1) unsigned 로선언시 : 0 ~ 4,294,967,295 (0 ~ 2 32-1) 28
정수형 : 음수표현 자료형 (8/11) 음수표현 : 2의보수로표현 int i = -65; 128... 16 8 4 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 부호비트 (MSB) 가 1 이면음수 (2 의보수로표현 ) unsigned int i = 4294967231; 128... 16 8 4 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 29
실수형 (real type) 자료형 (9/11) 실수 : 소수점이하의값을가진다 ( 정수부분과소수부분 ). 단정도형식 (single precision format) : float 0 지수 (8 비트 ) Excess_127 가수 ( 소수, 23 비트 ) 가수부의부호비트 0 배정도형식 (double precision format) : double 지수 (11 비트 ) Excess_1023 가수 ( 소수, 52 비트 ) 30
실수형 : 부동소수점오차 부동소수점오차 자료형 (10/11) 컴퓨터는우리가표현하고자하는실수의값을정확하게표현하는것이아니라, 아주가까운, 전혀문제가없을만큼의근사치를통해서실수를표현한다. 부동소수점오차에대한문제는컴퓨터의문제이지, C 언어의문제는아니다. 따라서다른프로그래밍언어들도기본적으로지니고있는문제이다. #include <stdio.h> int main(void) { int i; float f = 0.0f; for(i=0; i<100; i++) f += 0.1f; printf("%f \n", f); } return 0; 31
자료형 (11/11) typedef 지정자 (typedef specifier) 식별자를별칭형식으로선언 주로복잡한유형이름을대체하는데사용되는방법이다. #include <stdio.h> typedef int Clickseo; int main(void) { int a = 10; Clickseo b = 20; // stdio.h 파일에서 typedef 선언적용예 #include <stdio.h> typedef unsigned int size_t; printf("int a : %d \n", a ); printf("clickseo b : %d \n", b ); } return 0; 32
콘솔입출력 C 언어개요 C 언어기본문법 콘솔입출력 문자입출력 형식화된입출력 C 프로그램구조 33
스트림 (Stream) 데이터의논리적흐름 콘솔입출력 (1/5) 개발자와하드웨어장치사이에존재하는추상적계층 하드웨어장치파일과연결되어데이터전송을중재 표준입출력스트림의종류 <stdio.h> 에입출력스트림정의 입출력스트림 기능 디바이스장치 stdin 표준입력 키보드 stdout 표준출력 모니터 stderr 표준오류 모니터 stdprn 표준프린터 프린터 (LPT1) stdaux 표준보조입출력 직렬포트 (COM1) 34
입출력스트림 콘솔입출력 (2/5) 저장장치 파일스트림 ( 파일포인터 ) 파일스트림 ( 파일포인터 ) 저장장치 stdout stdin 표준출력 입력장치 표준입력 프로그램 stderr 표준오류 출력장치 35
콘솔입출력 (3/5) 콘솔입출력함수 : 표준입출력함수 형식화되지않은입출력 : 문자입출력 함수의선언기능헤더파일 int getchar( void ); stdin 에서다음한문자를읽어들인다. getc( stdin ) 와동일 int putchar( int ch ); stdout 에한문자를출력한다. putc( ch, stdout ) 와동일 stdio.h int getc( FILE *stream ); 지정된입력 stream 으로부터다음문자를읽어들인다. int putc( int ch, FILE *stream ); 문자 ch 를지정된출력 stream 에출력한다. int ungetc( int ch, FILE *stream ); 지정된 stream 에문자 ch 를되돌려놓는다. 36
콘솔입출력 (4/5) 콘솔입출력함수 : 비표준입출력함수 함수의선언 기능 헤더파일 int getch( void ); 한문자를읽어들인다 ( 입력한문자는화면에표시되지않는다 ). int putch( int ch ); 한문자를출력 ( \n 을 CR/LF 의조합으로변환하지않는다 ). int getche( void ); 한문자를읽어들인다 ( 입력한문자는화면에출력 ). conio.h int kbhit( void ); 키의입력여부조사 ( 키의입력이있을경우 0 이아닌수를반환 ) // 헤더파일 : conio.h 콘솔입출력함수를제공하는헤더파일 MS-DOS 시절부터사용되었다. 지금은 C 언어표준도아니고 POSIX 함수도아니다. GNU/Linux 와 Mac OS X 에서는사용할수없다. 37
비표준문자입출력함수 콘솔입출력 (5/5) getch 와 getche 함수 #include <conio.h> 비표준입력함수 : 직접문자입력함수 - getchar 함수보다빠른입력속도 int getch( void ); int getche( void ); abc a _ abc 입력 표준입력버퍼 (stdin) c b a getchar() a 입력 a 입력 getche() getch() 메모리 ( 프로그램 ) 키보드 38
표준문자입출력함수 getchar 함수 문자입출력 (1/2) 표준입력버퍼 (stdin) 로부터다음한문자를읽어들인다. 파일의끝을만나거나입력오류가발생했을경우에만중지된다. 만약파일의끝을만나거나입력오류가발생하면 EOF 값반환한다. #include <stdio.h> int getchar( void ); ( 성공 ) : 읽어들인문자를반환 ( 실패 ) : EOF 를반환 putchar 함수 표준출력버퍼 (stdout) 에한문자를출력한다. 내부적으로문자는쓰여지기직전에 unsigned char 로변환된다. #include <stdio.h> int putchar( int ch ); ( 성공 ) : 방금쓴문자를반환 ( 실패 ) : EOF 를반환 39
#include <stdio.h> 문자입출력 (2/2) 예제 1-3 : 한문자입출력 -- getchar / putchar int main(void) { char ch; printf(" 한문자입력 : "); ch = getchar(); printf(" 문자출력 : "); putchar( ch ) ; putchar('\n'); } return 0; 40
콘솔입출력 형식화된입출력 41
표준입출력함수 표준입출력 형식화된입출력 (1/16) 표준입력 (standard input) : 키보드 표준출력 (standard output) : 모니터 scanf() 표준입력버퍼 키보드 printf() 표준출력버퍼 메모리 모니터 42
형식화된입출력 (2/16) 표준입출력함수 : 콘솔입출력 형식화된입출출력 : printf / printf_s, scanf / scanf_s 함수의선언기능헤더파일 int printf( const char *control-string,... ); 문자열을주어진서식에맞춰 stdout 으로출력한다. // until C99 int printf( const char *restrict format,... ); // since C99 int printf_s( const char *restrict format,... ); // since C11 stdio.h int scanf( const char *control-string,... ); int scanf( const char *restrict format,... ); stdin 으로부터형식화된바이트 문자를읽어들인다. // until C99 // since C99 int scanf_s( const char *restrict format,... ); // since C11 43
형식화된입출력 (3/16) 형식화된출력 : printf 계열함수 필드명세 % 부호와변환코드는필수이며나머지는생략가능 일반적으로출력은오른쪽으로맞춰진다. 맞춤을반대로하기위해서는플래그를마이너스기호 (-) 로지정한다. % < 플래그 > < 출력할최소자릿수 > < 정확도변환지정자 > < 크기 > 변환코드 44
형식화된입출력 (4/16) 형식화된출력 : printf 계열함수서식지정자 서식지정자 의미 데이터형 %c 인자를 char 형의한문자로출력 문자형 %d 또는 %i 인자를부호있는 10진수로출력 정수형 %u 인자를부호없는 10진수로출력 ( unsigned ) 정수형 %o 인자를부호없는 8진수로출력 정수형 %x, %X 인자를부호없는 16진수로출력 정수형 %f 인자를 float 나 double 형의실수로출력 부동소수형 %e, %E 인자를과학기술계산용표기법으로출력 부동소수형 %g, %G %e 와 %f 중더짧은표현선택 부동소수형 %s 문자열출력 문자열포인터 %p 포인터의주소를출력 포인터 %% % 부호를그대로출력 45
형식화된입출력 (5/16) 형식화된출력 : printf 계열함수 출력을위한양식 크기 변환코드 자료형 사용예 none c char %c h d / i short int %hd / %hi h u unsigned short int %hu none d / i int %d / %i none u unsigned int %u l / L d / i long int %ld / %li l / L u unsigned long int %lu ll / LL d / i long long int %lld / %lli ll / LL u unsigned long long int %llu none f float %f / %F l f double %lf / %LF L f long double %LF / %LF 46
형식화된입출력 (6/16) 형식화된출력 : printf 계열함수의부동소수점출력 %e, %E : 부동소수점표현방식에의한출력 %g, %G 3.1245e+2 3.1245 10 +2 2.45e-4 2.45 10-4 1. %f 형태출력 : 표현하고자하는실수의값이소수점이하 6자리인경우 2. %e 형태출력 : 이범위를넘길경우 %e 의형태로출력 #include <stdio.h> int main(void) { printf("%g \n", 0.00123); printf("%g \n", 0.000123); printf("%g \n", 0.0000123); printf("%g \n", 0.00000123); // 0.00123 출력 // 0.000123 출력 // 1.23e-005 출력 // 1.23E-006 출력 } return 0; 47
형식화된입출력 (7/16) 예제 1-4 : printf 계열함수의필드명세 -- 정수형데이터 #include <stdio.h> int main(void) { int a = 12345; printf( [%d]\n", a); // 정수출력 printf("[%8d]\n", a); // 출력할최소자리수 : 8 printf("[%08d]\n", a); // 0 플래그 : 빈칸을공백으로채움 printf("[%-8d]\n", a); // - : 왼쪽정렬 printf("[%+8d]\n", a); printf("[%+08d]\n", a); // + : 부호 (+) 출력 } return 0; 48
형식화된입출력 (8/16) 예제 1-5 : printf 계열함수의필드명세 -- 실수형데이터 #include <stdio.h> int main(void) { double d = 3.14159; printf("[%f]\n", d); // 실수출력 printf("[%8.2f]\n", d); printf("[%08.2f]\n", d); // 출력할최소자리수 (8) 와소수점 2 번째자리까지출력 printf("[%-8.2f]\n", d); printf("[%+8.2f]\n", d); // - : 왼쪽정렬 // + : 부호 (+) 출력 printf("[%+08.2f]\n", d); } return 0; 49
예제 1-6 : 다양한데이터출력 형식화된입출력 (9/16) #include <stdio.h> int main(void) { char ch = 'A'; double d = 3.14159; printf(" 실수형상수출력 : %lf \n", 3.14159 ); // long double printf(" 실수형변수출력 : %le \n\n", d ); // 지수형소수형태출력 printf(" 문자상수의출력 : %c \n", B ); printf(" 문자변수의출력 : %c \n\n", ch ); printf(" 문자열상수의출력 : %s \n", " 서두옥 ); printf(" 문자열상수의출력 : %5.3s \n", "Hi~ Clickseo ); } return 0; 50
형식화된입출력 (10/16) 형식화된입력 : scanf 계열함수 필드명세 % 부호로시작하며, 정확히하나의필드 ( 변수 ) 를기술한다. 문자형식코드 (%c) 를제외하고 scanf 는모든여백은건너뛴다. ( 입력의모든공백, 탭, 줄바꿈을무시한다.) 입력변환은다음과같은상황이발생할때까지입력문자를처리한다. 파일의끝 (EOF, end of file) 에도달했을때 부적절한문자를만났을때 읽은문자의수가명시된최대필드길이에도달했을때 모든필드명세에대하여대응되는변수가주소리스트에존재한다. C 에서 & 부호는주소연산자 (address operator) % < 플래그 > < 입력받을최대자리수 > < 크기 > 변환코드 51
형식화된입출력 (11/16) 형식화된입력 : scanf 계열함수 서식지정자 의미 자료형 %c 입력데이터를하나의문자상수로읽어들임 문자형 %d, %i 입력데이터를 10진수로읽어들임 정수형 %u 부호없는 10진수정수를읽어들임 정수형 %o 부호없는 8진수정수로읽어들임 정수형 %x 부호없는 16진수정수로읽어들임 정수형 %f, %e, %g 입력데이터를실수로읽어들임 (float) 실수형 %lf, %LF 입력데이터를실수로읽어들임 (double, long double) 실수형 %p 포인터를읽어들임 포인터 %s 입력데이터를문자열로읽어들임 문자포인터 %n 읽어들인문자수를저장 정수포인터 %[] 입력대상문자의필터링 (scanset의지정 ) 52
#include <stdio.h> int main(void) { char 형식화된입출력 (12/16) 예제 1-7 : 한문자입출력 -- scanf ch; printf(" 한문자입력 : "); scanf( %c", &ch); printf(" 문자출력 : %c \n", ch); } return 0; // scanf함수사용시visual Studio 경고메시지 warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. ------------------------------------------------------------------------------ 1) 첫번째해결방법 : #define _CRT_SECURE_NO_WARNINGS 2) 두번째해결방법 : #pragma warning(disable:4996) 3) 세번째해결방법 : scanf_s 함수사용 53
#include <stdio.h> 형식화된입출력 (13/16) 예제 1-8 : 한문자입출력 -- scanf_s int main(void) { char ch; printf(" 한문자입력 : "); scanf_s( %c", &ch); printf(" 문자출력 : %c \n", ch); } return 0; // scanf_s 함수사용시 Visual Studio 경고메시지 warning C4473: 'scanf_s': 서식문자열에대한인수가충분하게전달되지않았습니다. ----------------------------------------------------------------------------------------------- // 인자로버퍼의크기지정 * 해결방법 scanf_s( %c", &ch, sizeof(ch) ); 54
#include <stdio.h> 형식화된입출력 (14/16) 예제 1-9 : 두개의정수입출력과계산 int main(void) { int a, b; printf(" 두개의정수입력 : "); scanf_s( %d %d", &a, &b); printf( %3d + %3d = %3d\n", a, b, a + b); printf("%3d - %3d = %3d\n", a, b, a - b); } return 0; 55
형식화된입출력 (15/16) 예제 1-10 : 두개의실수입출력과계산 #include <stdio.h> int main(void) { double a, b; printf(" 두개의실수입력 : "); scanf_s( %lf %lf", &a, &b); printf( %.2f + %.2f = %.2f \n", a, b, a + b); printf( %.2f - %.2f = %.2f \n", a, b, a - b); } return 0; 56
형식화된입출력 (16/16) 형식화된입력 : scanf 계열함수의필터링기능 scanf / scanf_s 함수는문자열입력에적당한함수가아니다. 문자열에포함된공백문자로인해긴문장을입력받기에상당히불편 단어단위의입력에는 scanf / scanf_s 함수가적합할지모르겠으나, 문자열의입력은 gets / gets_s 함수를사용하는편이훨씬효율적이다. scanf / scanf_s 함수의필터링기능 입력받을대상문자를선별 (filtering) 하기위해사용 원하지않는문자의입력을막을수있는유용한기능 %[A-Z] // 대문자 A-Z 사이의문자만받아들인다. %[A-Za-z0-9] // 영문자및숫자만받아들인다. %[^0-9] // 숫자를제외한모든문자를받아들인다. 57
C 프로그램구조 C 언어개요 C 언어기본문법 콘솔입출력 C 프로그램구조 수식 논리적데이터와연산자 우선순위와결합성 데이터형변환 비트연산자 58
수식 (expression) 수식 (1/11) 단일값으로변환하기위한피연산자와연산자의나열 연산자 (operator) 피연산자 (operand) 수식들은항상단일값으로변형된다. 수식의종류 일차식 (primary expression) 이진식 (binary expression) 배정식 (assignment expression) 후위식 (postfix expression) 단항식 (unary expression) 콤마식 (comma expression) 삼원식 (ternary expression) 59
수식 (2/11) 일차식 (primary expression) temp 식별자 10 상수 (a + 5-3) 표현식 이름 (name) nvalue w100 Clickseo MAX_SIZE size 상수 (constant) 5 123.98 A Hi~ Clickseo 괄호식 (10 * 5 + 20) (a = 10 + b * 5) 60
수식 (3/11) a + 5 이진식 (binary expression) 피연산자 연산자 피연산자 곱셈식 (multiplicative expression) 종류 * / % 내용두피연산자들의대수곱셈첫번째피연산자를두번째피연산자로나누는대수나눗셈 - 두피연산자가정수 정수몫 - 둘중어느한쪽의피연산자가부동소수점이면부동소수점몫첫번째피연산자를두번째피연산자로나눈나머지 (remainder) 정수 나눗셈 : 10 / 3 3 나머지 : 10 % 3 1 부동소수점수 나눗셈 : 10.0 / 3.0 3.333333 모듈러스 (Modulus) 연산자의두피연산자들은반드시정수형태가되어야한다. 61
수식 (4/11) 예제 1-11 : 이진식 #include <stdio.h> int main(void) { int a = 10; int b = 3; printf( %d + %d = %d\n, a, b, a + b); printf( %d - %d = %d\n, a, b, a - b); printf( %d * %d = %d\n, a, b, a * b); printf( %d / %d = %d\n, a, b, a / b); printf( %d %% %d = %d\n, a, b, a % b); } return 0; 62
수식 (5/11) 배정식 (assignment expression) 할당연산자 (=) 의오른쪽피연산자를평가하고, 왼쪽변수에대입 하나의값과하나의결과 두가지형태 단일배정 (simple assignment) 복합배정 (compound assignment) temp = 10 + 5 변수 할당연산자 표현식 63
수식 (6/11) 배정식 : 복합배정 복합배정 (compound assignment) : 단일배정에대한약칭표기 복합식 등가식 a *= b a /= b a %= b a += b a -= b a = a * b a = a / b a = a % b a = a + b a = a b 만약복합배정이이진식과함께사용된다면이진식이먼저평가된다. a *= b + 3 --> a = a * (b + 3) 64
수식 (7/11) 예제 1-12 : 복합배정 #include <stdio.h> int main(void) { int a = 10, b = 3; printf("a : %d, b : %d \n", a, b); printf("a += b : %d \n", a += b ); printf("a : %d, b : %d \n\n", a, b); a = 10; b = 3; printf("a : %d, b : %d \n", a, b); printf("a %%= b : %d \n", a %= b ); printf("a : %d, b : %d \n", a, b); } return 0; 65
수식 (8/11) 후위식 (postfix expression) 후위연산자 a++ 피연산자 함수호출 함수이름은피연산자이고연산자는이름뒤에오는괄호이다. 후위증가 (postfix increment) 와후위감소 (postfix decrement) 수식 a++ a-- 등가식 a = a + 1 a = a 1 66
단항식 (unary expression) 수식 (9/11) 하나의연산자와하나의피연산자로구성단항연산자 ++a 피연산자 전위증가 (prefix increment) 와전위감소 (prefix decrement) 수식 ++a --a 등가식 a = a + 1 a = a - 1 67
예제 1-13 : 전위증가와후위증가 #include <stdio.h> 수식 (10/11) int main(void) { int a = 30, b = 30; printf("%d, %d\n", a, b); printf("%d\n", ++a ); printf("%d, %d\n", a, b); printf("%d\n", a++ ); printf("%d, %d\n", a, b); printf("%d\n", ++a + ++b ); printf("%d, %d\n", a, b); printf("%d\n", b++ + b++ ); printf("%d, %d\n", a, b); } return 0; 68
수식 (11/11) 단항식 : 부호와 sizeof 연산자 sizeof 연산자 sizeof (int) // 할당받는메모리공간의크기를바이트단위로반환 res = sizeof (int) // sizeof 연산자의결과 ( 정수형의값 ) 를저장 sizeof (-345.23) // 실수형상수가할당받는메모리공간의크기를확인 단항플러스 (unary plus) 와단항마이너스 (unary minus) 수식수식평가전 / 후 a 의내용수식값 +a -a +a -a 10 10-10 -10 +10-10 -10 +10 69
C 프로그램구조 논리적인데이터와연산자 70
논리적데이터와연산자 (1/4) 논리연산자 (logical operators) 논리적데이터 (logical data) ( 명제 ) 실생활에서 예-아니요 와같은데이터 컴퓨터과학에서는참 (true) 과거짓 (false) 을사용한다. not 연산자 :! 15의선행을갖는단항연산자 (unary operator) 참값 (nonzero) 을거짓 (zero) 으로바꾸고, 거짓값 (0) 을참 (1) 으로바꾼다. and 연산자 : && 5의선행을갖는이진연산자 (binary operator) or 연산자 : 4의선행을갖는이진연산자 만약값이 0 이면, 논리값이거짓으로사용된다. 만약값이 0 이아니면, 논리값은참으로사용된다. 71
예제 1-14 : 논리식 #include <stdio.h> int main(void) { int a = 5; int b = -5; int c = 0; 논리적데이터와연산자 (2/4) printf(" %2d && %2d : %2d\n", a, b, a && b ); printf(" %2d && %2d : %2d\n", a, c, a && c ); printf(" %2d && %2d : %2d\n\n", c, a, c && a ); printf(" %2d %2d : %2d\n", a, c, a c ); printf(" %2d %2d : %2d\n", c, a, c a ); printf(" %2d %2d : %2d\n\n", c, c, c c ); printf("!%2d &&!%2d : %2d\n", a, c,!a &&!c ); printf("!%2d && %2d : %2d\n", a, c,!a && c ); printf(" %2d &&!%2d : %2d\n", a, c, a &&!c ); } return 0; 72
논리적데이터와연산자 (3/4) 관계연산자 (relational operators) 두개의피연산자를받아서서로비교하는이진연산자 결과는논리적데이터값 : 항상참 (1) 과거짓 (0) 관계연산자의미우선순위 < <= > >= ==!= less than less than or equal greater than greater than or equal equal not equal 10 9 73
#include <stdio.h> 논리적데이터와연산자 (4/4) 예제 1-15 : 관계연산자 int main(void) { int a = 5; int b = -5; printf(" %2d > %2d : %2d\n", a, b, a > b ); printf(" %2d >= %2d : %2d\n\n", a, b, a >= b ); printf(" %2d < %2d : %2d\n", a, b, a < b ); printf(" %2d <= %2d : %2d\n\n", a, b, a <= b ); printf(" %2d == %2d : %2d\n", a, b, a == b ); printf(" %2d!= %2d : %2d\n", a, b, a!= b ); } return 0; 74
C 프로그램구조 우선순위와결합성 데이터형변환 75
우선순위와결합성 (1/2) 기능별분류 연산자 결합성 우선순위 일차연산자 ( ) [ ] ->. 1 단항연산자 + - ++ --! ~ * & sizeof (datatype) 2 산술연산자 * / % 3 + - 4 시프트연산자 << >> 5 비교연산자 < <= > >= 6 등가연산자 ==!= 7 & 8 비트논리연산자 ^ 9 10 논리연산자 && 11 12 조건연산자? : 13 대입연산자 = += -= *= /= %= <<= >>= &= ^= = 14 콤마연산자, 15 76
우선순위와결합성 (2/2) 결합성 (associativity) 왼쪽결합성 (left associativity) 왼쪽에서시작하여오른쪽으로이동해가면서수식을평가하는것 3 * 8 / 4 % 4 * 5 --> (((3 * 8) / 4) % 4) * 5) 오른쪽결합성 (right associativity) 오른쪽에서왼쪽으로진행해가면서수식을평가하는것 3 가지형식 : 단항식, 조건부삼원식, 그리고배정식 a += b *= c -= 5 --> (a += (b *= (c -= 5))) 77
데이터형변환 (1/7) 묵시적형변환 (implicit type conversion) C 컴파일러가자동으로데이터의형식을변형시키는것 C 언어는내부적으로정해진자동변환규칙에따라혼합식을처리 long double double 수 식 중간형식 char + int int long int * double int long double 자동형변환 float unsigned long int long int float / double (char + int) / double double double unsigned int int short int char 78
예제 1-16 : 묵시적형변환 #include <stdio.h> int main(void) { char ch; int i; float f; double d; 데이터형변환 (2/7) ch = 35; i = 35000; f = 1.3; // warning C4305: '=' : truncation from 'const double ' to 'float ' d = ch * i * f + 30000; printf(" 최종결과 : %lf \n", d); } return 0; 79
예제 1-17 : 묵시적형변환 #include <stdio.h> 데이터형변환 (3/7) int main(void) { int i; double d; i = 10; d = 3.14159; /* i * d 의연산도중컴파일러가 double 형의메모리공간을할당하고그값을출력할뿐이지 i 의크기가실제로변하는것은아니다. */ printf( 최종결과 : %lf \n", i * d ); } return 0; 80
예제 1-18 : 데이터손실 데이터형변환 (4/7) #include <stdio.h> int main(void) { int i; char ch; i = 128; // warning C4244: '=' : conversion from int to char, possible loss of data ch = i; // 데이터손실발생 printf("i = %d \n", i); printf("ch = %d \n", ch); } return 0; 81
예제 1-19 : 데이터손실 데이터형변환 (5/7) #include <stdio.h> int main(void) { int i; double d; d = 3.14159; // warning C4244: '=' : conversion from double' to int', possible loss of data i = d; // 소수점이하가모두잘려나간다 ( 데이터손실발생 ). printf("d = %lf \n", d); printf("i = %d \n", i); } return 0; 82
데이터형변환 (6/7) 명시적형변환 (explicit type conversion) 임의로어떤형식에서다른형식으로데이터를변환시킨다. cast 수식연산자 (cast expression operator) (double) a; // 피연산자는단항식이어야한다. (double) (a + b); // 두개의정수합을하나의부동소수로변형 ave = (double) tot / num; (double) (a / 10); // a 가 3 이라면결과값은 0.0 (double) a / 10; // 부동소수결과는숫자들중하나를명시적형변환 83
#include <stdio.h> int main(void) { double a, b; int res1, res2; a = 3.4; b = 2.1; 데이터형변환 (7/7) 예제 1-20 : 명시적형변환과묵시적형변환 // warning C4244: '=' : conversion from 'double ' to 'int ', possible loss of data res1 = a * b; // 묵시적 ( 자동 ) 형변환 res2 = (int) a * (int) b; // 명시적 ( 수동 ) 형변환 printf("res1 = %d \n", res1); printf("res2 = %d \n", res2); } return 0; 84
C 프로그램구조 비트연산자 85
비트연산자 (1/8) 비트연산자 비트단위의정밀한데이터제어를위해사용 char 를포함한정수계산이가능한정수형데이터에서만동작 ( 주의 ) 피연산자로 double 이나 float 과같은부동형을사용할수없다. 구분연산자의미 ~a 1 의보수연산 비트논리연산 시프트연산 a & b a b a ^ b a << n a >> n a와 b의비트단위논리곱 (AND) a와 b의비트단위논리합 (OR) a외 b의비트단위배타적논리합 (XOR) a의각비트를왼쪽으로 n 만큼이동 a의각비트를오른쪽으로 n 만큼이동 86
~ : 1 의보수연산자 1 s complement operator 비트연산자 (2/8) 단항연산자로각각의데이터비트를반대로바꾼다. 1은 0으로 0은 1로바꾼다 ( 부호비트도반전 ). & : 논리곱 비트단위논리곱 (AND) : 특정비트값을 0 으로만들기위해주로사용 a = a & 0x00FF; 00110100 01000001 : a 00000000 11111111 : 0x00FF 00000000 01000001 : a & 0x00FF 87
비트연산자 (3/8) : 논리합 비트단위논리합 (OR) : 특정비트값을 1 로만들기위해주로사용 a = a 0xFF00; ^ : 배타적논리합 00110100 01000001 : a 11111111 00000000 : 0xFF00 11111111 01000001 : a 0xFF00 비트단위배타적논리합 (XOR) : 특정비트를반전시키기위해사용 각각의비트가서로다를때 1 이된다. a = a ^ 0xFF00; 00110100 01000001 : a 11111111 00000000 : 0xFF00 11001011 01000001 : a ^ 0xFF00 88
예제 1-21 : 비트논리연산자 #include <stdio.h> 비트연산자 (4/8) int main(void) { int a = 0x00001111, b = 0x0000FFFF; printf(" a = %p, ~a = %p \n", a, ~a ); printf(" b = %p, ~b = %p \n\n", b, ~b ); printf("a & b = %p\n", a & b ); printf("a b = %p\n", a b ); printf("a ^ b = %p\n", a ^ b ); } return 0; 89
시프트연산 : 좌시프트 좌시프트연산자 : << 비트연산자 (5/8) 주어진자릿수만큼비트를왼쪽으로이동시킬수있는연산자 비트연산자의대상 : 정수 ( 즉, float 형이나 double 형에비트연산을할수없다.) 원래있던것은잘려나간다 int i = 10; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 i = i << 8; 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 이동된자리는 0 으로채워진다 90
시프트연산 : 우시프트 우시프트연산자 : >> 비트연산자 (6/8) 주어진자릿수만큼비트를오른쪽으로이동시킬수있는연산자 비트연산자의대상 : 정수 (float 형이나 double 형에비트연산을할수없다.) int i = -1; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 i = i >> 1; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 부호비트가이동하면빈자리는부호비트로복사된다 91
예제 1-22 : 비트연산자 - 좌시프트 #include <stdio.h> 비트연산자 (7/8) int main(void) { int a = 10; // 왼쪽으로 1비트씩시프트할때마다값은 2배가된다. printf("a = %3d\n", a ); printf("a << 1 = %3d\n", a << 1 ); printf("a << 2 = %3d\n", a << 2 ); printf("a << 3 = %3d\n", a << 3 ); printf("a << 4 = %3d\n", a << 4 ); } return 0; 92
예제 1-23 : 비트연산자 - 우시프트 #include <stdio.h> 비트연산자 (8/8) int main(void) { int a = 10; // 오른쪽으로 1비트씩시프트할때마다값은 1/2 이된다. printf("a = %3d\n", a ); printf("a >> 1 = %3d\n", a >> 1 ); printf("a >> 2 = %3d\n", a >> 2 ); printf("a >> 3 = %3d\n", a >> 3 ); printf("a >> 4 = %3d\n", a >> 4 ); } return 0; 93
참고문헌 [1] 서두옥, 이동호 ( 감수 ), ( 열혈강의 ) 또하나의 C : 프로그래밍은셀프입니다, 프리렉, 2012. [2] Paul Deitel, Harvey Deitel, "C How to Program", Global Edition, 8/E, Pearson, 2016. [3] SAMUEL P. HARBISON Ⅲ, GUY L. STEELE, C 프로그래밍언어, C : A Reference Manual, 5/E, Pearson Education Korea, 2005. [4] Behrouz A. Forouzan, Richard F. Gilberg, 김진외 7인공역, 구조적프로그래밍기법을위한 C, 도서출판인터비젼, 2004. [5] Brian W. Kernighan, Dennis M. Ritchie, 김석환외 2인공역, The C Programming Language, 2/E, 대영사, 2004. [6] 김일광, C 프로그래밍입문 : 프로그래밍을모국어처럼유창하게, 한빛미디어, 2004. 이강의자료는저작권법에따라보호받는저작물이므로무단전제와무단복제를금지하며, 내용의전부또는일부를이용하려면반드시저작권자의서면동의를받아야합니다. Copyright Clickseo.com. All rights reserved. 94