C언어 입문 강의 계획서.

Slides:



Advertisements
Similar presentations
기본 자료형 순천향대학교 정보기술공학부 이 상 정. 자료형의 선언 컴퓨터프로그래밍 1 순천향대학교 정보기술공학부 이 상 정 3 자료형 선언 기본 자료형문자형 char 정수형 int 실수형 float double 형없음 void.
Advertisements

YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
제6장 조건문.
C 프로그래밍 기초.
제 3 장 변수와 자료형.
제12장 표준 입출력과 파일 입출력.
C++ Espresso 제1장 기초 사항.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
제 1장 C 언어의 소개.
2014 ITA 8월 강의 C Programming -1주차- C언어 기초 정대진 ( )
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express Slide 1 (of 25)
C 프로그래밍 소개 숙명여대 창병모 2011 가을.
제 7 장 문장 구조화 제어문 지정문 조건문 반복문 GOTO 문 비결정적문.
Chapter 10– 표준 함수(1) Outline 10.1 스트림과 파일 10.2 입출력 표준 함수
구조체 활용 구조체 활용.
쉽게 풀어쓴 C언어 Express 제13장 구조체 C Express.
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
C 10장. 함수의 활용 #include <stdio.h> int main(void) { int num;
쉽게 풀어쓴 C언어 Express 제18장 입출력과 라이브러리 함수 C Express.
4장: 자료형과 수식.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
처음으로 배우는 C 프로그래밍 제2부 기초 제5장 반복문.
쉽게 풀어쓴 C언어 Express 제16장 파일 입출력 C Express Slide 1 (of 23)
HW#1 Source 파일 제출 3.20(수)까지 제출 학번_이름_01.c
Part 14 파일 입출력 ©우균, 창병모 ©우균, 창병모.
변수와 자료형.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
동적메모리와 연결리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
기초C언어 제3주 C프로그램 구성요소, 변수와 자료형 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원
쉽게 풀어쓴 C언어 Express 제3장 C프로그램 구성요소 C Express.
10장 포인터와 문자열 포인터 기본 배열과 포인터 매개변수 전달방법 포인터와 문자열.
처음으로 배우는 C 프로그래밍 제5부 추가적인 화제들 제 11 장 파일 처리.
C언어 프로그래밍의 이해 Ch05. 명령문 Phylogenetic: 계통, 발생(학)의.
12장 파일처리와 매크로 파일 입출력 함수 문자 입출력 함수 라인 입출력 함수 불록 입출력 함수 매크로.
제 2 장 변수와 상수.
Chapter 3 Flow of Control
Chapter 11 Strings.
C언어 프로그래밍의 이해 Ch14. 파일 입출력.
14주차.
제 3 장 상수와 변수
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
Chapter 13 Input/Output and Files
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
4장 제어문 선택문: if 문, if – else 문, switch 문
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
Derived Types-- Enumerated, Structure and Union
adopted from KNK C Programming : A Modern Approach
Chapter 2 Lexical Elements, Operators, and the C System
제2장 데이터형과 표준 입출력문 문봉근.
C언어 프로그래밍의 이해 Ch13. 선행처리기와 주석문.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
자전거를 배우려면 안장에 올라가 페달을 밟아라.
컴퓨터 프로그래밍 기초 - 4th : 수식과 연산자 -
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
컴퓨터 프로그램 제2,3장 간단한 C 프로그램 김 문 기.
처음으로 배우는 C 프로그래밍 제3부 함수 제 6 장 함수 작성.
Chapter 05. 입출력 함수.
C언어 프로그래밍의 이해 Ch05. 명령문.
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express Slide 1 (of 28)
1학기 정리 지난 학기에 배운 내용을 복습해 본다..
C언어 프로그래밍의 이해 Ch03. 기본 자료형, 변수와 상수.
반복문의 기능 반복문 반복문 특정 영역을 특정 조건이 만족하는 동안에 반복 실행하기 위한 문장 while문
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
3주차: Control Flow and Others
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
printf("Global Korea\n");
개정판 누구나 즐기는 C언어 콘서트 제12장 파일 입출력 출처: pixabay.
배열, 포인터, 함수 Review & 과제 1, 2.
Presentation transcript:

C언어 입문 강의 계획서

제 1 장 C 언어의 시작 : 기초 C 언어의 역사 C 언어의 특징 1972년 미국 Bell 연구소에서 Denis Richie에 의해 개발 ALGOL60  CPL  BCPL  B  C 언어로 개발 C 언어의 특징 다양한 연산자 명쾌한 구조 함수에 의한 구성 표준함수 사용자 정의 함수 간결하고 일관된 데이터 처리 동적이며 능동적인 메모리 관리 포인터 사용 높은 이식성

프로그램의 개발 흐름 프로그램의 설계 Library 최종 프로그램 자료구조설계 알고리즘 설계 Source Code 생성 struct Student { int i; char name[10]; } for ( int j=0 ; j <= 10 ; j++) { ……. } Source Code 생성 Library 테스트 & 디버깅 최종 프로그램

#include <stdio.h> #define MAX 100 void getInput(); int x, y; void main(void) { int a, b, c ; for ( a = 0 ; a < 10 ; a++) ……………. } Header 선언부 매크로 정의 문 Prototype 부분 변수 선언 부분 Main 함수 지역변수 선언부

