Transcript C Language

Introduce C Language
What is C Language?
 C언어란?
 구조화된 프로그래밍 언어
 프로그램을 만들기 위해 개발된 강력한 기능을 가진 프로그래밍 언어
 C언어의 특징
 간결한 문법
 대중적으로 널리 사용되는 언어
 다양한 종류의 운영체제에서 사용할 수 있다.
 완성된 프로그램의 크기가 작고 실행속도가 빠르다.
 모든 분야에 두루 활용 할 수 있도록 범용적이다.
What is C Language?
 프로그래밍 언어
 오늘날 전세계적으로 프로그래밍 언어는 약 3000개 이상
 최초의 고급언어인 Fortran이후 여러 고급언어 출현
 C언어의 탄생 및 역사
APL



CPL
BCPL
B
APL,CPL, BCPL 언어의 기틀을 마련
1970년 Ken Thompson이 B언어를 개발
1972년 벨 연구소의 Dennis Ritchie에 의해 C언어 탄생
C
What is C Language?
 실행파일이 만들어 지는 원리
Error!
Source
Code
Error!
기계어
Compiler
(코드 번역)
실행파일
Linker
(실행 파일 생성)
Memory
Loader
(메모리에 적재)
What is C Language?
 컴파일러 종류
 통합개발 환경이 일반화 되어 개발환경 자체를 컴파일러라 칭한다.
 무료 컴파일러
Borland의 Turboc C/C++
 Borland의 Dev-C++
 GNU의 gcc (Linux or Windows)


유료 컴파일러
Microsoft의 Visual Studio
 Borland의 C/C++ Builder


무료 컴파일러 다운로드
Dev C++ : http://www.bloodshed.net/dev/devcpp.html
 Microsoft Visual Studio 2008 Express Edition :
http://www.microsoft.com/express/download/

 프로젝트 생성
 파일 -> 새로만들기 -> 프로젝트 를 선택
 Win32 콘솔 응용 프로그램 선택 및 프로젝트 이름(Day1) 설정
 위치는 "D:\사용자이름"으로 설정한다.
 응용프로그램은 콘솔 응용 프로그램으로 작성
 빈 프로젝트를 체크하여 깨끗한 프로젝트 생성
 소스파일(우클릭) -> 추가 -> 새 항목을 선택
 코드를 추가할 때 C++파일을 추가
 파일의 확장자는 항상 .C 설정 ( 예 : test.c )
소스코드 작성
 간단한 소스코드 작성
 "Hello World" 문자열을 출력하는 프로그램 작성


