#include<stdlib.h>
 
void* malloc(size_t size) //malloc 함수의 원형.
void* calloc(size_t elt_count, size_t elt_size) //calloc 함수의 원형.
↓↓↓↓↓↓↓↓↓↓
int *arr = (int*)calloc(size, sizeof(int));
int *arr = (int*)malloc(size*sizeof(int)); //둘 다 같은 결과.
 
 free함수
#include<stdlib.h>
 
void free(void* ptr) //free 함수의 원형.
- Heap 영역은 컴퓨터가 알아서 올리고 내리고 해주지 않는다. 그래서 메모리를 할당하는 것과
더불어 할당된 메모리를 해제하는 것도 프로그래머가 직접해 주어야 한다.
free함수로 힙영역의 메모리를 해주지 않으면 쌓이고쌓여서 메모리 부족현상이 일어나게 된다.
 
#include<stdio.h>
#include<stdlib.h>
 
int main(void)
{
       int size, i;
       int *arr;
 
       fputs("Input number!! to memory allocate: ", stdout);
       scanf("%d", &size);
 
       arr = (int*)calloc(size, sizeof(int));
       //arr = (int*)malloc(size*sizeof(int)); //위의 것과 같다.
       if(arr == NULL)
       {
              puts("Meomory allocation filed\n");
              exit(1); //비 정상적 종료를 의미.
       }
 
       for(i=0; i<size; i++)
              scanf("%d", &arr[i]);
 
      for(i=0; i<size; i++)
              printf("%d ", arr[i]);
 
       free(arr);
 
       return 0;
}


Stack Area = 지역변수, 매개변수가 올라가는 메모리 지역. (정적으로 할당)
- 함수호출이 끝나면 메모리상에서 없어짐.
 
Data Area = 전역변수, static변수가 올라가는 메모리 직역. (정적으로 할당)
- 프로그램이 종료되어야 메모리상에서 사라짐.
 
Heap Area = 프로그래머 할당 메모리 지역. (동적으로 할당)
- 데이터 영역이나 스택과 달리 프로그래머에 의해 필요한 만큼 메모리를 할당하고 해제할 수 있다.
 
※ Stack, Data 영역은 컴파일-타임에서 할당될 메모리의 크기가 결정되어야 한다.
※ Heap 영역은 런-타임에서 할당될 메모리의 크기가 결정되어야 한다.
break, return, exit(0 or 1)
break문은 반복문이나 제어문등을 종료할 때 쓰인다.
return문은 함수를 종료할 때 쓰인다.
exit문은 프로그램을 완전히 종료할 때 쓰인다. exit(1)이면 오류로 인해 프로그램 완전종료를 알린다.
break < return < exit 순으로 exit가 가장 크다.
return이 만약 void function(void)에 쓰이면 해당 함수만 종료하고 main함수로 돌아간다.
exit이 만약 void function(void)에 쓰이면 main함수가 아니라 다른 함수에 있더라도 프로그램을 완전 종료해 버린다.

Posted by scii
:

/* strcat을 이용한 파일 복사 프로그램 */

#include<stdio.h>
#include<string.h>

int main(int argc, char* argv[])
{
      int state;
      char buf[100];
      char bufCp[100];

      //file open
      FILE * file = fopen(argv[1], "rb");
      if(file == NULL){
             puts("file open error!\n");
            return 1;
      }

      //문서의 내용을 bufCp 배열에 저장.
      strcpy(bufCp, "");
      while(1)
      {
            fgets(buf, sizeof(buf), file);
            if(feof(file) != 0)
                  break;
            strcat(bufCp, buf);
      }

      //file close
      state = fclose(file);
      if(state != 0){
            puts("file close error!\n");
            return 1;
      }

      //file open
      file = fopen(argv[2], "wb");
      if(file == NULL){
            puts("file open error!\n");
            return 1;
      }

      //bufCp배열의 내용을 main함수 세번째 인자의 이름으로 파일로 만들어서 저장.
      fputs(bufCp, file);

      //file close
      state = fclose(file);
      if(state != 0){
            puts("file close error!\n");
            return 1;
      }

      return 0;
}


----------------------------------------------------------------------------------------------------------------
위의 코드와 결과는 같다.

/* FILE 구조체 변수 2개를 이용한 파일 복사 프로그램 */

#include<stdio.h>

