2016년 9월 19일 월요일

간단한 게임 만들기


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void game()
{
 int b;
 int a;
 srand(time(NULL));   // 순차문이라 rand()가 뒤에 있어야한다. 그렇지않으면 계속 같은 숫자가 나온다.
 a= rand()%100;
 for( ; ; )
 {
  scanf("%d",&b);
  if(a == b)
  {
   printf(" 정답! 게임종료 \n ");
   break;
  }
  else if(a > b)
  {
   printf("High \n");
   printf("다시입력하세요.");
  }
  else if(a < b)
  {
   printf("Low \n");
   printf("다시입력하세요.");
  }
 }
}
int main(void)
{
 printf("게임 이름:\n number checker \n");
 printf("게임 룰 :\n 컴퓨터가 랜덤으로 숫자를 0~99까지 고릅니다.\n 사용자가 컴퓨터가 고를 숫자를 예상해서 적습니다.\n 그 수보다 높으면 High, 낮으면 low를 출력 합니다. 맞으면 게임종료.\n");
 printf("숫자를 입력하세요.");
 game();
}

2016년 2월 23일 화요일

C언어 메모리 조작 함수 : memcpy, memmove

메모리 조작 함수 memcpy, memmove 는 strcpy와 흡사 하다.

헤더는 include<memmory.h> or string.h 이다.

memcpy(복사될 문자열 B+시작할 주소, 복사할 문자열 A+시작할 주소, 복사될 메모리의 크기)
memmove(이동될 문자열 B+시작할 주소,이동할 문자열 B+시작할 주소, 이동 메모리의 크기)

결과적으로 memcpy, memmove는 문자열을 복사한다는 면에서 같다.

#include<stdio.h>
#include<string.h>
int main()
{
 char A[] = "I love her";
 char B[] = "I feel you";
 int C[] = {1,2,3,4,5};
 int D[] = {6,7,8,9,10,11};
 int i;

 printf("원래 문장 A : %s \n",A);
 printf("원래 문장 B : %s \n",B);
 printf("원래 문장 C :");
 for(i=0;i<5;i++)
 {
  printf("%d ",C[i]);
 }
 printf("\n");
 printf("원래 문장 D :");
 for(i=0;i<6;i++)
 {
  printf("%d ", D[i]);
 }
 printf("\n");


 memcpy(B+7,A+7,3);
 memmove(D,C,sizeof(int)*5);       //D[1]과 C[3]을 하고 싶다면 &D[1],&C[3],4 를 하면 된다.

 printf("바뀐 후 A : %s \n",A);
 printf("바뀐 후 B : %s \n",B);
 printf("바뀐 후 C :");
 for(i=0;i<5;i++)
 {
  printf("%d ",C[i]);
 }
 printf("\n");
 printf("바뀐 후 D :");
 for(i=0;i<6;i++)
 {
  printf("%d ", D[i]);
 }
 printf("\n");
}

아래 그림처럼  A[7] 부터 3개가 B[7] 부분으로 복사 되었고
C를 D에 이동시켰다.
이렇게 결과는 둘이 같다.



C언어 문자열 비교 : strcmp 함수

문자열을 비교하는 함수 strcmp 가 있다.
헤더는 include<string.h>
 
  •  strcmp(문자열 A, 문자열 B) 는 A와 B를 비교하는 것이다. 
    A>B 일때 양수
    A=B 일때 '0'
    A<B 일때 음수로 나온다.
 
이때 비교는 아스키 코드값으로 비교한다.
 만약 char A[4]: "abc" , char B[4] : "def" 면  A<B 이다.
 
#include<stdio.h>
int main()
{1
     char A[] = "Happy day";
     char B[] = "Happy day";
    
    if(A == B)
     {
         printf("두 문자열은 같다. \n");
      }
     else
      {
         printf("두 문자열은 같지 않다. \n");
       }
}
 
이렇게 되면 두 문자열은 같다고 나오지 않는다.
왜냐하면 if(A == B)는 주소값을 비교하는 것이기 때문이다.
문자열 A와 B는 주소값이 다르다.
 