C 프로그램의 구성 요소 상수 : 정수 상수, 실수 상수, 문자 상수, 문자열 상수, 열거형 상수 상수 : 정수 상수, 실수 상수, 문자 상수, 문자열 상수, 열거형 상수 변수 : 정수형 변수, 문자형 변수, 실수형 변수, 배열 연산자 할당연산자 : = 산술연산자 : +, -, * , / , %(정수 나머지), ++, -- 관계연산자 : <, >=, <, <=, ==, != 논리연산자 : &&(AND), ||(OR), !(NOT) 비트연산자 : ~, &, ^, <<, >> 복합연산자 : +=, -=, *=, /= 제어문 조건문 : if, switch 반복문 : for, do-while, while 함수 표준 함수 사용자 정의함수

표준 입력과 표준 출력 표준 입출력 라이브러리 함수 이용 한 문자 단위의 입출력 형식화된 입출력 제공 getchar 키보드로부터 한 문자를 입력 c = getchar() ; putchar 화면에 한 문자를 출력하는 함수 putchar(c) ; 형식화된 입출력 제공 printf : 형식화 출력 scanf : 형식화 입력 기본 형식 문자형 : %(-, k)s : -(정렬기준), k(출력 자릿수) 정수형 : %(+,-,k)d/u/x/o/ : +(양수의 + 기호 출력), -(왼쪽기준정렬) 실수형 : %(w.k)f/lf/e/g : w(전체 자릿수), k(소수점 아래 자릿수)

입력과 출력 printf() , scanf() 함수의 중요 서식

출력과 입력 예제 1 } #include <stdio.h> void main() { printf("%10d , %10u,%#10x, |%-10ld| \n",123, 50000, 123, 123456); printf("%10.3lf, %10.2e, \n ",42.195, 42.195); printf("%c , |%10c|, %s ”, ‘q’, ‘q’, “good”); } #include <stdio.h> void main() { float c, f; printf("Type Fahrenheit(F) degree : "); scanf("%f", &f); c= (f - 32) * 5 / 9.0; printf("Centigrade degree = %3.1f\n", c); }

#include <stdio.h> 출력과 입력 예제 2 #include <stdio.h> void main() { char ch; int age = 19 ; int days = 365; scanf ("%c", &ch); printf(“%c\n”, ch); printf ("%d, %d", age, days); }

함수 프로그램의 기능적 분할 호출부(caller)에 내부 구현 내용이 보이지 않음 함수의 정의 방법 되돌림_자료형 함수_이름(매개변수 리스트 …) { 변수 선언 및 초기화부 C 구문들 …... } 호출부와 피호출 함수사이의 데이터 전달 인자(argument) 전달 : Call by Value, Call by Reference 함수의 Return Value

변수 변수와 심볼 상수 모든 변수는 사용되기 전에 반드시 선언되어야 한다. 문자, 숫자, '_'(underscore)로 구성됨 반드시 첫 글자는 문자 또는 '_’ 처음 31자까지만 의미가 있음 대문자와 소문자 구별(case sensitive) 변수는 주로 소문자를, 심볼 상수는 대문자를 사용 C 언어의 키워드는 변수의 이름으로 사용될 수 없음 모든 변수는 사용되기 전에 반드시 선언되어야 한다. 변수의 초기화 : 변수는 사용되기 전 초기화 되어야 한다. 한정사 const 값이 변경되지 않는 변수의 선언에 사용 ex) const char msg[] = "This will not be changed.";

C언어의 자료형과 크기 정수형 실수형 문자형

상수 정수 상수(integer constant) 실수 상수 문자 상수 십진수, 8진수, 16진수로 표현가능 접미사 l or L: long 상수 u or U: unsigned 상수 ex) 1234, -1234, 1234L, 01234, 0xabcd, 0XABCD 실수 상수 123.4, 1.234e2, 1.234E2의 형태로 표현 f or F: float l or L: long double 문자 상수 ‘a’, ‘A’, ‘0’ 과 같이 표현(single quote 사용) escape sequence: 제어 문자 표현

상수(con’d)

상수(con’d) 문자열(String) 상수 열거형 상수(enumeration constant) “SEOUL”와 같이 double quote로 둘러싸인 일련의 문자들 “SEOUL”  “”: 빈 문자열 문자 상수 ‘a’와 문자열 상수 “a”는 구분되어야 한다. 문자열은 반드시 Null(‘\0’) 문자로 끝난다. 열거형 상수(enumeration constant) enum boolean FALSE, TRUE ; FALSE는 0값을 갖고 TRUE는 1값을 갖는다. #define을 사용하는 것보다 간결함 enum형 변수를 정의할 수 있다. enum boolean bool; ex) enum escapes { BELL = ‘\a’, BACKSPACE = ‘\b’, TAB = ‘\t’ }; enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ; /* FEB = 2, MAR = 3, ..... */

예제 프로그램 void main() { char ch = 256 ; printf ("%d \n", 256); 다음 프로그램은 결과의 값이 바뀌어 출력된다. 그 이유는? 실수값을 하나 읽어 들여, 이를 소수점 이하 2째 자리에서 반올림하여 출력하는 프로그램을 작성하시오. void main() { char ch = 256 ; printf ("%d \n", 256); printf ("ch = %d \n", ch); }

프로그래밍 실습 초급 중급 고급 사용자의 입력을 받아서 평균, 분산을 출력하는 프로그램을 작성하라. 사용자의 입력을 받아서 대문자를 소문자로 소문자를 대문자로 바꾸는 프로그램을 작성하라.(scanf, printf 사용.) 중급 이차 방정식의 계수를 입력 받아서 이차방정식의 해가 있으면 해를 출력하고 그렇지 않으면 해가 없다는 것을 출력하는 프로그램을 작성하라. printf문에서 제공하는 기능을 구현할 수 있는 myprintf를 구현하라. 고급 포스트픽스(postfix) 계산기를 구현하라.

제 2 장 연산자와 제어문 : 산술 연산자 사칙 연산과 나머지 연산(%) 관계연산자와 논리연산자 제 2 장 연산자와 제어문 : 산술 연산자 사칙 연산과 나머지 연산(%) 이항(binary) 연산자: +. -. *, /, % *, /, % 연산은 +, -보다 연산 우선순위가 높다. % 연산은 float와 double형에는 사용될 수 없다. 단항(unary) 연산자 +와 -는 이항 연산자보다 우선순위가 높다. 관계연산자와 논리연산자

비트 연산자와 증감 연산자 char, short, int, long형의 피연산자만을 취함 비트 연산자의 종류 증감연산자 ++: 1만큼 증가시킴 -- : 1만큼 감소시킴 전위(prefix) 또는 후위(postfix)에 위치할 수 있음 전위에 오는 경우: 변수를 참조하기 전에 증감 연산 수행 후위에 오는 경우: 변수를 참조하고 증감 연산을 수행 ex) n = 0; n = 0; x = ++n; x = n++; n = 1, x = 1 n = 1, x = 0;