int main(int argc, char* argv[])
{
      char c;
      int state1, state2;
      FILE *sour, *dest;

       //file open
      sour = fopen(argv[1], "rb");
      dest = fopen(argv[2], "wb");
      if(sour == NULL || dest == NULL){
            puts("file open error!\n");
            return 1;
      }

      while(1)
      {
            c = fgetc(sour); //sour가 가리키는 문서의 단어를 읽어들여와서 c에 저장.
            if(feof(sour) != 0)
                  break;
            fputc(c, dest); //c가 가지고 있는 문자를 dest가 가리키는 문서의 쓴다.
      }

       //file close
      state1 = fclose(sour);
      state2 = fclose(dest);
      if(state1 != 0 || state2 != 0){
            puts("file close error!\n");
            return 1;
      }

      return 0;
}

Posted by scii
:

#include<stdio.h>

main(void)
{
      int state;
      char buf[30];

      //file open
      FILE * file = fopen("c:\\test.txt", "wt");
      if(file == NULL){
            puts("file open error!");
            return 1;
      }

      //test.txt에 abcdefg12345를 입력.
      fputs("abcdefg12345", file);

      //file close
      state = fclose(file);
      if(state != 0){
            puts("file close error!");
            return 1;
      }

      //file open
      file = fopen("c:\\test.txt", "rt");
      if(file == NULL){
             puts("file open error!\n");
            return 1;
      }

      /* test.txt의 내용을 입력받아서 모니터에 출력. */
      fgets(buf, 7, file);         //7개만큼의 문자만 받아서 buf에 저장.
      puts(buf);//출력

      /* 파일 위치 지시자 이동 */
      fseek(file, 2, SEEK_CUR);         //현재 위치에서 +2만큼 간다.
      //fseek(file, -2, SEEK_CUR);         //현재 위치에서 -2만큼 간다.
      //fseek(file, 2, SEEK_SET);         //파일의 처음가서 +2만큼 간다.
      //fseek(file, -2, SEEK_END);         //파일의 끝으로 가서 -2만큼 간다.

      printf("%c \n", fgetc(file));         //파일 위치 지시자가 위치하고 있는 곳의 문자를 모니터에 출력.

      //file close
      state = fclose(file);
      if(state != 0){
            puts("file close error!\n");
            return 1;
      }

      return 0;
}


int fseek(FILE * stream, long offset, int wherefrom)
성공 시 0을, 실패 시 0이 아닌 값을 리턴.

stream이 가리키는 파일의 파일 위치 지시자를 시작 위치 wherefrom에서부터 offset 만큼 이동한다. 라고 이해하면 된다.

SEEK_SET(0) - 파일의 맨 앞으로 이동.
SEEK_CUR(1) - 이동하지 않음.
SEEK_END(2) - 파일의 끝으로 이동.

 SEEK_SET 과 rewind(file* stream)는 같음. 둘 다 파일위치 지시자 초기화.

참고로, "SEEK_END"의 이동하는 파일의 끝이란, 파일의 끝인 EOF를 의미한다.

Posted by scii
:

#include<stdio.h>

main()
{
      int state;
      char ch;

      /* 파일의 개방 */
      FILE * file = fopen("c:\\test.txt", "wb");
      if(file == NULL){
            printf("file open error!\n");
            return 1;
      }

      fputc('1', file);
      fputc((char)255, file); //(char)255로 파일에 쓰면 -1이 들어간다. char 255는 11111111이므로
      fputc('2', file);

      /* 파일의 종결 */
      state = fclose(file);
      if(state != 0){
            printf("file close error!\n");
            return 1;
       }

      /* 파일의 개방 */
      file = fopen("c:\\test.txt", "rb");
      if(file == NULL){
            printf("file open error!\n");
            return 1;
      }

      while(1)
      {
            ch=fgetc(file);
            if(feof(file) != 0) //file을 이용하여 FILE의 구조체 변수를 참조한다. 그래서 파일의 끝이 아니면 
                  break;            //0을 리턴해주고 파일의 끝을 만나면 0이 아닌 값을 리턴한다.
            fputc(ch, stdout);
            putchar('\n');
      }

      /* 파일의 종결 */
      state = fclose(file);
      if(state != 0){
            printf("file close error!\n");
            return 1;
       }

      return 0;
}


feof 함수는 전달되는 파일 포인터가 가리키는 FILE 구조체 변수를 참조한다. 
왜냐하면 그곳에는 파일의 끝에 도달했는지에 대한 정보가 존재하기 때문이다.

int feof(FILE * stream)
feof 함수는 호출 시 전달되는 파일 포인터가 가리키는 파일이 끝에 도달한 경우 0이 아닌 값을 리턴한다.