Build (F7)
Execute Program (Ctrl+F5)
#include <stdio.h>
/* Test Code */
int main(void)
{
printf("Hello World \n"); // \n 은 개행문자를 의미
return 0;
}
소스코드 분석
 #include <stdio.h>
 #문자로 시작하는 문장을 전처리 구문이라 한다.
 표준입출력(Standard Input Output) 헤더 파일을 포함
 입출력함수 printf() , scanf() 등을 사용 가능
 int main(void)
 main()는 함수의 이름 이며, C프로그램은 항상 main 함수부터 시작
 함수는 " { " 로 시작하며 " } "로 끝난다.
 함수내부의 코드는 순차적으로 실행되며,return문은 함수를 종료시킨다.
 주석문(Comment) // or /* */
 설명을 위해 삽입되는 문자열이며 실행에 아무런 영향도 주지 않는다.
 한줄주석( // ) , 구문주석(/* */)
프로그램 작성 준비
 식별자 (identifier)
 프로그램 내에서 사용하는 변수,함수,상수 등에 부여한 이름
 작성규칙
1.
 2.
 3.
 4.
 5.


영문자 대 소문자 , 숫자 , _ (underline) 의 조합으로 구성
숫자의 경우 가장 첫 글자로 쓰여서는 안 된다.
예약어를 사용하면 안 된다.
공백이 있어선 안 된다.
변수명으로 한글 사용 불가.
프로그래밍 활용을 위한 TIP
의미를 잘 설명할 수 있는 이름
 제약은 없지만 3~10자 내외
 대소문자 구성을 일괄되게 한다.
 변수명은 보통 짧은 영어 단어를 활용

프로그램 작성 준비
 키워드(keyword)
 의미를 미리 정해놓은 단어 , 예약어(Reserved word)라고도 한다.
 이미 사용하고 있는 단어들이므로 다른 목적으로 사용할 수 없다.
auto
break
char
continue
else
enum
extern
goto
if
int
return
short
signed
struct
switch
typedef
void
volatile
case
default
while
cdecl
do
float
long
sizeof
union
const
double
for
register
static
unsigned
실습예제-1
 printf함수를 이용하여 다음 예제를 출력하시오
===================
/)/)
( ..)
( >♡
Have a Good Time.
====================
printf 함수
printf 함수
printf functions
 print formatting 서식화된 출력이란 뜻
int printf (const char *format [, argument, ...]);

큰따옴표("") 안에 있는 일정한 형식의 문장을 출력해주는 함수
printf 함수
 Escape Sequence
 의미를 가지는 특수한 문자들을 위해 사용하는 제어문자
문자열
Command
\n
new line
새로운 줄, 줄 바꿈
\b
back space
앞으로 한 블럭 이동
\r
carriage return
줄의 맨 처음으로 이동
\t
horizontal tab
Tab 만큼 이동
\a
alert
비프음 출력
\\
\ 문자 출력
\"
" 문자 출력
\0
NULL 문자
\x
16진수를 문자로 출력
실습예제-2
 Escape Sequence 문자 사용
#include <stdio.h>
int main()
{
printf("새로운 줄 바꿈\n");
printf("앞으로 한 블럭 이동~\b!\n");
printf("Tab\t만큼 이동\n");
printf("Two 줄의 맨 처음으로 이동\rOne\n");
printf(" \\문자\"문자출력\n");
printf("\0 NULL 문자");
printf("\x64 16진수\n");
return 0;
}
printf 함수
 서식 문자열 (%)
 문자열을 조립하는 형식
 뒤에 오는 인수들을 앞의 서식과 1대1로 대입하여 출력한다.
 서식에 따라 출력 형태가 달라진다.
2
3
printf("%c의 %s는 16진수로 표현하면 %x이다.",'A', "아스키코드",'A');
1
A의 아스키코드는 16진수로 표현하면 41이다.
printf 함수
 서식의 종류
종류
서식
정수형
문자형
실수형
%%
설명
%d
Decimal
10진 정수로 출력
%o
Octal
8진 정수로 출력
%x
hexadecimal
16진 정수로 출력
%c
character
한 개의 문자를 출력
%s
string
문자열을 출력
%f
float
실수로 출력
%문자 출력
실습예제-3
 서식을 이용한 출력
#include <stdio.h>
int main()
{
printf("10진수출력 : %d \n",100);
printf("8진수출력
: %o \n",100);
printf("16진수출력 : %x \n",100);
printf("단일문자출력 : %c \n",'A');
printf("문자열출력
: %s \n","Apple");
printf("원주율은? %f \n",3.141592);
return 0;
}
printf 함수
 서식을 이용한 정렬
 동일한 값을 다양한 형태로 출력가능하며 정렬할 때 주로 사용
 정수 또는 문자열


%[-][0][전체 자리 수][ l ]d or s
실수

%[-][0][전체 자리 수][.소수점 이하 자리 수][ l ] f
서식
의미
-
왼쪽으로 정렬
0
남은 공간을 0으로 채움(선행제로)
전체 자리 수
출력할 공간을 확보
.
소수점 이하의 자릿수
l
대응하는 인수를 Long형으로 출력
실습예제-4
 서식을 이용한 출력
#include <stdio.h>
int main()
{
printf("▧▧%d▧▧\n",49);
printf("▧▧%8d▧▧\n",49);
printf("▧▧%-8d▧▧\n",49);
printf("▧▧%08d▧▧\n",49);
printf("▧▧%f▧▧\n",3.141592);
printf("▧▧%.2f▧▧\n",3.141592);
printf("▧▧%8.f▧▧\n",3.141592); // 소수점 없이 출력
printf("▧▧%-8.2f▧▧\n",3.141592);
printf("▧▧%08.2f▧▧\n",3.141592);
return 0;
}
printf 함수
 예외적인 상황
 변환할 서식은 없는데 대입할 인수는 있는 경우
printf("변환 서식 없음",100); // 문자열만 출력

변환할 서식은 있는데 대입할 인수가 없는 경우
printf("값 = %d");

// 엉뚱한 값(쓰레기 값)이 출력
정수형을 실수형으로 출력 한 경우(또는 실수형을 정수형으로)
printf("값 = %f",100);
printf("값 = %d",3.15);// 엉뚱한 값(형 변환 실패 값)이 출력

표현할 수 있는 범위를 넘어서는 값을 가질 때
printf("값 = %d",10000000000);//엉뚱한 값(Overflow)이 출력
변수 및 연산자
변수
변수란?


일반적인 변수의 뜻 -> 고정되어 있지 않은 수
C언어에서의 변수의 뜻 -> 데이터 또는 자료를 저장하기 위한 공간
 변수선언
 변수를 사용하기 위해서는 변수를 선언해야 한다.
 선언된 변수는 메모리에 할당이 된다.
DataType 변수명 ;
변수
 Data Type ( 32bit 운영체제 기준)
자료형
Byte
char
1
-128 ~ 127
short
2
-32768 ~ 32767
int
4
-2147483648 ~ 2147483647
__int64
8
-2^64 ~ 2^64
float
4
10^-38 ~ 10^38
double
8
10^-308 ~ 10^308
void
범
위
값을 갖지 않는 특수한 데이터 형
변수
Datatype
Name
byte
Value
int
A
4
100
char
ch
1
'K'
float
fl
4
3.199
double
d
8
4.168
1244984
Low
4.168
dummy
1245000
1245012
3.199
dummy
Push
'K'
변수 선언
* Visual Studio 2008 기준
1245024
dummy
100
High
Stack Memory
실습예제
 변수 선언 및 출력
#include <stdio.h>
int main()
{
int Num = 100;
char ch = 'A';
float F = 3.141592;
double D = 5.11;
printf("변수 Num = %-8d \t Byte : %d \n",Num,sizeof(Num));
printf("변수 ch = %-8c \t Byte : %d \n",ch,sizeof(ch));
printf("변수 F
= %-8.2f \t Byte : %d \n",F,sizeof(F));
printf("변수 D
= %-8lf \t Byte : %d \n",D,sizeof(D));
return 0;
}
연산자
 Operator(연산자)?
 연산에 사용되는 +,-,* 등의 기호들을 연산자라 한다.
 연산자의 사용
 데이터의 처리 및 가공하는 목적으로 사용한다.
연산자
 연산자의 종류
연산자
기호
대입 연산자
= ,+=, -=, *=, /=, %=
산술 연산자
+-*/%
증가, 감소 연산자
++ --
관계 연산자
== != < > <= >=
논리 연산자
! && ||
캐스트 연산자
()
조건부 연산자
?:
시프트 연산자
<< >>
실습예제-6
 변수 선언 및 출력
#include <stdio.h>
int main()
{
int x = 10;
int y = 20;
int result;
result = x + y; // 산술 연산자 사용
printf("%d + %d = %d \n",x,y,result);
x = y = 2; // 변수 x와 y에 2를 대입
printf("x = %d , y = %d \n",x++,++y);//증가,감소 연산자 사용
printf("x = %d , y = %d \n",x,y);
y = 10;
result = !(( (x>y) || (y==x) ) ||( (x!=y) && (x<y) )) ;
printf("참 또는 거짓 : %d \n", result); // 0 또는 1을 출력
return 0;
}
scanf 함수
scanf 함수
scanf functions
 scan formatting 서식화된 입력이란 뜻
 기존의 서식 형태는 printf랑 동일하다.
int scanf (const char *format [, argument, ...]);
scanf 함수
Low
scanf("%d", &Num );
1
1245024
%d
4
1245024
5
2
100 입력
입력 대기
3
Enter Key
100
stdin
Buffer
100 \n
High
Stack Memory
실습예제-1
 변수 선언 및 출력
#include <stdio.h>
int main()
{
int Num1,Num2;
int result;
printf("첫번째 수를 입력 : ");
scanf("%d",&Num1);
printf("두번째 수를 입력 : ");
scanf("%d",&Num2);
result = Num1 + Num2;
printf("두 수의 합은 %d 입니다.\n“,result);
return 0;
}
실습예제-2
 변수 선언 및 출력
#include <stdio.h>
int main()
{
char ch;
float f;
printf("문자 입력 : ");
scanf("%c",&ch);
printf("실수 입력 : ");
scanf("%f",&f);
printf("입력한 문자는 %c 이고 실수는 %.2f 이다\n",ch,f);
return 0;
}
//문자와 실수의 입력 순서를 바꾸어 프로그램을 실행 시켜본다.
실습문제 1
 대문자를 입력 받아 소문자로 변환하여 출력 하시오. (10분)
문자 입력 : A
==== 출 력 ====
입력하신 문자 : A
소문자로 변환 : a
사용자 입력
실습문제 2
 학생의 성적을 입력한 뒤 합계와 평균을 구해보시오. (20분)
 정수형 변수 3개만 사용하여 코드를 작성
================
이 름 : 홍 길 동
================
국 어 : 100
영 어 : 98
수 학 : 75
================
합 계 : 273
평 균 : 91.00
================
사용자 입력
제어문
제어문
 제어문이란?
 순차적인 흐름을 조건에 따라 통제하는 명령
 사용자의 요구에 따라 프로그램이 동작
 제어문의 종류
 조건


반복


while, do while, for
선택


if - else
switch - case
흐름 변경

continue, break
if - else 문
 if문
 가정과 결과에 따라 행위를 결정하는 제어문
 if문 안의 결과가 참일 때 명령을 수행
 else문
 if문과 함께 쓰이며 if문의 결과가 참이 아닐 때 else문을 수행
 if문은 단독으로 쓸 수 있으나 else문은 단독으로 쓰지 못함
 else if 문
 복수의 조건 중 각각 다른 처리를 수행하고자 할 때 사용
if - else 문
 if문의 문법
조건문
if( 조건문 )
{
실행문1;
}
if( 조건문 )
{
실행문1;
}else{
실행문2;
}
false
true
실행문1
조건문
false
true
실행문1
실행문2
실습예제-1
 변수 선언 및 출력
#include <stdio.h>
int main()
{
int Num;
printf("1~5까지 숫자 입력 : ");
scanf("%d",&Num);
if(Num < 1 || Num > 5 ){ //단일 if문
printf("입력범위를 벗어났습니다.");
}
if(Num == 1){ //조건이 참일 때
printf("당신이 입력한 수는 1 입니다.");
}else{ //조건이 거짓일 때
printf("당신이 입력한 수는 1이 아닙니다.");
}
return 0;
}
if - else 문
 중첩 if문의 문법
if(조건문1)
{
if(조건문2){
실행문1;
조건문1
true
false
실행문3
}else{
실행문2;
}
}else{
실행문3;
}
조건문2
true
false
실행문2
실행문1
실습예제-2
 변수 선언 및 출력
#include <stdio.h>
int main()
{
int Num1;
printf("1부터 100까지의 수 중 선택: ");
scanf("%d",&Num1);
if(Num1 > 0 && Num1 <= 100){
if(Num1%2==0) printf("입력한 수는 짝수 입니다\n");
else printf("입력한 수는 홀수 입니다\n");
}else{ //조건이 거짓일 때
printf("잘못된 수를 입력하였습니다.");
}
return 0;
}
if - else 문
 다중 if문의 문법
if(조건문1){
실행문 1;
}else if(조건문2){
실행문 2;
} ...
else if(조건문n){
실행문n;
}else{
실행문;
}
조건문1
true
실행문1
true
실행문2
false
조건문2
false
...
...
조건문n
false
실행문L
true
실행문n
실습예제-2
 변수 선언 및 출력
#include <stdio.h>
int main()
{
int Num1;
printf("Input Number 1 ~ 3 :");
scanf("%d",&Num1);
if(Num1 == 1){
printf("One !");
}else if(Num1 == 2){
printf("Two !");
}else if(Num1 == 3){
printf("Three !");
}else {
printf("Error !");
}
return 0;
}
실습문제 1
 두 숫자를 입력 받아 대소를 비교하시오
 입력 받은 숫자가 같을 경우도 처리
첫번째 숫자 입력 : 10
두번째 숫자 입력 : 17
==== 결 과 ====
두 번 째 입력 한 값이 더 크다.
실습문제 2
 영문자를 입력 받아 대,소문자를 구분 한 뒤 소문자는 대문자로 대문자
는 소문자로 서로 변환하여 출력 하시오. (20분)

특수문자 및 숫자를 입력할 시 잘못된 입력이라는 문구 표시
문자 입력 : a
==== 결 과 ====
소문자를 입력 하였습니다.
대문자로 변환 : A
-------------------------------------> Restart
문자 입력 : C
==== 결 과 ====
대문자를 입력 하였습니다.
소문자로 변환 : c
-------------------------------------> Restart
문자 입력 : @
==== 결 과 ====
잘못 입력하셨습니다 영문자를 입력해주세요
while문
 while문
 사용자가 원하는 만큼 명령들을 여러 번 실행하는 제어구조.
 특정 조건이 만족되는 동안 명령을 계속적으로 실행한다.
 while문의 문법
 식이 참일 경우에만 루프 처리를 반복한다.
while( 조건문 )
{
실행문1;
}
실행문1
조건문
false
true
실습예제-1
 while문을 사용하여 1~10까지 출력
#include <stdio.h>
int main()
{
int i;
i = 0; //초기값 지정
while(i<10){ //조건문
i = i +1; //증감문
printf("i = %d \n",i);
}
return 0;
}
실습문제 1
 사용자가 선택한 구구단을 출력(10분)
 변수를 적절히 사용하여 두 수의 곱을 출력
=== 구구단 출력 프로그램 ===
1 ~ 9단 중 선택 : 3
3 * 1=3
3 * 2=6
3 * 3=9
...
3 * 9 = 27
do - while문
 do - while문
 while문과 유사하지만 조건문이 실행문 뒤에 위치한다.
 do - while문의 문법
 do 와 while이 짝을 이루어 사용된다.
 조건문이 거짓일 때라도 한번 이상 실행한다.
do{
실행문;
}while( 조건문 );
문법 숙지!
실행문
조건문
false
true
실습 예제 2
 입력된 수를 거꾸로 출력하시오 (예 123->321).
#include <stdio.h>
int main(){
int i;
printf(“정수 입력 : ");
scanf("%d",&i);
do{
printf("%d",i%10);
i/=10;
}while(i>0);
return 0;
}
//While문을 사용하고 0을 입력하면 출력이 안됨.
실습문제 2
 1 ~ n 까지의 합 구하기 (10분)
 합계를 누적시키며 더한다.
=== 1 ~ n 까지의 합 구하기 ===
n 입력 : 100
1 ~ 100 까지의 합은 5050입니다.
for문
 for문
 초기,조건,증감문을 한번에 선언 가능
 가장 보편적인 반복문으로 가독성이 높다.
 for문의 문법
 초기, 조건, 증감문은 일부 또는 전부를 생략 가능하다.
for(초기문;조건문;증감문){
실행문;
}
초기문
조건문
true
실행문
증감문
false
실습예제-3
 for문을 사용하여 1 ~ 10 까지 출력
#include <stdio.h>
int main()
{
int i;
for(i=1;i<=10;i++){
printf("i = %d \n",i);
}
return 0;
}
반복문의 흐름제어
 break문
 반복문이 실행되고 있는 시점에서 가장 근접한 반복문(루프) 탈출
 여러 개의 루프가 중첩된 경우 현재 위치한 루프 하나만 탈출
 continue문
 반복도중 처리를 중단하고 반복문의 시작 위치로 이동
 정밀한 제어 구조를 만들 때 사용
 goto문
 지정한 곳으로 무조건 점프
 사용하기 쉬운 제어문.
 프로그램의 구조를 해치기 쉬워 이식성과 재사용이 어렵다.
실습예제-4
 continue문 및 break문 실습
#include <stdio.h>
int main()
{
int i;
for(i=1;i<=10;i++){
if(i==2||i==5)continue;
printf("i = %d \n",i);
if(i==8)break;
}
return 0;
}
무한루프
 무한루프
 반복 횟수가 미리 정해져 있지 않고 무한히 반복되는 루프
 무한루프 생성 코드
 for문
for( ; ; ){ 실행문; }

while문
while(0이 아닌 정수형 상수){ 실행문; }

보편적으로 while(1) 을 사용
실습예제-5
 무한루프 실습
#include <stdio.h>
int main()
{
int Sel = 0;
int Sum = 0;
while(1){
printf("더할 수를 입력하세요 (종료 ==0) : ");
scanf("%d",&Sel);
if(Sel==0)break;
Sum = Sum + Sel;
}
printf("입력하신 값들의 전체 합은 %d입니다 \n",Sum);
return 0;
}
다중루프
 다중루프
 두 개 이상의 루프가 겹쳐져 있는 제어구조
 이중 루프가 보편적으로 많이 사용된다.
 다중루프 생성 코드 예제
i=0
j=0
j=1
j=2
j=3
j=4
i=1
j=0
j=1
j=2
j=3
j=4
i=2
j=0
j=1
j=2
j=3
j=4
i=3
j=0
j=1
j=2
j=3
j=4
i=4
j=0
j=1
j=2
j=3
j=4
int i,j;
for(i=0;i<5;i++ ){
for(j=0;j<5;j++){
printf("☆");
}
printf("\n");
}
실습문제 3
 이중루프를 사용하여 삼각형을 출력 (10분)
 Q3과 Q4는 if문을 사용하여 코드를 작성한다.
==== Q1 =====
☆
☆☆
☆☆☆
☆☆☆☆
☆☆☆☆☆
==== Q2 =====
☆☆☆☆☆
☆☆☆☆
☆☆☆
☆☆
☆
==== Q3 =====
☆☆☆☆☆
☆☆☆☆
☆☆☆
☆☆
☆
==== Q4 =====
☆
☆☆
☆☆☆
☆☆☆☆
☆☆☆☆☆
switch문
 switch문
 하나의 변수값에 따라 개별적인 처리가 가능한 다중 선택문.
 전체적인 메뉴 구성 시 보편적으로 사용.
 switch문의 문법
정수형 또는 문자형 변수
switch(변수){
}
정수형 상수만 사용 가능
case 1:
실행문1; // 변수의 값이 1일 경우 실행
break;
제외 시 다음명령 실행
case 2:
실행문2; // 변수의 값이 2일 경우 실행
break;
....
default : // 변수의 값이 case문에 없을 경우 실행
실행문l;
생략 가능
실습예제-5
 Switch - case 문 실습
#include <stdio.h>
int main()
{
int Select;
printf("1~3까지 숫자 입력 : ");
scanf("%d",&Select);
switch(Select){
case 1: printf("One !\n");
break;
case 2: printf("Two !\n");
break;
case 3: printf("Three !\n");
break;
default :
printf("잘못된 값을 입력하셨습니다.");
}
return 0;
}
실습문제 3
 계산기 프로그램
 (+,-,*,/)연산자를 사용하여 코드를 작성
 연산자에 q를 입력 받기 전까지 프로그램을 종료하지 않는다.
=== 계산기 프로그램 ===
연산자 입력 ( + , - ,* , / ) : +
첫 번째 숫자 입력 : 100
두 번째 숫자 입력 : 15
====== 결 과 =======
100 + 15 = 115
난수
 난수(Random Number)
 임의의 값 또는 무작위로 만들어지는 알 수 없는 값
 난수생성의 활용
 주사위 게임, 포커게임 및 슈팅게임 등
 난수 생성 함수
 stdlib.h 헤더파일에 정의
rand()
 srand()

난수
 rand 함수
int rand(void);


0 ~ RAND_MAX 의 범위중 무작위 수를 추출 (RAND_MAX = 32767)
seed 값에 따라 발생하는 난수의 값이 결정된다.
 srand 함수
void srand( unsigned int seed );


난수에 발생되는 seed 값을 지정
rand함수가 실행되고 난 뒤 seed 값은 변경된다.
난수
printf("rand() = %d \n",rand()); // 41
printf("rand() = %d \n",rand()); // 18467
printf("rand() = %d \n",rand()); // 6334
1
rand()
Seed
1
2
rand()
41
3
rand()
18467
6334
srand(100);
1
Seed
100
rand()
2
365
rand()
3
1216
rand()
5415
난수
 시간값을 사용하여 완벽한 난수 생성
 time함수를 쓰기 위해서는 time.h 헤더파일을 포함
srand( (unsigned)time(NULL) );
1
Seed
현재시간
rand()
2
??
rand()
3
??
rand()
??
실습문제 1
 사용자가 원하는 랜덤범위의 값 추출 (10분)
 랜덤범위를 구하는 공식 알아볼 것.
0 ~ 9 까지의 랜덤 수 : 8
1 ~ 10 까지의 랜덤 수 : 6
20~35 까지의 랜덤 수 : 26
0 또는 1 : 1
실습문제 2
 동전 앞 뒤 맞추기 (20분)
 1또는 2의 랜덤 수를 추출 한 뒤 사용자가 입력한 값과 비교
=== 동전 앞 뒤 맞추기 ===
숫자를 입력해주세요 (1.앞면 / 2.뒷면) : 1
맞췄습니다^^
-------------------------------------------->restart
=== 동전 앞 뒤 맞추기 ===
숫자를 입력해주세요 (1.앞면 / 2.뒷면) : 1
땡! 틀렸습니다!
숙제 1
 가위바위 보 게임
 가위 바위 보 중 하나를 선택 승패를 결정하는 게임
 승패를 결정하는 if문은 중첩if문 금지. ( || , && 연산자를 적절히 활용)
=== 가위 바위 보 게임 ===
숫자를 선택하세요(1.가위 / 2.바위 / 3.보 ) : 1
======== 결과 ========
당신은 가위를 냈습니다.
컴퓨터는 보를 냈습니다.
=====================
컴퓨터가 이겼습니다. ㅠ.ㅠ
Programming
실습문제 1
 UP & Down Game 코드 작성


1~99까지 범위의 랜덤한 숫자를 맞추는 게임
전체적인 메뉴는 switch-case문으로 만들 것
== Up & Down Game ==
1. Game Start
2. Game Score
3. End Game
>1
<< Game Start >>
Input Number : 30
<<
<<
<<
U
P
D O W N
정
답
>>
>>
>>
실습문제 2
 Baskin Robbins 31 Game 코드 작성


1부터 시작, 31이 될때까지 서로 턴을 교대하며 숫자를 증가.
31을 먼저 외치는 사람이 지는 게임
Baskin Robbins31 Game
1. Game Start
2. Game Score
3. End Game
>1
<< Game Start >>
Input Number(1~3): 3
<Computer Turn>
4!
5!
31! 나의 승리
<< 게임 종료 >>
1!
2!
3!
31! 나의 패배
<< 당신의 전적 >>
W I N :
L O S E :
D R A W :
실습문제 3
 Dice Game


주사위를 3번 던져 그 합을 서로 비교하여 승패를 가린다.
금액을 지정하여 배팅이 가능하도록 설정한다.
==
1.
2.
3.
>1
Dice Game ==
Game Start
Game Score
End Game
판돈 지불
<< Game Start >>
당신의 주사위의 합 : 10
배팅을 하겠습니까(y/n) : y
금액 설정
금액 처리
돈이 없을 시 게임종료
승패 판단
<< 당신의 전적 >>
W I N :
L O S E :
D R A W :
함 수 ( Function )
함수
 함수란?
 인수를 전달 받아 일련의 작업을 수행한 뒤 그 결과를 반환하는 코드
 프로그램의 부품 역활을 하는 함수들이 모여 큰 함수로 만들어진다.
 표준함수와 사용자 정의 함수로 구분
main함수
printf
함수
scanf
함수
rand
함수
srand
함수
system
함수
time
함수
사용자정의
함수
함수
 함수의 장점
 Divide and Conquer !




재사용이 가능하다.
관리가 용이하다.
큰 프로그램 작성시 공동작업이 유리하다.
가독성을 높일 수 있다.
함수
 함수의 선언
 두 정수를 인자값으로 넘긴 뒤 두 수의 합을 반환하는 함수
함수의 이름
int Function(int A, int B)
{
int C;
C = A + B ;
return C;
}
return 값(반환값)
Return의 데이터 타입
전달된 인수의 값
함수
 인수(argument or parameter)
 원하는 함수를 호출할 때 넘겨주는 값
 return문
 함수가 종료되며 리턴한 값을 함수의 결과값으로 취한다.
 단지 함수의 종료를 위해 사용되기도 한다.


main에서의 return문은 프로그램 종료
void형 함수에서는 return 문이 생략 가능하다.
 return문의 데이터 타입
 리턴값에 맞는 데이터 타입을 설정
함수
 함수의 호출 방식
 함수를 호출할 때 인수를 전달하는 방식
 전달방식에 따른 2가지 방식
 값 호출(Call by value)


인수의 값을 호출한 함수에 전달
참조 호출(Call by Reference)

인수의 주소를 호출한 함수에 전달
실습예제1
 두 수의 합을 구하는 함수
#include <stdio.h>
3 int sum(int Num1, int Num2){ // sum함수 선언
int result;
result = Num1 + Num2;
4 return result; // 두수의 결과값을 리턴
}
int main()
{
1 int A = 12;
int B = 19;
int C;
2 C = sum(A,B);
5
}
printf("%d + %d = %d \n",A,B,C); // 12 + 19 = 31
printf("%d + %d = %d \n",100,200,sum(100,200));
return 0;
실습문제 1
 대 소문자 변환 프로그램을 함수로 선언
#include <stdio.h>
char change(char ch){
//코드를 작성하시오
}
int main()
{
char ch;
printf("영문자 입력 : ");
scanf("%c",&ch);
printf("====== 변환 ======\n");
printf("%c\t->\t",ch);
printf("%c \n",change(ch));
return 0;
}
영문자 입력 : A
====== 변환 ======
A
->
a
영문자 입력 : z
====== 변환 ======
z
->
Z
함수
 기억 부류 (Storage Class)
 변수가 저장되는 위치에 따라 결정되는 변수의 여러 가지 성질
 지역 변수 (local)
 함수 내부에 선언되는 변수.
 선언된 변수는 해당 함수의 안에서만 사용 가능.
 함수가 호출 될 때 스택이란 메모리 공간에 선언된다.
 함수 종료 시 내부에 선언된 지역변수의 값이 메모리상에서 사라진다.
 초기값은 쓰레기 값으로 지정된다.
함수
 전역 변수 (global)
 함수의 외부에 선언되는 변수
 전역변수는 데이터 영역에 메모리가 위치.
 프로그램 전체에서 변수 사용 가능
 프로그램이 종료될 때까지 값이 사라지지 않음
 초기값은 0으로 지정
 Register 변수
 메모리가 아닌 CPU의 레지스터에 저장된다.
 최소 2개까지만 지원하고 그 이후에는 지역변수로 선언된다.
 빠른 속도를 위하여 사용 현재는 거의 사용되지 않는다.
실습예제 2
 전역변수와 지역변수의 차이
#include <stdio.h>
int data; // 전역변수 data 선언
int func(int stack){
data = 10;
stack = 200;
return data; // 전역변수의 값을 리턴
}
int main()
{
int stack = 50; // 지역변수 stack 선언
printf("stack = %d \n",stack);
printf("data = %d \n",data);
printf("stack : %d, return값 : %d\n",stack,func(stack));
printf("stack = %d \n",stack);
printf("data = %d \n",data);
return 0;
}
함수
 정적 변수(Static)
 함수 내부에 선언되지만 프로그램이 종료될 시 까지 그 값을 유지한다.
 전역 변수와 마찬가지로 데이터 영역에 저장.
 초기값이 없을 시 0으로 초기화되며 프로그램 실행 시 한번만 초기화.
 정적 변수의 선언
 정적변수는 변수 앞에 static을 붙여 선언
static DataType 변수명 ;
실습예제 3
 정적 변수를 사용.
#include <stdio.h>
void func(void){
static int x = 0;
x++;
if(x==1){
printf("처음으로 함수가 호출 되었습니다\n");
}else{
printf("%d번째 호출 입니다.\n",x);
}
}
int main()
{
int i;
for(i=0;i<5;i++){
func();
}
return 0;
}
실습예제 4
 my_rand 함수 구현
#include <stdio.h>
int my_rand(){
static int seed = 1;
seed = ((seed*1103515245+12345)/65535)%32768;
return seed;
}
사용자 정의 랜덤 공식
int main()
{
printf("my_rand함수 = %d \n",my_rand());
printf("my_rand함수 = %d \n",my_rand());
printf("my_rand함수 = %d \n",my_rand());
printf("my_rand함수 = %d \n",my_rand());
return 0;
}
실습문제 3
 정적 변수를 사용하여 baserand 함수 작성
#include <stdio.h>
int baserand(int x, int y){
//코드를 작성하시오
}
int main()
{
printf("10 ~ 20
printf("23 ~ 31
printf("1 or 2
return 0;
}
10 ~ 20 : 15
23 ~ 31 : 27
1 or 2 : 1
:
:
:
%d\n",baserand(10,20));
%d\n",baserand(23,31));
%d\n",baserand(1,2));
재귀함수
 재귀 호출 함수(Recursive call Function)
 함수 안에서 자기자신의 함수를 다시 호출하는 형태의 함수
 재귀 함수의 장점
 직관적이고 속도가 빠르다.
 재귀적 함수 구현의 두 가지 용법
 함수 안에서 자기자신의 함수를 호출하는 방법
 두 개의 함수가 상호간 호출하는 방법
 재귀함수의 쓰임
 트리 구조의 디렉터리 폴더 목록 출력
 지뢰찾기의 빈 블럭을 모두 열어주는 구조
실습예제 5
 재귀 함수 구현
#include <stdio.h>
int func(int data){
if(data){
printf("%d + ",data);
return func(data-1)+data;
}
printf("\b\b= ");
return 0;
}
int main()
{
int i = 30;
printf("%d\n",func(i));
return 0;
}
재귀 함수 부분
재귀함수
6
1 func(30)
2
return func(data-1)+data;
printf("%d\n",func(i));
func(30-1)+30
5
func(29-1)+29
...
func(2-1)+2
func(1-1)+1
3
4
func(0)
printf("\b\b= ");
return 0;
}
실습문제 3
 재귀함수를 사용하여 피보나치 수열 작성
피보나치 수열 출력
1 2 3 5 8 13 21 34
배열
배열
 배열이란?
 동일한 타입을 가지는 변수들의 집합
 언어에서 제공하는 가장 기본적인 자료구조형
 배열의 쓰임
 여러 개의 변수를 한번에 선언 가능.
 같은 형의 변수들을 연속적으로 쓸 수 있다.
 배열을 통해 문자열 사용이 가능.
배열
 배열의 선언
DataType 배열이름[배열크기][배열크기]... ;





일반 선언문과 동일하며 배열이름 뒤 배열의 요소 크기를 정한다.
배열 선언 시 [ ] 괄호가 1개일 때 1차원 배열 2개 일 때 2차원 배열이라 한다.
배열크기는 선언했던 만큼 메모리상에 잡히고 프로그램도중 변경할 수 없다.
사용할 수 있는 배열의 요소의 첨자는 0부터 시작한다.
배열의 이름은 배열의 첫 번째 주소를 가지고 있다. (포인터 상수)
실습예제 1
 배열의 선언
#include <stdio.h>
int main()
{
int x = 100;
int y = 200;
//정수형 변수 x , y 선언
int A[5]={ 1,2,3,4,5};
//정수형 배열 A 선언
Low
1244984
1244988
1244992
1244996
1245000
1245012
A[3] = 200;
1245024
printf("A = %d \n", A );
//배열의 이름은 배열의 첫 번째 주소
return 0;
}
1
A[0]
2
A[1]
3
A[2]
4
A[3]
5
A[4]
dummy
y
200
dummy
x
100
High
Stack Memory
실습예제 2
 5명의 학생의 성적을 입력 받고 총 합계와 평균 구하기
#include <stdio.h>
int main()
{
int grade[5];
int i,sum = 0;
for(i=0;i<5;i++){
printf("%d 번째 학생의 성적 : ",i+1);
scanf("%d",&grade[i]);
}
printf("<< 입력한 학생들의 성적 >>\n");
for(i=0;i<5;i++){
printf("%d ",grade[i]);
sum += grade[i];
}
printf("\n학생들의 총 합계 : %d\n",sum);
printf("학생들의 평균 점수 : %.2f\n",(float)sum/5);
return 0;
}
실습예제 3
 문자열 다루기
#include <stdio.h>
int main()
{
char String[10] = "Apple"; //초기값 설정
char String1[10];
int i;
String1[0] = 'O';
String1[1] = 'r';
String1[2] = 'a';
String1[3] = 'n';
String1[4] = 'g';
String1[5] = 'e';
String1[6] = '\0'; //문자열 마지막에 NULL문자 삽입
printf("String = ");
for(i=0;i<sizeof(String);i++){
if(String[i]==NULL){break;} //String[i]가 NULL문자일 시 for문 종료
printf("%c",String[i]);
}
printf("\nString1 = %s \n",String1);
return 0;
}
실습문제 1
 "실습예제 3"을 응용하여 문자열 대 소문자 변환
String = Apple
문자열을 소문자로 변환
String = apple
문자열을 대문자로 변환
String = APPLE
실습예제 4
 두 문자 서로 바꾸기
#include <stdio.h>
int main()
{
char A[2];
char tmp;
A[0] = 'A';
A[1] = 'B';
printf("%c , %c\n",A[0],A[1]);
① tmp = A[0];
② A[0] = A[1];
③ A[1] = tmp;
printf("%c , %c\n",A[0],A[1]);
return 0;
}
도식화
A[0]
2
1
A[1]
3
tmp
실습문제 1
 Reverse 문자열 출력
알고리즘
문자열 출력
Reverse
everseR
verseRe
erseRev
rseReve
seRever
eRevers
Reverse
2
R
3
e
4
v
5
e
1
6
r
7
s
e
8
tmp
'\0'
배열
 Sort
 대량의 데이터를 어떤 순서에 따라 정렬하는 것
 오름차순(작은수부터)과 내림차순(큰 수부터)으로 나뉜다.
 sort의 종류
 버블소트 , 삽입 소트, 히프소트 ,퀵 소트 , 힙 소트 등등
 버블 sort
 인접원소를 비교해서 더 큰 원소를 뒤로 보내는 방식
 병 밑바닥에서 생긴 버블이 점점 더 커지는 것에 비유
 매우 간단히 구현이 가능하지만 많은 양일 경우에는 비효율 적이다.
실습문제 3
 배열에 10개의 값을 저장하여 정렬하는 프로그램 작성
모든 값 출력
15, 9, 1, 8, 60, 99, 100, 70, 50, 20
정렬 후
1 , 8, 9, 15, 20, 50, 66, 70, 99, 100
포인터
포인터
 포인터란?
 포인터란 메모리의 번지 주소이다.
 포인터 변수는 메모리의 주소를 가지는 변수이다.
 포인터 변수의 크기는 4byte의 부호없는 정수형이다.
 포인터 연산자
 &는 변수의 메모리 주소를 출력하는 연산자이다.
 *는 주소를 이용하여 변수값을 접근하는 연산자이다.
실습예제 1
 포인터 선언 및 활용
Low
#include <stdio.h>
int main()
{
int x = 100;
① int *p;
//포인터 변수 p 선언
dummy
1245012
1
② p = &x;
//변수 x의 주소를 p에 연결
printf("p = %d\n", p );
//p의 값 출력
③ printf("*p = %d\n", *p );
//p의 주소에 접근하여 x의 값 출력
return 0;
}
p
1245024
2
dummy
3
1245024
x
100
High
Stack Memory
실습예제 2
 배열과 포인터
#include <stdio.h>
int main()
{
int A[5]={ 1,2,3,4,5};
① int *p = A;
//p에 A 배열의 첫 주소를 저장
② printf("*p = %d\n", *p );
③ printf("*(p+3) = %d\n", *(p+3) );
④ printf("*(A+3) = %d\n", *(A+3) );
//포인터와 배열의 성질은 동일.
A++; //A는 포인터 상수라 Error
⑤ p++; //p는 포인터 변수라 가능
return 0;
}
A
1
2
1
3
2
4
5
3
p
5
A
1
2
3
4
5
실습예제 3
 Call by Reference
#include <stdio.h>
void Reference(int * x , int * y){
printf("x = %d , y = %d\n",x,y);
①
*x = 100;
②
*y = 200;
//main함수의 x,y에 접근
}
int main()
{
int x=10,y=20;
printf("x = %d , y = %d\n",x,y);
Reference(&x,&y);
printf("x = %d , y = %d\n",x,y);
return 0;
}
Low
1245024
x
1245012
y
Reference
2
1
y
20
dummy
x
10
High
main function
Stack Memory
실습문제 1
 두 값을 서로 교환하는 함수를 작성하라
#include <stdio.h>
void change(char * ch1, char * ch2){
//코드를 작성하시오
}
int main()
{
char x='A',y='B';
printf("x = %c , y = %c\n",x,y);
change(&x,&y);
printf("x = %c , y = %c\n",x,y);
return 0;
}
x=A,y=B
x=B,y=A
실습 문제 2
 base ball 게임
 컴퓨터가 가지고 있는 랜덤의 3가지 수를 맞추는 게임
 함수를 효율적으로 사용하여 코드를 작성할 것
== Base Ball Game ==
Input ball
0 strike 1
Input ball
1 strike 1
Input ball
: 123
ball
: 456
ball
: 254
== !!Congraturation!! ==
2차원 배열 및 다중 포인터
2차원 배열
 2차원 배열
 배열의 첨자를 2개 이상 사용하는 배열
 자료를 더욱 효율적으로 저장
 2차원 배열의 선언의 예
char String[5][10]; // 문자형 변수 5 * 10
50byte
int A[3][4];
//정수형 변수 4개의 묶음 3개 48byte
A[0][0] A[0][1] A[0][2] A[0][3] A[1][0] A[1][1] A[1][2] A[1][3] A[2][0] A[2][1] A[2][2] A[2][3]
A[0][0] A[0][1]
A[0][2] A[0][3]
A[1][0] A[1][1]
A[1][2] A[1][3]
A[2][0] A[2][1]
A[2][2] A[2][3]
실습예제1
 2차원 배열의 초기화 및 값 넣기
#include <stdio.h>
int main()
{
int A[3][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
printf("%d \n",A);
printf("%d \n",A[0]);
printf("%d \n", &(A[0][0]));
printf("%d \n", A[2][1]);
return 0;
}
A[0]
A
A[0][0]
A[0][1]
A[0][2]
A[0][3]
A[1]
A[1][0]
A[1][1]
A[1][2]
A[1][3]
A[2]
A[2][0]
A[2][1]
A[2][2]
A[2][3]
1
2
3
4
5
6
7
8
9
10
11
12
실습예제 2
 3명의 학생의 성적을 입력 받고 총 합계와 평균 구하기
#include <stdio.h>
int main()
{
int A[3][4];
int i,j;
printf("<<성적관리프로그램>>\n");
for(i=0;i<3;i++){
printf("<< %d번째 학생>>\n",i+1);
printf("
국어 : ");
scanf("%d",&(A[i][0]));
printf("
영어 : ");
scanf("%d",&(A[i][1]));
printf("
수학 : ");
scanf("%d",&(A[i][2]));
A[i][3]=A[i][0]+A[i][1]+A[i][2];
}
//--앞 페이지에 이어서 코드 작성
printf("<< 학생의 전체 성적 >>\n");
printf(" 번호 국어 영어 수학 합계\n");
for(i=0;i<3;i++){
printf("%5d",i+1);
for(j=0;j<4;j++){
printf("%6d",A[i][j]);
}
printf("\n");
}
return 0;
}
실습 문제 1
 달팽이 배열 구현
길이를 입력하세요 : 7
1
24
23
22
21
20
19
2
25
40
39
38
37
18
3
26
41
48
47
36
17
4
27
42
49
46
35
16
5
28
43
44
45
34
15
6
29
30
31
32
33
14
7
8
9
10
11
12
13
다중 포인터
 다중 포인터란?
 포인터 변수의 주소를 담고 있는 포인터이다.
 선언할 때 * 구두점을 쓴 만큼 해당 주소에 관한 값으로 접근 가능
 다중 포인터 선언의 예
int **pp;
int ***ppp;
// 이중 포인터 , 포인터에 연결해서 사용
// 삼중 포인터
실습예제 1
 포인터 선언 및 활용
#include <stdio.h>
int main()
{
int x = 100;
int *p = &x;
int **pp = &p;
int ***ppp = &pp;
int ****pppp = &pp;
int y = 50;
x = &y; //y의 주소를 x로
printf("%d \n",****pppp);
return 0;
}
실습예제 2
 2차원 배열을 통한 2중 포인터 예제
#include <stdio.h>
int main()
{
int array[3][4]={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
printf("array = %d \n",array);
printf("array[0] = %d \n",array[0]);
printf("&array[0][0] = %d \n",&array[0][0]);
printf("*array = %d \n",*(array+1));
printf("*(*(array+1)) = %d \n",*( *(array+1) ));
printf("*(*(array+1) +2) = %d \n",*( *(array+1) +2 ));
printf("*(*(array+2) +3) = %d \n",*( *(array+2) +3 ));
return 0;
}
포인터 문제 1
 문자열 중에 일치되는 첫 문자의 위치 구하기
문자열 : None but The Brave deserves the Fair
찾을 문자 입력 : b
일치되는 첫 번째 문자열은 6
포인터 배열
 포인터 배열(Array of Pointer)이란?
 각각의 요소가 포인터의 주소가 담겨진 배열을 의미한다.
 필요한 메모리 만큼만 할당이 되는 이점이 있다.
 포인터 배열의 선언의 예
char *name[5] = { "Apple","Orange","Banana","Grape" };

각각의 문자를 담은 포인터 변수 가 name이라는 배열로 선언이 된다.
Apple
name
주소
Orange
주소
주소
Grape
주소
Banana
포인터 배열
 2차원 배열과 포인터배열의 차이점
#include <stdio.h>
int main(){
char arr[3][10]={"apple","banana","pear"};
char *pt[3]={"apple","banana","orange"};
return 0;
}
arr[0]
arr[1]
arr[2]
a
p
p
l
e
\0
0
0
0
0
b
a
n
a
n
a
\0
0
0
0
p
e
a
r
\0
0
0
0
0
0
Pt[0]
a
p
p
l
e
\0
Pt[1]
b
a
n
a
n
a
Pt[2]
p
e
a
r
\0
\0
실습예제 3
 2차원 배열과 포인터 배열의 차이
#include <stdio.h>
int main()
{
char *name1[4] = { "apple", "Orange", "Banana", "Grape" };
char name2[4][10] = { "apple", "Orange", "Banana", "Grape" };
int i;
//2차원 배열
for(i=0;i<4;i++){
printf("name2[%d] = %8s (%x) \n",i,name2[i],name2[i]);
}
printf("=============================\n");
//포인터 배열
for(i=0;i<4;i++){
printf("name1[%d] = %8s (%x) \n",i,name1[i],name1[i]);
}
return 0;
}
배열 포인터
 배열 포인터(Pointer of Array)란?
 각 배열의 번지수를 담고 있는 포인터 변수
 2차원 배열이상부터 배열 포인터 선언이 가능하다.
 배열 포인터 선언과 예
DataType (*포인터명)[배열의 첨자 크기];
char (*p)[5]; // 배열의 요소가 5개인 2차원 포인터 생성
실습예제 4
 배열 포인터의 예제
#include <stdio.h>
int main()
{
char name[4][10] = {"apple", "Orange", "Banana", "Grape"};
char **p;
//2중 포인터
char (*pt)[10]; //배열 포인터
int i;
p = name; //name에 2중 포인터를 연결
pt = name; //pt를 2차원 배열처럼 사용 가능
for(i=0;i<4;i++){
// printf("p[%d] = %8s (%x) \n",i,p[i],p[i]); // 사용 불가
printf("pt[%d] = %8s (%x) \n",i,pt[i],pt[i]);
}
for(i=0;i<4;i++){ printf("%s\n",*pt++); }
return 0;
}
문자열
문자열
 스트림에 대한 이해
 바이트들이 순서대로 입 출력되는 논리적인 장치
 데이터를 받아들이는 것을 입력 스트림이라 한다.
 데이터를 내보내는 것을 출력 스트림이라 한다.
OS
(운영체제)
입력스트림
출력스트림
문자열
 입력함수
 표준 입력 함수
int scanf(const *format[,argumen],...);
int getchar(void); //키보드로부터 한 개의 문자를 입력 받는다.
int getch(void);
//문자 하나를 입력 받는 즉시 반환한다.
char * gets(char *buffer); //버퍼로부터 한줄을 읽어온다.

스트림을 지정할 수 있는 입력 함수
int fgetc(FILE * stream); //문자 하나를 입력 스트림을 지정
char * fgets(char *str,int n,FILE * stream);
int fscanf(FILE * stream,const *format[,argumen],...);
문자열
 출력함수
 표준 출력 함수
int printf(const *format[,argumen],...);
int putchar(void); //한 개의 문자를 출력한다.
char * puts(const char *string); //문자열을 읽어와 출력한다.

스트림을 지정할 수 있는 출력 함수
int fputc(int c ,FILE * stream);
char * fputs(const char *str , FILE * stream);
int fprintf(FILE * stream,const *format[,argumen],...);
실습예제 1
 입력함수 및 출력함수의 예제
#include <stdio.h>
int main()
{
char c;
printf("getchar : ");
c = getchar();
printf("입력한 값 : %c\n",c);
fflush(stdin);
printf("fgetc : ");
c = fgetc(stdin);
printf("입력한 값 : %c\n",c);
return 0;
}
실습예제 2
 getch함수 예제
#include <stdio.h>
int main()
{
int c;
while(1){
c = getch();
if(c == 0xE0){
//확장키 검사
c = getch();
//확장키는 2번 입력 받는다.
printf("Function키 입력한 값 : %c (%x)\n",c,c);
}else{
printf("입력한 값 : %c (%x)\n",c,c);
}
if(c == 'q' || c == 'Q')break;
}
return 0;
}
실습예제 3
 gets함수 예제
char ch[10];
puts("gets함수 사용");
gets(ch); //10개의 문자 이상의 값을 입력 받을 시 에러
puts(ch);
 fgets함수 예제
char ch[10];
puts("fgets함수 사용");
fgets(ch,sizeof(ch),stdin);
puts(ch);
//입력 받을 size크기를 조절 가능
실습 문제 1
 함수를 사용하여 '\n'문자 없애기
 fgets함수로 입력 받을 시 '\n'문자가 자동으로 배열에 입력된다.
 이 '\n'문자를 없애는 함수를 작성
#include <stdio.h>
void delete_NULL(char * ch){
// 코드 작성
}
int main(void){
char ch[10];
puts("fgets함수 사용");
fgets(ch,sizeof(ch),stdin);
delete_NULL(ch);
puts(ch);
return 0;
}
문자열
 문자열 조작 함수
 표준 C라이브러리에서 제공하는 다양한 문자열 함수
 사용하기가 편리하며 직접 구현도 가능하다.
 string.h 헤더파일에 선언되어 있다.
 문자열 처리 함수의 종류
 str로 시작되는 함수
 mem으로 시작되는 함수
문자열
 문자열의 길이를 반환하는 함수
size_t strlen(const char *string);



String Length.
문자열의 전체 길이를 계산하여 반환
마지막의 NULL 문자를 포함하지 않는다.
#include <stdio.h>
int main()
{
char ch[20];
printf("문자열 입력 : ");
fgets(ch,sizeof(ch),stdin);
printf("입력한 문자열의 크기는 : %d\n",strlen(ch));
return 0;
}
문자열
 문자열을 복사하는 함수
char * strcpy(char * dest, const char * src);


String Copy.
dest로 전달된 배열에 src 로 전달된 문자열을 복사
 문자열을 정해진 크기만큼 복사하는 함수
char * strncpy(char * dest, const char * src ,size_t n);


복사하는 문자열의 최대길이는 n을 넘지 않는다.
Overflow가 일어나지 않으므로 보안상으로 안전하다.
실습예제 4
 strcpy , strncpy함수 예제
#include <stdio.h>
#include <string.h>
int main()
{
char ar1[10] = "Apple";
char ar2[10] = "Orange";
printf("ar1 : %s\n",ar1);
strcpy(ar1,ar2);
printf("ar1 : %s\n",ar1);
strncpy(ar1,"Banananananananana",sizeof(ar1)-1);
printf("ar1 : %s\n",ar1);
return 0;
}
문자열
 문자열을 연결하는 함수
char * strcat(char * dest, const char * src);


dest로 전달된 배열에 src 로 전달된 문자열을 연결한다.
두 문자열을 합쳐야 함으로 배열의 크기계산을 잘 해준다.
 문자열을 정해진 크기만큼 연결하는 함수
char * strncat(char * dest, const char * src ,size_t n);

연결하는 문자열의 최대길이는 n을 넘지 않는다.
실습예제 5
 strcat함수 예제
#include <stdio.h>
#include <string.h>
int main()
{
char si[10] = "서울시 ";
char gu[10] = "동대문구 ";
char dong[10] = "신설동";
char address[100] = "\0";
strncat(address, si, sizeof(address)-1);
strncat(address, gu, sizeof(address)-1);
strncat(address, dong, sizeof(address)-1);
puts(address);
return 0;
}
문자열
 문자열을 비교하는 함수
int strcmp(char * dest, const char * src);



string compare.
문자열을 비교하여 어떠한 결과를 리턴한다.
두 문자열이 같을 경우 0을 반환 그렇지 않을 경우 음수나 양수를 반환
 문자열을 정해진 크기만큼만 비교하는 함수
int strncmp(char * dest, const char * src ,size_t n);


비교하는 문자열의 최대길이는 n을 넘지 않는다.
정해진 구역까지만 비교 할 수 있어 유용하게 사용 가능하다.
실습예제 6
 strcmp 함수 예제
#include <stdio.h>
#include <string.h>
int main()
{
char ar1[10] = "Apple";
char ar2[10] = "Apple";
int tmp;
tmp = strcmp(ar1,ar2);
//두 문자열이 같을 때 0을 반환
printf("비교 값 %d\n",tmp);
tmp = strcmp(ar1,"Orange"); //뒤의 문자열의 값이 더 클 때 -1 반환
printf("비교 값 %d\n",tmp);
tmp = strcmp(ar1,"Appld");
//앞의 문자열의 값이 더 클 때 1을 반환
printf("비교 값 %d\n",tmp);
tmp = strncmp(ar1,"Apppp",3);
printf("비교 값 %d\n",tmp);
//앞의 3문자만 비교하여 결과를 반환
return 0;
}
구조체
구조체
 구조체란?
 하나 이상의 변수를 그룹 지어서 새로운 자료형을 정의하는 것
 붙어 다니게 되는 데이터들은 하나로 묶어서 관리하는 것이 편리하다.
 구조체의 쓰임
 복잡한 데이터를 표현할 때 구조화 하여 정의
 윈도우 운영체제는 대부분 구조체로 이루어져 있다.
 표현하고자 하는 객체에 대해서 구조화 한다.
예) 학생 : 나이, 성별, 이름, 성적 등등
 예) 도서정보 : 저자, 판매가격, 출판사, 출판날짜 등
 예) 게임유저 : 보유한 돈, 능력치, 아이템, 현재 위치 등

구조체
 구조체의 정의

사용자 정의 자료형을 정의하며 기존자료를 묶어 새로운 자료형을 만든다.
struct 구조체명{
변수 선언;
배열 및 포인터도 선언 가능;
구조체도 선언 가능;
※ 중요
};

구조체의 멤버에 초기값을 설정하지 못한다.
구조체의 선언 및 초기화
Low
 구조체의 선언 및 초기화
struct 구조체명 구조체변수명;
struct Student{
int id;
char name[12];
int kor,eng,math;
char address[50];
};
//==== 선언 ====
struct Student ST ={ 1001,
"hacker",90,80,60,"서울시"
};
ST
1001
ID
hacker
name
90
kor
80
eng
60
math
서울시
address
High
Stack Memory
실습예제 1
 구조체 선언 및 사용
#include <stdio.h>
struct Student{
int id;
char name[12];
int kor,eng,math;
char address[50];
};
int main()
{
struct Student ST ={ 1001,"hack",90,80,60,"서울시 동대문구 신설동" };
printf("ST 구조체의 전체 크기 %d \n",sizeof(ST));
printf("ST의 ID : %d \n",ST.id);
printf("ST의 이름 : %s \n",ST.name);
printf("ST의 성적(국,영,수) : %d ,%d ,%d\n",ST.kor,ST.eng,ST.math);
printf("ST의 주소 : %s \n",ST.address);
return 0;
}
실습예제 2
 구조체 배열과 포인터를 이용한 반 배정 프로그램
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<time.h>
<windows.h>
struct ST_class{
char name[20];
int st_class;
};
int main(){
struct ST_class st[10];
struct ST_class *pt_st;
int i;
for(i=0;i<5;i++){
printf("%d번째 이름을 입력하시오: ",i+1);
gets(st[i].name);
}
다음 장에 계속..
실습예제 2
 구조체 배열과 포인터를 이용한 반 배정 프로그램
..이어서
pt_st=st;
srand(time(NULL));
rand(); rand(); rand();rand();
for(i=0;i<5;i++){
(pt_st+i)->st_class = rand()%10+1;
printf("%s = %d반\n",(pt_st+i)->name,st[i].st_class);
Sleep(1000);
}
return 0;
}
실습문제 1
 구조체를 이용해 경마게임을 만드시오.
규칙.
말은 5마리.
맴버 변수 : 말 번호, 나이, 전적, 배당금
배당금 및 룰은 각자 정하시오.
User Interface
UI
 UI(User Interface)
 사용자가 조금 더 보기 좋고 사용하기 편리하도록 UI를 구축한다.
 UI의 장점
 유저의 알고리즘 실력을 더욱 견고하게 다듬어준다.
 원하는 위치에 문자를 출력을 할 수 있어 알아보기 편리하다.
 문자열을 움직이는 등 애니매이션을 구현하여 프로그램을 돋보인다.
 윈도우 API를 사용하여 콘솔창을 더 멋지게 꾸민다.
UI
 gotoxy함수
 내가 원하는 좌표에 문자 출력
 사용자가 API를 이용해 만든 함수를 사용한다..
 사용자가 원하는 애니메이션도 구현이 가능하다.
 Sleep 함수
 프로그램의 실행을 잠시 중지 시킨다.
 Sleep함수에 인자값을 사용하여 정지되는 시간을 조절 할 수 있다.
 1000 = 1초 단위

500 = 0.5초 , 10 = 0.001초
UI
 콘솔창 색 변경
 API함수를 사용하는 방법


textcolor함수를 정의하고 사용
system함수를 사용하여 전체 색을 바꾸는 방법

system("color 색상");
 콘솔창 크기 변경
 system함수를 사용하여 콘솔창의 크기를 변경

system("mode con cols=가로창크기 lines=세로창크기");
실습예제 1
 화면에 랜덤한 좌표로 문자를 출력
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
gotoxy(int x, int y);
textcolor(int color_number);
int main(){
int i;
char ch;
int color;
for(i=0;i<1000;i++){
gotoxy(rand()%50,rand()%20); // 랜덤한 위치로 커서이동
color = rand()%15+1;
textcolor(color); // 글자에 랜덤 하게 색을 설정
ch = rand()%(123-65+1)+65;
putchar(ch); // A ~ Z 까지 랜덤한 문자출력
Sleep(5);
}
return 0;
}
다음에 계속…
실습예제 1
 화면에 랜덤한 좌표로 문자를 출력
이어서…
gotoxy(int x, int y){
COORD pos = {x, y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
textcolor(int color_number){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color_number);
}
실습문제 1
 문자열 떨어트리기
 문자열을 입력한 뒤 5초 후 차례차례 문자가 떨어지는 코드
 카운트다운 후 문자들이 하나씩 떨어진다.
Honey! 5 <--CountDown
5에서 차례대로
줄여가며 출력
oney! 0 <--CountDown
H
파일 입출력
파일 입출력
 파일 입출력
 디스크에 있는 파일을 읽어오거나 저장하는 것
 많은 정보를 메모리에 모두 불러올 수 없으므로 외부에 저장해둔다
 이미지나 사운드 파일 같은 경우는 필요할 때만 불러와서 출력
 영구적으로 보관 되야 할 경우 파일 저장이 필수 (문서를 저장)
파일 입출력
 입 출력할 주변 장치나 파일에 관한 정보 (stdio.h)
struct _iobuf {
char *_ptr; // 버퍼를 첫위치로부터 쓰거나 읽은 위치
int
_cnt; // 버퍼의 카운터
char *_base; // 버퍼의 첫 위치
int
_flag; // 입력과출력 및 입력 중과 출력중을 나타냄
int
_file; // 입력 장치
int
_charbuf;
int
_bufsiz; //버퍼의 전체 사이즈
char *_tmpfname;
};
typedef struct _iobuf FILE;
FILE * p; 파일 구조체 선언
파일 입출력
 파일을 엑세스 하기 위한 과정
 파일 Open
: 해당 파일을 연다.
 파일 Access : 파일을 저장하거나 읽어 들인다.
 파일 Close
: 파일을 닫는다.
파일 입출력
 파일 Open
FILE * fopen(const char *filename, const char mode);
대상 파일의 이름
파일 접근 형태


대상 파일의 이름은 c:\에 있는 경우 '\'문자를 두 번을 써줘야 한다.
지정된 파일을 엑세스 하여 그 정보들을 포인터로 반환한다.
파일 열기
 파일 접근 형태(Mode)
Mode
기 능
파일 존재
파일 미존재
r
읽기
정상 처리
NULL 리턴
w
쓰기
이전 내용 제거
파일 생성 후 새로 작성
a
추가 쓰기
이전내용 끝부터 추가
파일 생성 후 새로 작성
rb
바이너리 모드로 읽기
정상 처리
NULL 리턴
wb
바이너리 모드로 쓰기
이전 내용 제거
파일 생성 후 새로 작성
ab
바이너리 모드로 추가 쓰기
이전내용 끝부터 추가
파일 생성 후 새로 작성
r+
읽고 쓰기 (갱신)
정상 처리
NULL 리턴
w+
읽고 쓰기 (갱신)
이전 내용 제거
파일 생성 후 새로 작성
a+
이어 쓰기
이전내용 끝부터 추가
파일 생성 후 새로 작성
r+b , rb+
바이너리 모드로 r+기능
정상 처리
NULL 리턴
w+b , wb+
바이너리 모드로 w+기능
이전 내용 제거
파일 생성 후 새로 작성
a+b , ab+
바이너리 모드로 a+기능
이전내용 끝부터 추가
파일 생성 후 새로 작성
파일 입출력
 파일 close
int fclose(FILE * stream);



파일 입출력을 위해 내부적으로 생성했던 FILE 구조체를 해제한다.
해당 스트림이 소멸되며 성공하면 0을 리턴한다.
사용한 파일은 반드시 fclose함수를 이용하여 닫아준다.
실습예제 1
 파일 저장
#include <stdio.h>
int main()
{
char ar1[10] = "Apple! ";
FILE * f = fopen("c:\\test.txt","w");
puts(ar1);
//모니터에 출력
fputs(ar1,f);
//스트림을 통해 출력한다.
fclose(f);
//꼭 닫아준다.
return 0;
}
실습예제 2
 파일 열기
#include <stdio.h>
int main()
{
char ar1[10] = "Empty!";
FILE * f = fopen("c:\\test.txt","r");
if(f==NULL){
printf("파일을 열 수 없습니다 \n");
return 1;
}
puts(ar1);
//모니터에 출력
fgets(ar1,sizeof(ar1),f);
puts(ar1);
fclose(f);
return 0;
}
실습예제 3
 fprintf 함수를 통해 구구단 파일 저장
#include <stdio.h>
int main()
{
int i,j;
FILE * f = fopen("c:\\test.txt","w");
for(i=1;i<10;i++){
for(j=1;j<10;j++){
fprintf(f,"%2d * %2d = %2d",i,j,i*j);
if(!(j%3)){
fprintf(f,"\n");
}else{
fprintf(f," // ");
}
}
for(j=0;j<25;j++)fprintf(f,"─");
fprintf(f,"\n");
}
fclose(f);
return 0;
}
실습예제 4
 구구단 파일을 읽어와서 출력
#include <stdio.h>
#include <string.h>
int main()
{
char Read[100] = "\0";
char String[10000] = "\0";
int i,j;
FILE * f = fopen("c:\\test.txt","r");
while(!feof(f)){
fgets(Read,sizeof(Read),f);
strcat(String,Read);
}
puts(String);
fclose(f);
return 0;
}
동적 메모리
동적메모리
 동적 메모리
 동적 메모리란?
 동적 메모리 할당의 필요성
 동적 메모리 할당 방법
동적메모리
 운영체제의 메모리 관리 원칙
 메모리 관리 주체는 운영체제
 운영체제는 메모리가 있는 한은 할당 요청을 거절하지 않는다
 할당된 메모리 공간은 다른 목적으로 재할당 되지 않는다
 메모리를 다른 목적을 위해 사용할 수 있도록 한다.
동적 메모리
 동적 메모리 할당 함수
void * malloc( size_t n );
1
3
size만큼 할당
메모리 주소 반환
2
* 메모리 확보에 실패 시(메모리 부족) NULL 반환
Heap Memory
동적 메모리
 동적 메모리 해제 함수
void free( void * );
1
메모리 해제
2
free
Heap Memory
실습예제
 동적 할당 예제
#include <stdio.h>
#include <stdlib.h> //malloc함수 및 free 함수
int main()
{
int* int_p;
int_p = (int *)malloc(4); //heap영역에 4byte를 할당
if(int_p==NULL){ //메모리 할당 실패 시 종료
printf("메모리 할당 실패\n");
return 1;
}
*int_p = 100;
printf("*int_p의 값은 : %d \n",*int_p);
free(int_p); //메모리 해제
return 0;
}
동적 메모리
 섬세한 동적 할당
 정수형 배열처럼 사용 가능한 연속적인 메모리 할당


2차원 배열처럼 사용한 동적 할당


(int *)malloc( 크기 * sizeof(int) ) ;
(int (*)[열])malloc( sizeof(int) * 행 * 열 ) ;
구조체를 이용한 동적 할당

(struct ST *)malloc( 크기 * sizeof(struct ST) );
실습예제
 연속적인 메모리 선언
#include <stdio.h>
#include <stdlib.h> //malloc함수 및 free 함수
int main()
{
int* int_ar;
int i;
int sel;
printf("메모리를 할당할 공간 : ");
scanf("%d",&sel);
int_ar = (int*)malloc(sel*sizeof(int));
for(i=0;i<sel;i++){
int_ar[i] = (i+1)*2;
printf("ar[%d] = %d \n",i,int_ar[i]);
}
free(int_ar); //메모리 해제
return 0;
}
실습예제
 2차원 배열과 동일하게 할당
#include <stdio.h>
#include <stdlib.h>
int main()
{
int (*arr)[4]; // 배열 포인터 선언
arr = (int (*)[4])malloc(sizeof(int)*3*4); // 3 * 4 배열
arr[0][2] = 79;
arr[2][3] = 100;
printf("arr[0][2] : %d \n",arr[0][2]);
printf("arr[2][3] : %d \n",arr[2][3]);
free(arr); //메모리 해제
return 0;
}
실습예제
 구조체 동적할당
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ST{
int id;
char name[12];
};
void print_ST(struct ST tmp){
printf("ID : %d , Name : %s \n",tmp.id,tmp.name);
}
int main()
{
struct ST* test;
test = (struct ST *)malloc( 3 *sizeof(struct ST)); //구조체형 * 3 메모리 할당
test[0].id = 10;
strcpy(test[0].name,"홍길동");
test[1] = test[0];
print_ST(test[0]);
print_ST(test[1]);
free(test);
return 0;
}
Dynamic String Allocation
Dynamic String Allocation
 일반적인 문자열 사용
char memo[50];

memo에 정해진 50byte로 인해 생기는 문제점 발생
printf(“Input any String >”);
gets(memo);

A type
Input any String >testing

B type
Input any String >Hello~ Every one!! Nice to meet you.
It’s C Language! It’s Nice! It’s So Easy!!!! Let’s
Start!!
Dynamic String Allocation
 일반적인 문자열 사용
 A type은 낭비
 B type Overflow
A type
memo[50]
50 byte
B type
Stack memory
Dynamic String Allocation
 문자열 동적 할당 사용
 일반 문자와 다르게 Pointer 형으로 사용
char * memo;

입력할 String을 담는 임시 저장공간을 받아서 크기만 큼 동적 할당하
여 Heap 영역에 지정한 후 사용
char buff[1024];
......
gets(buff);
memo = (char *)malloc(1*(strlen(buff)+1));
strcpy(memo, buff);
실습예제 1
 문자열 동적 할당
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* buff(){
char buff[1024];
char *memo;
gets(buff);
memo = (char *)malloc(strlen(buff)+1);
strcpy(memo,buff);
return memo;
}
int main(){
char *memo1;
memo1=buff();
printf("입력 값은%s 입니다.",memo1);
free(memo1);
return 0;
}
Linked List
Linked List
 Linked List
 일반적인 동적 할당은 사용상 메모리 낭비를 최대한으로 막을 수 없음
 입력이 시작되면 그때 한번만 동적으로 생성되어 추가
 일반 구조체에 자기 참조 구조체를 추가 함
struct node{
int data;
char * memo;
struct node * link
};
Linked List
 Linked List 구성
 입력, 삽입, 삭제
 Linked List 한 개 Node 구성
Struct
Data
* Link

Node 구성 시 * Link는 NULL
Linked List
 입력
 List의 마지막, link가 NULL인 부분을 찾아 추가될 Node 주소 입력
Root
Struct
Data
00421E54
00401450
tmp
Struct
Data
NULL
<004A76E0>
00421E54
Struct
Data
NULL
004A76E0
Linked List
 삽입
Struct
Data
NULL
<004A76E0>
2
1
004FF760
Root
Struct
Data
00421E5A
00401450
Struct
Data
004A76E0
<004FF760>
00421E54
Struct
Data
NULL
004A76E0
Linked List
 삭제
 Root 삭제와 타 node 삭제는 구분

Root 삭제
Root
1
Root
Struct
Data
Struct
Data
Struct
Data
00421E5A
004A76E0
NULL
00401450
00421E54
004A76E0
2 FREE
Linked List

일반 node 삭제
1
Root
Struct
Data
00421E5A
<0040A76E0>
00401450
Struct
Data
Struct
Data
004A76E0
NULL
00421E54
004A76E0
2 FREE
The End
191