그래서 문자열을 비교해주는 함수 strcmp가 필요한 것이다.
 
#include<stdio.h>
#include<string.h>
 
int main()
{
   char A[] = "Happy day";
   char B[] = "Happy day";
 
   if(strcmp(A,B) == 0)
   {
         printf("A와 B는 같은 문자열이다.\n");
    }
    else
           printf("A와 B는 같은 문자열이 아니다. \n");
}
 
이렇게 해야 같은 문자열이라는 경우가 나온다.

2016년 2월 20일 토요일

C언어 선택정렬 실습

배열을 정렬하는 방법은 여러가지가 있다.
그 중 선택 정렬이라는 것은 배열의 자리를 하나씩 비교하면서 자리를 바꾼다.
 오름차순으로 또는 내림차순으로 정렬하게 해주는 것이다.

우선 4개를 정한 상태에서 실습이다.
#include<stdio.h>
int main()
{
 int aa[4]={75,34,39,80};
 int i,k,change;

 printf("바뀌기전 %d %d %d %d \n",aa[0],aa[1],aa[2],aa[3]);
 for(i=0;i<4;i++)
  for(k=i+1;k<4;k++)
  {
   if(aa[i] > aa[k])
   {
    change = aa[i];
    aa[i] = aa[k];
    aa[k] = change;
   }
 
  }
 
  printf("바뀐후 %d %d %d %d \n", aa[0],aa[1],aa[2],aa[3]);
}
이렇게 예를 들수 있다.
좀더 심화로 포인터와 동적메모리 함수를 이용한 예를 보겠다.

#include<stdio.h>
#include<malloc.h>
int main()
{
 int *p;
 int s;
 int j,i,k,change;
 printf("정렬할 숫자의 갯수를 입력하세요.:");
 scanf_s("%d",&s);
 p=(int*)malloc(4*s);
 printf("정렬할 수를 입력하세요. :");
 for(j=0;j<s;j++)
 {
  scanf("%d",&*(p+j));
 }
 printf("정렬전 :");
 for(j=0;j<s;j++)
 {
  printf(" %d",*(p+j));
 }
 printf("\n");
 for(i=0;i<s;i++)
  for(k=i+1;k<s;k++)
  {
   if(*(p+i) > *(p+k))
   {
    change = *(p+i);
    *(p+i) = *(p+k);
    *(p+k) = change;
   }
 
  }
 printf("정렬 후 :");
  for(j=0;j<s;j++)
 {
  printf(" %d",*(p+j));
 }
 printf("\n");
}

이렇게 되면 사용자가 입력을 마음대로 정할 수도 있다.

2016년 2월 14일 일요일

C언어 열거형, 공용체

열거형 공용체 둘다 구조체와 사용법은 비슷하나 활용이 조금다르다.
구조체와 같이 많이 쓰는 문법은아니다.

열거형은 변수를 지정하면  변수들이 차례대로 0부터 지정이 되는 것이다.
사용법은
enum 열거형이름 { 변수1,변수2,변수3,...};

enum 열거형 이름 열거형 변수;

ex)
#include<stdio.h>
int main()
{
 enum aa{ 장미, 수국, 안개꽃};
 enum aa b;
 int c;
 printf("0~2을 입력하세요:");
 scanf("%d",&c);
 b = c;
 if(b == 장미)
  printf("장미입니다. \n", b);
 else if(b == 수국)
  printf("수국입니다. \n",b);
 else
  printf("안개꽃 입니다.\n",b);
}

공용체는 구초제와 거의 흡사하지만 메모리를 같이 쓰기 때문에 정수형과 문자형 변수를 같이 쓰면 겹쳐져서 오류가 날 수 있다.

공용체는
union 공용체형이름{
         데이터형 변수;
         데이터형  변수;
};

구조체와 같이 쓰는 방식은 같다.

2016년 2월 12일 금요일

C언어 고급포인터: 동적메모리 함수