지정 연산자와 조건부 수식 i = i + 2;와 같이 왼쪽의 변수가 오른쪽에서 반복되는 경우에 사용 연산자의 사용 예 i += 2; -= 2; *= 2; 아래와 같은 동작을 취하는 삼항(ternary) 연산자 ?: if (expr1) expr2; else expr3; => expr1 ? expr2 : expr3으로 표현 계산 과정 expr1을 계산하여 결과가 참이면 expr2가 수행되고 거짓이면 expr3을 수행 ex) max = (a > b) ? a : b;

형변환(type conversion) 연산자가 서로 다른 형의 피연산자를 가질 때 형변환이 필요 일반적으로 크기가 작은 피연산자를 큰 연산자로 바꿈 배열의 첨자에 float를 쓰는 것과 같은 의미가 맞지 않는 수식은 형변환이 허용되지 않음 형변환 규칙 Rule 1. 피연산자 중 long double이 있으면 나머지는 long double로 변환 Rule 2. 피연산자 중 double이 있으면 나머지는 double로 변환 Rule 3. 피연산자 중 float가 있으면 나머지는 float로 변환 Rule 4. 피연산자 중 char나 short는 int로 변환 Rule 5. 피연산자 중 long이 있으면 나머지는 long으로 변환 type cast: 명시적 형 변환 int i ; float f = 12.34 ; i = (int) f ;

연산자 간의 우선순위

예제 #include <stdio.h> main() { int x, y, z; x = 1, y = 2, z = 4; x = x || y && z; printf ("%d\n",x); x = 1, y = 2, z = 3; x = (x > y || z ==y && x<z); x = y = z = 1; x = -y++ + ++z; printf ("%d\n%d\n%d\n",x,y,z); }

문장(statement)와 블록(block) 지정문, 증감 연산( ++, -- ), 함수 호출 등의 서식 문장문 ;( semicolon)으로 끝남 블록 복합문(compound statement) brace { } 로 선언과 문장들을 모아서 복합문을 만듦 ex) function body

If 조건문 판단이나 결정을 나타내기 위해 사용 if (expression) 모호성(ambiguity) statement1 for true else statement2 for false 모호성(ambiguity) if ( n > 0 ) if ( a > b ) z = a ; else z = b ; /* else 와 매치되는 if는 ? */ 모호성의 해결 가장 가까운 if 의 else로 취급, 브레이스를 사용(명시적 지정) ex) if ( n > 0 ) { if ( a > b ) z = a ; } else z = b ;

if 문 사용예제 #include <stdio.h> void main() { char ch; ch = getch(); if( ch >= 'a' && ch <= 'z') printf("it's small case\n"); else if ( ch > '9' || ch < '0') printf("it's not number\n"); } #include <stdio.h> void main() { int num1, num2; printf("Input two numbers: "); scanf("%d %d",&num1, &num2); printf("\nThe maximum number is :"); if (num1 > num2) printf("%d\n", num1); else printf("%d\n", num2); }

switch문 switch 문은 다중 비교 분기의 특별한 경우 구문 switch (expression) { break case const-expr : statements break : .................... default: statements } break case는 레이블로만 사용됨 제어의 흐름을 switch문에서 벗어나게 함

switch 문 사용예제 #include <stdio.h> void main() { char ch; printf("type a char : "); switch(ch = getchar()) case 'y' : case 'Y' : printf("Yes"); break; case 'n' : case 'N' : printf("No"); case 'q' : case 'Q' : printf("Quit"); default : printf(“Nothing”); }

반복문 : while 문 구문 while ( expression ) statement expression은 계산되어 만약 0이 아닌 값을 가지면 statement가 수행이 되고 expression을 다시 계산, 이러한 반복은 expression이 0이 될 때까지 계속됨 예제 int i = 0 ; while ( i <= 100 ) { .......... i++ ; }

반복문 : for 문 구문 for ( expr1 ; expr2 ; expr3 ) for문의 구조 statement for문의 구조 expr1과 expr3은 일반적으로 지정문이나 함수 호출로 구성 expr2는 관계 수식(relational expression)으로 표현 세 개의 수식 중 어느 하나를 생략하더라도 세미콜론(;)은 그대로 존재 expr2가 생략되면 항상 참인 조건을 의미 for ( ; ; ;) { /* infinite loop */ ....... } 순환문의 중단 break와 return 사용 순환문 내에 순환문을 중첩시킬 수 있음