Posted by scii
:

#include<stdio.h>

main()
{
       char c1, c2;
       int state;
       int i,j;
       int a, b, c;

       /* 파일의 개방 */
       FILE* file = fopen("c:\\test.txt", "wt");
       if(file == NULL)
       {
              printf("file open error!\n");
              return 1;
       }

       //fprintf 함수를 이용하여 test.txt에다가 구구단을 쓰게 함.
       for(i=2; i<10; i++)
              for(j=1; j<10; j++)
                     fprintf(file, "%d * %d = %d\n", i, j, i*j);

       /* 파일의 종결 */
       state = fclose(file);
       if(state != 0)
       {
              printf("file close error!\n");
              return 1;
       }

       /* 파일의 개방 */
       file = fopen("c:\\test.txt", "rt");
       if(file == NULL)
       {
              printf("file open errer!\n");
              return 1;
       }

       // fscanf 함수를 이용하여 test.txt의 내용을 a,c1,b,c2,c에 받아옴.
       for(i=2; i<10; i++)
       {
              for(j=1; j<10; j++)
              {
                     fscanf(file, "%d %c %d %c %d", &a, &c1, &b, &c2, &c); //file의 내용을 받아서.
                     fprintf(stdout, "%d %c %d %c %d\n", a, c1, b, c2, c); //모니터로 출력.
              }
       }

       /* 파일의 종결 */
        state = fclose(file);
       if(state != 0)
       {
              printf("file close error\n");
              return 1;
       }
        return 0;
}


       - fprintf와 fscanf의 형식 -

fprintf(FILE* stream, const char* format, ...)
fscanf(FILE* stream, const char* format, ...)

일반적으로 데이터 입력, 출력의 형식은 일치해야한다.!!!

그리고, 파일을 스무번 개방하면 스무번 모두 꼭 필히 닫아줘야 한다.

Posted by scii
:

#include<stdio.h>

main()
{
       int state;
       /* 파일의 개방 */
       FILE * file = fopen("c:\\Jeon.txt", "wt"); //fopen함수는 인자로 파일의 접근모드와 개방모드를 가진다.
       if(file==NULL)                                        //리턴값은 구조체변수 포인터이다. 오류발생시 NULL포인터 리턴.
       {
              printf("file error! \n");
              return 1;
       }

       /* 파일의 종결 */
       state = fclose(file); //fclose함수는 인자로 구조체변수 포인터를 가진다.
       if(state != 0)           //리턴값은 int형이고 오류발생시 0이 아닌 값이 리턴됨.
       {
              printf("file close error!");
              return 1;
       }

       return 0;
}

파일의 개방 == 스트림 생성


                            - fopen 함수 -
FILE * file fopen(const char * filename, const char * mode)
성공 시 해당 파일의 파일포인터, 실패 시 NULL 포인터 리턴

fopen함수의 인자 접근 모드, 개방 모드

◆ 접근 모드 : 파일이 있는 곳을 말함. 접근할 수 있는 곳. 파일의 경로와 파일명!! 위에 \\를 두번 쓴 이유는 
\를 표현하기 위하여 \를 두번 썼다. 읽어들인땐 이렇다. c:\Jeon.txt

◆ 개방 모드 : 개방 모드는 파일 접근 모드+데이터 입력, 출력 모드를 말한다.
└ 파일 접근 모드 : 개방한 파일의 사용 용도를 결정짓는다.
read, write, append 파일을 읽을 것인지, 쓸 것인지, 추가할 것인지!!
(r, w, a, r+, w+, a+) 총 6가지가 있다. +붙은 것은 모두 입력, 출력을 할 수 있지만 버퍼를 계속 비워야 한다는 점
때문에 잘 쓰지 않는다. 하지만 쓰긴쓴다.!!

└ 데이터 입력, 출력 모드 : 데이터를 입력 혹은 출력하는 방식을 의미한다.
두 가지가 있는데 't' 와 'b' 이다. t는 텍스트 모드(text mode)이고, b는 2진 모드(binary mode)이다.
*텍스트 모드란 데이터 변환이 일어나는 입.출력 모드를 의미. (문자열과 같은 텍스트 기반의 데이터에 쓰는 것이 좋음)
*2진 모드란 아무런 데이터의 변환도 일으키지 않는 입.출력 모드를 의미. (영상이나 음성 데이터 입.출력에 쓰임)


fopen함수의 리턴타입

