20140721 - 포인터 주소

2014. 7. 21. 18:49

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

20140305 - 비주얼 환경변수

c언어 2014. 5. 26. 15:20 Posted by Owen.K

Visual Stdio 2010 환경변수 설정

1.실행파일 위치찾기

설치한 Visual Stidio2010 안에 cl.exe란 실행파일이 있는지 확인한다.

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin

경로를 찾아 복사를 한후에 윈도우키 + Pause Break를 동시에 눌리면 시스템 설정창이 나온다

시스템 속성에 들어가 환경변수를 눌려 위에 path에 경로를 추가해준다.

추가할때 문장 제일뒤에 ;를 한후 추가한다.(path가 없을 경후 새로만들기를 하면된다)

 

환경변수 설정후 cmd창에 cl 명령어를 치면 mspdb100.dll이 없다는 오류가 뜰것이다.

그러면 당황하지 말고 mspdb100.dll 파일의 경로를 찾아 환경변수에 추가를 해주자.

xp 사용자는 처음 경로를 추가하고 명령어를 입력했을 때 mspdb100.dll 오류가 안뜰 수가 있다 그러면 mspdb100.dll를 찾아 추가해주면 된다.

경로검색은 윈도우키 + e 를 눌리면 나온다. xp는 탐색기가 나올 것이고 win7은 내 컴퓨터가 나올 것이다.

그러면 Visual Stdio 2010 폴더로 들어가서  mspdb100.dll를 검색하면 2개가 나온다.

그 중에 Common7에 있는  mspdb100.dll 파일의 위치로 들어가면 된다.

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE 의 경로를 복사하여 환경변수 path에 추가를 해준다 그 뒤 cl 명령어를 치면 stdio.h 파일이 없다고 나올 것이다.

본인은 오류가 안뜬 관계로 경로 찾기와 추가부분만 설명으로 들어가겠다.

 

와 동일하게 검색을 하여 경로 복사 후 환경변수로 들어가 위에 있는 새로 만들기를 눌려 변수명은 INCLUDE 하고 경로를 추가한다.  

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include

Stdio.h 경로를 설정해주면 libcmt.lib파일이 오류가 뜬다  libcmt.lib 파일도 위와 동일하게 경로를 찾아

새로 만들기를 하여 경로를 추가해 준다.

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib

Kernel32.lib 파일은 Visual Stdio 2010 폴더에서는 검색이 안되므로 상위 폴더인 Program Files(x86)에서 찾아준다.

 C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib

Kernel32.lib 파일도 방금 만든 LIB에 경로를 추가해주면 환경변수 설정은 끝난다.

윈도우 xp에서는 win7에서 나온 검색보다 간단하게 나온다. 

환경변수를 끝낸 후 cmd 창에 cl 명령어를 입력하면 이런 화면이 나올 것이다.

이제 Visual Stdio 2010를 사용하지 않고도 메모장으로 작성된 파일을 명령 창에서 컴파일 할 수 있다.

 

%팁 : 컴파일을 하게되면 지정된 위치에 **.obj 파일과 **.exe 실행파일이 생성되는데

중간에 컴파일 되는 **.i 과 **.asm을 만들기 위해서는 뒤에 컴파일 명령어 뒤에

/P , /FA를 적어주면 **.i 과 **.asm이 만들어진다.

북 연결리스트


Book_DBopen


Book_DBclose


Book_FileIn


Book_FileOut


Book_DBsave

북 연결리스트


Book_Alldel 


LinkedList.c

LinkedList.h

main.c


향후 그림 설명으로 대체하겠음!!

Book_Insert 



Book_Print







가변인자 함수에 대한 이해


printf함수와 scanf함수의 사용 방법을 생각해 보면

첫 번째 전달인자인 문자열에 존재하는 서식문자의 수만큼 전달인자의 수도 증가한다.

printf, scanf 함수는 전달인자의 수가 제한되어 있지 않다는 특징이 있다.

num = Sum(4, 1, 2, 3, 4);                1, 2, 3, 4의 합

Sum과 같은 형태의 호출이 가능한 함수를 가변인자 함수라 한다. 이 함수의 모든 헤더파일은 stdarg.h에 선언되어 있다. 



가변인자 매개변수의 선언방법


main.c



전달된 인자들 추출해내는 방법

1단계 : 가변인자를 가리킬 수 있는 참조자를 선언한다.

2단계 : 참조자가 가변인자를 실제로 참조할 수 있도록 한다.

3단계 : 참조자를 통해 전달된 정보를 추출한다.

4단계 : 참조자가 더 이상 가변인자를 가리키지 않도록 해제한다.

1단계 : va_list

2단계 : va_start

3단계 : va_arg

4단계 : va_end



main1.c




연결리스트 : 도서관리


제목 - char[31]            |    caTitle

가격 - unsigned int       |    uiPrice

저자 - char                  |    caAuthor   

분류 - char                  |    caType

LinkedList.c

LinkedList.h

main.c


ListList.h에서는 Book구조체를 typedef형으로 선언 및 정의하고 있다.

LinkedList.c에서 Book_Stdin함수로 책 제목, 가격, 저자, 장르 등을 입력받고,

Book_Stdout으로 구조체 Book의 주소를 가지는 std가 가리키는 각각의 제목, 가격, 저자, 장르를

출력해낸다.

main.c에서 Book의 주소를 가지는 head에 Book 크기의 동적할당을 받고

Book_Stdin함수를 호출하여 인자로 head를 넘기고, Book_Stdout도 같이 호출하여 전과 동일하게 head를 인자로 넘겨준다. 


매크로 함수의 단점


정의하기가 정말 까다롭다.

디버깅하기가 쉽지 않다.

하지만 c++에서는 이런 단점을 보완할 만할 매크로가 존재한다.

inline이라는 함수인데 나중에 차차 배워 나가게 될 것이다.

위와는 관련 없지만 커맨드 창에서도 -D라는 것을 이용해서 매크로 정의를 할 수 있다.

main.c

위그림과 같이 소스 내에서 #define을 쓸 수 있는 방법도 있지만, 커맨드 창이나 linux환경에서 

-D를 사용해서 define을 할 수 있다.



파일의 분할


컴파일러는 파일 단위로 컴파일을 진행한다. 다른 파일의 정보를 참조하여 컴파일을 진행하지 않는다.



외부에 선언 및 정의되었다고 컴파일러에게 알려줘야한다.

extern int num;     //int 형 변수 num이 외부에 선언되어 있다.

extern은 int 형 변수 num이 외부에 선언되었음을 컴파일러에게 알릴 때 사용.



main2.c

test.c

extern은 위 그림과 같이 선언된 변수가 main파일에 없고 다른 곳에 존재함을 의미한다.

하지만, extern을 이용해서 main.c와 test.c파일에서 iNum이라는 하나의 변수를 공유할 수 있다.



다른 파일에서 접근을 못하게 하고 싶다면 static!

static선언은 다음의 의미를 가진다. 이 변수는 외부 파일에서의 접근을 허용하지 않는다.

접근범위는 파일 내부로 제한한다.

c언어에서 유일한 보안방법


main2.c

test.c

위 그림처럼 static은 전역으로는 쓸 수 있지만, 파일 내에서만 가능하기 때문에 main2.c와 test.c     두 개의 파일을 각각 따로 컴파일하면 잘 되지만, 두 파일을 함께 실행하면 에러가 발생한다.

c언어에서 유일한 보안방법이다. 이 방법은 함수에서도 통한다. 


서식에 따른 데이터 입출력 : fprintf, fscanf








임의 접근을 위한 '파일 위치 지시자'의 이동


파일 위치 지시자의 이동 : fseek - 파일포인터

#include <stdio.h>

int fseek(FILE * stream, long offset, int wherefrom);

->성공 시 0, 실패 시 0이 아닌 값을 반환


제일 앞을 기준으로 잡을 때 SEEK_SET(0)(왼쪽 기준)

현재 위치 기준으로 잡을 때 SEEK_CUR(1)(현재 위치)

파일 끝을 기준으로 잡을 때 SEEK_END(2)(오른쪽 기준)


현재 파일 위치 지시자의 위치는 : ftell

#include <stdio.h>

long ftell(FILE * stream);

-> 파일 위치 지시자의 위치 정보 반환


파일 위치 지시자의위치 정보를 반환하는데, 파일 위치 지시자가 첫 번째 바이트를 가리킬 경우 0을 반환하고, 세 번째 바이트를 가리킬 경우 2를 반환한다. 가장 앞 부분의 바이트 위치를 0으로 간주한다는 점에 주의.











ch25.메모리 관리와 메모리의 동적 할당

p.549 

malloc 함수의 사촌 뻘 되는 calloc 함수

#incluse <stdlib.h>

void * calloc(size_t elt_count, size_t elt_size);

-> 성공 시 할당된 메모리의 주소 값, 실패 시 NULL 반환


인자값을 이용해 파일복사하기

 

a.cb.cmain1.c

 

des.txt main2.csrc.txt


바이너리 데이터의 입출력 : fread, fwrite

바이너리 데이터의 입출력을 진행하는 함수이다.

size_t fread(void *buffer, size_t size, size_t count, FILE * stream);

->성공 시 전달인자 count, 실패 또는 파일의 끝 도달 시 count보다 작은 값 반환

fread((void *)buf, sizeof(int), 12, fp);    fp는 FILE 구조체 포인터

sizeof(int)크기의 데이터 12개를 fp로부터 읽어 들여 배열 buf에 저장해라.

fread 함수는 두 번째 전달인자와 세 번째 전달인자의 곱 바이트 크기만큼 데이터를 읽어 들이는 함수이다. 따라서 위의 fread함수호출을 통해서 int형 데이터 12개를 fp로부터 읽어서 배열 buf에 저장하게 된다.

이 함수는 실제로 읽어 들인 데이터의 갯수를 반환하는데(읽어 들인 바이트 수가 아니라 갯수이다.), sizeof(int) 크기의 데이터를 12개 읽어 들이는 경우이다. 함수의 호출이 성공을 하고 요청한 분량의 데이터가 모두 읽혀지면 12가 반환된다.

함수의 호출이 성공을 했지만 파일의 끝에 도달을 해서 12개를 모두 읽어 들이지 못했거나 오류가 발생하는 경우에는 12보다 작은 값이 반환된다.

size_t fwrite(const void * buffer, size_t size, size_t count, FILE * stream);

->성공 시 전달인자 count, 실패 시 count보다 작은 값 반환

int buf[7]={1, 2, 3, 4, 5, 6, 7};

fwrit((void*)buf, sizeof(int), 7, fp);

sizeof(int)크기의 데이터 7개를 buf로부터 읽어서 fp에 저장하라.

 

AA.binmain3.c



문제 ch24-1

 

ch24quiz1.c

 

ch24quiz2.c

 ch24quiz3.c


20140425 -

c언어 2014. 4. 25. 17:17 Posted by Owen.K

파일과 스트림 그리고 기본적인 파일의 입출력


파일에 저장되어 있는 데이터를 참조하길 원한다고 가정한다면 구현한 프로그램과 참조할 데이터가 저장되어 있는 파일 사이에 데이터가 이동할수 있는 다리를 놓는 일. 그 데이터 이동의 경로가 되는 다리를 가리켜 '스트림(stream)'이라 한다. 


fopen함수 호출을 통한 파일과의 스트림 형성과 FILE 구조체


스트림을 형성할 때는 호출하는 함수. 굳이 알 필요는 없다.



입력 스트림과 출력 스트림의 생성


스트림은 한 방향으로 흐르는 데이터의 흐름을 의미한다. 스트림은 데이터를 파일로부터 읽어 들이기 위한 입력 스트림과 데이터를 파일에 쓰기 위한 출력 스트림으로 구분된다. 스트림 형성을 위한 fopen 함수의 호출방법은 두 가지가 인자로 전달되어야 한다.

첫 번째 전달인자            스트림을 형성할 파일의 이름

두 번째 전달인자            형성하고자 하는 스트림의 종류

ex) FILE * fp = fopen("data.txt", "wt");        //출력 스트림의 형성

"파일 data.txt와 스트림을 형성하되 wt모드로 스트림을 형성해라!" -> wt모드의 스트림은 텍스트 데이터를 쓰기 위한 출력 스트림을 뜻한다.

위의 스트림은 출력 스트림이기 때문에 파일에 데이터를 쓸 수는 있어도 읽지는 못한다. 만일 파일로부터 데이터를 읽기 원한다면 입력 스트림을 형성해야 한다.


FILE * fp = fopen("data.txt", "rt");            //입력 스트림 형성

"파일 data.txt와 스트림을 형성하되 rt모드로 스트림을 형성하라!" -> rt모드의 스트림은 텍스트 데이터를 읽기 위한 입력 스트림을 뜻한다.


fopen함수의 호출을 통해서 파일과의 스트림이 형성되었을 때 파일이 오픈되었다라고 표현하는 것이 일반적이다.


파일에 데이터를 써보자.

FirstFileWrite.c

해당 파일이 생성되는데 실행방법에 따라, 실행환경 및 설정에 따라서 파일이 생성되는 위치는 달라진다. 그래서 경로를 포함해서 이름을 지정해도 된다.

ex) FILE * fp = fopen("C:\\Project\\data.txt", "wt");

이런식으로, 경로도 설정할 수 있다. 여튼 이렇게 스트림이 형성되면, fp는 파일 data.txt를 지칭하는 포인터가 된다. 

fputc('A', fp);

 fp가 지칭하는 파일 data.txt에 문자 A가 저장되고 B 등등이 저장된다. fclose함수가 호출되면 데이터는 저장이 되고, data.txt와 연결되었던 출력 스트림은 소멸된다. 저장된 data파일을 찾아 실행 해보자.


스트림의 소멸을 요청하는 fclose 함수


fclose 함수의 호출을 통해서 개방되었던 파일을 닫아줘야 하는 이유는,

운영체제가 할당한 자원의 반환

버퍼링 되었던 데이터의 출력

함수 호출을 통해 스트림의 형성을 요청하는 것은 프로그래머지만 실제로 스트림을 형성하는 주체는 운영체제이다. 그리고 스트림의 형성을 위해서 시스템의 자원(메모리 등)을 할당한다.  이 자원은 파일을 닫아주지 않으면 할당된 채로 남아있게 되어, 그만큼의 자원손실을 초래, 파일의 사용이 끝나는 즉시 자원을 반환해줘야 한다. 



fflush함수

출력버퍼를 비운다는 것은 출력버퍼에 저장된 데이터를 목적지로 전송한다는 의미

입력버퍼를 비운다는 것은 입력버퍼에 저장된 데이터를 소멸시킨다는 의미

fflush 함수는 출력버퍼를 비우는 함수.    fflush 함수는 입력버퍼를 대상으로 호출할 수 없다.

파일대상의 입력버퍼를 비워야한 하는 상황이라는 것이 특별히 존재하지 않는다.


파일로 부터 데이터를 읽기.


FirstFileRead



파일의 개방 모드

스트림을 구분하는 기준1 : 읽기 위한 스트림..쓰기 위한 스트림 앞서 언급했기 때문에 넘어가도록 하겠다.


개행은 환경마다 다 틀리다.

MS-DOS의 파일 내 개행            \r\n

Mac의 파일 내 개행                  \r

UNIX                                      \n


스트림을 구분하는 기준 : 텍스트 모드, 바이너리 모드


파일 입출력 함수의 기본

int fputc(int c, FILE * stream)                        //문자출력

int fgetc(FILE * stream)                                //문자입력

int fputs(const char * s, FILE * stream)        //문자열 출력

char * fgets(char *s, int n, FILE * stream);    //문자열 입력



fprintf(fp, "123");

fprintf(fp, "567");            123567이 출력되는데 출력이 되는 순서위치를 기억하고 있다.

123567..EOF

feof함수 기반의 파일복사 프로그램

feof(fp) 파일 끝이 아니면 0이 반환

파일 끝이면 0이 아닌 값을 반환

fclose(stdout)에 대한 설명


main1.c

fclose(stdin)에 대한 설명


main3.c


fopen 함수 호출을 통한 파일과의 스트림 형성과 FILE 구조체



위 함수의 첫 번째 인자로는 스트림을 형성할 파일의 이름을, 두 번째 인자로는 형성할 스트림의 종류에 대한 정보를 문자열의 형태로 전달한다. 이 함수는 해당 파일과의 스트림을 형성하고 스트림 정보를 FILE 구조체 변수에 담아서 그 변수의 주소 값을 반환한다.

FILE 구조체가 어떻게 정의되어 있는지 알 필요는 없다.


main2.c