for 문 사용예제 #include <stdio.h> #include <ctype.h> char message[] = "Hello My name is xxx"; unsigned long count[256]; void main() { int i; for(i=0; message[i]; i++) count[message[i]]++; for (i = 0; i < sizeof(count)/sizeof(count[0]); i++) if (count[i]) { isprint(i) ? printf("%c(%#x)", i,i) : printf(" %#x", i); printf("- %lu\n", count[i]); }

comma 연산자 하나의 수식에서 여러 개의 계산을 수행하는 경우에 사용 comma는 함수의 인자를 분리하는 데도 사용하고 변수의 선언에도 사용되지만 이는 comma 연산자가 아님 예제 #include <string.h> main() { int c, i, j; char *s = “Hello world”; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; }

do while문 for문과 while문은 순환문의 종료 조건을 순환문의 시작 위치에서 검사 구문 do { statement } while (expression); 동작 statement가 먼저 수행이 되고 expression이 계산됨 만약 expression이 참이면 statement는 다시 수행을 반복하게 되고 expression이 거짓이 되면 반복을 종료

do while문(con’d) 예제 #include <stdio.h> main() { int ch; do { printf("Once again? (y/n) "); ch = getchar(); } while (ch != 'n' && ch != 'y'); }

Break 와 Continue Break Continue for, while, do while, switch문 바깥으로 빠져 나가는데 사용 순환문이 중첩되는 경우에는 break를 둘러싸는 가장 안쪽 순환문을 빠져 나옴 Continue break 문에 비해 자주 사용되지는 않음 for, while, do while 문에서만 사용될 수 있음 순환문의 실행 도중 continue문을 만나면 순환문의 나머지 부분은 수행하지 않고 다음 번의 반복을 수행

Break, Continue 의 사용 예 #include <stdio.h> void main() { char ch; switch(ch = getch()) { case 'a' : putch('a'); case 'b' : putch('b'); case 'c' : putch('c'); break; case 'd' : putch('d'); } putch('e'); putch('f'); #include <stdio.h> void main() { while(1) { printf("\n press 'q' : "); if(getch() != 'q') continue; else break; }

예제 /* 소수 추출 프로그램(C Primer Plus에서 발췌) */ #include <stdio.h> main() { int number, divisor, limit; int count = 0; printf("상한 값을 입력하라.(2보다 커야함) :"); scanf("%d",&limit); while (limit < 2) { /* 입력오류 검사 */ printf("다시 입력하라: "); }

예제(con’d) printf("1에서 %d까지의 소수들은..\n",limit); for (number=2;number<=limit;number++) { for (divisor=2;number%divisor != 0;divisor++) ; if (divisor == number) { printf("%5d ",number); count++; if (count % 10 == 0) /*한 줄에 10개의 소수출력*/ printf("\n"); } getch();

프로그래밍 실습 초급 중급 고급 입력 받은 데이터 중에서 가장 큰 값과 가장 작은 값의 중간값을 출력하는 프로그램을 작성하라. 프로그램 file에서 주석을 제거 하는 프로그램을 작성하라. \n, \t을 실제로 newline character와 tab character로 바꿔주는 프로그램을 작성하라. 고급 C의 reserved word, operater, string, character, function name 등을 token으로 분리해 내는 lexer를 작성하라.

제3장 함수와 기억 클래스 : 함수의 기초 함수 함수를 사용하는 이유 함수 간의 통신 주 프로그램으로부터 인수(argument)를 전달 받아 일련의 작업을 수행한 후 생성된 결과를 주프로그램(main)으로 전달하는 하나의 단위 프로그램 함수를 사용하는 이유 반복되는 코드 작성을 없애 줌 프로그램을 이해하기 쉽고 이식이 용이하게 함 모듈성(modularity) 향상시킴 함수 간의 통신 인자의 전달과 리턴되는 값 외부 변수를 이용

return STATEMENT return 문을 만났을 때 return 문이 expression을 가지고 있을 때 예 함수의 실행이 종료 제어가 calling environment로 넘겨진다 return 문이 expression을 가지고 있을 때 expression의 값이 calling environment로 전달됨 해당 값은 함수 정의에 명시된 type으로 변환됨 예 return; return ++a; return (a * b);

정수 이외의 값을 리턴하는 함수 void 형 함수 정수 이외의 값을 리턴하는 함수 리턴 값이 없는 함수 return ; 의 형태로 사용 정수 이외의 값을 리턴하는 함수 C는 함수의 리턴형이 명시되지 않으면 int형으로 간주 함수의 원형(prototype)이 필요 함수의 원형(prototype)이 필요한 이유 함수의 리턴값을 알 수 있음 함수 호출 시 자동적인 인자의 형 검사 컴파일 시 인자 전달 오류 검사 가능

함수의 원형 선언 선언 방법 인자 리스트에 인자의 데이터형만을 지정해도 됨 인자가 없는 경우는 void로 지정 return-type function-name(argument type list); 인자 리스트에 인자의 데이터형만을 지정해도 됨 인자가 없는 경우는 void로 지정 함수의 원형 선언은 함수의 정의와 일치하여야 한다 형식 인자의 이름은 달라도 됨 예제 double sqrt(double x); double atof(char []); int getchar(void);

표준 함수와 사용자 정의 함수 표준 함수 사용자가 정의한 함수 printf(), scanf(), getch() reference guide 참조 헤더 파일 표준 함수들을 기능별로 구분하여 선언해 놓은 파일 #include를 사용하여 포함 ex) math.h : 수학적 처리에 담당하는 함수 graphics.h : 그래픽 관련 함수 string.h : 문자열 처리 함수 사용자가 정의한 함수 사용자가 직접 선언 필요 함수의 정의 return-type fuction-name(argument declarations) { declarations and statements }

main 함수와 인자 main() 함수의 원형 int main( int argc, char *agrv[] ) ; int argc : command line에 쓰여지는 인자의 갯수 char *argv[] : command line에서 입력한 인자들이 존재하는 메모리의 번지수를 차레대로 기억하고 있다. argv[0] : 실행 파일 이름(경로가 입력된 경우는 경로까지 포함) argv[1] : 첫 번째 인자의 내용 인자들 사이는 white character(space나 tab)에 의해 구분

인수의 전달 Call by value Call by reference 복사한 값 사용, 다른 기억장소에 저장 함수 내에서 값을 변경하여도 원본에는 바뀌지 않는다. Call by reference 인수의 메모리 번지가 전달, 함수에서 메모리 번지를 참조하여 값을 읽음 함수에서 값을 바꾸면 주프로그램의 값 자체가 바뀐다. 주 프로그램으로 여러 개의 계산 결과를 전달하고자 할 때 유용 void swap (int a, int b) { int t; t = a ; a = b ; b = t; } void swap (int *a, int *b) { int t; t = *a ; *a = *b ; *b = t; }

Recursion 함수 재귀 호출(recursion) 함수가 자기자신을 직접 또는 간접적으로 호출 재귀 호출을 사용하지 않았을 때보다 훨씬 코드가 간결 코드를 이해하기 어렵게 만들고 기억 공간을 많이 요구하는 단점을 가짐 재귀적인 특성을 갖는 자료 구조(트리, 리스트)나 작업에 사용 #include <stdio.h> long fact(int n) { if(n <= 1) return 1; else return(n * fact(n-1)); } main() int num; for(num = 1;num <= 10;num++) printf("%2d = %10ld",num, fact(num));

C 전처리기(preprocessor) 전처리기(preprocessor) 컴파일의 첫번째 단계를 수행 기능 파일의 포함 화일의 포함: #include 매크로 치환: #define 조건부 컴파일: #if, #else, #endif, #ifdef, #ifndef 파일의 포함 헤더 화일을 포함시킬 때 사용 #include "filename" 또는 #include <filename> "filename"이면 소스 프로그램이 존재하는 디렉토리부터 화일의 탐색 시작 <filename>이면 컴파일러가 사용하는 규칙에 따라 화일을 찾음 #define은 심볼 상수나 인자를 갖는 매크로를 정의하는데 사용 #define name replacement text replacement text가 두개이상의 행으로 나타날 때 각 행의 끝에 \ 토큰 name을 replacement text로 치환하는 일을 수행 #define은 인자를 갖는 매크로를 정의할 수 있음 #define max(A, B) ((A) > (B) ? (A) : (B))

기억 클래스(1) 모든 변수는 참조될 수 있는 범위(scope)를 가진다. 지역 변수(local variable, 내부 변수) 함수 안에 즉 어떠한 블록 안에 정의된 변수 블록({}으로 묶인 부분)안에서만 통용 다른 함수에서는 참조될 수 없다 함수가 호출되면 생성되었다가 리턴하면 소멸(자동변수, automatic variable) 전역 변수(global variable, 외부 변수) 함수의 바깥에서 정의된 변수로 여러 함수가 전역적으로 접근 가능 함수와 함수 사이에서 데이터 전달 수단으로 사용될 수 있음 프로그램 시작 시 생성되고 종료될 때가지 유지 반드시 한 번만 정의되어야 하며 여러 번 선언 가능

Scope rule { int a = 1, b = 2, c = 3; printf(“%3d%3d%3d\n”, a, b, c); /* 1 2 3 */ int b = 4; float c = 5.0; printf(“%3d%3d%5.1f\n”, a, b, c); /* 1 4 5.0 */ a = b; int c; c = b; printf(“%3d%3d%3d\n”, a, b, c); /* 4 4 4 */ } printf(“%3d%3d%5.1f\n”, a, b, c); /* 4 4 5.0 */ printf(“%3d%3d%3d\n”, a, b, c); /* 4 2 3 */

기억 클래스(2) 외부 변수와 범위 변수의 정의 변수의 선언 ex) int extvar ; /* 정의 */ 변수를 선언 변수의 데이터형에 해당하는 크기의 기억 장소 할당 변수의 선언 기능도 수행 변수의 선언 변수의 이름과 데이터 형을 알림 기억 장소 할당이 없음 ex) int extvar ; /* 정의 */ char extarray[100] ; /* 정의 */ extern int extvar ; /*선언, 보통 extvar은 다른 모듈에 선언*/ extern char extarray[100] ; /*선언*/

기억 클래스(3) 정적 변수(static variable) register 변수 지역 변수의 값을 유지하기 위해 사용 프로그램의 종료 후에도 그 값이 소멸되지 않고 보관되며 다시 호출될 때에는 그 직전의 값 참조 ex) static int c ; register 변수 기억할 자료의 값을 메모리에 저장하는 대신 직접 CPU내의 기억 장소인 레지스터내에 기억 performance 측면 int형과 unsigned int 형만 가능

기억 클래스 예제(static 변수) #include <stdio.h> void test() { static int s_count = 0; int a_count = 0; s_count++; a_count++; printf("static count = %dcount = %d",s_count,a_count); } main() int i; for(i=1; i<=10;i++) test();

예제 임의의 정수 n을 입력 받아 n의 계승(!)을 구하는 프로그램 작성 #include <stdio.h> double fact(int); /* 함수 선언 */ main() { int n = 0; /* 내부변수의 선언 */ do { printf("양수 입력:"); scanf("%d",&n); if (n<0) return(0); /*입력된 수가 0보다 작*/ /* 으면 프로그램 종료 */ else fact(n); printf("\n"); } while (1); /* 조건이 1(참)이므로 무한루프 */ } double fact( int k ) register int i; /* 레지스터 변수 선언 */ double s = 1; for (i = 1;i <= k;i++) s *= i; printf("%3d! => %16.0f\n",k,s); return(s);