배열을 사용자가 사용할 때 입력할 개수를 정해야 할 때가 있다.
배열의 메모리10000개 잡아놨을 때 aa[10000] 이중에 5개만 쓸 경우 나머지 9995개는 쓸데 없이 낭비가 되는 것이다. 메모리를 적절하게 사용하기위해
메모리를 미리 잡아두지않고, 필요할 때마다 확보하는 것을 동적메모리 확보라고 한다. 이때 사용하는 함수가 malloc()이다.  이때 헤더는 #include<malloc.h>이다.
malloc는
포인터 변수 = ( 포인터 변수의 데이터형*)malloc(포인터 변수의 데이터형 크키 * 필요한 크기)
ex)
include<stdio.h>
include<malloc.h>

int main()
{
     int *p;
     int i,hap=0;
     int cnt;

     printf("입력할 개수는?");
     scanf("%d",&cnt);  
    
     p=(int*)malloc(4*cnt);  // 데이터형의 크기를 모를시 4대신에 sizeof(int)를 사용 가능
    
     for(i=0;i<cnt;i++)
     {
          printf("%d 번째 숫자는?",i+1);
          scanf("%d",&*(p+i));
     }
    
     for(i=0;i<cnt;i++)
          hap= hap+ (p+i);

     printf("입력 숫자의 합 ==> %d \n", hap);

     free(p);
}
출처 : c언어 기초   우재남 저자   한빛미디어 출판사
이렇게 메모리를 유동적으로 만들 수 있다.

또한  malloc()를 사용 했다면 free() 함수도 같이 써서 사용 했던 메모리를 다시 운영체제에 반납한다. free()는 널(null)값을 넣는다는 뜻이다.

이외에도 calloc(), realloc()함수를 사용하는 경우도 있다.
malloc() 함수는 메모리를 확보한 후 초기화를 하지 않기 때문에 최초에는 쓰레기값이 들어가 있다. 처음부터 0으로 초기화된 메모리를 확보하고 싶다면 calloc()함수를 사용한다.

realloc()함수는 최초로 확보한 메모리 크기를 변경 할 때 사용한다.
포인터 변수 =(포인터 변수의 데이터형*)realloc(기본 포인터,포인터 변수의 데이터형 크기 * 필요한 크기)

realloc()는 반복문에 사용하여 계속 필요한 크기를 변경 할 수 있다. malloc or calloc은 한 번 정해지면 바꿀 수 없다.

2016년 2월 10일 수요일

C언어 STDOUT, STDIN 란

데이터 이동 수단인 stream
c언어에서 기본적으로 제공하는 스트림은 우리가 컴퓨터에 모니터, 마우스, 키보드등의 연결되어 있지 않은 개체들을 연결시켜주는 다리이다.

stdin 표준 입력 스트림
stdout 표준 출력 스트림
stderr표준 에러 스트림이다.

에러스트림과 표준 출력 스트림은 자세히 보면 모니터로 출력이 이뤄진다는 점에서 둘이 차이가 없다. 하지만 표준 에러 스트림의 출력 대상을 변경시킬 수 있어서, stdout 와 stderr의 용도를 구분할 수 있다.
scanf, printf 함수들도 표준 입출력 스트림을 사용한 함수들이다.

일반적으로 콘솔은 키보드와 모니터를의미하는데 콘솔 입풀력을 위한 스트림은 자동으로 생성되고 프로그램이 종료된면 자동으로 소멸된다.

서식화된 입출력 함수 printf, scanf 말고

문자열 입출력 함수
gets 표준입력장치(키보드)로부터 문자열을 입력 받는다. 숫자를 입력해도 문자열로 인식
puts 표준출력장치(모니터)에 문자열을 출력한다.

ex)
char aa[20];
gets(aa);
puts(aa);

문자 입출력 함수
셋 모두 키보드를 통해 문자 하나 입력 받는다.
getch() : 키보드를 통해 문자 하나 입력 받고 입력한 내용을 화면에 보여주지 않는다.
getche() : 입력한 내용을 화면에 보여준다.
getchar() : 사용자가 키보드로 엔터키를 누를 떄까지 입력한 것을 메모리에 모두 저장해 놓는다. 그중에 한 문자만 꺼낸다.

putchar, putch 표준출력장치(모니터)에 문자 하나를 출력한다.