Presentation is loading. Please wait.

Presentation is loading. Please wait.

C언어 입문 강의 계획서.

Similar presentations


Presentation on theme: "C언어 입문 강의 계획서."— Presentation transcript:

1 C언어 입문 강의 계획서

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

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

4 #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 함수 지역변수 선언부

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

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

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

8 출력과 입력 예제 1 } #include <stdio.h> void main() {
printf("%10d , %10u,%#10x, |%-10ld| \n",123, 50000, 123, ); printf("%10.3lf, %10.2e, \n ",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); }

9 #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); }

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

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

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

13 상수 정수 상수(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: 제어 문자 표현

14 상수(con’d)

15 상수(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, */

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

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

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

19 비트 연산자와 증감 연산자 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;

20 지정 연산자와 조건부 수식 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;

21 형변환(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 = ; i = (int) f ;

22 연산자 간의 우선순위

23 예제 #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); }

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

25 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 ;

26 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); }

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

28 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”); }

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

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

31 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]); }

32 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; }

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

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

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

36 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; }

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

38 예제(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();

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

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

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

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

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

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

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

46 인수의 전달 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; }

47 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));

48 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))

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

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

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

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

53 기억 클래스 예제(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();

54 예제 임의의 정수 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);

55 프로그래밍 실습 초급 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 프로그램을 구현하라.

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

57 참조 연산자 * 연산자 포인터가 가리키는 대상을 접근하는데 사용 예) 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] */

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

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

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

61 포인터와 배열(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++;

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

63 주소 계산 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을 지정하면 포인터는 기억 장소의 어떤 위치도 가리키고 있지 않다는 것을 의미

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

65 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

66 예제(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++) != '') ;

67 포인터 배열 포인터 배열 원소가 포인터인 배열 예) 문자열 저장 #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]); }

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

69 다차원 배열(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]을 의미

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

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

72 명령행(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) ? ", " : ""); }

73 포인터 예제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]); }

74 포인터 예제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++); }

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

76 제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]; } ;

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

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

79 구조체 멤버와 중첩 정의 및 연산 구조체 멤버의 참조 구조체의 중첩 정의 구조체 적용 연산
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 구조체 적용 연산 지정문에서 하나의 단위로 복사 & 연산자를 사용하여 주소를 얻음 멤버를 참조 함수의 인자로 전달, 함수의 리턴값: 복사에 의해 전달 구조체는 비교에 사용될 수 없음

80 구조체 배열 선언의 예 원소의 접근 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

81 자기 참조 구조체와 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형의 바이트 크기

82 자기 참조 구조체의 예제 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; }

83 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];

84 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; }

85 공용체 사용예 #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]); }

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

87 파일 입출력(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);

88 파일 입출력 예 파일 복사 프로그램 #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);

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

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


Download ppt "C언어 입문 강의 계획서."

Similar presentations


Ads by Google