프로그래밍 실습 초급 swap(a, b)와 같은 함수를 구현하라. 단, 위 함수의 기능은 a와 b의 값을 서로 바꿔 주는 역할을 한다. 중급 stringindex(s, t)와 같은 함수를 구현하라. 단, 위 함수는 s라는 string에 t라는 패턴의 string이 존재할 때, 가장 오른쪽에 있는 패턴의 첫 위치를 출력하는 기능을 한다. 그리고 t라는 패턴이 존재하지 않으면 -1을 return한다. Stack 구조와 stack를 다룰 수 있는 operation을 구현하라. (initialize(), pop(), push(), isempty(), isfull(), top() 등) Queue 구조와 queue를 다룰 수 있는 operation을 구현하라. (initialize(), pop(), push(), isempty(), isfull() 등) 고급 quick sort 프로그램을 구현하라.

제4장 배열과 포인터 : 포인터와 주소 포인터 & 연산자 p = &v; 기억 장소의 위치(주소)를 저장하는 변수 포인터 변수의 선언 type *pointer-variable; & 연산자 피연산자의 주소를 의미 반드시 기억 장소에 존재하는 객체를 피연산자로 가져야 함 상수, 수식, 레지스터 변수를 피연산자로 가질 수 없음 p = &v;

참조 연산자 * 연산자 포인터가 가리키는 대상을 접근하는데 사용 예) int x = 1, y = 2, z[10]; int *ip; /* ip is a pointer to int */ ip = &x; /* now ip points to x */ y = *ip; /* y is now 1 */ *ip = 0; /* x is now 0 */ ip = &z[0]; /* now ip points to z[0] */

포인터 변수의 연산 void형의 포인터를 제외한 모든 포인터는 가리키는 대상의 데이타형이 있음 예) 정수형 포인터 ip가 있을 때 *ip는 정수형 변수가 사용될 수 있는 모든 수식에 사용가능 *ip += 1; ++*ip; void형 포인터: generic pointer (*ip)++ 과 *ip++의 차이 포인터는 그 자체가 변수이므로 다른 포인터 변수의 값을 지정하는 지정문에도 사용됨 예) int i, *ip, *iq; ip = &i; iq = ip;

포인터를 이용한 인자 전달 호출 함수에서 피호출 함수가 변경한 변수의 결과를 사용하려면 값을 변경시키려는 인자를 포인터로 전달하여야 함 swap 함수 void swap(int *a, int *b) { temp; temp = *a; *a = *b; *b = temp; }

포인터와 배열 포인터 pa a : int *pa; pa = &a[0]; pa는 a의 첫번째 원소를 가리킨다 pa+i는 pa에서 i 만큼 뒤에 있는 원소를 가리킨다. pa가 a[0]을 가리키고 있다면 *(pa+i)는 a[i]를 참조

포인터와 배열(con’d) 배열의 이름과 포인터의 유사점 배열의 이름과 포인터의 차이점 pa = a; a = pa; 배열의 이름은 배열의 첫번째 원소의 주소와 같다 pa = &a[0]; 은 pa = a; 과 동일 배열 a의 원소 a[i]를 *(a+i)로 나타내는 것도 가능 &a[i]와 a+i는 동일한 의미를 가짐 pa[i]는 *(pa+i)와 같은 의미를 나타냄 배열의 이름과 포인터의 차이점 포인터는 변수이고 배열의 이름은 변수가 아니다 포인터의 경우는 다음과 같은 연산이 가능 pa = a; pa++; 배열의 이름은 다음과 같은 연산이 허용되지 않음 a = pa; a++;

배열의 함수 이름 전달 배열의 이름을 함수의 인자로 전달 int strlen(char *s) 배열의 처음 원소의 주소가 전달이 된다 피호출 함수에서 배열 이름을 나타내는 인자는 포인터이다 int strlen(char *s) { int n; for (n = 0; *s != ''; s++) n++; return n; } 함수를 정의할 때 형식 인자 char s[]와 char *s는 동등 그러나 char *s라고 선언하는 것이 더 좋음

주소 계산 p가 포인터라면 p++는 기억 장소에서 바로 다음 원소를 가리키도록 p를 증가 type *p; 일 때 p++은 포인터는 1만큼 증가하지만 실제로 기억 장소의 주소는 sizeof(type)만큼 증가됨 포인터와 정수는 연산에서 호환되지 않음 0은 예외적으로 지정 또는 비교에 사용 <stdio.h>의 심볼 상수 NULL은 포인터와 관련하여 0 대신에 사용 int *p; p = NULL; /* make p point to nothing */ if (p == NULL) ..... /* test if p is NULL pointer */ 포인터 p에 NULL을 지정하면 포인터는 기억 장소의 어떤 위치도 가리키고 있지 않다는 것을 의미

주소 계산(con’d) 포인터에 대해 허용되는 연산 int strlen(char *s) 같은 형의 포인터에 의한 지정 포인터의 증감 포인터끼리의 비교 연산 포인터끼리의 뺄셈 int strlen(char *s) { char *p = s; while (*p != NULL) p++; return p-s; }

char형 포인터 now is the time\0 now is the time\0 문자열 상수 문자 배열 함수의 인자로 사용되는 경우: 문자열의 시작 주소가 인자로 전달 printf("hello, world"); char형 포인터의 초기화에 사용 char *pmessage; pmessage = "now is the time"; /* 문자열 복사와 다름 */ 배열의 초기화와 포인터의 초기화 char amessage[] = "now is the time"; /* 배열 */ char *pmessage = "now is the time"; /* 포인터 */ amessage: pmessage: now is the time\0 now is the time\0

예제(strcpy 함수) /* strcpy: version using array subscript */ void strcpy(char *s, char *t) { int i = 0; while ((s[i] = t[i++]) != '') ; } /* strcpy: version using pointer */ while ((*s++ = *t++) != '') ;

포인터 배열 포인터 배열 원소가 포인터인 배열 예) 문자열 저장 #include <stdio.h> main() { static char *week[] = { "Sunday","Monday","Tuesday","Wednesday", "Thursday","Friday","Saturday"}; int k; for (k=0;k<7;k++) printf("week[%d]=%c, %s\n",k,*week[k],week[k]); }

다차원 배열 다차원 배열(multi-dimensional array) 선언 방법 type array-name[d1][d2] ......[dn]; C는 다차원 배열을 행-열 순서로 저장 예를 들어 2차원 배열 int m[3][3]는 다음과 같이 저장됨

다차원 배열(con’d) 다차원 배열을 인자로 갖는 함수의 형식 인자 선언 void a(int m[3][3]); 허용되는 인자 선언 void a(int m[3][3]); void a(int m[][3]); void b(f[4][2][3]); void b(f[][2][3]); void a(int (*m)[3]); => int (*m)[3]는 pointer to array of size 3을 의미 void b(int (*f)[2][3]); => int (*f)[2][3]는 pointer to array of 2d array of [2][3]을 의미

포인터와 2차원 배열 2차원 배열 int a[10][20]; 포인터 int *b[10]; a[row][col]에 해당하는 원소를 참조하기 위해 20×row+col의 위치 계산 포인터 int *b[10]; b는 10개의 포인터만을 저장할 수 있는 기억 공간을 할당받음 각 행이 가리키는 배열의 길이가 각기 다를 수 있다

포인터와 2차원 배열(con’d) 포인터와 2차원 배열의 기억 장소 사용 char *name[] = "Christoper", "Michael", "John", "Tom" ; char aname[][11] = "Christoper", "Michael", "John", "Tom" ;

명령행(command line) 인자 명령행 인자를 처리하기 위한 main함수의 형태 main(int argc, char *argv[]) argc는 명령행에서 입력된 토큰의 갯수를 의미 argv는 입력된 각 토큰들의 포인터를 저장하고 있는 배열 argc는 항상 1이상의 값을 갖는다. argv[0]는 프로그램의 이름을 가리키기 때문 명령행 입력: prog arg1 arg2 arg3 argc는 4, argv는 다음과 같이 구성 #include <stdio.h> main(int argc, char *argv[]) { int i; for (i = 0; i < argc; i++) printf("argv[%d] = %s%s", i, argv[i], (i < argc-1) ? ", " : ""); }

포인터 예제1 #include <stdio.h> void main() { int atom[3] = {100, 200, 300}; printf("%d %d %d\n", atom[0], atom[1], atom[2]); printf("%d %d %d\n", *atom, *(atom + 1), *(atom + 2)); printf("%d \n", atom - &atom[0]); printf("%d \n", (atom + 1) - &atom[1]); printf("%d \n", (atom + 2) - &atom[2]); }

포인터 예제2 #include <stdio.h> void main() { int atom[3] = {100, 200, 300}, i; int *p = atom; printf("%d %d %d\n", atom[0], atom[1], atom[2]); printf("%d %d %d\n", *atom, *(atom + 1), *(atom + 2)); printf("%d %d %d\n", p[0], p[1], p[2]); printf("%d %d %d\n", *p, *(p + 1), *(p + 2)); printf("%d \n", p - &atom[0]); printf("%d \n", (p + 1) - &atom[1]); printf("%d \n", (p + 2) - &atom[2]); for(i=0; i < sizeof(atom)/sizeof(atom[0]); i++) printf("%d ", p++); }

프로그래밍 실습 초급 중급 고급 pointer를 이용하여 swap(a, b) 함수를 구현하라. pointer와 위에서 구현한 swap을 이용하여 quick sort 프로그램을 구현하라. 고급 달력을 출력하는 프로그램을 작성하라.

제5장 구조체와 공용체 : 구조체 구조체(structure) 구조체의 예 학생 선언 struct tag-name { 여러 개의 서로 연관된 변수들을 하나의 단위로 묶어서 처리 구조체의 예 학생 선언 struct tag-name { type variable1; type variable2; ........... } ; struct student { int number; char dept[MAXDEPT]; char name[MAXNAME]; int year; char address[MAXADDR]; char phone[MAXPHONE]; } ;

구조체 변수 선언 구조체 변수 선언 태그(tag)의 사용 struct point { 구조체의 선언은 형(type)을 정의 구조체 선언의 오른쪽 struct tag-name x, y, z ; 태그(tag)의 사용 변수들의 리스트가 없는 구조체 선언은 메모리 할당을 하지 않고 구조체의 구성요소만을 기술 태그를 사용한 경우에는 추후 변수 선언 가능 struct point { int x; int y; } ; struct point pt;

구조체 변수 선언(con’d) 태그를 사용하지 않은 경우 struct { 구조체 변수의 초기화 추후 변수 선언 불가능 int x; int y; } pt; 구조체 변수의 초기화 초기값에 의한 초기화 struct point pt = { 640, 480 } ; 구조체 변수에 의한 지정이나 함수의 리턴값으로 초기화 가능

구조체 멤버와 중첩 정의 및 연산 구조체 멤버의 참조 구조체의 중첩 정의 구조체 적용 연산 structure-name.member 예) printf("x = %d, y = %d", pt.x, pt.y); 구조체의 중첩 정의 예) struct rect { struct point pt1; struct point pt2; } rectangle; 멤버의 참조: rectangle.pt1.x, rectangle.pt1.y 구조체 적용 연산 지정문에서 하나의 단위로 복사 & 연산자를 사용하여 주소를 얻음 멤버를 참조 함수의 인자로 전달, 함수의 리턴값: 복사에 의해 전달 구조체는 비교에 사용될 수 없음