리턴 값은 FILE 구조체 변수의 포인터이다.(파일 포인터)
FILE 구조체 변수는 개방한 파일에 대한 여러 가지 정보를 지니는 변수이다.
(개방한 파일이 무엇인지, 파일 내에 존재하는 데이터를 어디까지 읽어들였는지, 파일의 끝에 도달했는지)




파일의 종결

                             - fclose 함수 -
int fclose(FILE * stream)
종료가 오류 없이 제대로 이뤄지면 0을 리턴.

파일의 정보를 지니는 FILE 구조체 변수의 포인터를 전달하면 해당 파일이 닫힌다. 즉 해당 스트림이 소멸된다.
스트림의 소멸이 제대로 이뤄지면 0을 리턴하므로, 이 결과를 통해서 오류의 유.무를 확인할 수 있다.

파일을 개방하였으면 파일을 꼭 닫아주어야 한다. 왜냐면, 프로그램이 종료되기 전에 예측지 못한 오류가 발생하면 데이터의
손실이 발생할 수 있기 때문이다.
*프로그램상에서 파일을 개방한 후에 파일의 사용이 끝나면 바로 닫아주는 것이 좋은 습관이다.

Posted by scii
:

#include<stdio.h> 

 

enum color {RED, GREEN=2, BLUE}; //enumeration(열거, 목록) 사용자자료형 정의
                                          //red, green, blue는 상수이다.
typedef enum color color;                 //이것들은 디폴트가 앞에서부터 0,1,2로 시작한다.
                                          //만약 green이 2라면 red는 0, green은 2, blue는 3이된다.
main()
{
        color c1, c2, c3;

 

        c1 = RED, c2 = GREEN, c3 = BLUE;

 

        printf("RED=%d, GREEN=%d, BLUE=%d\n", c1, c2,c3);
        printf("RED=%d, GREEN=%d, BLUE=%d\n", RED, GREEN, BLUE);

 

        return 0;
}

 


 

열거형의 정의는 두 가지 의미를 지닌다. 

 

1. color라는 이름의 자료형(열거형)정의. 

2. 상수의 선언.

 

----------------------------------------------------------------------------------------------------------------

 

#include<stdio.h> 

 

typedef enum days {MON,TUE,WED,THU,FRI,SAT,SUN} days; 

 

main()
{
        days day; //열거형 days의 변수 day를 생성.

 

        printf("Input a day(0:Monday ~ 6:Sunday) : ");
        scanf("%d", &day);

 

        switch(day)
        {
        case MON: //case 0: 이랑 똑같은 의미.
                printf("월요일입니다.\n");
                break;
        case TUE:
                printf("화요일입니다.\n");
                break;
        case WED:
                printf("수요일입니다.\n");
                break;
        case THU:
                printf("목요일입니다.\n");
                break;
        case FRI:
                printf("금요일입니다.\n");
                break;
        case SAT:
                printf("토요일입니다.\n");
                break;
        case SUN:
                printf("일요일입니다.\n");
                break;
        }

 

        return 0;

 


열거형을 사용하는 이유 

 

1. 열거형을 사용함으로써 변수가 지니는 값에 의미를 부여할 수 있다. 

2. 프로그램의 가독성이 높아진다. (가독성: 전체코드 쉽게 분석, 코드의 일부분만을 보고서도 의미 파악)

 

열거형은 switch문하고 비번하게 사용되어진다.

Posted by scii
:

공용체 union

Programming/C 2013. 2. 15. 01:19 |

#include<stdio.h>

 

union u_data //공용체 정의.
{
        int d1;
        double d2;
        char d3;
};

 

main()
{
        union u_data data; //공용체 변수 선언.

 

        data.d2=3.14; //이렇게 초기화를 하면 나머지 d1, d3는 아무 의미없는 값을 지니게 된다.
        printf("%d, %lf, %c \n", data.d1, data.d2, data.d3);

 

        data.d1=5;
        printf("%d, %lf, %c \n", data.d1, data.d2, data.d3);

 

        data.d3='a';
        printf("%d, %lf, %c \n", data.d1, data.d2, data.d3);

 

        return 0;
}

 

구조체와의 차이점은, 구조체 멤버는 모두 메모리 공간에 각각 할당되지만, 

공용체 멤버는 멤버중 가장 메모리를 많이 차지하는 멤버에 초점을 둬서 

메모리를 할당한다.

그래서 공용체는 공유한다는 뜻으로 공용체라 한다.

 

공용체는 일반적인 프로그래밍에서는 사용빈도가 낮고 하드웨어 프로그래밍에서 

사용빈도가 높다고 한다.

 

Posted by scii
: