void pointer 예제
Programming/C 2013. 9. 18. 03:32 |'Programming > C' 카테고리의 다른 글
scanf 함수의 리턴 값 (0) | 2013.03.27 |
---|---|
Bit Field (0) | 2013.02.15 |
Bit Mask (0) | 2013.02.15 |
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
난수 (Random Number) (0) | 2013.02.15 |
scanf 함수의 리턴 값 (0) | 2013.03.27 |
---|---|
Bit Field (0) | 2013.02.15 |
Bit Mask (0) | 2013.02.15 |
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
난수 (Random Number) (0) | 2013.02.15 |
이 하나의 예제로 scanf 함수의 리턴 값의 의미를 알 수 있다.
실행 결과
실행 결과로 알 수 있듯이, 서식문자에 합당한 값이 정확히 들어오면 그에 맞게 몇개가 정확히 들어왔는지 그 개수를 리턴해준다.
void pointer 예제 (0) | 2013.09.18 |
---|---|
Bit Field (0) | 2013.02.15 |
Bit Mask (0) | 2013.02.15 |
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
난수 (Random Number) (0) | 2013.02.15 |
비트(Bit) - 데이터(자료)를 표현하기 위한 최소 단위.
필드(Field) - 데이터(자료)를 처리하기 위한 최소 단위
비트 필드
: 비트 구조체는 비트들을 멤버로 가지는 구조체이며, 비트 필드(Bit Field) 라고도 부른다.
: 비트 하나로 2가지를 표현할 수 있다. (0, 1) 비트 두개로는 4가지를 표현할 수 있다.
즉, 비트 n개는... 로 표현이 된다.
비트 필드를 쓰는 이유
: 멤버가 가질 수 잇는 값의 범위가 아주 작다면 char보다 더 작은 단위로 비트를 쪼개어 알뜰히 정보를 기억시킬 수 있다. 이때 사용하는 것이 "비트 필드"이다.
기본 틀
: struct 이름
{
타입 멤버1 : 비트 수;
타입 멤버2 : 비트 수;
...
};
: 멤버의 타입은 정수만 가능하며, 부호의 여부에 따라 unsigned, signed int 둘 중 하나의 타입을 지정한다.
: 비트로 표현해야 할 정보는 수치값이라기보다는 일종의 기호나 표식인 경우가 많이 때문에 부호를 쓰는 경우는 드물다. 따라서 비트 필드의 멤버들은 통상 unsigned 타입이다.
: double 자료형이나 포인터, 배열은 비트 필드가 될 수 없다.
: A는 1비트를 사용함으로 0~1 까지 표현 가능하다.
: B와 C는 2비트를 사용함으로 0~3 까지 표현 가능하다.
: D는 3비트를 사용함으로 0~7 까지 표현 가능하다.
A(1bit) |
B (2Bit) |
C (2Bit) |
D (3Bit) |
1 |
1 1 |
0 0 |
1 1 1 |
※ C는 4를 넣어서 표현 한계인 3을 넘어버렸다. 그래서 오버플로우가 발생하여 경고 메시지가 뜨고 실행이 안되는 것이다.
C 변수는 0~3 까지 표현 가능하다는 사실을 알 수 있다.
비트 필드의 활용 예
void pointer 예제 (0) | 2013.09.18 |
---|---|
scanf 함수의 리턴 값 (0) | 2013.03.27 |
Bit Mask (0) | 2013.02.15 |
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
난수 (Random Number) (0) | 2013.02.15 |
비트 마스크
: 비트의 열에다가 씌울 수 있는 마스크란 뜻이다.
마스크를 씌우는 이유
: 마스크를 잘 정의하고 사용하면 비트 열의 특정부분을 뽑아 낼 수 있다.
비트 마스크를 언제 사용하는가
: 결정해야 할 동작방식이 한 두 가지라면, 일반적으로 구현해도 무리가 없다. 그러나 셋을 넘어간다면 프로그램이 복잡해진다는 단점이 생긴다.
만약 결정해야 할 동작방식이 열 가지라면, 열 개의 변수를 선언하고 열 개의 함수를 정의해야만 한다. 뿐만 아니라 main 함수에서는 총 열 번의 함수 호출을 해야만 한다.
따라서 이는 분명 문제가 된다. 그런데 이러한 단점의 해결을 위해 비트 마스크의 활용을 고려해 볼 수 있다.
※ 비트 마스크는 비트 연산자 중에 <<, >> 쉬프트 연산자를 활용할 수도 있겠다.
왜냐하면, << 연산자는 곱하기 2가 되고, >> 연산자는 나누기 2가 되기 때문이다. 주의할 점은 >> 연산자일 경우, 대상이 짝수일때만 정확한 값을 얻는다.
그리고, 여담이지만 비트 연산자는 정말 엄청나게 빠르다. 그래서 비트 단위 연산자는 곱셈과 나눗셈이라는 상대적으로 느린 연산을 대신할 수 있는 힌트가 된다.
비트 연산자 중 '|' 를 하였기때문에 비트의 변경이 이루어진다.
비트 마스크의 활용 예
이 소스코드에서의 가장 큰 특징은 "한번의 함수 호출로 둘 이상의 특성을 설정할 수 있다" 는 것이다.
"설정해야 할 정보가 많이 필요한 상황에서는 비트 마스크 방식을 선택하자."
scanf 함수의 리턴 값 (0) | 2013.03.27 |
---|---|
Bit Field (0) | 2013.02.15 |
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
난수 (Random Number) (0) | 2013.02.15 |
r+, w+ a+ 모드의 활용 (0) | 2013.02.15 |
■ clock 함수 : 성능을 확인.
#include <time.h>
clock_t clock(void);
성공 시 프로세스 타임 반환, 실패 시 형 변환하여 -1 반환.
: '프로세스 타임(process time)'이라는 것이 있다. 이는 프로그램이 실행된 이후로 지나간 시간을 의미한다.
그리고 이 값이 1씩 증가하는 시간의 간격(이를 가리켜 '클럭 틱(clock tick)'이라 한다)은 매크로 CLOCKS_PER_SEC를 통해서 확인할 수 있다. 따라서 이 매크로의 값이 1000이면 이는 다음과 같은 의미로 이어지게 된다.
◎ 클럭 틱은 0.001초에 한번씩 발생(증가)한다.
◎ 1초에 총 1000회의 클럭 틱이 발생한다.
◎ 1초가 지날 때마다 clock 함수의 반환 값은 1000씩 증가한다.
세 문장은 모두 동일한 의미를 담고 있다.
※ clock 함수는 성능 측정을 위해서 사용이 되기 때문에 알고리즘을 평가하는 수단으로 사용이 된다.
■ time 함수 : 날짜와 시간
: 1970년 1월 1일 00시 00분 00초 이후로 경과한 시간을 표현.
UTC(Coordinated Universal Time) : '협정 세계시'라 하여 국제 사회가 사용하는 과학적 시간의 표준. 그리고 대한민국의 시간은 협정 세계시보다 9시간이 빠르다.
ctime 함수 : time함수가 반환한 값을 가지고 현재의 날짜와 시간을 계산.
#include <time.h>
char* ctime(const time_t* tptr);
성공 시 현재 지역의 시간과 날짜를 문자열의 형태로, 실패 시 NULL반환.
■ localtime 함수 : 년, 월, 일, 시, 분, 초 정보를 정수의 형태로 얻을 수 있다.
#include <time.h>
struct tm* localtime(const time_t* t);
현재 지역의 시간과 날짜 정보를 담은 tm 구조체 변수의 포인터 반환.
:ctime 함수의 장점은 현재 시간을 보기 좋게 출력할 수 있다는데 있다. 하지만 시간 정보를 가지고 연산을 해야 하는 상황에서는 활용하기 힘든 함수이다. 한 예로 프로그램상에서 두 개의 시간 정보를 비교해야 하는 상황이 등장할 수 있는데, 이러한 경우에는 정수의 형태로 년, 월, 일 그리고 시, 분, 초 정보를 추출할 수 있어야 한다.
이럴 때 유용한 함수가 localtime 함수이다.
struct tm
{
int tm_sec; //초 [0, 59]
int tm_min; //분 [0, 59]
int tm_hour; //시 [0, 23]
int tm_mday; //일 [1, 31]
int tm_mon; //월 [0, 11]
int tm_year; //년 [1900년 이후를 기준으로]
int tm_wday; //요일 [0, 6]
int tm_yday; //일 [0, 365]
int tm_isdst; //써머타임 적용여부
};
# time 함수의 활용
Bit Field (0) | 2013.02.15 |
---|---|
Bit Mask (0) | 2013.02.15 |
난수 (Random Number) (0) | 2013.02.15 |
r+, w+ a+ 모드의 활용 (0) | 2013.02.15 |
표준 입력 및 출력 그리고 에러의 리다이렉션 (0) | 2013.02.15 |
rand
#include <stdlib.h>
int rand(void)
의사 난수(Pseudo-Random Number) 반환.
호출될 때마다 난수가 반환되는 이 함수 역시 수학 관련 함수이다. 다만 함수가 정수와 관련 있기 때문에 stdlib.h에 선언되어 있는 상태이다.
이 소스코드는 몇 번을 실행해도 달라지지 않는다. rand함수가 난수를 발생시키지만, 생성되는 패턴이 항상 동일하기 때문에 수학에서 말하는 진정한 난수는 아니다. 그래서 rand함수가 반환하는 수를 가리켜 "의사난수"라 한다.
※ rand 함수가 동일한 패턴의 난수를 발생시키는 이유는 난수를 생성하는 기초 정보인 씨드(seed) 값이 항상 동일하기 때문이다.
srand
#include <stdlib.h>
void srand(unsigned seed)
반환하지 않는다.
위 함수를 호출하면서 정수를 전달하면, 전달된 정수로 씨드 값이 변경된다 따라서 이 함수를 통해서 씨드 값을 변경시키면 rand 함수의 난수 생성 패턴은 달라진다.
■ [난수의 범위 제한] ■
난수의 범위 20~70사이의 값
- 조 건 -
§ rand 함수가 최소값을 반환하면 이 값은 20 정도가 되어야 한다.
§ rand 함수가 최대값을 반환하면 이 값은 70 정도가 되어야 한다.
§ rand 함수가 중간 크기의 값을 반환하면, 이 값은 20과 70의 중간 크기인 45 정도의 값이 되어야 한다.
이는 rand 함수가 반환하는 값의 크기 분포 비율을 거의 그대로 유지하기 위함이다.
rand 함수의 반환 값을 RAND_MAX로 나누되 double형 나눗셈을 진행하고 있다. 따라서 나눗셈의 결과는 0 이상 1 이하의 실수가 된다.
이어서 변수 diff에 저장된 값 50을 곱하니, 연산의 결과는 최대 0 이상 50 이하의 실수가 된다.
이 결과에다 RAND_MIN을 더하니 20이상 70이하의 값이 된다.
참고로 다음과 같이 문장을 구성해도 20이상 70이하의 값을 얻을 수는 있다. 문제는 rand 함수가 반환하는 값의 크기 분포를 유지하지 못한다는데 있다. 따라서 문제의 조건을 만족시키려면 22행과 같이 문장을 구성해야 한다.
rand2070 = (rand() % diff+1) + RND_MIN;
이 문장과 위의 코드 22행의 문장은 지정한 범위 내의 난수 생성에 사용되는 대표적인 문장들이다.
■ [난수의 범위 제한] ■
난수의 범위가 10이상 100이하 중에서 3의 배수가 되게 하라.
단 값의 크기 분포 비율이 rand 함수가 반환하는 값의 크기 분포 비율과 유사해야 한다.
22행 23행은 반환 값을 rnd3div 보다 작은 3의 배수로 변화하는 방법이다. 22행의 정수형 나눗셈에 의해서 소수점 이하의 부분은 잘려나간다. 그리고 이렇게 소수점 이하가 잘려나간 정수에 3을 곱하기 때문에 RND_MAX를 넘지 않는 3의 배수가 된다.
Bit Mask (0) | 2013.02.15 |
---|---|
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
r+, w+ a+ 모드의 활용 (0) | 2013.02.15 |
표준 입력 및 출력 그리고 에러의 리다이렉션 (0) | 2013.02.15 |
fsetpos, fgetpos 함수 (0) | 2013.02.15 |
w+ 모드로 개방한 파일의 입출력 방법의 예.
시간과 날짜 관련 함수들 (0) | 2013.02.15 |
---|---|
난수 (Random Number) (0) | 2013.02.15 |
표준 입력 및 출력 그리고 에러의 리다이렉션 (0) | 2013.02.15 |
fsetpos, fgetpos 함수 (0) | 2013.02.15 |
ftell함수를 이용한 파일 사이즈 알아내는 프로그램. (0) | 2013.02.15 |
■ 리다이렉션이란 입력과 출력의 대상을 변경시키는 것이다.
※ 리다이렉션은 windows의 DOS와 같은 프로그램에서 제공하는 기능이기 때문에 운영체제 별로 그 방식에 있어서 약간의 차이를 보인다. 때문에 Linux 콘솔에서의 리다이렉션 방법과 DOS에서의 리다이렉션 방법에는 차이가 있다.
■ DOS상에서의 리다이렉션.
- 키보드로부터 문자열을 읽어 들여서 출력하는 예제 -
stdout을 리다이렉션 시킬 때에는 기호 >를 활용한다.
review.exe > review.txt 명령의 의미
: "review.exe를 실행하되 이 프로그램의 표준 출력(stdout)을 파일 review.txt로 리다이렉션 시키라" 라는 뜻이 된다.
stdin을 리다이렉션 시킬 때에는 기호 < 를 활용한다.
review.exe < review.txt > reCopy.txt 명령의 의미
: "review.exe를 실행하되 이 프로그램의 표준 입력(stdin)은 review.txt로 리다이렉션 시키고, 표준 출력(stdout)은 파일 reCopy.txt로 리다이렉션 시켜라" 라는 뜻이 된다.
■ stdout과 stderr을 동시에 제공하는 이유
표준 에러의 리다이렉션에는 2> 가 사용된다.
이렇게 표준 에러를 활용하면 에러메시지는 log.txt 파일로 보내지고 나머지 stdout(표준 출력)은 화면상에 나오게끔 할 수 있다.
그래서 프로그램을 사용하다 오류가 나면 표준 에러를 파일문서로 만들어 어디에서 에러가 났는지 확인할 수 있다.
난수 (Random Number) (0) | 2013.02.15 |
---|---|
r+, w+ a+ 모드의 활용 (0) | 2013.02.15 |
fsetpos, fgetpos 함수 (0) | 2013.02.15 |
ftell함수를 이용한 파일 사이즈 알아내는 프로그램. (0) | 2013.02.15 |
fread, fwrite 함수 (1) | 2013.02.15 |