구조체 배열 선언의 예 원소의 접근 employee[i].name.last employee[i].serialno struct ename { char last[30]; char mi; char first[20]; } ; struct person { struct ename name; int serialno; char sex; } ; struct person employee[MAX]; 원소의 접근 employee[i].name.last employee[i].serialno

자기 참조 구조체와 sizeof 연산자 구조체는 자기자신을 멤버로 가질 수 없음 자기 참조 구조체(self-referential structure) 자기자신을 가리키는 포인터를 멤버로 가지는 구조체 리스트(list)나 트리(tree)와 같은 자료 구조를 구현에 사용 struct book { /* 자기 참조 구조체 */ char title[80]; char author[80]; struct book *nextbook; } ; sizeof 연산자 컴파일 시 대상의 크기를 계산하는 연산자 sizeof object 또는 sizeof(object) 데이타형의 크기를 바이트 단위로 계산한 정수값을 의미 ex) int n; sizeof(n) 또는 sizeof(int) => int형의 바이트 크기

자기 참조 구조체의 예제 struct robot void main { { int head; int arm[2]; struct robot *next; struct robot *before; } struct robot atom[3] = { 30, 31, 32, 0, 0, 40, 41, 42, 0, 0, 50, 51, 52, 0, 0, }; void main { atom[0].next = &atom[1]; atom[1].next = &atom[2]; atom[2].next = 0x00; atom[2].next = &atom[1]; atom[1].next = &atom[0]; atom[0].next = 0x00; }

typedef 새로운 데이타형을 정의하는데 사용 Length len, maxlen; String p, lineptr[10]; typedef int Length; int형과 동일한 Length라는 새로운 데이타형을 만드는 것 Length len, maxlen; Length *lengths[]; typedef char *String; char형의 포인터형에 해당하는 String형을 정의 String p, lineptr[10];

typedef(con’d) typedef와 #define의 차이점 #define String char * String p, lineptr[10]; => char * p, lineptr[10]의 의미를 나타냄 typedef의 예 typedef struct { double real; /* 실수부 */ double imag; /* 허수부 */ } COMPLEX; COMPLEX complex_add(COMPLEX a, COMPLEX b) { a.real += b.real; a.imag += b.imag; return a; }

공용체 사용예 #include <stdio.h> union robot { long head; int body; char arm[2]; } atom; void main() atom.head = 0x1234L; atom.body = 0x123; atom.arm[0] = 'a'; printf("%x ", atom.head); printf("%x ", atom.body); printf("%x ", atom.arm[0]); }

파일 입출력 열기 사용 닫기 fopen() fputc() fclose() 파일을 사용하기 위한 절차 파일 열기 FILE *fopen( const char *filename, const char *mode); mode “r” : 읽기용으로 연다. “w” : 파일을 생성하고 쓰기용으로 연다. 파일이 이미 존재하면 그 파일은 없어진다. “a” : 추가용으로 연다. 파일이 없으면 파일을 생성하고 연다. 열기 사용 닫기 fopen() fputc() fclose()

파일 입출력(Cont’d) 파일 사용 파일 닫기 한 문자 입출력 서식화 입출력 블록 입출력 문자열 입출력 int fgetc(FILE *fp); int fputc(int c, FILE *fp) 서식화 입출력 int fprintf(FILE *fp, const char *format, …); int fscanf(FILE *fp, const cahr *format, …); 블록 입출력 size_t fread(void *ptr, size_t size, size_t n, FILE *fp); size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp); 문자열 입출력 char *fgets(char *s, int n, FILE *fp); int fputs(const char *s, FILE *fp); 파일 닫기 int fclose(FILE *fp);

파일 입출력 예 파일 복사 프로그램 #include <stdio.h> void main(int argc, char *argv[]) { FILE *srcfp, *destfp; int ch; if(argc != 3){ printf(“Usage Error\n”); exit(-1); } if((srcfp = fopen(argv[1], “rb”)) == NULL){ printf(“File Open Error\n”); if((destfp = fopen(argv[2], “wb”)) == NULL){ printf(“File Creation Error\n”); printf(“File Copy %s to %s. \n”, argv[1], argv[2]); while((ch = fgetc(srcfp)) != EOF) fputc(ch, destfp); fclose(srcfp); fclose(destfp);

프로그래밍 실습 초급 구조체를 이용하여 좌표 평면의 두 점을 주어졌을 때 두 점으로 만들 수 있는 직사각형의 면적을 구하는 프로그램을 작성하라. 중급 학생의 성적을 관리할 수 있는 프로그램을 작성하라. (학생의 정보를 사용자가 화면을 통해서 입력할 수 있어야 하고, 결과는 학생의 이름에 따라서 sort가 된 성적표를 출력할 수 있어야 한다. ) 고급 binary search tree를 traverse하고 자료를 입력하고 삭제하고 업데이트하는 프로그램을 작성하라.

제작자 수정 : 김철홍 (1999년 12월; 서울대학교 컴퓨터공학과 석사과정)